@the-portland-company/shell 0.2.0 → 0.3.0

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/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
2
3
  import { ReactNode, CSSProperties } from 'react';
3
4
  import { User, Session, SupabaseClient } from '@supabase/supabase-js';
4
5
 
@@ -100,8 +101,13 @@ interface AppRegistryEntry {
100
101
  * fuel/modal/notification components into the relevant slots.
101
102
  */
102
103
  interface ShellSlots {
103
- /** Right side of the header (next to user menu). */
104
- headerExtrasSlot?: ReactNode;
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;
105
111
  /** Modal layer rendered above everything (positioned absolute). */
106
112
  modalsSlot?: ReactNode;
107
113
  /** Notifications layer (toasts, popovers, badges). */
@@ -111,6 +117,119 @@ interface ShellSlots {
111
117
  /** Overlay always-on-top components (e.g., import progress indicator). */
112
118
  overlaySlot?: ReactNode;
113
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
+ environmentLabel?: string;
232
+ }
114
233
  /** Props for the top-level ShellProvider. */
115
234
  interface ShellProviderProps {
116
235
  children: ReactNode;
@@ -122,7 +241,7 @@ interface ShellProviderProps {
122
241
  appRegistry?: AppRegistryEntry[];
123
242
  /** Optional override for the base path if the app is mounted under a sub-path (e.g., '/contacts'). */
124
243
  basename?: string;
125
- /** If provided, shell renders <OrgSelector /> in the header. */
244
+ /** If provided, shell renders <OrgPill /> in the sidebar. */
126
245
  organization?: ShellOrganizationValue;
127
246
  /** If provided, UserMenu shows account switcher + add-account button. */
128
247
  linkedAccounts?: ShellLinkedAccountsValue;
@@ -142,7 +261,7 @@ interface ShellAuthValue {
142
261
  }
143
262
  /**
144
263
  * Organization that the current user belongs to. Apps supply this via
145
- * ShellProvider so the shell can render <OrgSelector /> in the header.
264
+ * ShellProvider so the shell can render <OrgPill /> in the sidebar.
146
265
  */
147
266
  interface ShellOrganization {
148
267
  id: string;
@@ -150,6 +269,8 @@ interface ShellOrganization {
150
269
  logoUrl?: string | null;
151
270
  /** Brand color as a hex string (e.g., '#0066cc'). Used for the org badge fallback. */
152
271
  brandColor?: string | null;
272
+ /** Optional user-facing role label in this organization ('owner' | 'admin' | etc.). */
273
+ role?: string | null;
153
274
  }
154
275
  interface ShellOrganizationValue {
155
276
  currentOrg: ShellOrganization | null;
@@ -159,6 +280,8 @@ interface ShellOrganizationValue {
159
280
  switchOrganization: (orgId: string) => Promise<void> | void;
160
281
  /** Optional link rendered at the bottom of the org menu, e.g., '/organizations/new'. */
161
282
  createOrgHref?: string;
283
+ /** True while the app is still resolving the org list (renders a skeleton). */
284
+ loadingOrgs?: boolean;
162
285
  }
163
286
  /**
164
287
  * An alternate user account the current user can switch into without signing
@@ -198,6 +321,30 @@ interface ShellSupportValue {
198
321
  }) => Promise<void>;
199
322
  }
200
323
 
324
+ declare const ShellOrgContext: react.Context<ShellOrganizationValue | null>;
325
+ declare const ShellLinkedAccountsContext: react.Context<ShellLinkedAccountsValue | null>;
326
+ declare const ShellSupportProviderContext: react.Context<ShellSupportValue | null>;
327
+ declare const ShellModeContext: react.Context<ShellModeValue | null>;
328
+ declare const ShellNavItemsContext: react.Context<ShellNavItemsValue | null>;
329
+ declare const ShellNavigationPreferenceContext: react.Context<ShellNavigationPreferenceValue | null>;
330
+ declare const ShellRoleContext: react.Context<ShellRoleValue | null>;
331
+ declare const ShellFooterContext: react.Context<ShellFooterValue | null>;
332
+ interface ShellChromeValue {
333
+ devNotesMenu: ReactNode | null;
334
+ myProfileHref: string;
335
+ brandLogoSrc?: string;
336
+ headerIconsSlot?: ReactNode;
337
+ organizationSettingsHref?: string;
338
+ showContinueOnboarding?: boolean;
339
+ onContinueOnboarding?: () => void;
340
+ pageTitle?: string;
341
+ breadcrumbs?: Array<{
342
+ label: string;
343
+ href?: string;
344
+ }>;
345
+ headerActions?: ReactNode;
346
+ }
347
+ declare const ShellChromeContext: react.Context<ShellChromeValue | null>;
201
348
  declare function ShellProvider({ children, supabaseClient, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
202
349
 
203
350
  declare function useShellAuth(): ShellAuthValue;
@@ -225,33 +372,105 @@ declare function useShellLinkedAccounts(): ShellLinkedAccountsValue | null;
225
372
  */
226
373
  declare function useShellSupport(): ShellSupportValue | null;
227
374
 
228
- interface ShellChromeValue {
229
- devNotesMenu: ReactNode | null;
230
- myProfileHref: string;
231
- }
232
375
  /**
233
- * Returns chrome-level options supplied to ShellProvider (devNotesMenu slot,
234
- * myProfileHref). Throws if used outside <ShellProvider>.
376
+ * Returns chrome-level options supplied to ShellProvider/ShellChrome
377
+ * (devNotesMenu slot, myProfileHref, header data, brand logo src, etc.).
378
+ * Throws if used outside <ShellProvider>.
235
379
  */
236
380
  declare function useShellChrome(): ShellChromeValue;
237
381
 
382
+ /**
383
+ * Returns the mode value supplied to ShellProvider/ShellChrome, or null if
384
+ * the host app didn't pass a `mode` prop. Components like <ModePill /> use
385
+ * this to conditionally render.
386
+ */
387
+ declare function useShellMode(): ShellModeValue | null;
388
+
389
+ /**
390
+ * Returns the nav items value supplied to ShellChrome, or null if the host
391
+ * app didn't pass a `navItems` prop. The sidebar uses this to decide what
392
+ * rows to render.
393
+ */
394
+ declare function useShellNavItems(): ShellNavItemsValue | null;
395
+
396
+ /**
397
+ * Returns the user's navigation rendering preference supplied to
398
+ * ShellChrome, or null if not provided. NavItem uses this to decide
399
+ * whether to expand sub-menus.
400
+ */
401
+ declare function useShellNavigationPreference(): ShellNavigationPreferenceValue | null;
402
+
403
+ /**
404
+ * Returns the active-role info supplied to ShellChrome, or null if not
405
+ * provided. UserMenu uses this to render the ROLES & ORGANIZATIONS badge.
406
+ */
407
+ declare function useShellRole(): ShellRoleValue | null;
408
+
409
+ /**
410
+ * Returns the footer data supplied to ShellChrome (links, commit/version
411
+ * info), or null if not provided. The Sidebar footer reads this to render
412
+ * Privacy / Terms / Subscriptions + commit copy button.
413
+ */
414
+ declare function useShellFooter(): ShellFooterValue | null;
415
+
238
416
  interface AppLayoutProps extends ShellSlots {
239
417
  children: ReactNode;
240
418
  buildInfo?: string;
241
419
  }
242
- declare function AppLayout({ children, buildInfo, headerExtrasSlot, modalsSlot, notificationsSlot, sidebarFooterSlot, overlaySlot, }: AppLayoutProps): react_jsx_runtime.JSX.Element;
420
+ /**
421
+ * Authenticated app shell composition: <Sidebar> on the left, <Header> on
422
+ * top, <main> for routed children, optional <Footer>, plus modal + overlay
423
+ * slots. All chrome data flows through ShellProvider/ShellChrome contexts —
424
+ * AppLayout itself takes only optional slots for modals/overlays/notifs.
425
+ */
426
+ declare function AppLayout({ children, buildInfo, modalsSlot, notificationsSlot, overlaySlot, }: AppLayoutProps): react_jsx_runtime.JSX.Element;
243
427
 
244
428
  interface HeaderProps {
245
- extrasSlot?: ReactNode;
429
+ /** Mobile menu open handler (renders the hamburger icon on mobile). */
430
+ onOpen?: () => void;
431
+ /** DOM id (defaults to 'mobile-nav-container'). */
432
+ id?: string;
246
433
  }
247
- declare function Header({ extrasSlot }: HeaderProps): react_jsx_runtime.JSX.Element;
434
+ /**
435
+ * Politogy header (top bar). Ported from
436
+ * react/app/src/layouts/AuthenticatedLayout.tsx lines 2545–2924 (2026-05-13).
437
+ *
438
+ * Composition (left → right):
439
+ * 1. Hamburger (mobile only) + small brand logo (mobile only) + title +
440
+ * breadcrumbs.
441
+ * 2. headerActions (app-supplied React node, e.g., page action buttons).
442
+ * 3. headerIconsSlot (app-supplied React node, e.g., FuelPopover,
443
+ * NewTextBellPopup, SystemAlertsMenu, NavigationToggleMenu,
444
+ * ImportProgressIndicator).
445
+ * 4. DevNotesMenu (from useShellChrome().devNotesMenu).
446
+ * 5. UserMenu (avatar + name/email VStack + chevron).
447
+ *
448
+ * NOTE: app-specific widgets stay in the app. The shell only renders
449
+ * what the app passes through `headerActions` + `headerIconsSlot` +
450
+ * `devNotesMenu`.
451
+ */
452
+ declare function Header({ onOpen, id }: HeaderProps): react_jsx_runtime.JSX.Element;
248
453
 
249
454
  interface SidebarProps {
250
- entries: AppRegistryEntry[];
251
- currentApp: string;
252
- footerSlot?: ReactNode;
455
+ /** Mobile close handler (renders the X button on mobile when set). */
456
+ onClose?: () => void;
457
+ /** DOM id for the sidebar root (defaults to 'sidebar-container'). */
458
+ id?: string;
253
459
  }
254
- declare function Sidebar({ entries, currentApp, footerSlot }: SidebarProps): react_jsx_runtime.JSX.Element;
460
+ /**
461
+ * Politogy sidebar. Ported from
462
+ * react/app/src/layouts/AuthenticatedLayout.tsx lines 3289–4192 (2026-05-13)
463
+ * but stripped of the AI-sidebar block (moved to app's navItems pipeline).
464
+ *
465
+ * Renders, top to bottom:
466
+ * - Brand logo + (mobile) close button
467
+ * - Org logo (large) if present
468
+ * - <OrgPill /> — organization switcher
469
+ * - <ModePill /> — mode switcher
470
+ * - Nav items (from useShellNavItems)
471
+ * - Footer (Privacy / Terms / Subscriptions links + commit/version display)
472
+ */
473
+ declare function Sidebar({ onClose, id }: SidebarProps): react_jsx_runtime.JSX.Element;
255
474
 
256
475
  interface FooterProps {
257
476
  buildInfo?: string;
@@ -259,17 +478,111 @@ interface FooterProps {
259
478
  declare function Footer({ buildInfo }: FooterProps): react_jsx_runtime.JSX.Element;
260
479
 
261
480
  /**
262
- * Avatar dropdown rendered at the right side of the header. Reads auth,
263
- * linked-accounts, and chrome context from ShellProvider.
481
+ * Avatar dropdown rendered on the right of the header. Ported to match the
482
+ * legacy menu in react/app/src/layouts/AuthenticatedLayout.tsx lines
483
+ * 2680–2898 (2026-05-13).
484
+ *
485
+ * Sections (in order):
486
+ * 1. Trigger — avatar + name/email VStack + chevron (md+ only).
487
+ * 2. My Profile / Continue Onboarding (gated) / Organization Settings.
488
+ * 3. ROLES & ORGANIZATIONS — current-org role Badge OR activeRoleConfig.
489
+ * 4. ACCOUNTS — current account indicator + linkedAccounts list with
490
+ * inline FiTrash2 remove + "Add Account" item.
491
+ * 5. Sign out.
264
492
  */
265
493
  declare function UserMenu(): react_jsx_runtime.JSX.Element | null;
266
494
 
267
495
  /**
268
- * Organization switcher rendered in the header. Reads from
269
- * useShellOrganization(); renders nothing when no `organization` prop was
270
- * supplied to ShellProvider.
496
+ * Sidebar organization switcher pill. Ported from
497
+ * react/app/src/layouts/AuthenticatedLayout.tsx lines 3795–3957 (2026-05-13).
498
+ *
499
+ * Reads useShellOrganization + useShellAuth. Renders nothing when there's
500
+ * no organization context.
501
+ */
502
+ declare function OrgPill(): react_jsx_runtime.JSX.Element | null;
503
+
504
+ /**
505
+ * Sidebar mode selector pill. Ported from
506
+ * react/app/src/layouts/AuthenticatedLayout.tsx lines 3959–4006 (2026-05-13).
507
+ *
508
+ * Reads useShellMode. Renders nothing when no mode context is supplied or
509
+ * when the app has only one mode available.
510
+ */
511
+ declare function ModePill(): react_jsx_runtime.JSX.Element | null;
512
+
513
+ interface NavItemSubItem {
514
+ name: string;
515
+ icon?: unknown;
516
+ brandIcon?: string;
517
+ href?: string;
518
+ badge?: string;
519
+ subLabel?: string;
520
+ disabled?: boolean;
521
+ }
522
+ interface NavItemProps {
523
+ icon?: unknown;
524
+ brandIcon?: string;
525
+ children: ReactNode;
526
+ href?: string;
527
+ action?: () => void;
528
+ subItems?: NavItemSubItem[];
529
+ badge?: string;
530
+ subLabel?: string;
531
+ isSubItem?: boolean;
532
+ isExpanded?: boolean;
533
+ onToggle?: (menuKey?: string | null) => void;
534
+ menuKey?: string;
535
+ isDisabled?: boolean;
536
+ disabled?: boolean;
537
+ /** Catch-all for one-off Chakra Box overrides passed by callers. */
538
+ [key: string]: unknown;
539
+ }
540
+ /**
541
+ * Single sidebar nav row. Ported verbatim from
542
+ * react/app/src/layouts/AuthenticatedLayout.tsx lines 1292–1730 (2026-05-13)
543
+ * with mode + navigation-preference context reads swapped for shell hooks.
544
+ *
545
+ * Renders:
546
+ * - Top-level rows with optional children (accordion).
547
+ * - Sub-items inside an expanded parent (children list).
548
+ * - Active state via `data-nav-item-active` and primary-color fill.
549
+ * - Mode-aware hover gradient that sweeps left-to-right.
550
+ */
551
+ 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;
552
+
553
+ interface BrandLogoProps {
554
+ src?: string;
555
+ alt?: string;
556
+ className?: string;
557
+ style?: CSSProperties;
558
+ }
559
+ /**
560
+ * Mode-aware brand logo rendered in the sidebar header. The host app
561
+ * supplies `src` (e.g., a different image per mode); the shell wraps it
562
+ * in a non-draggable <img> so it never accidentally drags on click.
563
+ *
564
+ * Render returns null when no src is supplied so consuming chrome can
565
+ * gracefully omit the slot.
566
+ */
567
+ declare function BrandLogo({ src, alt, className, style }: BrandLogoProps): react_jsx_runtime.JSX.Element | null;
568
+
569
+ interface BrandIconProps {
570
+ /** Brand-icon name keyed off `/brand/icons/<name>.svg` in the app's public dir. */
571
+ name: string;
572
+ /** Pixel size shorthand — sets both width and height. */
573
+ size?: number;
574
+ className?: string;
575
+ style?: CSSProperties;
576
+ alt?: string;
577
+ /** Optional prefix for the icon path. Defaults to '/brand/icons/'. */
578
+ basePath?: string;
579
+ }
580
+ /**
581
+ * Brand-icon component used by sidebar NavItems. The actual SVG assets live
582
+ * in the consuming app's `public/brand/icons/<name>.svg` — shell never
583
+ * imports them directly, only references them by URL.
271
584
  */
272
- declare function OrgSelector(): react_jsx_runtime.JSX.Element | null;
585
+ declare function BrandIcon({ name, size, className, style, alt, basePath, }: BrandIconProps): react_jsx_runtime.JSX.Element;
273
586
 
274
587
  /**
275
588
  * Support icon + modal rendered in the header. Reads auth, org, and support
@@ -278,6 +591,111 @@ declare function OrgSelector(): react_jsx_runtime.JSX.Element | null;
278
591
  */
279
592
  declare function SupportRequestButton(): react_jsx_runtime.JSX.Element | null;
280
593
 
594
+ interface ShellChromeProps {
595
+ children: ReactNode;
596
+ /** Drives <OrgPill /> in the sidebar. */
597
+ organization?: ShellOrganizationValue | null;
598
+ /** Drives the UserMenu Switch-account section. */
599
+ linkedAccounts?: ShellLinkedAccountsValue | null;
600
+ /** Drives <SupportRequestButton /> and modal submission. */
601
+ support?: ShellSupportValue | null;
602
+ /** Rendered in the header (typically <DevNotesMenu />). */
603
+ devNotesMenu?: ReactNode;
604
+ /** UserMenu profile link target. Defaults to '/my-profile'. */
605
+ myProfileHref?: string;
606
+ /** Drives <ModePill /> + active row colors. */
607
+ mode?: ShellModeValue | null;
608
+ /** The sidebar nav rows. */
609
+ navItems?: ShellNavItem[];
610
+ /** User's nav-rendering preference. */
611
+ navigationPreference?: ShellNavigationPreferenceValue | null;
612
+ /** Active-role display info for the UserMenu role badge. */
613
+ role?: ShellRoleValue | null;
614
+ /** Footer data for the sidebar bottom row. */
615
+ footer?: ShellFooterValue | null;
616
+ /** Image src for the sidebar BrandLogo (top-left). */
617
+ brandLogoSrc?: string;
618
+ /** Header right-side icon stack (Fuel, NewTextBell, Alerts, Toggle, ImportProgress, etc). */
619
+ headerIconsSlot?: ReactNode;
620
+ /** href used by the UserMenu "Organization Settings" item. */
621
+ organizationSettingsHref?: string;
622
+ /** When true, UserMenu shows "Continue Onboarding" item. */
623
+ showContinueOnboarding?: boolean;
624
+ /** Click handler for UserMenu "Continue Onboarding". */
625
+ onContinueOnboarding?: () => void;
626
+ /** Header page title text. */
627
+ pageTitle?: string;
628
+ /** Header breadcrumb chips. */
629
+ breadcrumbs?: Array<{
630
+ label: string;
631
+ href?: string;
632
+ }>;
633
+ /** Header right-side action buttons (rendered before the icon row). */
634
+ headerActions?: ReactNode;
635
+ }
636
+ /**
637
+ * Drop-in chrome binding for apps where the org/linked-account/support data
638
+ * lives in React contexts nested BELOW <ShellProvider> (e.g., an
639
+ * <OrganizationProvider> that itself depends on <AuthProvider>).
640
+ *
641
+ * Use this component inside those providers to feed the values into the
642
+ * shell's chrome contexts. Nested <Context.Provider> overrides the empty
643
+ * defaults set by <ShellProvider> at the top of the tree.
644
+ *
645
+ * Apps that have all the data available at the ShellProvider construction
646
+ * site can pass the same props to <ShellProvider> directly instead.
647
+ */
648
+ 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;
649
+
650
+ /** Returns a normalized 7-char hex color, or null if the input isn't valid. */
651
+ declare function normalizeHexColor(value?: string | null): string | null;
652
+ /**
653
+ * Returns an `rgba(...)` string lightened toward white by `amount` (0–1),
654
+ * or null if the input isn't a valid hex.
655
+ */
656
+ declare function hexToRgba(hex: string, alpha: number): string | null;
657
+ /**
658
+ * Returns a hex color that is `amount` (0–1) blended from `hex` toward
659
+ * white. Used for the org-menu hover background.
660
+ */
661
+ declare function lightenHexColor(hex: string, amount: number): string | null;
662
+ /**
663
+ * Reads `settings.brand_colors[0].value` off an org-like input and returns
664
+ * the first valid normalized hex. Returns null if the input doesn't have
665
+ * a usable brand color.
666
+ */
667
+ declare function getOrganizationBrandColor(organization?: {
668
+ brandColor?: string | null;
669
+ settings?: {
670
+ brand_colors?: Array<{
671
+ value?: string | null;
672
+ }> | null;
673
+ } | null;
674
+ } | null): string | null;
675
+ /**
676
+ * Returns the two-letter badge for an organization name (e.g., "The Portland
677
+ * Company" -> "TP"). Falls back to "OR" when the input has no letters.
678
+ */
679
+ declare function getOrganizationBadgeLetters(name?: string | null): string;
680
+
681
+ interface UserLike {
682
+ profile?: {
683
+ full_name?: string | null;
684
+ name?: string | null;
685
+ } | null;
686
+ user_metadata?: {
687
+ full_name?: string | null;
688
+ name?: string | null;
689
+ } | null;
690
+ email?: string | null;
691
+ }
692
+ /**
693
+ * Resolves a user-facing display name from a user object. Tries profile
694
+ * fields first, then user_metadata, then the email local-part, then the
695
+ * raw email, finally falling back to "User".
696
+ */
697
+ declare function getUserDisplayName(user: UserLike | null | undefined): string;
698
+
281
699
  interface RegisterShellPrecacheOptions {
282
700
  /** Path the host app serves the SW from. Default: '/sw-shell.js'. */
283
701
  scriptUrl?: string;
@@ -304,4 +722,4 @@ declare function registerShellPrecache(opts?: RegisterShellPrecacheOptions): Pro
304
722
  */
305
723
  declare function buildSpeculationRules(currentApp: string, registry: AppRegistryEntry[]): string | null;
306
724
 
307
- export { AppLayout, type AppRegistryEntry, BreadcrumbBar, Card, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, OrgSelector, PageContainer, PageHeader, type ShellAuthStatus, type ShellAuthValue, type ShellLinkedAccount, type ShellLinkedAccountsValue, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, type ShellSlots, type ShellSupportContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellLinkedAccounts, useShellOrganization, useShellSupport };
725
+ export { AppLayout, type AppRegistryEntry, BrandIcon, BrandLogo, BreadcrumbBar, Card, 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 };