Skip to content

feat(react-ui): AgentInterface welcome-glow rework, DotMatrixLoader, and blue default accent - #787

Merged
ankit-thesys merged 9 commits into
mainfrom
pr3/agent-interface-example
Jul 21, 2026
Merged

feat(react-ui): AgentInterface welcome-glow rework, DotMatrixLoader, and blue default accent#787
ankit-thesys merged 9 commits into
mainfrom
pr3/agent-interface-example

Conversation

@pr3khar

@pr3khar pr3khar commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR reworks the AgentInterface welcome experience, adds a branded loading indicator, and flips the default theme accent from neutral (black/white) to blue. It introduces two new components — DotMatrixLoader (a public, reusable rAF-driven loader) and WelcomeGlow/WelcomeGlowProvider (an opt-in, CSS-only entrance glow around the welcome composer) — then wires them through the existing AgentInterface surfaces (Thread loader, artifact browser/view loading states, WelcomeScreen). Alongside the components, the default accent identity is rebranded to blue in both the JS theme generator and the static CSS fallback, and a batch of coordinated SCSS changes re-aligns the welcome screen (centered → left, ~748px column), narrows the content column (880 → 768px), flattens sidebar nav, restyles long conversation starters, and repositions the thread-list row-action button. The change is almost entirely additive at the API level; the two behavior-level shifts are the blue accent (a token mutation) and the removal of date-grouping in the thread list. All changes live under packages/react-ui; no examples/ files change.

What changed

New components

  • DotMatrixLoader (components/DotMatrixLoader/) — a 4×4 (16-dot) role=status loader. Animation is a requestAnimationFrame loop mutating each dot's inline opacity per frame (two comet trails on hand-authored OUTER_RING/INNER_RING coordinates, REVOLUTION_MS = 1400, exponential opacity falloff). Variants default (36px) / compact (24px) plus a size override; SCSS holds only static geometry/color. Cleanup is correct (cancelAnimationFrame on unmount). Promoted to the public API (index.ts).
  • WelcomeGlow + WelcomeGlowProvider (components/AgentInterface/WelcomeGlow.tsx, welcomeGlow.scss) — a context (default false) gating an optional one-shot entrance/composer glow. When disabled, renders a bare <>{children}</> (no wrapper DOM, zero cost); when enabled it wraps children with two decorative aria-hidden blobs. All motion is pure CSS @keyframes, theme-token driven, and reduced-motion-guarded. Exposed as AgentInterface.WelcomeGlow.

AgentInterface UX

  • WelcomeScreen — new opt-in glowAnimation?: boolean (default false). Both render branches wrap in <WelcomeGlowProvider> and add --animated; the props branch also wraps <DesktopWelcomeComposer/> in <WelcomeGlow>. The rest of the large diff is JSX re-nesting — default-off, so existing consumers render identically.
  • Thread — the streaming/thinking loader row now renders <DotMatrixLoader variant="compact" /> instead of the old three-dot MessageLoading. ScrollArea's default userMessageSelector also widened to match .openui-shell-thread-message-user.
  • ThreadListfeature removal (+5/−67): the groupThreads() recency bucketing (Today / Yesterday / Previous 7/30 Days / This Year / Older) is deleted and replaced with a single static "Threads" header + flat threads.map(...). Thread order now depends entirely on useThreadList.
  • ConversationStarter — new public optional onSelect?(starter) prop overriding the default send. Long variant gains hairline separators; default colors dim to secondary and brighten on hover.
  • ArtifactBrowserPage / ArtifactViewPageLoading… text replaced with <DotMatrixLoader />. No-results message becomes No results found for "<query>"; empty illustration uses the category's own artifact-type icon.

Theming

  • Default accent: neutral → blue. defaultTheme.ts flips brandSwatch "neutral" → "blue" (light + dark), so brandSolid = blue-600 and feeds textBrand, interactiveAccent*, borderAccent*, and the accent-text contrast picker. Mirrored in openui-defaults.scss for raw-CSS-var consumers.
  • DEFAULT_ACCENT_SOLID (indigo) — new; the explicit brandSwatch:"neutral" branch now returns this indigo instead of pure black/white.
  • chatUserResponseBg switched to overlayBase so user bubbles stay neutral under the new blue brand.
  • New --openui-agent-sidebar-shadow-color token drives a sidebar right-edge inset shadow.

Cleanup / structural SCSS

  • Card/card.scss — removed padding / border-radius / border-color / background-color (keeps box-shadow: none); defers surface styling to the base Card.
  • assistantMessage.scss / thread.scss — removed the center-align gutter; messages + loading row sit flush.
  • Content column narrowed (composer 880→768, welcome composer 800→768 + radius-3xl); welcome screen left-aligned; sidebar padding + inset shadow + agent-name ellipsis; thread-list kebab repositioned (hover/focus reveal).

How to review / showcase

Storybook runs at http://localhost:6006; story IDs follow components-agentinterface--<id>. Only the WithWelcome story changed (adds a glowAnimation toggle); every other change is observed through existing stories.

  • WelcomeGlow + WelcomeScreen--with-welcome. Glow OFF already shows the rework (hero left-aligned, 748px). Toggle glowAnimation = true in Controls + remount: staggered entrance + two blue glow blobs behind the composer.
  • Blue theme + sidebar shadow + flat "Threads" list + hover kebab + user bubble--default. Threads under one "Threads" header; blue send button/focus/accents; faint sidebar inset shadow; hover a row → kebab fades in; user bubble neutral gray.
  • DotMatrixLoader (compact)--with-workspace, click "Create a revenue dashboard" (~400ms) for the 24px loader.
  • DotMatrixLoader (36px) + artifact browser--artifact-browser. Click a category → 36px loader; type a no-match query → No results found for "<query>".
  • Long starters--long-starters. Separators between rows; secondary→primary color on hover.
  • Compare subtle deltas (blue accent, sidebar shadow, message padding) against origin/main, and exercise dark mode.

Risks & notes

  • DotMatrixLoader has no prefers-reduced-motion handling. The rAF loop runs unconditionally while mounted and is the default per-turn thread loader, with no opt-out (unlike WelcomeGlow, which is SCSS-guarded). Gate the loop on matchMedia('(prefers-reduced-motion: reduce)') with a static fallback.
  • Blue default accent is a mutation, not additive. Every existing consumer on the default ThemeProvider theme silently shifts its whole accent identity to blue. Confirm this rebrand is intended/approved.
  • Card/card.scss surface stripping. Cards look correct only if the base react-ui Card supplies matching defaults; verify against components-card--card-story (not touched by this PR).
  • ThreadList date-grouping removal. Recency sections are gone; order now depends entirely on useThreadList. Confirm the store pre-sorts newest-first.
  • Formatting. ConversationStarter.tsx and DotMatrixLoader.tsx fail prettier --check (run format:fix).
  • Positives. Both new components are theme-token compliant and SSR-safe; WelcomeGlow no-ops to a bare fragment when disabled; DotMatrixLoader a11y is good (role=status, glow blobs aria-hidden); all public-API changes are additive.

pr3khar and others added 2 commits July 10, 2026 12:36
Polish navigation and conversation spacing, add category-aware empty states and a reusable dot-matrix loader, and restore branded accent defaults.

Co-authored-by: Cursor <cursoragent@cursor.com>
@pr3khar
pr3khar requested a review from ankit-thesys July 17, 2026 09:10

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Self Note test this out, why the function type changes needed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Resolved my own note after testing. The type change is a consequence of the new onSelect?(starter) prop: the parent now needs the whole starter object (not just the prompt string), so it closes over each item — onClick={() => handleClick(item)} — and the child's internal onClick becomes a plain () => void thunk that no longer passes prompt back. ConversationStarterItemProps is not exported, so no consumer impact. Tested both variants in Storybook: short and long starters send starter.prompt through processMessage (long variant correctly sends the prompt, not the displayText), and the isRunning guard holds. The onSelect override path has no story exercising it — noted as a showcase gap.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Update: with the export removed (8215f424), onSelect became unreachable, so the whole cluster is reverted — prop, starter-object handler, and the item onClick type change. ConversationStarter.tsx is now a 3-line diff vs main (just the long-variant separators); the function-type question is moot.

Comment thread packages/react-ui/src/components/AgentInterface/sidebar.scss Outdated
Comment thread packages/react-ui/src/components/AgentInterface/Thread.tsx

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@abhithesys should check this file.

style.setAttribute("data-openui-theme", id);
style.textContent = `${styleSelector}, .${portalClassName} { ${cssVarsString} }`;
style.textContent = `${styleSelector}, .${portalClassName} { ${cssVarsString}
--openui-agent-sidebar-shadow-color: ${sidebarShadowColor}; }`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

cant do this, variable should be introduced through theme Provider

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Resolved — this injection was removed entirely; ThemeProvider.tsx is now byte-identical to main. The sidebar shadow is a local SCSS variable on $sunk-deep instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

selfNote:- review this, standard are not getting followed here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@pr3khar review this file. I think this is also moving away from the standard

gap: cssUtils.$space-2xl;
background-color: cssUtils.$highlight-subtle;
box-shadow: inset -10px 0 18px -18px
var(--openui-agent-sidebar-shadow-color, cssUtils.$sunk-deep);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

new variable got introduced here this is not the right approach

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Addressed in 10901b8 + the merge: the ThemeProvider-injected --openui-agent-sidebar-shadow-color is fully gone (ThemeProvider.tsx now has zero diff vs main) and sidebar.scss uses a local SCSS variable on an existing token: $sidebar-shadow: inset -10px 0 18px -18px cssUtils.$sunk-deep;.

@ankit-thesys ankit-thesys changed the title Pr3/agent interface example feat(react-ui): AgentInterface welcome-glow rework, DotMatrixLoader, and blue default accent Jul 20, 2026
Improve sidebar and workspace feedback, standardize loader behavior, and remove the superseded message-loading component.

Co-authored-by: Cursor <cursoragent@cursor.com>
@ankit-thesys
ankit-thesys self-requested a review July 20, 2026 14:30
ankit-thesys
ankit-thesys previously approved these changes Jul 20, 2026

@ankit-thesys ankit-thesys left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LG

ankit-thesys and others added 2 commits July 21, 2026 13:50
Lockfile resolved to main's wholesale: this branch changes no
manifests, so its lockfile diff was regeneration noise.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011nPH2Rn2XGXETgx5Yu5seX
ankit-thesys and others added 4 commits July 21, 2026 13:50
CI (pnpm 9) resolves the react-ui prettier script to prettier@3.5.3
while a pnpm 10 install resolves 3.9.4, and the two disagree on these
files; 3.5.3 is the gate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011nPH2Rn2XGXETgx5Yu5seX
With the component not exported (8215f42), nothing can pass onSelect —
the prop, the starter-object handler, and the item onClick type change
all served only that path. Handler wiring returns to main's shape; the
long-variant separators and hover styling stay.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011nPH2Rn2XGXETgx5Yu5seX

@ankit-thesys ankit-thesys left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LG

@ankit-thesys
ankit-thesys merged commit 9510fa3 into main Jul 21, 2026
2 checks passed
@ankit-thesys
ankit-thesys deleted the pr3/agent-interface-example branch July 21, 2026 11:23
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.

2 participants