Skip to content

Added loading spinner for Flows that take time to load - #1929

Open
gaokevin1 wants to merge 4 commits into
mainfrom
loading-spinner
Open

Added loading spinner for Flows that take time to load#1929
gaokevin1 wants to merge 4 commits into
mainfrom
loading-spinner

Conversation

@gaokevin1

Copy link
Copy Markdown
Member

Related Issues

Fixes https://github.com/descope/etc/issues/18199

Description

This change adds a configurable loading spinner for when flow screens take some time to load, or for when you're doing redirects via OAuth and SSO actions at the beginning of the flow.

Screenshots

Must

  • 📱 Responsiveness (mobile/XL resolutions)
  • 🧪 Tests
  • 📃 Documentation (if applicable)

@shuni-bot

shuni-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🐕 Review complete — View session on Shuni Portal 🐾

🤖 Model: claude-opus-5

@gaokevin1
gaokevin1 requested a review from talkapi September 3, 2026 20:31
@gaokevin1
gaokevin1 requested a review from asafshen September 3, 2026 20:31
@shuni-bot

shuni-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🐕 Suggested Reviewers

Loading spinner feature review assignment examines JSX and CSS contributions, prioritizes component overlay and responsive styling verification

Reviewer Reason
ckiee Reviews the new FlowLoadingOverlay component (FlowLoadingOverlay.tsx) and CSS styling changes (App.css, src/App.css) that implement the loading spinner UI and animations
omercnet Evaluates the main App changes (App.tsx) integrating the loading overlay, as well as App.css and the new FlowLoadingOverlay component for global loading spinner implementation
dorsha Assesses the flow integration (App.tsx) and loading overlay component (FlowLoadingOverlay.tsx) for redirect handling, overlay visibility logic, and spinner configuration
asafshen Reviews test coverage additions (App.test.tsx) for the loading spinner, .env.example configuration, and documentation updates (README.md) related to the new feature
talkapi Verifies the new component implementation (FlowLoadingOverlay.tsx), tests (App.test.tsx), and configuration/docs (README.md) for the loading spinner feature

Suggested by Shuni based on git history and PR context. Names are not @-mentioned to avoid notifying anyone — request a review from whoever fits best.

@gaokevin1
gaokevin1 requested a review from dorsha September 3, 2026 20:31
@gaokevin1
gaokevin1 enabled auto-merge (squash) September 3, 2026 20:34

@shuni-bot shuni-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🐕 Shuni Review

Adds a full-screen loading overlay/spinner shown until the Descope flow fires onReady/onError, configurable via the loading and loading_color query params (defaulting to the bg color).

Actionable comments posted: 3

  • 1 🟠 Major: overlay never dismissed when FlowGate blocks the flow, permanently hiding the error screen
  • 2 🟡 Minor: http:// background URL leaks into the spinner color; color-mix() border shorthand drops the whole border on invalid/unsupported values

Merge risk: 🟡 Moderate: the blocked-domain path now renders an undismissable spinner over the error screen.

See inline comments for details.

🤖 Model: claude-opus-5


Review scope: Full review

Reviewed files (6)
  • .env.example
  • README.md
  • src/App.css
  • src/App.test.tsx
  • src/App.tsx
  • src/components/FlowLoadingOverlay.tsx

Comment thread src/App.tsx
Comment on lines +405 to +407
{showFlow && showFlowLoading && !isFlowReady && (
<FlowLoadingOverlay color={loadingSpinnerColor} />
)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🛠️ Moderate

Dismiss the overlay when the flow never mounts

The overlay is gated only on showFlow and on readyFlowKey, which is set exclusively by <Descope>'s onReady/onError. When FlowGate gets success !== true from /v1/flow/validate-domain it renders <ErrorScreen /> instead of its children, so <Descope> never mounts and neither callback ever fires — the position: fixed; z-index: 1000 overlay then covers the error message forever with a spinning indicator and no way out. The same dead end occurs whenever the web component fails to initialize without emitting error.

Proposed fix

Either render the overlay inside FlowGate (so the blocked branch replaces it too) or have FlowGate report its blocked state up to App and include it in the overlay condition. Also add a max-wait timeout that clears the overlay so an SDK that emits neither event can't strand the page.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still open on the current head (2da0004). The overlay condition and FlowGate are unchanged; making the spinner opt-in (loading=true / DESCOPE_FLOW_LOADING=true) narrows the blast radius to deployments that enable it, but for those the blocked-domain path still renders ErrorScreen behind an undismissable overlay, and there is still no max-wait fallback.

Comment thread src/App.tsx
Comment on lines +37 to +38
const isBackgroundImageUrl = (value: string | undefined) =>
Boolean(value?.startsWith('https://'));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick fix

Exclude http:// background URLs from the spinner color

isBackgroundImageUrl only matches https://, so an http:// image URL in bg/DESCOPE_BG is treated as a color and passed through to --flow-loading-color. Because the custom property is set (just not a color), the var(..., #0082b5) fallbacks in .flow-loading-spinner never apply and the declarations become invalid at computed-value time instead of falling back to the default color.

Suggested change
const isBackgroundImageUrl = (value: string | undefined) =>
Boolean(value?.startsWith('https://'));
const isBackgroundImageUrl = (value: string | undefined) =>
/^https?:\/\//i.test(value ?? '');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still open on the current head (2da0004): isBackgroundImageUrl is unchanged, so an http:// value in bg/DESCOPE_BG continues to reach --flow-loading-color whenever the spinner is enabled.

Comment thread src/App.css
Comment on lines +106 to +107
color-mix(in srgb, var(--flow-loading-color, #0082b5) 20%, transparent);
border-top-color: var(--flow-loading-color, #0082b5);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick fix

Keep the spinner visible when the color value is unusable

Putting color-mix() with a var() reference in the border shorthand makes width and style depend on the color resolving: if --flow-loading-color holds any non-color string (an arbitrary bg/loading_color value reaches it unvalidated) or the browser lacks color-mix() — still possible under the repo's >0.2%, not dead browserslist — the whole shorthand is dropped to border-style: none and the spinner renders invisible while the opaque overlay keeps blocking the flow. A static track color isolates the failure to the accent arc.

Suggested change
color-mix(in srgb, var(--flow-loading-color, #0082b5) 20%, transparent);
border-top-color: var(--flow-loading-color, #0082b5);
border: 3px solid rgba(0, 0, 0, 0.12);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Still open on the current head (2da0004): src/App.css was not touched by the follow-up commits, so the border shorthand still collapses to border-style: none when the color value is invalid or color-mix() is unsupported.

@shuni-bot

shuni-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🐕 Review complete — View session on Shuni Portal 🐾

🤖 Model: claude-opus-5

@shuni-bot shuni-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🐕 Shuni Review

No new issues found.

3 unresolved prior findings

⚠️ Review follow-up issue: Unresolved prior review threads: PRRT_kwDOJrNxSs6fEmoG, PRRT_kwDOJrNxSs6fEmoL, PRRT_kwDOJrNxSs6fEmoU.

🤖 Model: claude-opus-5


Review scope: Incremental re-review

Reviewed new changes (4)
  • .env.example
  • README.md
  • src/App.test.tsx
  • src/App.tsx
Previously reviewed and unchanged: 2 files.

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