@xenide-io/the-old-ui-theme 0.5.2 → 0.5.4

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.
Files changed (59) hide show
  1. package/README.md +47 -34
  2. package/dist/{index-Od4pIP4F.d.mts → Chip-C5hRFAhe.d.mts} +10 -606
  3. package/dist/{index-Od4pIP4F.d.ts → Chip-C5hRFAhe.d.ts} +10 -606
  4. package/dist/{chunk-G53YLHVE.mjs → chunk-E5ZBQYEX.mjs} +59 -9
  5. package/dist/{chunk-RZXHZWUB.mjs → chunk-SBBKXV35.mjs} +174 -222
  6. package/dist/index.d.mts +4 -80
  7. package/dist/index.d.ts +4 -80
  8. package/dist/index.js +562 -3746
  9. package/dist/index.mjs +3 -765
  10. package/dist/suite.d.mts +56 -25
  11. package/dist/suite.d.ts +56 -25
  12. package/dist/suite.js +248 -107
  13. package/dist/suite.mjs +217 -105
  14. package/dist/ui.d.mts +608 -2
  15. package/dist/ui.d.ts +608 -2
  16. package/dist/ui.js +232 -230
  17. package/dist/ui.mjs +2 -2
  18. package/package.json +2 -6
  19. package/scripts/install-theme-dev.sh +60 -0
  20. package/scripts/sync-posthog-icons.mjs +75 -0
  21. package/src/app/globals.css +1 -0
  22. package/src/components/ui/Chip.tsx +36 -18
  23. package/src/components/ui/CommandPalette.test.tsx +41 -0
  24. package/src/components/ui/CommandPalette.tsx +58 -9
  25. package/src/components/ui/DropdownMenu.tsx +50 -11
  26. package/src/components/ui/SegmentedControl.tsx +2 -1
  27. package/src/components/ui/SettingsLayout.tsx +19 -5
  28. package/src/components/ui/ThemeSwitcher.tsx +12 -3
  29. package/src/components/ui/interaction-primitives.test.tsx +52 -0
  30. package/src/styles/suite-skin.css +53 -1
  31. package/src/styles/themes.css +445 -1656
  32. package/src/suite/components/app-switcher.tsx +32 -25
  33. package/src/suite/components/command-palette-host.tsx +20 -8
  34. package/src/suite/components/suite-app-layout.tsx +31 -10
  35. package/src/suite/components/suite-bottom-nav.tsx +23 -18
  36. package/src/suite/components/suite-layout.test.tsx +44 -0
  37. package/src/suite/components/suite-layout.tsx +3 -3
  38. package/src/suite/components/suite-mobile-drawer.tsx +12 -0
  39. package/src/suite/components/suite-mobile-header.tsx +15 -9
  40. package/src/suite/components/suite-notification-bell.tsx +23 -11
  41. package/src/suite/components/suite-settings-mobile-nav.tsx +2 -0
  42. package/src/suite/components/suite-sidebar.tsx +54 -43
  43. package/src/suite/components/suite-user-menu.tsx +54 -26
  44. package/src/suite/components/today-page-frame.tsx +1 -1
  45. package/src/suite/icons/app-accents.ts +38 -43
  46. package/src/suite/icons/glyph-parts.tsx +16 -9
  47. package/src/suite/icons/glyphs.ts +130 -99
  48. package/src/suite/lib/apps.ts +1 -1
  49. package/src/suite/lib/injected.ts +12 -11
  50. package/src/suite/lib/use-sidebar-width.ts +23 -8
  51. package/src/components/charts/index.ts +0 -9
  52. package/src/components/charts/quill/BarChart.tsx +0 -85
  53. package/src/components/charts/quill/FunnelChart.tsx +0 -49
  54. package/src/components/charts/quill/InsightShell.tsx +0 -27
  55. package/src/components/charts/quill/MetricCard.tsx +0 -44
  56. package/src/components/charts/quill/PieChart.tsx +0 -81
  57. package/src/components/charts/quill/Sparkline.tsx +0 -57
  58. package/src/components/charts/quill/TimeSeriesLineChart.tsx +0 -62
  59. package/src/components/charts/quill/index.ts +0 -9
package/dist/suite.d.mts CHANGED
@@ -4,7 +4,7 @@ import { ClassValue } from 'clsx';
4
4
  export { m } from 'motion/react';
5
5
 
6
6
  /**
7
- * Today page content wrapper with soft atmosphere.
7
+ * Today page content wrapper with a soft themed visual treatment.
8
8
  * Does not own scrolling — `#main-content` is the scrollport so sticky headers work.
9
9
  * Glow/clouds are absolute and do not create a nested scrollport.
10
10
  */
@@ -130,10 +130,12 @@ declare function TodayEmptyState({ title, description, }: {
130
130
  */
131
131
  interface SuiteDropdownMenuProps {
132
132
  trigger: ReactNode;
133
+ triggerId?: string;
134
+ triggerDataTest?: string;
133
135
  children: ReactNode;
134
- 'aria-label': string;
135
- align?: 'start' | 'center' | 'end';
136
- side?: 'top' | 'right' | 'bottom' | 'left';
136
+ "aria-label": string;
137
+ align?: "start" | "center" | "end";
138
+ side?: "top" | "right" | "bottom" | "left";
137
139
  sideOffset?: number;
138
140
  className?: string;
139
141
  panelClassName?: string;
@@ -155,10 +157,14 @@ type SuiteCommandPaletteComponent = ComponentType<{
155
157
  onClose: () => void;
156
158
  placeholder?: string;
157
159
  className?: string;
160
+ id?: string;
161
+ dataTest?: string;
162
+ inputId?: string;
163
+ inputDataTest?: string;
158
164
  }>;
159
165
  /** App-branded spinner (each app has its own AppSpinner design). */
160
166
  type SuiteSpinnerComponent = ComponentType<{
161
- size?: 'sm' | 'md' | 'lg';
167
+ size?: "sm" | "md" | "lg";
162
168
  className?: string;
163
169
  label?: string;
164
170
  }>;
@@ -186,7 +192,7 @@ interface SuiteAppEntry {
186
192
  * visible app list, the cross-app navigation handler, and the theme
187
193
  * dropdown primitives.
188
194
  */
189
- declare function AppSwitcher({ apps, currentApp, onSelect, mark, title, collapsed, dropdownMenu: DropdownMenu, dropdownItem: DropdownItem, }: {
195
+ declare function AppSwitcher({ apps, currentApp, onSelect, mark, title, collapsed, dropdownMenu: DropdownMenu, dropdownItem: DropdownItem, triggerId, triggerDataTest, }: {
190
196
  apps: SuiteAppEntry[];
191
197
  currentApp: string;
192
198
  onSelect: (app: SuiteAppEntry) => void;
@@ -195,6 +201,8 @@ declare function AppSwitcher({ apps, currentApp, onSelect, mark, title, collapse
195
201
  collapsed?: boolean;
196
202
  dropdownMenu: SuiteDropdownMenuComponent;
197
203
  dropdownItem: SuiteDropdownItemComponent;
204
+ triggerId?: string;
205
+ triggerDataTest?: string;
198
206
  }): react.JSX.Element;
199
207
 
200
208
  /** Cross-app (suite) notification from `/api/notifications/` — shared across ShellStack apps. */
@@ -214,23 +222,30 @@ interface SuiteNotificationsResponse {
214
222
  notifications: SuiteNotification[];
215
223
  unread_count: number;
216
224
  }
217
- declare function SuiteNotificationBell({ fetchNotifications, markRead, markAllRead, dropdownMenu: DropdownMenu, cacheKey, }: {
225
+ declare function SuiteNotificationBell({ fetchNotifications, markRead, markAllRead, dropdownMenu: DropdownMenu, cacheKey, dataTest, triggerId, triggerDataTest, }: {
218
226
  fetchNotifications: () => Promise<SuiteNotificationsResponse>;
219
227
  markRead: (id: string) => Promise<unknown>;
220
228
  markAllRead: () => Promise<unknown>;
221
229
  dropdownMenu: SuiteDropdownMenuComponent;
222
230
  /** sessionStorage key for stale-while-revalidate; `null` disables caching. */
223
231
  cacheKey?: string | null;
232
+ dataTest?: string;
233
+ triggerId?: string;
234
+ triggerDataTest?: string;
224
235
  }): react.JSX.Element;
225
236
 
226
237
  /**
227
238
  * Cmd/Ctrl+K command palette host. Apps build the item list and inject the
228
239
  * theme CommandPalette primitive.
229
240
  */
230
- declare function CommandPaletteHost({ items, isAuthenticated, placeholder, commandPalette: CommandPalette, }: {
241
+ declare function CommandPaletteHost({ items, isAuthenticated, placeholder, id, dataTest, inputId, inputDataTest, commandPalette: CommandPalette, }: {
231
242
  items: SuiteCommandItem[];
232
243
  isAuthenticated?: boolean;
233
244
  placeholder?: string;
245
+ id?: string;
246
+ dataTest?: string;
247
+ inputId?: string;
248
+ inputDataTest?: string;
234
249
  commandPalette: SuiteCommandPaletteComponent;
235
250
  }): react.JSX.Element | null;
236
251
 
@@ -244,7 +259,7 @@ declare function DeferredChrome({ children }: {
244
259
  * close, body scroll-lock and focus hand-off while open. Nav content stays
245
260
  * app-side via `children`.
246
261
  */
247
- declare function SuiteMobileDrawer({ open, onClose, children, side, showCloseButton, title, closeLabel, backdropLabel, dialogLabel, durationMs, dataTest, panelDataTest, panelClassName, }: {
262
+ declare function SuiteMobileDrawer({ open, onClose, children, side, showCloseButton, title, closeLabel, backdropLabel, dialogLabel, durationMs, dataTest, panelDataTest, backdropId, backdropDataTest, closeButtonId, closeButtonDataTest, panelClassName, }: {
248
263
  open: boolean;
249
264
  onClose: () => void;
250
265
  children: ReactNode;
@@ -262,13 +277,17 @@ declare function SuiteMobileDrawer({ open, onClose, children, side, showCloseBut
262
277
  durationMs?: number;
263
278
  dataTest?: string;
264
279
  panelDataTest?: string;
280
+ backdropId?: string;
281
+ backdropDataTest?: string;
282
+ closeButtonId?: string;
283
+ closeButtonDataTest?: string;
265
284
  /** Panel surface overrides (e.g. `bg-ph-canvas`). */
266
285
  panelClassName?: string;
267
286
  }): react.JSX.Element | null;
268
287
 
269
288
  type SuiteMenuIcon = ComponentType<{
270
289
  className?: string;
271
- 'aria-hidden'?: boolean | 'true' | 'false';
290
+ "aria-hidden"?: boolean | "true" | "false";
272
291
  }>;
273
292
  /**
274
293
  * Suite mobile app bar — the standardized top of every app on phone/tablet.
@@ -276,7 +295,7 @@ type SuiteMenuIcon = ComponentType<{
276
295
  * Translucent + blurred (suite-skin.css `.suite-app-bar`), safe-area aware,
277
296
  * 44px minimum touch targets. Desktop chrome (rail/top bar) stays app-side.
278
297
  */
279
- declare function SuiteMobileHeader({ onMenuClick, menuIcon: MenuIcon, title, actions, menuLabel, menuDataTest, dataTest, className, }: {
298
+ declare function SuiteMobileHeader({ onMenuClick, menuIcon: MenuIcon, title, actions, menuLabel, menuId, menuDataTest, dataTest, className, }: {
280
299
  /** Optional — omit to drop the hamburger (bottom-nav apps don't need one). */
281
300
  onMenuClick?: () => void;
282
301
  /** Leading button glyph — defaults to Menu; browse-style drawers can swap it. */
@@ -286,6 +305,7 @@ declare function SuiteMobileHeader({ onMenuClick, menuIcon: MenuIcon, title, act
286
305
  /** Right-hand slot — search, bell, avatar (keep this order). */
287
306
  actions?: ReactNode;
288
307
  menuLabel?: string;
308
+ menuId?: string;
289
309
  menuDataTest?: string;
290
310
  dataTest?: string;
291
311
  className?: string;
@@ -319,22 +339,25 @@ interface SuiteUserMenuProps {
319
339
  onSignOut: () => void;
320
340
  /** Fallback letter(s) when there is no avatar image. */
321
341
  fallbackInitials?: string;
342
+ /** Show the old desktop sidebar sign-out action beside the avatar. */
343
+ showSignOutAction?: boolean;
322
344
  dataTest?: string;
345
+ triggerId?: string;
346
+ triggerDataTest?: string;
323
347
  className?: string;
324
348
  }
325
349
  /**
326
- * Suite account context menu — one tap on the avatar opens a small menu
327
- * with profile settings and sign out. Used in the mobile app bar of every
328
- * app so account actions behave identically across the suite (no dedicated
329
- * logout icon cluttering the mobile chrome).
350
+ * Suite account context menu — one tap on the avatar opens a small menu with
351
+ * profile settings and sign out. Desktop sidebars can also expose the legacy
352
+ * adjacent sign-out action without adding it to mobile chrome.
330
353
  */
331
- declare function SuiteUserMenu({ name, email, image, settingsHref, onSignOut, fallbackInitials, dataTest, className, }: SuiteUserMenuProps): react.JSX.Element;
354
+ declare function SuiteUserMenu({ name, email, image, settingsHref, onSignOut, fallbackInitials, showSignOutAction, dataTest, triggerId, triggerDataTest, className, }: SuiteUserMenuProps): react.JSX.Element;
332
355
 
333
356
  /** Any icon component that accepts sizing/stroke props (Lucide, theme icons). */
334
357
  type SuiteNavIcon = ComponentType<{
335
358
  className?: string;
336
359
  strokeWidth?: number | string;
337
- 'aria-hidden'?: boolean | 'true' | 'false';
360
+ "aria-hidden"?: boolean | "true" | "false";
338
361
  }>;
339
362
  /**
340
363
  * Suite bottom navigation — the mobile/tablet primary nav, identical in
@@ -347,6 +370,7 @@ interface SuiteBottomNavItem {
347
370
  href: string;
348
371
  label: string;
349
372
  icon: SuiteNavIcon;
373
+ id?: string;
350
374
  active?: boolean;
351
375
  dataTest?: string;
352
376
  }
@@ -368,7 +392,7 @@ interface SuiteAppDefinition {
368
392
  slug: SuiteAppSlug;
369
393
  name: string;
370
394
  description: string;
371
- /** Public asset path — every app hosts all four icons. */
395
+ /** Public asset path — every app hosts its suite icon. */
372
396
  icon: string;
373
397
  /** Landing route used after cross-app SSO redirect. */
374
398
  landing: string;
@@ -506,19 +530,20 @@ declare function SuiteAiPanel({ presets, emptyState, title, fetchChat, sendMessa
506
530
  * colour like any lucide icon.
507
531
  */
508
532
  type SuiteGlyphElement = {
509
- kind: 'path';
533
+ kind: "path";
510
534
  d: string;
511
535
  accent?: boolean;
512
536
  filled?: boolean;
537
+ transform?: string;
513
538
  } | {
514
- kind: 'circle';
539
+ kind: "circle";
515
540
  cx: number;
516
541
  cy: number;
517
542
  r: number;
518
543
  accent?: boolean;
519
544
  filled?: boolean;
520
545
  } | {
521
- kind: 'rect';
546
+ kind: "rect";
522
547
  x: number;
523
548
  y: number;
524
549
  width: number;
@@ -537,7 +562,7 @@ interface SuiteGlyph {
537
562
  */
538
563
  animatedAccent?: boolean;
539
564
  }
540
- type SuiteIconName = 'timer-shell' | 'kanban-wave' | 'squid-doc' | 'stack-hex' | 'crew-bot' | 'workspace' | 'organisation' | 'integration-plug' | 'suite-grid' | 'bell-wave' | 'today-sun';
565
+ type SuiteIconName = "timer-shell" | "kanban-wave" | "squid-doc" | "stack-hex" | "crew-bot" | "nakama-fist" | "workspace" | "organisation" | "integration-plug" | "suite-grid" | "bell-wave" | "today-sun";
541
566
  declare const SUITE_GLYPHS: Record<SuiteIconName, SuiteGlyph>;
542
567
  declare const SUITE_ICON_NAMES: SuiteIconName[];
543
568
 
@@ -547,7 +572,7 @@ declare const SUITE_ICON_NAMES: SuiteIconName[];
547
572
  * `onTileAccent` drive `<SuiteAppIcon>` (the programmatic favicon-style
548
573
  * tile + glyph mark).
549
574
  */
550
- type SuiteAccentSlug = 'turtletime' | 'tides' | 'kraken' | 'shellstack' | 'crew' | 'nakama';
575
+ type SuiteAccentSlug = "turtletime" | "tides" | "kraken" | "shellstack" | "crew" | "nakama";
551
576
  interface SuiteAppAccent {
552
577
  /** Display name (default aria label for app marks). */
553
578
  label: string;
@@ -618,12 +643,13 @@ declare const SIDEBAR_DEFAULT_WIDTH = 320;
618
643
  * Shared suite sidebar resizing: drag below the threshold to collapse,
619
644
  * drag the rail edge out to expand, and double-click to reset.
620
645
  */
621
- declare function useSidebarWidth(storageKey: string): {
646
+ declare function useSidebarWidth(storageKey: string, defaultWidth?: number): {
622
647
  width: number;
623
648
  collapsed: boolean;
624
649
  setCollapsed: (value: boolean) => void;
625
650
  resetWidth: () => void;
626
651
  startResize: (event: PointerEvent<HTMLDivElement>) => void;
652
+ resizeBy: (delta: number) => void;
627
653
  };
628
654
 
629
655
  declare function cn(...inputs: ClassValue[]): string;
@@ -785,6 +811,7 @@ interface SuiteSettingsNavItem {
785
811
  label: string;
786
812
  href: string;
787
813
  icon: ElementType | ReactNode;
814
+ id?: string;
788
815
  testId?: string;
789
816
  }
790
817
  interface SuiteSettingsMobileNavProps {
@@ -808,6 +835,8 @@ interface SuiteSidebarNavItem {
808
835
  href: string;
809
836
  label: string;
810
837
  icon: SuiteNavIcon;
838
+ id?: string;
839
+ dataTest?: string;
811
840
  active?: boolean;
812
841
  onClick?: () => void;
813
842
  badge?: ReactNode;
@@ -857,6 +886,8 @@ interface SuiteAppLayoutProps {
857
886
  lockMainScroll?: boolean;
858
887
  /** Drag this to resize the sidebar. */
859
888
  onStartResize?: (e: PointerEvent<HTMLDivElement>) => void;
889
+ /** Keyboard equivalent for the resize handle. */
890
+ onResizeBy?: (delta: number) => void;
860
891
  /** Double-click to reset sidebar width. */
861
892
  onResetWidth?: () => void;
862
893
  className?: string;
@@ -866,6 +897,6 @@ interface SuiteAppLayoutProps {
866
897
  * one `#main-content` landmark. Desktop: fixed sidebar + scrollable main.
867
898
  * Mobile: header + main + bottom nav.
868
899
  */
869
- declare function SuiteAppLayout({ sidebar, children, mobileHeader, bottomNav, sidebarWidth, collapsed, lockMainScroll, onStartResize, onResetWidth, className, }: SuiteAppLayoutProps): react.JSX.Element;
900
+ declare function SuiteAppLayout({ sidebar, children, mobileHeader, bottomNav, sidebarWidth, collapsed, lockMainScroll, onStartResize, onResizeBy, onResetWidth, className, }: SuiteAppLayoutProps): react.JSX.Element;
870
901
 
871
902
  export { APP_ACCENTS, APP_GLYPHS, AnimatedMoon, AnimatedSun, AppSwitcher, AppSwitcherChevron, AppSwitcherMark, CommandPaletteHost, DeferredChrome, SIDEBAR_COLLAPSE_THRESHOLD, SIDEBAR_DEFAULT_WIDTH, SIDEBAR_MAX_WIDTH, SIDEBAR_MIN_EXPANDED_WIDTH, SIDEBAR_RAIL_WIDTH, SUITE_APPS, SUITE_APP_MAP, SUITE_GLYPHS, SUITE_ICON_NAMES, SUITE_OPEN_ASK_AI_EVENT, SUITE_SPRINGS, SourceAppGlyph, type SuiteAccentSlug, type SuiteAiChatMessage, SuiteAiPanel, type SuiteAiPreset, type SuiteAppAccent, type SuiteAppDefinition, type SuiteAppEntry, SuiteAppIcon, type SuiteAppIconProps, SuiteAppLayout, type SuiteAppLayoutProps, type SuiteAppSlug, SuiteAppStrip, type SuiteAskAiOpenDetail, SuiteBottomNav, type SuiteBottomNavItem, SuiteBreadcrumbs, type SuiteBreadcrumbsProps, type SuiteCommandItem, type SuiteCommandPaletteComponent, type SuiteDropdownItemComponent, type SuiteDropdownMenuComponent, type SuiteDropdownMenuProps, SuiteEmptyState, type SuiteGlyph, type SuiteGlyphElement, SuiteIcon, type SuiteIconName, type SuiteIconProps, SuiteMobileDrawer, SuiteMobileHeader, SuiteMotionProvider, type SuiteNotification, SuiteNotificationBell, type SuiteNotificationsResponse, SuitePage, SuitePageHeader, type SuitePageWidth, type SuiteResolvedTheme, SuiteSectionHeader, SuiteSettingsLayout, type SuiteSettingsLayoutProps, SuiteSettingsMobileNav, type SuiteSettingsNavItem, SuiteSidebar, type SuiteSidebarNavItem, SuiteSkeleton, SuiteSkeletonCard, SuiteSkeletonList, type SuiteSpinnerComponent, type SuiteSpringName, SuiteTabList, type SuiteTheme, type SuiteThemeConfig, type SuiteThemeContextValue, SuiteThemeProvider, SuiteToolbar, SuiteUserMenu, type SuiteUserMenuProps, TodayAskAiCard, TodayCalibrating, TodayEmptyAction, TodayEmptyState, TodayHero, TodayLayout, TodayPageFrame, TodayPanel, type TodayPrimaryAccent, TodayPrimaryAction, TodaySection, TodayTimeIcon, TodayTopBar, appSwitcherMarkClass, appSwitcherMenuItemClass, appSwitcherTriggerClass, cn, getTodayGreeting, openSuiteAskAi, resolveSuiteNotificationHref, sourceToSuiteApp, suiteAppBaseUrl, suiteAppLabel, useIdleMount, useSidebarWidth, useSuiteTheme };
package/dist/suite.d.ts CHANGED
@@ -4,7 +4,7 @@ import { ClassValue } from 'clsx';
4
4
  export { m } from 'motion/react';
5
5
 
6
6
  /**
7
- * Today page content wrapper with soft atmosphere.
7
+ * Today page content wrapper with a soft themed visual treatment.
8
8
  * Does not own scrolling — `#main-content` is the scrollport so sticky headers work.
9
9
  * Glow/clouds are absolute and do not create a nested scrollport.
10
10
  */
@@ -130,10 +130,12 @@ declare function TodayEmptyState({ title, description, }: {
130
130
  */
131
131
  interface SuiteDropdownMenuProps {
132
132
  trigger: ReactNode;
133
+ triggerId?: string;
134
+ triggerDataTest?: string;
133
135
  children: ReactNode;
134
- 'aria-label': string;
135
- align?: 'start' | 'center' | 'end';
136
- side?: 'top' | 'right' | 'bottom' | 'left';
136
+ "aria-label": string;
137
+ align?: "start" | "center" | "end";
138
+ side?: "top" | "right" | "bottom" | "left";
137
139
  sideOffset?: number;
138
140
  className?: string;
139
141
  panelClassName?: string;
@@ -155,10 +157,14 @@ type SuiteCommandPaletteComponent = ComponentType<{
155
157
  onClose: () => void;
156
158
  placeholder?: string;
157
159
  className?: string;
160
+ id?: string;
161
+ dataTest?: string;
162
+ inputId?: string;
163
+ inputDataTest?: string;
158
164
  }>;
159
165
  /** App-branded spinner (each app has its own AppSpinner design). */
160
166
  type SuiteSpinnerComponent = ComponentType<{
161
- size?: 'sm' | 'md' | 'lg';
167
+ size?: "sm" | "md" | "lg";
162
168
  className?: string;
163
169
  label?: string;
164
170
  }>;
@@ -186,7 +192,7 @@ interface SuiteAppEntry {
186
192
  * visible app list, the cross-app navigation handler, and the theme
187
193
  * dropdown primitives.
188
194
  */
189
- declare function AppSwitcher({ apps, currentApp, onSelect, mark, title, collapsed, dropdownMenu: DropdownMenu, dropdownItem: DropdownItem, }: {
195
+ declare function AppSwitcher({ apps, currentApp, onSelect, mark, title, collapsed, dropdownMenu: DropdownMenu, dropdownItem: DropdownItem, triggerId, triggerDataTest, }: {
190
196
  apps: SuiteAppEntry[];
191
197
  currentApp: string;
192
198
  onSelect: (app: SuiteAppEntry) => void;
@@ -195,6 +201,8 @@ declare function AppSwitcher({ apps, currentApp, onSelect, mark, title, collapse
195
201
  collapsed?: boolean;
196
202
  dropdownMenu: SuiteDropdownMenuComponent;
197
203
  dropdownItem: SuiteDropdownItemComponent;
204
+ triggerId?: string;
205
+ triggerDataTest?: string;
198
206
  }): react.JSX.Element;
199
207
 
200
208
  /** Cross-app (suite) notification from `/api/notifications/` — shared across ShellStack apps. */
@@ -214,23 +222,30 @@ interface SuiteNotificationsResponse {
214
222
  notifications: SuiteNotification[];
215
223
  unread_count: number;
216
224
  }
217
- declare function SuiteNotificationBell({ fetchNotifications, markRead, markAllRead, dropdownMenu: DropdownMenu, cacheKey, }: {
225
+ declare function SuiteNotificationBell({ fetchNotifications, markRead, markAllRead, dropdownMenu: DropdownMenu, cacheKey, dataTest, triggerId, triggerDataTest, }: {
218
226
  fetchNotifications: () => Promise<SuiteNotificationsResponse>;
219
227
  markRead: (id: string) => Promise<unknown>;
220
228
  markAllRead: () => Promise<unknown>;
221
229
  dropdownMenu: SuiteDropdownMenuComponent;
222
230
  /** sessionStorage key for stale-while-revalidate; `null` disables caching. */
223
231
  cacheKey?: string | null;
232
+ dataTest?: string;
233
+ triggerId?: string;
234
+ triggerDataTest?: string;
224
235
  }): react.JSX.Element;
225
236
 
226
237
  /**
227
238
  * Cmd/Ctrl+K command palette host. Apps build the item list and inject the
228
239
  * theme CommandPalette primitive.
229
240
  */
230
- declare function CommandPaletteHost({ items, isAuthenticated, placeholder, commandPalette: CommandPalette, }: {
241
+ declare function CommandPaletteHost({ items, isAuthenticated, placeholder, id, dataTest, inputId, inputDataTest, commandPalette: CommandPalette, }: {
231
242
  items: SuiteCommandItem[];
232
243
  isAuthenticated?: boolean;
233
244
  placeholder?: string;
245
+ id?: string;
246
+ dataTest?: string;
247
+ inputId?: string;
248
+ inputDataTest?: string;
234
249
  commandPalette: SuiteCommandPaletteComponent;
235
250
  }): react.JSX.Element | null;
236
251
 
@@ -244,7 +259,7 @@ declare function DeferredChrome({ children }: {
244
259
  * close, body scroll-lock and focus hand-off while open. Nav content stays
245
260
  * app-side via `children`.
246
261
  */
247
- declare function SuiteMobileDrawer({ open, onClose, children, side, showCloseButton, title, closeLabel, backdropLabel, dialogLabel, durationMs, dataTest, panelDataTest, panelClassName, }: {
262
+ declare function SuiteMobileDrawer({ open, onClose, children, side, showCloseButton, title, closeLabel, backdropLabel, dialogLabel, durationMs, dataTest, panelDataTest, backdropId, backdropDataTest, closeButtonId, closeButtonDataTest, panelClassName, }: {
248
263
  open: boolean;
249
264
  onClose: () => void;
250
265
  children: ReactNode;
@@ -262,13 +277,17 @@ declare function SuiteMobileDrawer({ open, onClose, children, side, showCloseBut
262
277
  durationMs?: number;
263
278
  dataTest?: string;
264
279
  panelDataTest?: string;
280
+ backdropId?: string;
281
+ backdropDataTest?: string;
282
+ closeButtonId?: string;
283
+ closeButtonDataTest?: string;
265
284
  /** Panel surface overrides (e.g. `bg-ph-canvas`). */
266
285
  panelClassName?: string;
267
286
  }): react.JSX.Element | null;
268
287
 
269
288
  type SuiteMenuIcon = ComponentType<{
270
289
  className?: string;
271
- 'aria-hidden'?: boolean | 'true' | 'false';
290
+ "aria-hidden"?: boolean | "true" | "false";
272
291
  }>;
273
292
  /**
274
293
  * Suite mobile app bar — the standardized top of every app on phone/tablet.
@@ -276,7 +295,7 @@ type SuiteMenuIcon = ComponentType<{
276
295
  * Translucent + blurred (suite-skin.css `.suite-app-bar`), safe-area aware,
277
296
  * 44px minimum touch targets. Desktop chrome (rail/top bar) stays app-side.
278
297
  */
279
- declare function SuiteMobileHeader({ onMenuClick, menuIcon: MenuIcon, title, actions, menuLabel, menuDataTest, dataTest, className, }: {
298
+ declare function SuiteMobileHeader({ onMenuClick, menuIcon: MenuIcon, title, actions, menuLabel, menuId, menuDataTest, dataTest, className, }: {
280
299
  /** Optional — omit to drop the hamburger (bottom-nav apps don't need one). */
281
300
  onMenuClick?: () => void;
282
301
  /** Leading button glyph — defaults to Menu; browse-style drawers can swap it. */
@@ -286,6 +305,7 @@ declare function SuiteMobileHeader({ onMenuClick, menuIcon: MenuIcon, title, act
286
305
  /** Right-hand slot — search, bell, avatar (keep this order). */
287
306
  actions?: ReactNode;
288
307
  menuLabel?: string;
308
+ menuId?: string;
289
309
  menuDataTest?: string;
290
310
  dataTest?: string;
291
311
  className?: string;
@@ -319,22 +339,25 @@ interface SuiteUserMenuProps {
319
339
  onSignOut: () => void;
320
340
  /** Fallback letter(s) when there is no avatar image. */
321
341
  fallbackInitials?: string;
342
+ /** Show the old desktop sidebar sign-out action beside the avatar. */
343
+ showSignOutAction?: boolean;
322
344
  dataTest?: string;
345
+ triggerId?: string;
346
+ triggerDataTest?: string;
323
347
  className?: string;
324
348
  }
325
349
  /**
326
- * Suite account context menu — one tap on the avatar opens a small menu
327
- * with profile settings and sign out. Used in the mobile app bar of every
328
- * app so account actions behave identically across the suite (no dedicated
329
- * logout icon cluttering the mobile chrome).
350
+ * Suite account context menu — one tap on the avatar opens a small menu with
351
+ * profile settings and sign out. Desktop sidebars can also expose the legacy
352
+ * adjacent sign-out action without adding it to mobile chrome.
330
353
  */
331
- declare function SuiteUserMenu({ name, email, image, settingsHref, onSignOut, fallbackInitials, dataTest, className, }: SuiteUserMenuProps): react.JSX.Element;
354
+ declare function SuiteUserMenu({ name, email, image, settingsHref, onSignOut, fallbackInitials, showSignOutAction, dataTest, triggerId, triggerDataTest, className, }: SuiteUserMenuProps): react.JSX.Element;
332
355
 
333
356
  /** Any icon component that accepts sizing/stroke props (Lucide, theme icons). */
334
357
  type SuiteNavIcon = ComponentType<{
335
358
  className?: string;
336
359
  strokeWidth?: number | string;
337
- 'aria-hidden'?: boolean | 'true' | 'false';
360
+ "aria-hidden"?: boolean | "true" | "false";
338
361
  }>;
339
362
  /**
340
363
  * Suite bottom navigation — the mobile/tablet primary nav, identical in
@@ -347,6 +370,7 @@ interface SuiteBottomNavItem {
347
370
  href: string;
348
371
  label: string;
349
372
  icon: SuiteNavIcon;
373
+ id?: string;
350
374
  active?: boolean;
351
375
  dataTest?: string;
352
376
  }
@@ -368,7 +392,7 @@ interface SuiteAppDefinition {
368
392
  slug: SuiteAppSlug;
369
393
  name: string;
370
394
  description: string;
371
- /** Public asset path — every app hosts all four icons. */
395
+ /** Public asset path — every app hosts its suite icon. */
372
396
  icon: string;
373
397
  /** Landing route used after cross-app SSO redirect. */
374
398
  landing: string;
@@ -506,19 +530,20 @@ declare function SuiteAiPanel({ presets, emptyState, title, fetchChat, sendMessa
506
530
  * colour like any lucide icon.
507
531
  */
508
532
  type SuiteGlyphElement = {
509
- kind: 'path';
533
+ kind: "path";
510
534
  d: string;
511
535
  accent?: boolean;
512
536
  filled?: boolean;
537
+ transform?: string;
513
538
  } | {
514
- kind: 'circle';
539
+ kind: "circle";
515
540
  cx: number;
516
541
  cy: number;
517
542
  r: number;
518
543
  accent?: boolean;
519
544
  filled?: boolean;
520
545
  } | {
521
- kind: 'rect';
546
+ kind: "rect";
522
547
  x: number;
523
548
  y: number;
524
549
  width: number;
@@ -537,7 +562,7 @@ interface SuiteGlyph {
537
562
  */
538
563
  animatedAccent?: boolean;
539
564
  }
540
- type SuiteIconName = 'timer-shell' | 'kanban-wave' | 'squid-doc' | 'stack-hex' | 'crew-bot' | 'workspace' | 'organisation' | 'integration-plug' | 'suite-grid' | 'bell-wave' | 'today-sun';
565
+ type SuiteIconName = "timer-shell" | "kanban-wave" | "squid-doc" | "stack-hex" | "crew-bot" | "nakama-fist" | "workspace" | "organisation" | "integration-plug" | "suite-grid" | "bell-wave" | "today-sun";
541
566
  declare const SUITE_GLYPHS: Record<SuiteIconName, SuiteGlyph>;
542
567
  declare const SUITE_ICON_NAMES: SuiteIconName[];
543
568
 
@@ -547,7 +572,7 @@ declare const SUITE_ICON_NAMES: SuiteIconName[];
547
572
  * `onTileAccent` drive `<SuiteAppIcon>` (the programmatic favicon-style
548
573
  * tile + glyph mark).
549
574
  */
550
- type SuiteAccentSlug = 'turtletime' | 'tides' | 'kraken' | 'shellstack' | 'crew' | 'nakama';
575
+ type SuiteAccentSlug = "turtletime" | "tides" | "kraken" | "shellstack" | "crew" | "nakama";
551
576
  interface SuiteAppAccent {
552
577
  /** Display name (default aria label for app marks). */
553
578
  label: string;
@@ -618,12 +643,13 @@ declare const SIDEBAR_DEFAULT_WIDTH = 320;
618
643
  * Shared suite sidebar resizing: drag below the threshold to collapse,
619
644
  * drag the rail edge out to expand, and double-click to reset.
620
645
  */
621
- declare function useSidebarWidth(storageKey: string): {
646
+ declare function useSidebarWidth(storageKey: string, defaultWidth?: number): {
622
647
  width: number;
623
648
  collapsed: boolean;
624
649
  setCollapsed: (value: boolean) => void;
625
650
  resetWidth: () => void;
626
651
  startResize: (event: PointerEvent<HTMLDivElement>) => void;
652
+ resizeBy: (delta: number) => void;
627
653
  };
628
654
 
629
655
  declare function cn(...inputs: ClassValue[]): string;
@@ -785,6 +811,7 @@ interface SuiteSettingsNavItem {
785
811
  label: string;
786
812
  href: string;
787
813
  icon: ElementType | ReactNode;
814
+ id?: string;
788
815
  testId?: string;
789
816
  }
790
817
  interface SuiteSettingsMobileNavProps {
@@ -808,6 +835,8 @@ interface SuiteSidebarNavItem {
808
835
  href: string;
809
836
  label: string;
810
837
  icon: SuiteNavIcon;
838
+ id?: string;
839
+ dataTest?: string;
811
840
  active?: boolean;
812
841
  onClick?: () => void;
813
842
  badge?: ReactNode;
@@ -857,6 +886,8 @@ interface SuiteAppLayoutProps {
857
886
  lockMainScroll?: boolean;
858
887
  /** Drag this to resize the sidebar. */
859
888
  onStartResize?: (e: PointerEvent<HTMLDivElement>) => void;
889
+ /** Keyboard equivalent for the resize handle. */
890
+ onResizeBy?: (delta: number) => void;
860
891
  /** Double-click to reset sidebar width. */
861
892
  onResetWidth?: () => void;
862
893
  className?: string;
@@ -866,6 +897,6 @@ interface SuiteAppLayoutProps {
866
897
  * one `#main-content` landmark. Desktop: fixed sidebar + scrollable main.
867
898
  * Mobile: header + main + bottom nav.
868
899
  */
869
- declare function SuiteAppLayout({ sidebar, children, mobileHeader, bottomNav, sidebarWidth, collapsed, lockMainScroll, onStartResize, onResetWidth, className, }: SuiteAppLayoutProps): react.JSX.Element;
900
+ declare function SuiteAppLayout({ sidebar, children, mobileHeader, bottomNav, sidebarWidth, collapsed, lockMainScroll, onStartResize, onResizeBy, onResetWidth, className, }: SuiteAppLayoutProps): react.JSX.Element;
870
901
 
871
902
  export { APP_ACCENTS, APP_GLYPHS, AnimatedMoon, AnimatedSun, AppSwitcher, AppSwitcherChevron, AppSwitcherMark, CommandPaletteHost, DeferredChrome, SIDEBAR_COLLAPSE_THRESHOLD, SIDEBAR_DEFAULT_WIDTH, SIDEBAR_MAX_WIDTH, SIDEBAR_MIN_EXPANDED_WIDTH, SIDEBAR_RAIL_WIDTH, SUITE_APPS, SUITE_APP_MAP, SUITE_GLYPHS, SUITE_ICON_NAMES, SUITE_OPEN_ASK_AI_EVENT, SUITE_SPRINGS, SourceAppGlyph, type SuiteAccentSlug, type SuiteAiChatMessage, SuiteAiPanel, type SuiteAiPreset, type SuiteAppAccent, type SuiteAppDefinition, type SuiteAppEntry, SuiteAppIcon, type SuiteAppIconProps, SuiteAppLayout, type SuiteAppLayoutProps, type SuiteAppSlug, SuiteAppStrip, type SuiteAskAiOpenDetail, SuiteBottomNav, type SuiteBottomNavItem, SuiteBreadcrumbs, type SuiteBreadcrumbsProps, type SuiteCommandItem, type SuiteCommandPaletteComponent, type SuiteDropdownItemComponent, type SuiteDropdownMenuComponent, type SuiteDropdownMenuProps, SuiteEmptyState, type SuiteGlyph, type SuiteGlyphElement, SuiteIcon, type SuiteIconName, type SuiteIconProps, SuiteMobileDrawer, SuiteMobileHeader, SuiteMotionProvider, type SuiteNotification, SuiteNotificationBell, type SuiteNotificationsResponse, SuitePage, SuitePageHeader, type SuitePageWidth, type SuiteResolvedTheme, SuiteSectionHeader, SuiteSettingsLayout, type SuiteSettingsLayoutProps, SuiteSettingsMobileNav, type SuiteSettingsNavItem, SuiteSidebar, type SuiteSidebarNavItem, SuiteSkeleton, SuiteSkeletonCard, SuiteSkeletonList, type SuiteSpinnerComponent, type SuiteSpringName, SuiteTabList, type SuiteTheme, type SuiteThemeConfig, type SuiteThemeContextValue, SuiteThemeProvider, SuiteToolbar, SuiteUserMenu, type SuiteUserMenuProps, TodayAskAiCard, TodayCalibrating, TodayEmptyAction, TodayEmptyState, TodayHero, TodayLayout, TodayPageFrame, TodayPanel, type TodayPrimaryAccent, TodayPrimaryAction, TodaySection, TodayTimeIcon, TodayTopBar, appSwitcherMarkClass, appSwitcherMenuItemClass, appSwitcherTriggerClass, cn, getTodayGreeting, openSuiteAskAi, resolveSuiteNotificationHref, sourceToSuiteApp, suiteAppBaseUrl, suiteAppLabel, useIdleMount, useSidebarWidth, useSuiteTheme };