Skip to content

feat(portal-app-shell, portal-framework-ui, portal-framework-auth): implement bootup and page loading screens with animations#482

Merged
pcfreak30 merged 1 commit intodevelopfrom
libs/portal-plugin-dashboard
Sep 1, 2025
Merged

feat(portal-app-shell, portal-framework-ui, portal-framework-auth): implement bootup and page loading screens with animations#482
pcfreak30 merged 1 commit intodevelopfrom
libs/portal-plugin-dashboard

Conversation

@pcfreak30
Copy link
Copy Markdown
Member

@pcfreak30 pcfreak30 commented Sep 1, 2025

  • Bootup screen:

    • Full-page overlay with animated progress bar
    • Random cycling technical messages
    • App logo integration
    • Automatic removal when app ready
    • SCSS styles with theme variables
  • Page loading:

    • Centered spinner component
    • Themed background overlay
    • Reusable React component
    • Integrated with auth flows
  • Infrastructure:

    • Global types for loading API
    • sass-embedded dependency
    • Vite build optimizations
    • Framework-wide exports

Summary by CodeRabbit

  • New Features

    • Full-screen startup loading overlay with progress bar, centered logo and rotating status messages that fades into the app.
  • UI Improvements

    • Reusable, accessible Loading component used across the app (including login checks and remote loads).
    • API key field now selects all text on click; refined loading skeleton visuals and improved accessibility labels.
  • Chores

    • Added Sass tooling to support loader styles.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Sep 1, 2025

⚠️ No Changeset found

Latest commit: 1ee68ed

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Sep 1, 2025

Walkthrough

Adds a host-level startup loading overlay (HTML/SCSS/TS), loads a loader script as its own chunk, introduces a reusable accessible Loading React component (exported) and integrates it into lazy-loading and auth flows; plus small formatting/import reorders across dashboard and config files.

Changes

Cohort / File(s) Summary
App shell loader integration
apps/portal-app-shell/index.html, apps/portal-app-shell/src/loader.scss, apps/portal-app-shell/src/loader.ts, apps/portal-app-shell/package.json, libs/portal-framework-core/src/vite/plugin.ts
Adds full-screen loading overlay and progress bar driven by :root.is-loading; new loader.ts cycles status messages and removes overlay on transition end; includes loader.scss; adds sass-embedded devDependency; Vite host build creates a loader manualChunk for loader.ts.
Loading component addition & wiring
libs/portal-framework-ui/src/components/Loading.tsx, libs/portal-framework-ui/src/index.ts, libs/portal-framework-ui/src/components/app/AppComponent.tsx, libs/portal-framework-auth/src/ui/components/index/AuthedIndex.tsx
Introduces accessible Loading component (named export) and re-exports it; AppComponent passes it as LoadingComponent to remote loader; AuthedIndex uses <Loading aria-label="Checking login status" /> instead of inline text.
Auth register form tweaks
libs/portal-framework-auth/src/ui/forms/register.tsx
Reorders autocomplete properties and className token order; no behavior changes.
Dashboard UI small fixes
libs/portal-plugin-dashboard/src/ui/components/ApiKeyAlertMessage.tsx, .../EmailVerificationBanner.tsx, .../dialogs/deleteAccount.tsx, .../dialogs/updatePassword.tsx, .../forms/updateEmail.tsx
ClassName reorderings, textarea select-on-click added, import/order and formatting tweaks; logic unchanged.
Tailwind config import order
libs/portal-framework-ui-core/config/tailwind.config.ts
Moves tailwindcss-animate import to after tailwind-scrollbar; no behavioral change.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant B as Browser
  participant H as index.html
  participant L as loader.ts
  participant A as app index.tsx

  B->>H: Load document & resources
  H->>B: Render .loading-overlay + `#root` (hidden via .is-loading)
  H-->>L: Execute loader.ts (start messages, listen for transitionend)
  H-->>A: Execute app bootstrap (index.tsx)
  A->>H: Remove `.is-loading` from :root when app ready
  H->>L: Overlay opacity transitions out
  L->>H: On transitionend (opacity != 1) remove overlay, clear intervals
  B->>A: User interacts with now-visible app
Loading
sequenceDiagram
  autonumber
  participant U as User
  participant AC as AppComponent
  participant RC as RemoteLoader
  participant L as Loading component

  U->>AC: Navigate to remote feature
  AC->>RC: getLazyComponent({ ..., LoadingComponent: L })
  RC-->>U: Show <Loading /> placeholder
  RC->>RC: Fetch remote bundle
  RC-->>AC: Resolve component
  AC-->>U: Render remote component
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

A tiny rabbit hums a tune,
Spinner bright beneath the moon,
Messages hop, then fade away,
Overlay bows to app's first sway.
I wiggle whiskers — launch, hooray! 🥕


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3d8d0f5 and 1ee68ed.

⛔ Files ignored due to path filters (3)
  • libs/portal-sdk/src/account/generated/accountAPI.schemas.ts is excluded by !**/generated/**
  • libs/portal-sdk/src/account/generated/default.ts is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • apps/portal-app-shell/index.html (1 hunks)
  • apps/portal-app-shell/package.json (1 hunks)
  • apps/portal-app-shell/src/loader.scss (1 hunks)
  • apps/portal-app-shell/src/loader.ts (1 hunks)
  • libs/portal-framework-auth/src/ui/components/index/AuthedIndex.tsx (2 hunks)
  • libs/portal-framework-auth/src/ui/forms/register.tsx (1 hunks)
  • libs/portal-framework-core/src/vite/plugin.ts (1 hunks)
  • libs/portal-framework-ui-core/config/tailwind.config.ts (1 hunks)
  • libs/portal-framework-ui/src/components/Loading.tsx (1 hunks)
  • libs/portal-framework-ui/src/components/app/AppComponent.tsx (3 hunks)
  • libs/portal-framework-ui/src/index.ts (1 hunks)
  • libs/portal-plugin-dashboard/src/ui/components/ApiKeyAlertMessage.tsx (1 hunks)
  • libs/portal-plugin-dashboard/src/ui/components/EmailVerificationBanner.tsx (1 hunks)
  • libs/portal-plugin-dashboard/src/ui/dialogs/deleteAccount.tsx (2 hunks)
  • libs/portal-plugin-dashboard/src/ui/dialogs/updatePassword.tsx (2 hunks)
  • libs/portal-plugin-dashboard/src/ui/forms/updateEmail.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • libs/portal-framework-ui-core/config/tailwind.config.ts
  • libs/portal-plugin-dashboard/src/ui/components/EmailVerificationBanner.tsx
🚧 Files skipped from review as they are similar to previous changes (14)
  • libs/portal-plugin-dashboard/src/ui/dialogs/updatePassword.tsx
  • apps/portal-app-shell/package.json
  • libs/portal-framework-ui/src/index.ts
  • apps/portal-app-shell/src/loader.scss
  • libs/portal-plugin-dashboard/src/ui/forms/updateEmail.tsx
  • libs/portal-framework-auth/src/ui/components/index/AuthedIndex.tsx
  • libs/portal-plugin-dashboard/src/ui/components/ApiKeyAlertMessage.tsx
  • libs/portal-plugin-dashboard/src/ui/dialogs/deleteAccount.tsx
  • apps/portal-app-shell/src/loader.ts
  • libs/portal-framework-core/src/vite/plugin.ts
  • apps/portal-app-shell/index.html
  • libs/portal-framework-ui/src/components/Loading.tsx
  • libs/portal-framework-auth/src/ui/forms/register.tsx
  • libs/portal-framework-ui/src/components/app/AppComponent.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch libs/portal-plugin-dashboard

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (10)
libs/portal-framework-core/src/vite/plugin.ts (1)

272-279: Optional: tighten manualChunks matcher to prevent future false positives
A search shows only apps/portal-app-shell/src/loader.ts matches loader.ts today, so no conflicts now. However, narrowing the check to only files named exactly “loader.ts” under src/ and excluding node_modules will guard against any similarly named files later:

           manualChunks:
             opts.type === "host"
               ? (id: string) => {
-                  if (id.includes("loader.ts")) {
-                    return "loader";
-                  }
+                  if (
+                    !id.includes("node_modules") &&
+                    /(?:^|[\\/])src[\\/].*?[\\/]?loader\.ts$/.test(id)
+                  ) {
+                    return "loader";
+                  }
               }
               : undefined,
libs/portal-plugin-dashboard/src/ui/dialogs/updatePassword.tsx (1)

3-4: Keep void-return onSuccess and tighten hook typing

DialogConfig.onSuccess is defined as (response: TResponse, values: TRequest) => void, and existing dialogs all use a void return, so no boolean is needed to auto-close—keeping onSuccess: () => void 0 is correct. Introduce a strongly-typed hook instead of any, for example:

type UpdatePasswordHook = (args: {
  currentPassword: string;
  password: string;
}) => Promise<void>;

and apply this type to your updatePassword hook.

apps/portal-app-shell/src/global.d.ts (1)

1-7: Make window.signalAppReady optional to avoid typing friction in hosts without the loader

Keeps strong typing where present while not forcing stubs in non-loader contexts.

 declare global {
   interface Window {
-    signalAppReady: () => void;
+    /** Set by the startup loader; call when the app is ready to hide the overlay. */
+    signalAppReady?: () => void;
   }
 }
libs/portal-plugin-dashboard/src/ui/dialogs/deleteAccount.tsx (1)

23-26: Preserve original error as cause; prefer structured logging

Helps debugging while keeping the user-facing message stable.

-        console.error("Failed to delete account:", error);
-        throw new Error(
-          "Failed to delete account. Please try again or contact support.",
-        );
+        console.error("Failed to delete account", { error });
+        throw new Error(
+          "Failed to delete account. Please try again or contact support.",
+          // TS 4.9+ / ES2022 ErrorOptions
+          { cause: error as unknown }
+        );
libs/portal-framework-ui/src/components/Loading.tsx (1)

1-29: Add ARIA status and motion-reduce-friendly spinner

Improves accessibility announcements and respects reduced motion preferences. Minor nit: transition-opacity won’t animate without toggling opacity classes.

-    <div
-      className={`bg-background fixed inset-0 z-50 transition-opacity duration-300`}>
+    <div
+      role="status"
+      aria-live="polite"
+      aria-busy="true"
+      className="bg-background fixed inset-0 z-50 transition-opacity duration-300">
@@
-            <svg
-              className="text-primary-foreground h-8 w-8 animate-spin"
+            <svg
+              className="text-primary-foreground h-8 w-8 motion-safe:animate-spin motion-reduce:animate-none"
               fill="currentColor"
               viewBox="0 0 24 24">
libs/portal-plugin-dashboard/src/ui/components/ApiKeyAlertMessage.tsx (2)

9-9: Class ordering improved for better consistency.

The reordering of classes from "space-y-2 relative w-full" to "relative w-full space-y-2" follows a more logical pattern (positioning → sizing → spacing) which improves maintainability.


18-18: Class ordering improved for consistency.

The reordering from "text-sm text-destructive" to "text-destructive text-sm" follows semantic color → size pattern which is more consistent with design system conventions.

apps/portal-app-shell/src/loader.scss (1)

28-36: Progress bar implementation with potential animation concern.

The progress bar setup looks good, but there's a potential issue with the animation definition:

Line 35 has both animation-name and animation shorthand properties. The animation shorthand will override animation-name, making line 34 redundant.

 .progress-bar {
-  animation-name: progress-animation;
   animation: progress-animation 3s ease-in-out infinite;
 }
libs/portal-framework-ui/src/index.ts (1)

10-10: Re-export looks good; keep an eye on default vs named export.

If Loading.tsx only has a default export, this star re-export won’t expose it. In that case, switch to a named alias re-export.

-export * from "./components/Loading";
+export { default as Loading } from "./components/Loading";
libs/portal-framework-auth/src/ui/components/index/AuthedIndex.tsx (1)

10-10: Small a11y improvement for screen readers.

If supported, pass an accessible label to announce the auth check status.

-      loading={<Loading />}
+      loading={<Loading aria-label="Checking login status" />}

If Loading doesn’t forward props, consider adding role="status" and aria-live="polite" inside the component.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 89d48d7 and 334b145.

⛔ Files ignored due to path filters (3)
  • libs/portal-sdk/src/account/generated/accountAPI.schemas.ts is excluded by !**/generated/**
  • libs/portal-sdk/src/account/generated/default.ts is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • apps/portal-app-shell/index.html (1 hunks)
  • apps/portal-app-shell/package.json (1 hunks)
  • apps/portal-app-shell/src/global.d.ts (1 hunks)
  • apps/portal-app-shell/src/loader.scss (1 hunks)
  • apps/portal-app-shell/src/loader.ts (1 hunks)
  • libs/portal-framework-auth/src/ui/components/index/AuthedIndex.tsx (2 hunks)
  • libs/portal-framework-auth/src/ui/forms/register.tsx (1 hunks)
  • libs/portal-framework-core/src/vite/plugin.ts (1 hunks)
  • libs/portal-framework-ui-core/config/tailwind.config.ts (1 hunks)
  • libs/portal-framework-ui/src/components/Loading.tsx (1 hunks)
  • libs/portal-framework-ui/src/components/app/AppComponent.tsx (3 hunks)
  • libs/portal-framework-ui/src/index.ts (1 hunks)
  • libs/portal-plugin-dashboard/src/ui/components/ApiKeyAlertMessage.tsx (1 hunks)
  • libs/portal-plugin-dashboard/src/ui/components/EmailVerificationBanner.tsx (1 hunks)
  • libs/portal-plugin-dashboard/src/ui/dialogs/deleteAccount.tsx (2 hunks)
  • libs/portal-plugin-dashboard/src/ui/dialogs/updatePassword.tsx (2 hunks)
  • libs/portal-plugin-dashboard/src/ui/forms/updateEmail.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
libs/portal-framework-auth/src/ui/components/index/AuthedIndex.tsx (1)
libs/portal-framework-ui/src/components/Loading.tsx (1)
  • Loading (29-29)
libs/portal-framework-ui/src/components/app/AppComponent.tsx (2)
libs/portal-framework-core/src/index.ts (1)
  • defaultRemoteOptions (28-28)
libs/portal-framework-ui/src/components/Loading.tsx (1)
  • Loading (29-29)
libs/portal-framework-auth/src/ui/forms/register.tsx (1)
go/portal-dashboard/build/static/js/index-78XEzhAn.js (1)
  • FormFieldType (326-341)
🔇 Additional comments (24)
apps/portal-app-shell/package.json (1)

35-35: SCSS tooling dependency looks good.

Adding sass-embedded for the loader.scss pipeline is appropriate here. No issues.

libs/portal-plugin-dashboard/src/ui/components/EmailVerificationBanner.tsx (1)

9-9: Import order change is safe.

Reordering lucide-react imports has no functional impact. All good.

libs/portal-framework-ui-core/config/tailwind.config.ts (1)

4-4: Import move is fine.

Import order change doesn’t affect plugin execution (plugins array order is unchanged). Looks good.

libs/portal-plugin-dashboard/src/ui/forms/updateEmail.tsx (1)

2-2: No-op rearrangement; fine to keep.

Whitespace and property order changes don’t alter behavior. Good to go.

Also applies to: 25-25

libs/portal-framework-auth/src/ui/forms/register.tsx (1)

22-30: LGTM on autocomplete and class reordering

The autocomplete tokens and presentational tweaks look correct and non-functional.

Also applies to: 32-40, 42-47, 49-54, 56-61, 64-76

libs/portal-plugin-dashboard/src/ui/dialogs/deleteAccount.tsx (1)

2-2: Import reordering is fine

No functional impact.

libs/portal-framework-ui/src/components/app/AppComponent.tsx (3)

332-336: LGTM! Enhanced remote component loading with consistent Loading component.

The addition of LoadingComponent: Loading to the options object improves the user experience by providing a consistent loading state while remote components are being fetched. This change maintains backward compatibility while enhancing the loading experience.


356-360: Minor UI improvements to skeleton loader.

The reordering of Tailwind CSS classes and spacing adjustments improve the visual hierarchy and consistency of the loading skeleton. These changes maintain the same functionality while providing better visual presentation.


34-34: No action needed: Loading import is valid

Verified that libs/portal-framework-ui/src/components/Loading.tsx defines and exports the Loading component (export { Loading }) and that src/index.ts re-exports it (export * from "./components/Loading"), so the import in AppComponent (import { Loading } from "@/components/Loading") resolves correctly.

libs/portal-plugin-dashboard/src/ui/components/ApiKeyAlertMessage.tsx (1)

12-13: Enhanced textarea styling and usability.

The comprehensive className update improves the visual appearance and usability:

  • min-h-[60px] ensures consistent minimum height
  • resize-none overflow-hidden prevents layout issues
  • break-all ensures long API keys wrap properly
  • onClick handler with select() provides better UX for copying
apps/portal-app-shell/src/loader.scss (3)

1-18: Well-structured loading state management with comprehensive theme variables.

The CSS structure effectively manages the loading state by:

  • Using :root.is-loading to hide the main app and define theme variables
  • Providing comprehensive theme variables for consistent styling across the loading UI
  • The color values appear to follow a cohesive dark theme design system

20-26: Smooth loading overlay transition implementation.

The transition logic is well-implemented:

  • Uses :root:not(.is-loading) selector for clean state management
  • 0.5s ease-out transition provides smooth fade-out
  • pointer-events: none prevents interaction during fade-out

38-41: Clarify Tailwind animation-duration utility
animate-duration-3000 isn’t a built-in Tailwind CSS class; use JIT arbitrary syntax like animate-duration-[3000ms] or [animation-duration:3s], or install/configure a plugin (e.g., tailwindcss-animated) to enable animate-duration-* utilities. Confirm your tailwind.config.js/plugins setup.

apps/portal-app-shell/src/loader.ts (4)

1-21: Well-architected AppLoader class with proper encapsulation.

The class design is excellent:

  • Private fields properly encapsulated with # syntax
  • Comprehensive message list with technical, relevant content
  • Constructor initiates the loading sequence immediately
  • Good separation of concerns between message cycling and overlay management

23-31: Effective random message selection with duplication prevention.

The algorithm ensures non-repeating messages by tracking the previous index, which provides better UX by preventing the same message from appearing consecutively.


33-47: Smooth message transition with proper timing.

The fade-out/fade-in sequence with 250ms delay provides smooth visual transitions between loading messages. The completion check prevents unnecessary operations.


82-90: Proper initialization and lifecycle management.

The message cycling setup and DOMContentLoaded event handler ensure the loader starts at the right time with appropriate intervals.

apps/portal-app-shell/index.html (6)

2-2: Loading state initialization properly configured.

The is-loading class on the root HTML element enables the CSS-based loading state management defined in loader.scss.


6-6: Loader stylesheet integration.

The stylesheet link properly includes the SCSS loader styles that will be compiled during the build process.


11-16: Well-structured loading overlay layout.

The overlay structure is comprehensive:

  • Fixed positioning with high z-index for proper layering
  • Progress container with proper positioning
  • Centered content layout with flexbox

14-14: Verify Tailwind class validity for progress bar animation.

The class animate-duration-3000 may not be a standard Tailwind CSS class. Based on my search, standard Tailwind uses duration-{value} for transition durations, not animate-duration-{value} for animations.

Since this appears to be a non-standard class, consider using the CSS animation defined in loader.scss or a standard Tailwind animation class:

-      <div class="progress-bar w-full h-full bg-primary animate-duration-3000"></div>
+      <div class="progress-bar w-full h-full bg-primary"></div>

The CSS in loader.scss already defines the animation duration (3s), so the HTML class may be redundant or conflicting.


17-63: Comprehensive loading UI with logo and messaging.

The loading interface is well-designed:

  • Proper logo implementation with inline SVG
  • Clear loading messaging structure
  • Good use of semantic HTML and Tailwind classes
  • Proper accessibility considerations with descriptive text

65-66: Dual script loading for main app and loader.

Loading both the main application and loader scripts ensures proper initialization sequence. The loader will manage the overlay lifecycle while the main app initializes.

libs/portal-framework-auth/src/ui/components/index/AuthedIndex.tsx (1)

1-1: No action required — Loading is a named export and re-exported correctly.
The component file exports { Loading } (line 29) and the package root re-exports it (line 10), so your import is valid.

@pcfreak30 pcfreak30 force-pushed the libs/portal-plugin-dashboard branch from 334b145 to 3d8d0f5 Compare September 1, 2025 02:48
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
libs/portal-framework-ui/src/components/Loading.tsx (6)

5-11: Don’t clobber consumer className; move spread first and merge classes.

Current ordering overrides any props.className and allows consumers to override role/aria-*. Reorder and merge to keep a11y semantics fixed while allowing style extension.

-      role="status"
-      aria-live="polite"
-      aria-busy="true"
-      {...props}
-      className="bg-background fixed inset-0 z-50 transition-opacity duration-300">
+      {...rest}
+      role="status"
+      aria-busy="true"
+      className={`bg-background fixed inset-0 z-50 transition-opacity duration-300 ${className ?? ""}`}>

15-18: Mark the spinner SVG as decorative for screen readers.

Avoid double announcements inside the status region.

-            <svg
+            <svg
+              aria-hidden="true"
+              focusable="false"
               className="text-primary-foreground h-8 w-8 motion-safe:animate-spin motion-reduce:animate-none"
               fill="currentColor"
               viewBox="0 0 24 24">

24-27: Allow custom/loading-specific copy (i18n) via children with a sensible default.

This keeps the component reusable across contexts without hardcoding English text.

-        <div className="text-center">
-          <p className="text-muted-foreground">Loading page...</p>
-        </div>
+        <div className="text-center">
+          {children ?? <p className="text-muted-foreground">Loading page...</p>}
+        </div>

3-3: Destructure props to support className merge and children.

Pairs with the outer div change.

-function Loading(props: React.HTMLAttributes<HTMLDivElement>) {
+function Loading(
+  { className, children, ...rest }: HTMLAttributes<HTMLDivElement> & { children?: ReactNode }
+) {

1-1: Use type-only imports to avoid an unnecessary runtime import.

With the React 17+ JSX transform, this trims the bundle.

-import React from "react";
+import type { HTMLAttributes, ReactNode } from "react";

6-9: Minor a11y nit: role=status already implies aria-live=polite.

You can drop the explicit aria-live to reduce redundancy.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 334b145 and 3d8d0f5.

⛔ Files ignored due to path filters (3)
  • libs/portal-sdk/src/account/generated/accountAPI.schemas.ts is excluded by !**/generated/**
  • libs/portal-sdk/src/account/generated/default.ts is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • apps/portal-app-shell/index.html (1 hunks)
  • apps/portal-app-shell/package.json (1 hunks)
  • apps/portal-app-shell/src/loader.scss (1 hunks)
  • apps/portal-app-shell/src/loader.ts (1 hunks)
  • libs/portal-framework-auth/src/ui/components/index/AuthedIndex.tsx (2 hunks)
  • libs/portal-framework-auth/src/ui/forms/register.tsx (1 hunks)
  • libs/portal-framework-core/src/vite/plugin.ts (1 hunks)
  • libs/portal-framework-ui-core/config/tailwind.config.ts (1 hunks)
  • libs/portal-framework-ui/src/components/Loading.tsx (1 hunks)
  • libs/portal-framework-ui/src/components/app/AppComponent.tsx (3 hunks)
  • libs/portal-framework-ui/src/index.ts (1 hunks)
  • libs/portal-plugin-dashboard/src/ui/components/ApiKeyAlertMessage.tsx (1 hunks)
  • libs/portal-plugin-dashboard/src/ui/components/EmailVerificationBanner.tsx (1 hunks)
  • libs/portal-plugin-dashboard/src/ui/dialogs/deleteAccount.tsx (2 hunks)
  • libs/portal-plugin-dashboard/src/ui/dialogs/updatePassword.tsx (2 hunks)
  • libs/portal-plugin-dashboard/src/ui/forms/updateEmail.tsx (2 hunks)
✅ Files skipped from review due to trivial changes (2)
  • libs/portal-framework-ui-core/config/tailwind.config.ts
  • libs/portal-framework-ui/src/index.ts
🚧 Files skipped from review as they are similar to previous changes (13)
  • apps/portal-app-shell/src/loader.scss
  • libs/portal-plugin-dashboard/src/ui/components/EmailVerificationBanner.tsx
  • libs/portal-plugin-dashboard/src/ui/forms/updateEmail.tsx
  • apps/portal-app-shell/package.json
  • libs/portal-plugin-dashboard/src/ui/dialogs/deleteAccount.tsx
  • libs/portal-framework-auth/src/ui/forms/register.tsx
  • libs/portal-plugin-dashboard/src/ui/dialogs/updatePassword.tsx
  • apps/portal-app-shell/index.html
  • libs/portal-framework-core/src/vite/plugin.ts
  • libs/portal-framework-auth/src/ui/components/index/AuthedIndex.tsx
  • apps/portal-app-shell/src/loader.ts
  • libs/portal-plugin-dashboard/src/ui/components/ApiKeyAlertMessage.tsx
  • libs/portal-framework-ui/src/components/app/AppComponent.tsx
🔇 Additional comments (1)
libs/portal-framework-ui/src/components/Loading.tsx (1)

12-22: Nice accessible defaults and reduced-motion handling.

Good use of role="status", aria-busy, and motion-reduce:animate-none.

…mplement bootup and page loading screens with animations

* Bootup screen:
  - Full-page overlay with animated progress bar
  - Random cycling technical messages
  - App logo integration
  - Automatic removal when app ready
  - SCSS styles with theme variables

* Page loading:
  - Centered spinner component
  - Themed background overlay
  - Reusable React component
  - Integrated with auth flows

* Infrastructure:
  - Global types for loading API
  - sass-embedded dependency
  - Vite build optimizations
  - Framework-wide exports
@pcfreak30 pcfreak30 force-pushed the libs/portal-plugin-dashboard branch from 3d8d0f5 to 1ee68ed Compare September 1, 2025 03:07
@pcfreak30 pcfreak30 merged commit 2082266 into develop Sep 1, 2025
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant