@the-portland-company/shell 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +123 -0
- package/dist/chrome.css +102 -0
- package/dist/index.cjs +1387 -219
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +477 -29
- package/dist/index.d.ts +477 -29
- package/dist/index.js +1367 -221
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.d.cts
CHANGED
|
@@ -101,8 +101,13 @@ interface AppRegistryEntry {
|
|
|
101
101
|
* fuel/modal/notification components into the relevant slots.
|
|
102
102
|
*/
|
|
103
103
|
interface ShellSlots {
|
|
104
|
-
/**
|
|
105
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Right side of the header — rendered in the icon row of the header (next
|
|
106
|
+
* to user menu). Used by the legacy app to mount FuelPopover,
|
|
107
|
+
* NewTextBellPopup, SystemAlertsMenu, NavigationToggleMenu, and
|
|
108
|
+
* ImportProgressIndicator. Replaces the older `headerExtrasSlot`.
|
|
109
|
+
*/
|
|
110
|
+
headerIconsSlot?: ReactNode;
|
|
106
111
|
/** Modal layer rendered above everything (positioned absolute). */
|
|
107
112
|
modalsSlot?: ReactNode;
|
|
108
113
|
/** Notifications layer (toasts, popovers, badges). */
|
|
@@ -112,6 +117,138 @@ interface ShellSlots {
|
|
|
112
117
|
/** Overlay always-on-top components (e.g., import progress indicator). */
|
|
113
118
|
overlaySlot?: ReactNode;
|
|
114
119
|
}
|
|
120
|
+
/** ---------------- Mode ---------------- */
|
|
121
|
+
/**
|
|
122
|
+
* Per-mode visual / display config supplied by the app. Mirrors the legacy
|
|
123
|
+
* `MODE_CONFIG[mode]` shape from `react/app/src/contexts/ModeContext.tsx`.
|
|
124
|
+
*
|
|
125
|
+
* `icon` is an already-resolved ReactNode (e.g., <FiUsers />) so the shell
|
|
126
|
+
* doesn't need to know about react-icons. `iconName` is kept around as an
|
|
127
|
+
* informational string for tooling that wants to look up the icon component
|
|
128
|
+
* by name.
|
|
129
|
+
*/
|
|
130
|
+
interface ShellModeConfig {
|
|
131
|
+
/** Stable mode identifier, e.g., 'relationship'. */
|
|
132
|
+
id: string;
|
|
133
|
+
/** Display name, e.g., 'Relationship Mode'. */
|
|
134
|
+
name: string;
|
|
135
|
+
/** Mode primary color (hex). */
|
|
136
|
+
primaryColor: string;
|
|
137
|
+
/** Mode accent color (hex). */
|
|
138
|
+
accentColor: string;
|
|
139
|
+
/** Mode background color (hex). */
|
|
140
|
+
bgColor: string;
|
|
141
|
+
/** Mode secondary color (hex) — typically muted text. */
|
|
142
|
+
secondaryColor: string;
|
|
143
|
+
/** Mode white color (hex), usually '#FFFFFF'. */
|
|
144
|
+
white: string;
|
|
145
|
+
/** Pre-resolved icon element for the mode pill leftIcon. */
|
|
146
|
+
icon?: ReactNode;
|
|
147
|
+
/** Informational icon name (for debugging or tooling). */
|
|
148
|
+
iconName?: string;
|
|
149
|
+
}
|
|
150
|
+
interface ShellModeValue {
|
|
151
|
+
/** Current mode id, e.g., 'relationship'. */
|
|
152
|
+
currentMode: string;
|
|
153
|
+
/** All available modes for the current org/user. */
|
|
154
|
+
modes: ShellModeConfig[];
|
|
155
|
+
/** Switch to a different mode. App owns side effects. */
|
|
156
|
+
switchMode: (modeId: string) => void;
|
|
157
|
+
/** Returns the config for the current mode (convenience). */
|
|
158
|
+
getModeConfig: () => ShellModeConfig;
|
|
159
|
+
}
|
|
160
|
+
/** ---------------- Nav items ---------------- */
|
|
161
|
+
/**
|
|
162
|
+
* One sidebar nav item. Apps build this list themselves (via
|
|
163
|
+
* `getLinkItemsForMode` + `applySidebarChildAccessState` etc.) and pass it
|
|
164
|
+
* through to <ShellChrome navItems={...}>. The shell renders the rows.
|
|
165
|
+
*/
|
|
166
|
+
interface ShellNavItem {
|
|
167
|
+
name: string;
|
|
168
|
+
/** A react-icons component (e.g., FiHome). Either icon or brandIcon set. */
|
|
169
|
+
icon?: unknown;
|
|
170
|
+
/** Brand-icon name keyed off `/brand/icons/<name>.svg`. */
|
|
171
|
+
brandIcon?: string;
|
|
172
|
+
/** Route the row navigates to. */
|
|
173
|
+
href?: string;
|
|
174
|
+
/** Nested rows. Renders an accordion when set. */
|
|
175
|
+
children?: ShellNavItem[];
|
|
176
|
+
/** Small badge shown next to the label (e.g., 'In Development'). */
|
|
177
|
+
badge?: string;
|
|
178
|
+
/** Secondary label rendered below the main label. */
|
|
179
|
+
subLabel?: string;
|
|
180
|
+
/** When true, the row is rendered disabled/non-interactive. */
|
|
181
|
+
disabled?: boolean;
|
|
182
|
+
/** Optional click handler (overrides href). */
|
|
183
|
+
action?: () => void;
|
|
184
|
+
}
|
|
185
|
+
interface ShellNavItemsValue {
|
|
186
|
+
items: ShellNavItem[];
|
|
187
|
+
}
|
|
188
|
+
/** ---------------- Nav preference ---------------- */
|
|
189
|
+
/**
|
|
190
|
+
* User preference for nav rendering — whether sub-menus (accordion children)
|
|
191
|
+
* are shown in the sidebar.
|
|
192
|
+
*/
|
|
193
|
+
interface ShellNavigationPreferenceValue {
|
|
194
|
+
showSubMenu: boolean;
|
|
195
|
+
}
|
|
196
|
+
/** ---------------- Role ---------------- */
|
|
197
|
+
/**
|
|
198
|
+
* Active-role display info for the user-menu role badge. App supplies the
|
|
199
|
+
* resolved values; shell renders the badge.
|
|
200
|
+
*/
|
|
201
|
+
interface ShellActiveRoleConfig {
|
|
202
|
+
name: string;
|
|
203
|
+
color: string;
|
|
204
|
+
}
|
|
205
|
+
interface ShellRoleValue {
|
|
206
|
+
activeRoleConfig: ShellActiveRoleConfig | null;
|
|
207
|
+
isSuperAdmin: boolean;
|
|
208
|
+
}
|
|
209
|
+
/** ---------------- Footer ---------------- */
|
|
210
|
+
interface ShellFooterLink {
|
|
211
|
+
label: string;
|
|
212
|
+
href: string;
|
|
213
|
+
/** When true, the link opens in a new tab (target='_blank'). */
|
|
214
|
+
external?: boolean;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Footer / sidebar-footer data shipped from the app. The legacy footer
|
|
218
|
+
* row shows Privacy / Terms / Subscriptions links plus a CommitCopyButton
|
|
219
|
+
* with version + commit metadata. All fields are optional so apps can
|
|
220
|
+
* supply only what they have.
|
|
221
|
+
*/
|
|
222
|
+
interface ShellFooterValue {
|
|
223
|
+
links: ShellFooterLink[];
|
|
224
|
+
commit?: string;
|
|
225
|
+
commitFull?: string;
|
|
226
|
+
commitDate?: string;
|
|
227
|
+
commitAuthor?: string;
|
|
228
|
+
commitLog?: string;
|
|
229
|
+
version?: string;
|
|
230
|
+
releaseName?: string;
|
|
231
|
+
/**
|
|
232
|
+
* Environment label rendered as a colored chip in the sidebar
|
|
233
|
+
* footer (e.g., 'production' = red, 'staging' = orange,
|
|
234
|
+
* 'local'/'development' = green).
|
|
235
|
+
*/
|
|
236
|
+
environmentLabel?: string;
|
|
237
|
+
/**
|
|
238
|
+
* Optional pre-rendered environment chip element. When supplied,
|
|
239
|
+
* <CommitCopyButton> renders this instead of building a default chip
|
|
240
|
+
* from `environmentLabel`. Use this when the app already has an
|
|
241
|
+
* <EnvironmentBanner> component it wants to drop in unchanged.
|
|
242
|
+
*/
|
|
243
|
+
envNode?: ReactNode;
|
|
244
|
+
/**
|
|
245
|
+
* When set, <CommitCopyButton> renders a diagnostics icon next to
|
|
246
|
+
* the version that, when clicked, fires this handler. The shell
|
|
247
|
+
* does not navigate or open anything — apps wire whatever they want
|
|
248
|
+
* (modal, route, console dump).
|
|
249
|
+
*/
|
|
250
|
+
onDiagnosticsClick?: () => void;
|
|
251
|
+
}
|
|
115
252
|
/** Props for the top-level ShellProvider. */
|
|
116
253
|
interface ShellProviderProps {
|
|
117
254
|
children: ReactNode;
|
|
@@ -123,11 +260,11 @@ interface ShellProviderProps {
|
|
|
123
260
|
appRegistry?: AppRegistryEntry[];
|
|
124
261
|
/** Optional override for the base path if the app is mounted under a sub-path (e.g., '/contacts'). */
|
|
125
262
|
basename?: string;
|
|
126
|
-
/** If provided, shell renders <
|
|
263
|
+
/** If provided, shell renders <OrgPill /> in the sidebar. */
|
|
127
264
|
organization?: ShellOrganizationValue;
|
|
128
265
|
/** If provided, UserMenu shows account switcher + add-account button. */
|
|
129
266
|
linkedAccounts?: ShellLinkedAccountsValue;
|
|
130
|
-
/**
|
|
267
|
+
/** Drives the modal submission flow used by app-supplied support widgets. */
|
|
131
268
|
support?: ShellSupportValue;
|
|
132
269
|
/** Optional element rendered in the header (typically <DevNotesMenu /> from @the-portland-company/devnotes). */
|
|
133
270
|
devNotesMenu?: ReactNode;
|
|
@@ -143,7 +280,7 @@ interface ShellAuthValue {
|
|
|
143
280
|
}
|
|
144
281
|
/**
|
|
145
282
|
* Organization that the current user belongs to. Apps supply this via
|
|
146
|
-
* ShellProvider so the shell can render <
|
|
283
|
+
* ShellProvider so the shell can render <OrgPill /> in the sidebar.
|
|
147
284
|
*/
|
|
148
285
|
interface ShellOrganization {
|
|
149
286
|
id: string;
|
|
@@ -151,6 +288,8 @@ interface ShellOrganization {
|
|
|
151
288
|
logoUrl?: string | null;
|
|
152
289
|
/** Brand color as a hex string (e.g., '#0066cc'). Used for the org badge fallback. */
|
|
153
290
|
brandColor?: string | null;
|
|
291
|
+
/** Optional user-facing role label in this organization ('owner' | 'admin' | etc.). */
|
|
292
|
+
role?: string | null;
|
|
154
293
|
}
|
|
155
294
|
interface ShellOrganizationValue {
|
|
156
295
|
currentOrg: ShellOrganization | null;
|
|
@@ -160,6 +299,8 @@ interface ShellOrganizationValue {
|
|
|
160
299
|
switchOrganization: (orgId: string) => Promise<void> | void;
|
|
161
300
|
/** Optional link rendered at the bottom of the org menu, e.g., '/organizations/new'. */
|
|
162
301
|
createOrgHref?: string;
|
|
302
|
+
/** True while the app is still resolving the org list (renders a skeleton). */
|
|
303
|
+
loadingOrgs?: boolean;
|
|
163
304
|
}
|
|
164
305
|
/**
|
|
165
306
|
* An alternate user account the current user can switch into without signing
|
|
@@ -202,11 +343,27 @@ interface ShellSupportValue {
|
|
|
202
343
|
declare const ShellOrgContext: react.Context<ShellOrganizationValue | null>;
|
|
203
344
|
declare const ShellLinkedAccountsContext: react.Context<ShellLinkedAccountsValue | null>;
|
|
204
345
|
declare const ShellSupportProviderContext: react.Context<ShellSupportValue | null>;
|
|
205
|
-
|
|
346
|
+
declare const ShellModeContext: react.Context<ShellModeValue | null>;
|
|
347
|
+
declare const ShellNavItemsContext: react.Context<ShellNavItemsValue | null>;
|
|
348
|
+
declare const ShellNavigationPreferenceContext: react.Context<ShellNavigationPreferenceValue | null>;
|
|
349
|
+
declare const ShellRoleContext: react.Context<ShellRoleValue | null>;
|
|
350
|
+
declare const ShellFooterContext: react.Context<ShellFooterValue | null>;
|
|
351
|
+
interface ShellChromeValue {
|
|
206
352
|
devNotesMenu: ReactNode | null;
|
|
207
353
|
myProfileHref: string;
|
|
354
|
+
brandLogoSrc?: string;
|
|
355
|
+
headerIconsSlot?: ReactNode;
|
|
356
|
+
organizationSettingsHref?: string;
|
|
357
|
+
showContinueOnboarding?: boolean;
|
|
358
|
+
onContinueOnboarding?: () => void;
|
|
359
|
+
pageTitle?: string;
|
|
360
|
+
breadcrumbs?: Array<{
|
|
361
|
+
label: string;
|
|
362
|
+
href?: string;
|
|
363
|
+
}>;
|
|
364
|
+
headerActions?: ReactNode;
|
|
208
365
|
}
|
|
209
|
-
declare const ShellChromeContext: react.Context<ShellChromeValue
|
|
366
|
+
declare const ShellChromeContext: react.Context<ShellChromeValue | null>;
|
|
210
367
|
declare function ShellProvider({ children, supabaseClient, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
|
|
211
368
|
|
|
212
369
|
declare function useShellAuth(): ShellAuthValue;
|
|
@@ -234,33 +391,108 @@ declare function useShellLinkedAccounts(): ShellLinkedAccountsValue | null;
|
|
|
234
391
|
*/
|
|
235
392
|
declare function useShellSupport(): ShellSupportValue | null;
|
|
236
393
|
|
|
237
|
-
interface ShellChromeValue {
|
|
238
|
-
devNotesMenu: ReactNode | null;
|
|
239
|
-
myProfileHref: string;
|
|
240
|
-
}
|
|
241
394
|
/**
|
|
242
|
-
* Returns chrome-level options supplied to ShellProvider
|
|
243
|
-
* myProfileHref
|
|
395
|
+
* Returns chrome-level options supplied to ShellProvider/ShellChrome
|
|
396
|
+
* (devNotesMenu slot, myProfileHref, header data, brand logo src, etc.).
|
|
397
|
+
* Throws if used outside <ShellProvider>.
|
|
244
398
|
*/
|
|
245
399
|
declare function useShellChrome(): ShellChromeValue;
|
|
246
400
|
|
|
401
|
+
/**
|
|
402
|
+
* Returns the mode value supplied to ShellProvider/ShellChrome, or null if
|
|
403
|
+
* the host app didn't pass a `mode` prop. Components like <ModePill /> use
|
|
404
|
+
* this to conditionally render.
|
|
405
|
+
*/
|
|
406
|
+
declare function useShellMode(): ShellModeValue | null;
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Returns the nav items value supplied to ShellChrome, or null if the host
|
|
410
|
+
* app didn't pass a `navItems` prop. The sidebar uses this to decide what
|
|
411
|
+
* rows to render.
|
|
412
|
+
*/
|
|
413
|
+
declare function useShellNavItems(): ShellNavItemsValue | null;
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Returns the user's navigation rendering preference supplied to
|
|
417
|
+
* ShellChrome, or null if not provided. NavItem uses this to decide
|
|
418
|
+
* whether to expand sub-menus.
|
|
419
|
+
*/
|
|
420
|
+
declare function useShellNavigationPreference(): ShellNavigationPreferenceValue | null;
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Returns the active-role info supplied to ShellChrome, or null if not
|
|
424
|
+
* provided. UserMenu uses this to render the ROLES & ORGANIZATIONS badge.
|
|
425
|
+
*/
|
|
426
|
+
declare function useShellRole(): ShellRoleValue | null;
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Returns the footer data supplied to ShellChrome (links, commit/version
|
|
430
|
+
* info), or null if not provided. The Sidebar footer reads this to render
|
|
431
|
+
* Privacy / Terms / Subscriptions + commit copy button.
|
|
432
|
+
*/
|
|
433
|
+
declare function useShellFooter(): ShellFooterValue | null;
|
|
434
|
+
|
|
247
435
|
interface AppLayoutProps extends ShellSlots {
|
|
248
436
|
children: ReactNode;
|
|
249
437
|
buildInfo?: string;
|
|
250
438
|
}
|
|
251
|
-
|
|
439
|
+
/**
|
|
440
|
+
* Authenticated app shell composition: <Sidebar> on the left, <Header> on
|
|
441
|
+
* top, <main> for routed children, optional <Footer>, plus modal + overlay
|
|
442
|
+
* slots. All chrome data flows through ShellProvider/ShellChrome contexts —
|
|
443
|
+
* AppLayout itself takes only optional slots for modals/overlays/notifs.
|
|
444
|
+
*/
|
|
445
|
+
declare function AppLayout({ children, buildInfo, modalsSlot, notificationsSlot, overlaySlot, }: AppLayoutProps): react_jsx_runtime.JSX.Element;
|
|
252
446
|
|
|
253
447
|
interface HeaderProps {
|
|
254
|
-
|
|
448
|
+
/** Mobile menu open handler (renders the hamburger icon on mobile). */
|
|
449
|
+
onOpen?: () => void;
|
|
450
|
+
/** DOM id (defaults to 'mobile-nav-container'). */
|
|
451
|
+
id?: string;
|
|
255
452
|
}
|
|
256
|
-
|
|
453
|
+
/**
|
|
454
|
+
* Politogy header (top bar). Ported from
|
|
455
|
+
* react/app/src/layouts/AuthenticatedLayout.tsx lines 2545–2924 (2026-05-13).
|
|
456
|
+
*
|
|
457
|
+
* Composition (left → right):
|
|
458
|
+
* 1. Hamburger (mobile only) + small brand logo (mobile only) + title +
|
|
459
|
+
* breadcrumbs.
|
|
460
|
+
* 2. headerActions (app-supplied React node, e.g., page action buttons).
|
|
461
|
+
* 3. headerIconsSlot (app-supplied React node, e.g., FuelPopover,
|
|
462
|
+
* NewTextBellPopup, SystemAlertsMenu, NavigationToggleMenu,
|
|
463
|
+
* ImportProgressIndicator, DevNotesMenu, SupportRequestAction).
|
|
464
|
+
* 4. UserMenu (avatar + name/email VStack + chevron).
|
|
465
|
+
*
|
|
466
|
+
* NOTE: app-specific widgets stay in the app. The shell only renders
|
|
467
|
+
* what the app passes through `headerActions` + `headerIconsSlot`. As of
|
|
468
|
+
* v0.3.1, the shell no longer renders a separate `devNotesMenu` slot
|
|
469
|
+
* after `headerIconsSlot` — apps must inline DevNotesMenu inside
|
|
470
|
+
* `headerIconsSlot` so they have full control of icon ordering. The
|
|
471
|
+
* `devNotesMenu` prop on <ShellChrome> is still accepted for backward
|
|
472
|
+
* compat but is ignored.
|
|
473
|
+
*/
|
|
474
|
+
declare function Header({ onOpen, id }: HeaderProps): react_jsx_runtime.JSX.Element;
|
|
257
475
|
|
|
258
476
|
interface SidebarProps {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
477
|
+
/** Mobile close handler (renders the X button on mobile when set). */
|
|
478
|
+
onClose?: () => void;
|
|
479
|
+
/** DOM id for the sidebar root (defaults to 'sidebar-container'). */
|
|
480
|
+
id?: string;
|
|
262
481
|
}
|
|
263
|
-
|
|
482
|
+
/**
|
|
483
|
+
* Politogy sidebar. Ported from
|
|
484
|
+
* react/app/src/layouts/AuthenticatedLayout.tsx lines 3289–4192 (2026-05-13)
|
|
485
|
+
* but stripped of the AI-sidebar block (moved to app's navItems pipeline).
|
|
486
|
+
*
|
|
487
|
+
* Renders, top to bottom:
|
|
488
|
+
* - Brand logo + (mobile) close button
|
|
489
|
+
* - Org logo (large) if present
|
|
490
|
+
* - <OrgPill /> — organization switcher
|
|
491
|
+
* - <ModePill /> — mode switcher
|
|
492
|
+
* - Nav items (from useShellNavItems)
|
|
493
|
+
* - Footer (Privacy / Terms / Subscriptions links + commit/version display)
|
|
494
|
+
*/
|
|
495
|
+
declare function Sidebar({ onClose, id }: SidebarProps): react_jsx_runtime.JSX.Element;
|
|
264
496
|
|
|
265
497
|
interface FooterProps {
|
|
266
498
|
buildInfo?: string;
|
|
@@ -268,17 +500,111 @@ interface FooterProps {
|
|
|
268
500
|
declare function Footer({ buildInfo }: FooterProps): react_jsx_runtime.JSX.Element;
|
|
269
501
|
|
|
270
502
|
/**
|
|
271
|
-
* Avatar dropdown rendered
|
|
272
|
-
*
|
|
503
|
+
* Avatar dropdown rendered on the right of the header. Ported to match the
|
|
504
|
+
* legacy menu in react/app/src/layouts/AuthenticatedLayout.tsx lines
|
|
505
|
+
* 2680–2898 (2026-05-13).
|
|
506
|
+
*
|
|
507
|
+
* Sections (in order):
|
|
508
|
+
* 1. Trigger — avatar + name/email VStack + chevron (md+ only).
|
|
509
|
+
* 2. My Profile / Continue Onboarding (gated) / Organization Settings.
|
|
510
|
+
* 3. ROLES & ORGANIZATIONS — current-org role Badge OR activeRoleConfig.
|
|
511
|
+
* 4. ACCOUNTS — current account indicator + linkedAccounts list with
|
|
512
|
+
* inline FiTrash2 remove + "Add Account" item.
|
|
513
|
+
* 5. Sign out.
|
|
273
514
|
*/
|
|
274
515
|
declare function UserMenu(): react_jsx_runtime.JSX.Element | null;
|
|
275
516
|
|
|
276
517
|
/**
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
518
|
+
* Sidebar organization switcher pill. Ported from
|
|
519
|
+
* react/app/src/layouts/AuthenticatedLayout.tsx lines 3795–3957 (2026-05-13).
|
|
520
|
+
*
|
|
521
|
+
* Reads useShellOrganization + useShellAuth. Renders nothing when there's
|
|
522
|
+
* no organization context.
|
|
523
|
+
*/
|
|
524
|
+
declare function OrgPill(): react_jsx_runtime.JSX.Element | null;
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Sidebar mode selector pill. Ported from
|
|
528
|
+
* react/app/src/layouts/AuthenticatedLayout.tsx lines 3959–4006 (2026-05-13).
|
|
529
|
+
*
|
|
530
|
+
* Reads useShellMode. Renders nothing when no mode context is supplied or
|
|
531
|
+
* when the app has only one mode available.
|
|
532
|
+
*/
|
|
533
|
+
declare function ModePill(): react_jsx_runtime.JSX.Element | null;
|
|
534
|
+
|
|
535
|
+
interface NavItemSubItem {
|
|
536
|
+
name: string;
|
|
537
|
+
icon?: unknown;
|
|
538
|
+
brandIcon?: string;
|
|
539
|
+
href?: string;
|
|
540
|
+
badge?: string;
|
|
541
|
+
subLabel?: string;
|
|
542
|
+
disabled?: boolean;
|
|
543
|
+
}
|
|
544
|
+
interface NavItemProps {
|
|
545
|
+
icon?: unknown;
|
|
546
|
+
brandIcon?: string;
|
|
547
|
+
children: ReactNode;
|
|
548
|
+
href?: string;
|
|
549
|
+
action?: () => void;
|
|
550
|
+
subItems?: NavItemSubItem[];
|
|
551
|
+
badge?: string;
|
|
552
|
+
subLabel?: string;
|
|
553
|
+
isSubItem?: boolean;
|
|
554
|
+
isExpanded?: boolean;
|
|
555
|
+
onToggle?: (menuKey?: string | null) => void;
|
|
556
|
+
menuKey?: string;
|
|
557
|
+
isDisabled?: boolean;
|
|
558
|
+
disabled?: boolean;
|
|
559
|
+
/** Catch-all for one-off Chakra Box overrides passed by callers. */
|
|
560
|
+
[key: string]: unknown;
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Single sidebar nav row. Ported verbatim from
|
|
564
|
+
* react/app/src/layouts/AuthenticatedLayout.tsx lines 1292–1730 (2026-05-13)
|
|
565
|
+
* with mode + navigation-preference context reads swapped for shell hooks.
|
|
566
|
+
*
|
|
567
|
+
* Renders:
|
|
568
|
+
* - Top-level rows with optional children (accordion).
|
|
569
|
+
* - Sub-items inside an expanded parent (children list).
|
|
570
|
+
* - Active state via `data-nav-item-active` and primary-color fill.
|
|
571
|
+
* - Mode-aware hover gradient that sweeps left-to-right.
|
|
280
572
|
*/
|
|
281
|
-
declare function
|
|
573
|
+
declare function NavItem({ icon, brandIcon, children, href, action, subItems, badge, subLabel, isSubItem, isExpanded, onToggle, menuKey, isDisabled: navIsDisabled, disabled, ...rest }: NavItemProps): react_jsx_runtime.JSX.Element;
|
|
574
|
+
|
|
575
|
+
interface BrandLogoProps {
|
|
576
|
+
src?: string;
|
|
577
|
+
alt?: string;
|
|
578
|
+
className?: string;
|
|
579
|
+
style?: CSSProperties;
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Mode-aware brand logo rendered in the sidebar header. The host app
|
|
583
|
+
* supplies `src` (e.g., a different image per mode); the shell wraps it
|
|
584
|
+
* in a non-draggable <img> so it never accidentally drags on click.
|
|
585
|
+
*
|
|
586
|
+
* Render returns null when no src is supplied so consuming chrome can
|
|
587
|
+
* gracefully omit the slot.
|
|
588
|
+
*/
|
|
589
|
+
declare function BrandLogo({ src, alt, className, style }: BrandLogoProps): react_jsx_runtime.JSX.Element | null;
|
|
590
|
+
|
|
591
|
+
interface BrandIconProps {
|
|
592
|
+
/** Brand-icon name keyed off `/brand/icons/<name>.svg` in the app's public dir. */
|
|
593
|
+
name: string;
|
|
594
|
+
/** Pixel size shorthand — sets both width and height. */
|
|
595
|
+
size?: number;
|
|
596
|
+
className?: string;
|
|
597
|
+
style?: CSSProperties;
|
|
598
|
+
alt?: string;
|
|
599
|
+
/** Optional prefix for the icon path. Defaults to '/brand/icons/'. */
|
|
600
|
+
basePath?: string;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Brand-icon component used by sidebar NavItems. The actual SVG assets live
|
|
604
|
+
* in the consuming app's `public/brand/icons/<name>.svg` — shell never
|
|
605
|
+
* imports them directly, only references them by URL.
|
|
606
|
+
*/
|
|
607
|
+
declare function BrandIcon({ name, size, className, style, alt, basePath, }: BrandIconProps): react_jsx_runtime.JSX.Element;
|
|
282
608
|
|
|
283
609
|
/**
|
|
284
610
|
* Support icon + modal rendered in the header. Reads auth, org, and support
|
|
@@ -287,9 +613,53 @@ declare function OrgSelector(): react_jsx_runtime.JSX.Element | null;
|
|
|
287
613
|
*/
|
|
288
614
|
declare function SupportRequestButton(): react_jsx_runtime.JSX.Element | null;
|
|
289
615
|
|
|
616
|
+
interface CommitCopyButtonProps {
|
|
617
|
+
/**
|
|
618
|
+
* Pre-rendered environment chip (e.g., the app's own `EnvironmentBanner`).
|
|
619
|
+
* Takes precedence over `environmentLabel`. Click anywhere on the chip
|
|
620
|
+
* copies the full commit SHA.
|
|
621
|
+
*/
|
|
622
|
+
envNode?: ReactNode;
|
|
623
|
+
/**
|
|
624
|
+
* Environment label (e.g., 'staging', 'production', 'local'). When
|
|
625
|
+
* `envNode` is not supplied, the component renders a default chip
|
|
626
|
+
* keyed off this label with appropriate background/border color.
|
|
627
|
+
*/
|
|
628
|
+
environmentLabel?: string;
|
|
629
|
+
/** Full git commit SHA. Last 4 characters are rendered; click copies the full SHA. */
|
|
630
|
+
commit?: string;
|
|
631
|
+
/** App version, e.g., '2.34.1'. Renders as `v{version}`. */
|
|
632
|
+
version?: string;
|
|
633
|
+
/** ISO date string of the commit. Formatted as 'Mon D'. */
|
|
634
|
+
commitDate?: string;
|
|
635
|
+
/** Commit author name (e.g., 'Leland Smith'). First name is shown. */
|
|
636
|
+
commitAuthor?: string;
|
|
637
|
+
/** Full commit message body — shown as a tooltip over the env chip. */
|
|
638
|
+
commitLog?: string;
|
|
639
|
+
/**
|
|
640
|
+
* Optional click handler for the diagnostics icon. When unset, the
|
|
641
|
+
* icon is not rendered.
|
|
642
|
+
*/
|
|
643
|
+
onDiagnosticsClick?: () => void;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Footer commit info pill. Ported from
|
|
647
|
+
* `react/app/src/layouts/AuthenticatedLayout.tsx::CommitCopyButton`
|
|
648
|
+
* (lines 3017–3284, 2026-05-13).
|
|
649
|
+
*
|
|
650
|
+
* Visual: two stacked rows.
|
|
651
|
+
* Row 1: [env chip] | {last4 SHA} | v{version} | [diagnostics icon]
|
|
652
|
+
* Row 2: | {Mon D} | {firstName} | (only when date or author present)
|
|
653
|
+
*
|
|
654
|
+
* Clicking the env chip copies the full SHA via `useClipboard`, with a
|
|
655
|
+
* brief "Copied" toast that fades up. Hovering the env chip shows the
|
|
656
|
+
* full commit log in a tooltip.
|
|
657
|
+
*/
|
|
658
|
+
declare function CommitCopyButton({ envNode, environmentLabel, commit, version, commitDate, commitAuthor, commitLog, onDiagnosticsClick, }: CommitCopyButtonProps): react_jsx_runtime.JSX.Element;
|
|
659
|
+
|
|
290
660
|
interface ShellChromeProps {
|
|
291
661
|
children: ReactNode;
|
|
292
|
-
/** Drives <
|
|
662
|
+
/** Drives <OrgPill /> in the sidebar. */
|
|
293
663
|
organization?: ShellOrganizationValue | null;
|
|
294
664
|
/** Drives the UserMenu Switch-account section. */
|
|
295
665
|
linkedAccounts?: ShellLinkedAccountsValue | null;
|
|
@@ -299,6 +669,35 @@ interface ShellChromeProps {
|
|
|
299
669
|
devNotesMenu?: ReactNode;
|
|
300
670
|
/** UserMenu profile link target. Defaults to '/my-profile'. */
|
|
301
671
|
myProfileHref?: string;
|
|
672
|
+
/** Drives <ModePill /> + active row colors. */
|
|
673
|
+
mode?: ShellModeValue | null;
|
|
674
|
+
/** The sidebar nav rows. */
|
|
675
|
+
navItems?: ShellNavItem[];
|
|
676
|
+
/** User's nav-rendering preference. */
|
|
677
|
+
navigationPreference?: ShellNavigationPreferenceValue | null;
|
|
678
|
+
/** Active-role display info for the UserMenu role badge. */
|
|
679
|
+
role?: ShellRoleValue | null;
|
|
680
|
+
/** Footer data for the sidebar bottom row. */
|
|
681
|
+
footer?: ShellFooterValue | null;
|
|
682
|
+
/** Image src for the sidebar BrandLogo (top-left). */
|
|
683
|
+
brandLogoSrc?: string;
|
|
684
|
+
/** Header right-side icon stack (Fuel, NewTextBell, Alerts, Toggle, ImportProgress, etc). */
|
|
685
|
+
headerIconsSlot?: ReactNode;
|
|
686
|
+
/** href used by the UserMenu "Organization Settings" item. */
|
|
687
|
+
organizationSettingsHref?: string;
|
|
688
|
+
/** When true, UserMenu shows "Continue Onboarding" item. */
|
|
689
|
+
showContinueOnboarding?: boolean;
|
|
690
|
+
/** Click handler for UserMenu "Continue Onboarding". */
|
|
691
|
+
onContinueOnboarding?: () => void;
|
|
692
|
+
/** Header page title text. */
|
|
693
|
+
pageTitle?: string;
|
|
694
|
+
/** Header breadcrumb chips. */
|
|
695
|
+
breadcrumbs?: Array<{
|
|
696
|
+
label: string;
|
|
697
|
+
href?: string;
|
|
698
|
+
}>;
|
|
699
|
+
/** Header right-side action buttons (rendered before the icon row). */
|
|
700
|
+
headerActions?: ReactNode;
|
|
302
701
|
}
|
|
303
702
|
/**
|
|
304
703
|
* Drop-in chrome binding for apps where the org/linked-account/support data
|
|
@@ -312,7 +711,56 @@ interface ShellChromeProps {
|
|
|
312
711
|
* Apps that have all the data available at the ShellProvider construction
|
|
313
712
|
* site can pass the same props to <ShellProvider> directly instead.
|
|
314
713
|
*/
|
|
315
|
-
declare function ShellChrome({ children, organization, linkedAccounts, support, devNotesMenu, myProfileHref, }: ShellChromeProps): react_jsx_runtime.JSX.Element;
|
|
714
|
+
declare function ShellChrome({ children, organization, linkedAccounts, support, devNotesMenu, myProfileHref, mode, navItems, navigationPreference, role, footer, brandLogoSrc, headerIconsSlot, organizationSettingsHref, showContinueOnboarding, onContinueOnboarding, pageTitle, breadcrumbs, headerActions, }: ShellChromeProps): react_jsx_runtime.JSX.Element;
|
|
715
|
+
|
|
716
|
+
/** Returns a normalized 7-char hex color, or null if the input isn't valid. */
|
|
717
|
+
declare function normalizeHexColor(value?: string | null): string | null;
|
|
718
|
+
/**
|
|
719
|
+
* Returns an `rgba(...)` string lightened toward white by `amount` (0–1),
|
|
720
|
+
* or null if the input isn't a valid hex.
|
|
721
|
+
*/
|
|
722
|
+
declare function hexToRgba(hex: string, alpha: number): string | null;
|
|
723
|
+
/**
|
|
724
|
+
* Returns a hex color that is `amount` (0–1) blended from `hex` toward
|
|
725
|
+
* white. Used for the org-menu hover background.
|
|
726
|
+
*/
|
|
727
|
+
declare function lightenHexColor(hex: string, amount: number): string | null;
|
|
728
|
+
/**
|
|
729
|
+
* Reads `settings.brand_colors[0].value` off an org-like input and returns
|
|
730
|
+
* the first valid normalized hex. Returns null if the input doesn't have
|
|
731
|
+
* a usable brand color.
|
|
732
|
+
*/
|
|
733
|
+
declare function getOrganizationBrandColor(organization?: {
|
|
734
|
+
brandColor?: string | null;
|
|
735
|
+
settings?: {
|
|
736
|
+
brand_colors?: Array<{
|
|
737
|
+
value?: string | null;
|
|
738
|
+
}> | null;
|
|
739
|
+
} | null;
|
|
740
|
+
} | null): string | null;
|
|
741
|
+
/**
|
|
742
|
+
* Returns the two-letter badge for an organization name (e.g., "The Portland
|
|
743
|
+
* Company" -> "TP"). Falls back to "OR" when the input has no letters.
|
|
744
|
+
*/
|
|
745
|
+
declare function getOrganizationBadgeLetters(name?: string | null): string;
|
|
746
|
+
|
|
747
|
+
interface UserLike {
|
|
748
|
+
profile?: {
|
|
749
|
+
full_name?: string | null;
|
|
750
|
+
name?: string | null;
|
|
751
|
+
} | null;
|
|
752
|
+
user_metadata?: {
|
|
753
|
+
full_name?: string | null;
|
|
754
|
+
name?: string | null;
|
|
755
|
+
} | null;
|
|
756
|
+
email?: string | null;
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Resolves a user-facing display name from a user object. Tries profile
|
|
760
|
+
* fields first, then user_metadata, then the email local-part, then the
|
|
761
|
+
* raw email, finally falling back to "User".
|
|
762
|
+
*/
|
|
763
|
+
declare function getUserDisplayName(user: UserLike | null | undefined): string;
|
|
316
764
|
|
|
317
765
|
interface RegisterShellPrecacheOptions {
|
|
318
766
|
/** Path the host app serves the SW from. Default: '/sw-shell.js'. */
|
|
@@ -340,4 +788,4 @@ declare function registerShellPrecache(opts?: RegisterShellPrecacheOptions): Pro
|
|
|
340
788
|
*/
|
|
341
789
|
declare function buildSpeculationRules(currentApp: string, registry: AppRegistryEntry[]): string | null;
|
|
342
790
|
|
|
343
|
-
export { AppLayout, type AppRegistryEntry, BreadcrumbBar, Card, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, OrgSelector, PageContainer, PageHeader, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellLinkedAccounts, useShellOrganization, useShellSupport };
|
|
791
|
+
export { AppLayout, type AppRegistryEntry, BrandIcon, BrandLogo, BreadcrumbBar, Card, CommitCopyButton, type CommitCopyButtonProps, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, ModePill, NavItem, OrgPill, OrgPill as OrgSelector, PageContainer, PageHeader, type ShellActiveRoleConfig, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellChromeValue, ShellFooterContext, type ShellFooterLink, type ShellFooterValue, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, type ShellModeConfig, ShellModeContext, type ShellModeValue, type ShellNavItem, ShellNavItemsContext, type ShellNavItemsValue, ShellNavigationPreferenceContext, type ShellNavigationPreferenceValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, ShellRoleContext, type ShellRoleValue, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, getOrganizationBadgeLetters, getOrganizationBrandColor, getUserDisplayName, hexToRgba, lightenHexColor, normalizeHexColor, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellFooter, useShellLinkedAccounts, useShellMode, useShellNavItems, useShellNavigationPreference, useShellOrganization, useShellRole, useShellSupport };
|