feat(sdk-app): selectable demo chromes#1734
Merged
jeffredodd merged 5 commits intomainfrom May 8, 2026
Merged
Conversation
serikjensen
approved these changes
May 8, 2026
0839911 to
0fa9eba
Compare
8fac174 to
7ceb7f3
Compare
Adds a "Chrome" section to the Settings panel with a dropdown of pre-built demo chromes that ship in this repo. Selecting a chrome replaces the SDK app's TopBar + Sidebar with a partner-styled shell whose nav links drive the existing react-router routes — so partners see a credible product context for screen-share demos without seeing any SDK-app chrome bleeding through. Two built-in entries to start: - sdk-native (default): the existing SDK app chrome, unchanged. - acme-hr: a generic partner-styled shell with branded header, left nav (Employees, Onboarding, Compensation, Run Payroll, Documents), and footer. Selection persists in sdk-app-chrome-id localStorage. Composes with the \ chrome-hide shortcut (it hides whichever chrome is active). The Settings panel and overlays continue to render at the app root so they're available regardless of which chrome is selected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The first cut of selectable demo chromes replaced the SDK-app TopBar + Sidebar entirely. The intended model is a nested chrome: the partner-styled demo chrome (e.g. Acme HR) wraps the rendered SDK component inside the SDK-app's main-content area, while the SDK-app TopBar + Sidebar stay above and to the left. The \ shortcut now hides only the SDK-app chrome (TopBar, Sidebar, breadcrumb, events log), leaving the demo chrome visible. That matches the screen-share demo flow: toggle \ to drop the dev-tool chrome and screen-share just the partner-styled context. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Every clickable element in the Acme HR chrome now navigates to a real SDK component that renders with the auto-provisioned demo data — so the chrome can drive a complete walkthrough. - Brand (▣ Acme HR) — was decorative, now links to /company/OnboardingOverview as a "home" affordance. - Avatar (JD) — was decorative, now links to /employee/Profile. - Top nav: Dashboard → /company/OnboardingOverview, People → /employee/Profile, Payroll → /payroll/PayrollLanding (was the ExecutionFlow which needs payrollId; PayrollLanding works with just companyId). - Sidebar adds Bank Account → /company/BankAccount and Pay Schedule → /company/PaySchedule for richer demo coverage. "Run Payroll" switches from PayrollExecutionFlow (needs payrollId) to PayrollFlow (companyId only) so it renders out of the box. Active state styling added for the top-nav links so the current section is highlighted. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7ceb7f3 to
d79914f
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds “demo chrome” selection to the sdk-app so demos can be shown inside partner-styled shells, and introduces a Code panel that renders a usage snippet for the currently displayed SDK component.
Changes:
- Add a demo-chrome registry (including an “Acme HR” chrome) and a Settings dropdown that persists the selected chrome in localStorage.
- Add a Code panel (toggleable via
?and TopBar) that generates/highlights JSX usage snippets based on the current route/component and entity IDs. - Wire the App layout to wrap routed content with the selected demo chrome and provide current-component context for snippet generation.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk-app/src/useDemoChrome.ts | Hook to persist/read the selected demo chrome ID. |
| sdk-app/src/useCurrentComponent.ts | Context + hooks for tracking the currently rendered component/entities. |
| sdk-app/src/useCodePanel.ts | Hook to manage Code panel open state + global ? shortcut persistence. |
| sdk-app/src/TopBar.tsx | Adds Code toggle button and new props for Code panel state. |
| sdk-app/src/TopBar.module.scss | Styles for active state of the Code toggle button. |
| sdk-app/src/generateSnippet.ts | Generates a JSX snippet from registry metadata + entity IDs + defaults. |
| sdk-app/src/DemoSettingsPanel.tsx | Adds “Chrome” section with demo chrome dropdown + description. |
| sdk-app/src/demoChromes/types.ts | Types for demo chrome entries and chrome component props. |
| sdk-app/src/demoChromes/registry.ts | Registry of built-in demo chromes + lookup helper. |
| sdk-app/src/demoChromes/AcmeHrChrome.tsx | Partner-styled chrome implementation with header/nav/sidebar/footer. |
| sdk-app/src/demoChromes/AcmeHrChrome.module.scss | Styling for the Acme HR chrome shell. |
| sdk-app/src/CurrentComponentContext.tsx | Provider implementation for the current-component registry. |
| sdk-app/src/ComponentRenderer.tsx | Registers/unregisters the current component/entities for snippet generation. |
| sdk-app/src/CodePanel.tsx | Code panel UI, copy-to-clipboard, and resize handling. |
| sdk-app/src/CodePanel.module.scss | Layout/styling for the Code panel and resize handle. |
| sdk-app/src/assets/icons/icon-code.svg | Adds Code icon used in the TopBar. |
| sdk-app/src/App.tsx | Integrates demo chrome selection, current-component provider, and Code panel into the app layout. |
| package.json | Adds prism-react-renderer dependency. |
| package-lock.json | Locks prism-react-renderer (and transitive deps). |
Comments suppressed due to low confidence (2)
sdk-app/src/App.tsx:98
- This effect disables
react-hooks/exhaustive-depsand omitssettingsOpenfrom the dependency list. That makes the behavior harder to reason about and can reintroduce stale-closure issues if this logic changes. Prefer includingsettingsOpen(and any referenced callbacks) in deps, or consolidating the mutual-exclusion logic into a single effect/state transition without lint overrides.
useEffect(() => {
if (codePanel.isOpen && settingsOpen) setSettingsOpen(false)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [codePanel.isOpen])
sdk-app/src/App.tsx:103
- This effect also disables
react-hooks/exhaustive-depsand omitscodePanel/codePanel.closefrom deps. SinceuseCodePanelreturns callbacks, include the referenced values in the dependency array (or refactor to avoid needing the lint override) to keep the effect correct if the hook implementation changes.
useEffect(() => {
if (settingsOpen && codePanel.isOpen) codePanel.close()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [settingsOpen])
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+138
to
+143
| const outletEl = <Outlet context={{ entities: activeEntities, chromeHidden }} /> | ||
| const chromedOutlet = customChrome ? ( | ||
| <customChrome.Chrome onOpenSettings={openSettings}>{outletEl}</customChrome.Chrome> | ||
| ) : ( | ||
| outletEl | ||
| ) |
Comment on lines
+156
to
+163
| <> | ||
| <TopBar | ||
| companyId={activeEntities.companyId} | ||
| tokenStatus={demoManager.tokenStatus} | ||
| onOpenSettings={openSettings} | ||
| onToggleCode={codePanel.toggle} | ||
| codeOpen={codePanel.isOpen} | ||
| /> |
Comment on lines
+164
to
+174
| <div className="app-body"> | ||
| <Sidebar | ||
| mode={appMode} | ||
| searchQuery={searchQuery} | ||
| onSearchChange={setSearchQuery} | ||
| isOpen={sidebarOpen} | ||
| onToggle={() => { | ||
| setSidebarOpen(open => !open) | ||
| }} | ||
| onShowShortcuts={shortcutHelper.open} | ||
| /> |
Comment on lines
+138
to
+139
| const outletEl = <Outlet context={{ entities: activeEntities, chromeHidden }} /> | ||
| const chromedOutlet = customChrome ? ( |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
chrome-hide shortcut from #1732 — pressing \\` hides whichever chrome is active.Screensho
Why
For customer demos we want to show SDK components inside a credible product context without seeing any SDK-app chrome bleeding through. Adding new chromes is a single registry entry — partners or PMs can fork/clone to build their own.
Test plan
Branch base
This branch stacks on `feat/sdk-app-code-panel` (#1733), which stacks on `feat/sdk-app-hide-chrome-shortcut` (#1732), which stacks on `feat/sdk-app-manual-token-mode` (#1727). Re-target to `al/create-secondary-ui-components` after upstream PRs merge.
🤖 Generated with Claude Code