@xenide-io/the-old-ui-theme 0.5.3 → 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 (49) hide show
  1. package/dist/{index-Od4pIP4F.d.mts → Chip-C5hRFAhe.d.mts} +10 -606
  2. package/dist/{index-Od4pIP4F.d.ts → Chip-C5hRFAhe.d.ts} +10 -606
  3. package/dist/{chunk-G53YLHVE.mjs → chunk-E5ZBQYEX.mjs} +59 -9
  4. package/dist/{chunk-VFTZXPXM.mjs → chunk-SBBKXV35.mjs} +144 -79
  5. package/dist/index.d.mts +3 -79
  6. package/dist/index.d.ts +3 -79
  7. package/dist/index.js +524 -3595
  8. package/dist/index.mjs +3 -765
  9. package/dist/suite.d.mts +38 -12
  10. package/dist/suite.d.ts +38 -12
  11. package/dist/suite.js +84 -15
  12. package/dist/suite.mjs +53 -13
  13. package/dist/ui.d.mts +608 -2
  14. package/dist/ui.d.ts +608 -2
  15. package/dist/ui.js +202 -87
  16. package/dist/ui.mjs +2 -2
  17. package/package.json +2 -6
  18. package/scripts/install-theme-dev.sh +60 -0
  19. package/scripts/sync-posthog-icons.mjs +75 -0
  20. package/src/components/ui/Chip.tsx +36 -18
  21. package/src/components/ui/CommandPalette.test.tsx +41 -0
  22. package/src/components/ui/CommandPalette.tsx +58 -9
  23. package/src/components/ui/DropdownMenu.tsx +50 -11
  24. package/src/components/ui/SegmentedControl.tsx +2 -1
  25. package/src/components/ui/SettingsLayout.tsx +19 -5
  26. package/src/components/ui/interaction-primitives.test.tsx +52 -0
  27. package/src/styles/suite-skin.css +17 -35
  28. package/src/suite/components/app-switcher.tsx +32 -25
  29. package/src/suite/components/command-palette-host.tsx +20 -8
  30. package/src/suite/components/suite-app-layout.tsx +1 -1
  31. package/src/suite/components/suite-bottom-nav.tsx +23 -18
  32. package/src/suite/components/suite-layout.test.tsx +44 -0
  33. package/src/suite/components/suite-layout.tsx +3 -3
  34. package/src/suite/components/suite-mobile-drawer.tsx +12 -0
  35. package/src/suite/components/suite-mobile-header.tsx +15 -9
  36. package/src/suite/components/suite-notification-bell.tsx +23 -11
  37. package/src/suite/components/suite-settings-mobile-nav.tsx +2 -0
  38. package/src/suite/components/suite-sidebar.tsx +6 -3
  39. package/src/suite/components/suite-user-menu.tsx +6 -0
  40. package/src/suite/lib/injected.ts +12 -11
  41. package/src/components/charts/index.ts +0 -9
  42. package/src/components/charts/quill/BarChart.tsx +0 -85
  43. package/src/components/charts/quill/FunnelChart.tsx +0 -49
  44. package/src/components/charts/quill/InsightShell.tsx +0 -27
  45. package/src/components/charts/quill/MetricCard.tsx +0 -44
  46. package/src/components/charts/quill/PieChart.tsx +0 -81
  47. package/src/components/charts/quill/Sparkline.tsx +0 -57
  48. package/src/components/charts/quill/TimeSeriesLineChart.tsx +0 -62
  49. package/src/components/charts/quill/index.ts +0 -9
package/dist/suite.d.mts CHANGED
@@ -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;
@@ -322,6 +342,8 @@ interface SuiteUserMenuProps {
322
342
  /** Show the old desktop sidebar sign-out action beside the avatar. */
323
343
  showSignOutAction?: boolean;
324
344
  dataTest?: string;
345
+ triggerId?: string;
346
+ triggerDataTest?: string;
325
347
  className?: string;
326
348
  }
327
349
  /**
@@ -329,13 +351,13 @@ interface SuiteUserMenuProps {
329
351
  * profile settings and sign out. Desktop sidebars can also expose the legacy
330
352
  * adjacent sign-out action without adding it to mobile chrome.
331
353
  */
332
- declare function SuiteUserMenu({ name, email, image, settingsHref, onSignOut, fallbackInitials, showSignOutAction, 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;
333
355
 
334
356
  /** Any icon component that accepts sizing/stroke props (Lucide, theme icons). */
335
357
  type SuiteNavIcon = ComponentType<{
336
358
  className?: string;
337
359
  strokeWidth?: number | string;
338
- 'aria-hidden'?: boolean | 'true' | 'false';
360
+ "aria-hidden"?: boolean | "true" | "false";
339
361
  }>;
340
362
  /**
341
363
  * Suite bottom navigation — the mobile/tablet primary nav, identical in
@@ -348,6 +370,7 @@ interface SuiteBottomNavItem {
348
370
  href: string;
349
371
  label: string;
350
372
  icon: SuiteNavIcon;
373
+ id?: string;
351
374
  active?: boolean;
352
375
  dataTest?: string;
353
376
  }
@@ -788,6 +811,7 @@ interface SuiteSettingsNavItem {
788
811
  label: string;
789
812
  href: string;
790
813
  icon: ElementType | ReactNode;
814
+ id?: string;
791
815
  testId?: string;
792
816
  }
793
817
  interface SuiteSettingsMobileNavProps {
@@ -811,6 +835,8 @@ interface SuiteSidebarNavItem {
811
835
  href: string;
812
836
  label: string;
813
837
  icon: SuiteNavIcon;
838
+ id?: string;
839
+ dataTest?: string;
814
840
  active?: boolean;
815
841
  onClick?: () => void;
816
842
  badge?: ReactNode;
package/dist/suite.d.ts CHANGED
@@ -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;
@@ -322,6 +342,8 @@ interface SuiteUserMenuProps {
322
342
  /** Show the old desktop sidebar sign-out action beside the avatar. */
323
343
  showSignOutAction?: boolean;
324
344
  dataTest?: string;
345
+ triggerId?: string;
346
+ triggerDataTest?: string;
325
347
  className?: string;
326
348
  }
327
349
  /**
@@ -329,13 +351,13 @@ interface SuiteUserMenuProps {
329
351
  * profile settings and sign out. Desktop sidebars can also expose the legacy
330
352
  * adjacent sign-out action without adding it to mobile chrome.
331
353
  */
332
- declare function SuiteUserMenu({ name, email, image, settingsHref, onSignOut, fallbackInitials, showSignOutAction, 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;
333
355
 
334
356
  /** Any icon component that accepts sizing/stroke props (Lucide, theme icons). */
335
357
  type SuiteNavIcon = ComponentType<{
336
358
  className?: string;
337
359
  strokeWidth?: number | string;
338
- 'aria-hidden'?: boolean | 'true' | 'false';
360
+ "aria-hidden"?: boolean | "true" | "false";
339
361
  }>;
340
362
  /**
341
363
  * Suite bottom navigation — the mobile/tablet primary nav, identical in
@@ -348,6 +370,7 @@ interface SuiteBottomNavItem {
348
370
  href: string;
349
371
  label: string;
350
372
  icon: SuiteNavIcon;
373
+ id?: string;
351
374
  active?: boolean;
352
375
  dataTest?: string;
353
376
  }
@@ -788,6 +811,7 @@ interface SuiteSettingsNavItem {
788
811
  label: string;
789
812
  href: string;
790
813
  icon: ElementType | ReactNode;
814
+ id?: string;
791
815
  testId?: string;
792
816
  }
793
817
  interface SuiteSettingsMobileNavProps {
@@ -811,6 +835,8 @@ interface SuiteSidebarNavItem {
811
835
  href: string;
812
836
  label: string;
813
837
  icon: SuiteNavIcon;
838
+ id?: string;
839
+ dataTest?: string;
814
840
  active?: boolean;
815
841
  onClick?: () => void;
816
842
  badge?: ReactNode;
package/dist/suite.js CHANGED
@@ -1266,13 +1266,17 @@ function AppSwitcher({
1266
1266
  title,
1267
1267
  collapsed = false,
1268
1268
  dropdownMenu: DropdownMenu2,
1269
- dropdownItem: DropdownItem2
1269
+ dropdownItem: DropdownItem2,
1270
+ triggerId,
1271
+ triggerDataTest
1270
1272
  }) {
1271
1273
  const [open, setOpen] = (0, import_react.useState)(false);
1272
1274
  return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1273
1275
  DropdownMenu2,
1274
1276
  {
1275
1277
  "aria-label": "Switch application",
1278
+ triggerId: triggerId != null ? triggerId : "app-switcher-trigger",
1279
+ triggerDataTest: triggerDataTest != null ? triggerDataTest : "app-switcher-trigger",
1276
1280
  className: collapsed ? "w-11 shrink-0" : "min-w-0 flex-1",
1277
1281
  panelClassName: "w-64",
1278
1282
  align: "start",
@@ -1294,11 +1298,12 @@ function AppSwitcher({
1294
1298
  ]
1295
1299
  }
1296
1300
  ),
1297
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "p-1", "data-test": "app-switcher-menu", children: [
1301
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { id: "app-switcher-menu", className: "p-1", "data-test": "app-switcher-menu", children: [
1298
1302
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "px-3 py-2 text-[10px] font-semibold uppercase tracking-[0.14em] text-ph-mutedtext", children: "Switch application" }),
1299
1303
  apps.map((app) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1300
1304
  DropdownItem2,
1301
1305
  {
1306
+ id: `switch-app-${app.slug}`,
1302
1307
  "data-test": `switch-app-${app.slug}`,
1303
1308
  onMouseDown: (e) => e.preventDefault(),
1304
1309
  onClick: () => {
@@ -1433,7 +1438,10 @@ function SuiteNotificationBell({
1433
1438
  markRead,
1434
1439
  markAllRead,
1435
1440
  dropdownMenu: DropdownMenu2,
1436
- cacheKey = "suite-notifications-cache"
1441
+ cacheKey = "suite-notifications-cache",
1442
+ dataTest = "suite-notifications",
1443
+ triggerId,
1444
+ triggerDataTest
1437
1445
  }) {
1438
1446
  const router = (0, import_navigation.useRouter)();
1439
1447
  const [open, setOpen] = (0, import_react2.useState)(false);
@@ -1534,11 +1542,13 @@ function SuiteNotificationBell({
1534
1542
  DropdownMenu2,
1535
1543
  {
1536
1544
  "aria-label": "Notifications",
1545
+ triggerId: triggerId != null ? triggerId : `${dataTest}-trigger`,
1546
+ triggerDataTest: triggerDataTest != null ? triggerDataTest : `${dataTest}-trigger`,
1537
1547
  align: "end",
1538
1548
  panelClassName: "w-80 overflow-hidden p-0",
1539
1549
  open,
1540
1550
  onOpenChange,
1541
- trigger: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "relative inline-flex h-9 w-9 items-center justify-center rounded-full text-ph-mutedtext transition hover:bg-ph-muted hover:text-ph-ink", children: [
1551
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "relative inline-flex h-11 w-11 items-center justify-center rounded-full text-ph-mutedtext transition hover:bg-ph-muted hover:text-ph-ink", children: [
1542
1552
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_iconoir_react3.Bell, { className: "h-5 w-5", strokeWidth: 1.75, "aria-hidden": true }),
1543
1553
  unread > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "absolute -right-0.5 -top-0.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-ph-brand px-1 text-[10px] font-semibold leading-none text-white ring-2 ring-ph-surface", children: unread > 9 ? "9+" : unread }) : null
1544
1554
  ] }),
@@ -1549,6 +1559,8 @@ function SuiteNotificationBell({
1549
1559
  "button",
1550
1560
  {
1551
1561
  type: "button",
1562
+ id: `${dataTest}-mark-all`,
1563
+ "data-test": `${dataTest}-mark-all`,
1552
1564
  onClick: markAll,
1553
1565
  className: "text-xs font-medium text-ph-brand hover:underline",
1554
1566
  children: "Mark all read"
@@ -1559,6 +1571,8 @@ function SuiteNotificationBell({
1559
1571
  "button",
1560
1572
  {
1561
1573
  type: "button",
1574
+ id: `${dataTest}-item-${n.id}`,
1575
+ "data-test": `${dataTest}-item-${n.id}`,
1562
1576
  onClick: () => void openItem(n),
1563
1577
  className: "flex w-full flex-col gap-0.5 px-3 py-2 text-left transition hover:bg-ph-muted",
1564
1578
  children: [
@@ -1603,6 +1617,10 @@ function CommandPaletteHost({
1603
1617
  items,
1604
1618
  isAuthenticated = true,
1605
1619
  placeholder = "Type a command or search\u2026",
1620
+ id,
1621
+ dataTest,
1622
+ inputId,
1623
+ inputDataTest,
1606
1624
  commandPalette: CommandPalette
1607
1625
  }) {
1608
1626
  const [open, setOpen] = (0, import_react3.useState)(false);
@@ -1623,7 +1641,11 @@ function CommandPaletteHost({
1623
1641
  items,
1624
1642
  isOpen: open,
1625
1643
  onClose: () => setOpen(false),
1626
- placeholder
1644
+ placeholder,
1645
+ id,
1646
+ dataTest,
1647
+ inputId,
1648
+ inputDataTest
1627
1649
  }
1628
1650
  );
1629
1651
  }
@@ -1671,6 +1693,10 @@ function SuiteMobileDrawer({
1671
1693
  durationMs = 200,
1672
1694
  dataTest,
1673
1695
  panelDataTest,
1696
+ backdropId,
1697
+ backdropDataTest,
1698
+ closeButtonId,
1699
+ closeButtonDataTest,
1674
1700
  panelClassName
1675
1701
  }) {
1676
1702
  const [rendered, setRendered] = (0, import_react5.useState)(open);
@@ -1722,6 +1748,8 @@ function SuiteMobileDrawer({
1722
1748
  "button",
1723
1749
  {
1724
1750
  type: "button",
1751
+ id: backdropId,
1752
+ "data-test": backdropDataTest,
1725
1753
  tabIndex: -1,
1726
1754
  className: cn(
1727
1755
  "absolute inset-0 bg-black/25 backdrop-blur-sm motion-safe:transition-opacity motion-safe:ease-spring-subtle",
@@ -1762,6 +1790,8 @@ function SuiteMobileDrawer({
1762
1790
  "button",
1763
1791
  {
1764
1792
  type: "button",
1793
+ id: closeButtonId,
1794
+ "data-test": closeButtonDataTest,
1765
1795
  onClick: onClose,
1766
1796
  className: "-mr-1.5 inline-flex h-11 w-11 items-center justify-center rounded-lg text-ph-mutedtext transition-colors hover:bg-ph-muted hover:text-ph-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-brand",
1767
1797
  "aria-label": closeLabel,
@@ -1787,6 +1817,7 @@ function SuiteMobileHeader({
1787
1817
  title,
1788
1818
  actions,
1789
1819
  menuLabel = "Open navigation",
1820
+ menuId,
1790
1821
  menuDataTest,
1791
1822
  dataTest,
1792
1823
  className
@@ -1804,6 +1835,7 @@ function SuiteMobileHeader({
1804
1835
  "button",
1805
1836
  {
1806
1837
  type: "button",
1838
+ id: menuId,
1807
1839
  "data-test": menuDataTest,
1808
1840
  className: "suite-press inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-xl text-ph-ink transition-colors hover:bg-ph-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-brand",
1809
1841
  onClick: onMenuClick,
@@ -1943,7 +1975,7 @@ function SuitePageHeader({
1943
1975
  "data-test": dataTest,
1944
1976
  "data-stuck": sticky ? stuck ? "true" : "false" : void 0,
1945
1977
  className: cn(
1946
- "flex items-start justify-between gap-4 pb-2 sm:pb-3",
1978
+ "flex min-w-0 flex-col items-start gap-3 pb-2 sm:flex-row sm:justify-between sm:gap-4 sm:pb-3",
1947
1979
  // No extra pt here — page inset sets the shared title baseline.
1948
1980
  // Stuck state adds pad via .suite-page-header-sticky[data-stuck].
1949
1981
  sticky && "suite-page-header-sticky",
@@ -1967,7 +1999,7 @@ function SuitePageHeader({
1967
1999
  "h1",
1968
2000
  {
1969
2001
  className: cn(
1970
- "font-display text-[1.625rem] font-bold leading-none tracking-tight text-ph-ink sm:text-[2.25rem]",
2002
+ "min-w-0 break-words font-display text-[1.625rem] font-bold leading-none tracking-tight text-ph-ink text-balance sm:text-[2.25rem]",
1971
2003
  titleClassName
1972
2004
  ),
1973
2005
  children: title
@@ -1987,7 +2019,7 @@ function SuitePageHeader({
1987
2019
  }
1988
2020
  ) : null
1989
2021
  ] }),
1990
- actions ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex shrink-0 items-center gap-2 self-center", children: actions }) : null
2022
+ actions ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex max-w-full items-center gap-2 self-stretch overflow-x-auto pb-1 sm:shrink-0 sm:self-center sm:overflow-visible sm:pb-0", children: actions }) : null
1991
2023
  ]
1992
2024
  }
1993
2025
  );
@@ -2148,7 +2180,14 @@ function DropdownContent({
2148
2180
  sticky: "partial",
2149
2181
  children: [
2150
2182
  children,
2151
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DropdownPrimitive.Arrow, { className: "ph-dropdown-arrow", width: 12, height: 6 })
2183
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2184
+ DropdownPrimitive.Arrow,
2185
+ {
2186
+ className: "ph-dropdown-arrow",
2187
+ width: 12,
2188
+ height: 6
2189
+ }
2190
+ )
2152
2191
  ]
2153
2192
  }
2154
2193
  ) });
@@ -2156,6 +2195,8 @@ function DropdownContent({
2156
2195
  function DropdownMenu(_a) {
2157
2196
  var _b = _a, {
2158
2197
  trigger,
2198
+ triggerId,
2199
+ triggerDataTest,
2159
2200
  children,
2160
2201
  align,
2161
2202
  side,
@@ -2173,6 +2214,8 @@ function DropdownMenu(_a) {
2173
2214
  disabled
2174
2215
  } = _b, props = __objRest(_b, [
2175
2216
  "trigger",
2217
+ "triggerId",
2218
+ "triggerDataTest",
2176
2219
  "children",
2177
2220
  "align",
2178
2221
  "side",
@@ -2197,7 +2240,17 @@ function DropdownMenu(_a) {
2197
2240
  onOpenChange,
2198
2241
  modal,
2199
2242
  children: [
2200
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DropdownPrimitive.Trigger, { asChild: true, disabled, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("button", { type: "button", className: "ph-dropdown-trigger", "aria-label": ariaLabel, children: trigger }) }),
2243
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DropdownPrimitive.Trigger, { asChild: true, disabled, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2244
+ "button",
2245
+ {
2246
+ type: "button",
2247
+ id: triggerId,
2248
+ "data-test": triggerDataTest,
2249
+ className: "ph-dropdown-trigger",
2250
+ "aria-label": ariaLabel,
2251
+ children: trigger
2252
+ }
2253
+ ) }),
2201
2254
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2202
2255
  DropdownContent,
2203
2256
  {
@@ -2216,7 +2269,15 @@ function DropdownMenu(_a) {
2216
2269
  ) }));
2217
2270
  }
2218
2271
  function DropdownItem(_a) {
2219
- var _b = _a, { className, children, disabled } = _b, props = __objRest(_b, ["className", "children", "disabled"]);
2272
+ var _b = _a, {
2273
+ className,
2274
+ children,
2275
+ disabled
2276
+ } = _b, props = __objRest(_b, [
2277
+ "className",
2278
+ "children",
2279
+ "disabled"
2280
+ ]);
2220
2281
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DropdownPrimitive.Item, { asChild: true, disabled, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2221
2282
  "button",
2222
2283
  __spreadProps(__spreadValues({
@@ -2244,6 +2305,8 @@ function SuiteUserMenu({
2244
2305
  fallbackInitials,
2245
2306
  showSignOutAction = false,
2246
2307
  dataTest = "suite-user-menu",
2308
+ triggerId,
2309
+ triggerDataTest,
2247
2310
  className
2248
2311
  }) {
2249
2312
  const router = (0, import_navigation2.useRouter)();
@@ -2263,6 +2326,8 @@ function SuiteUserMenu({
2263
2326
  DropdownMenu,
2264
2327
  {
2265
2328
  trigger: avatar,
2329
+ triggerId: triggerId != null ? triggerId : `${dataTest}-trigger`,
2330
+ triggerDataTest: triggerDataTest != null ? triggerDataTest : `${dataTest}-trigger`,
2266
2331
  "aria-label": "Account menu",
2267
2332
  align: "end",
2268
2333
  side: "bottom",
@@ -2363,6 +2428,7 @@ function SuiteBottomNav({
2363
2428
  import_link.default,
2364
2429
  {
2365
2430
  href: item.href,
2431
+ id: item.id,
2366
2432
  "data-test": (_a = item.dataTest) != null ? _a : `suite-nav-${item.label.toLowerCase().replace(/\s+/g, "-")}`,
2367
2433
  "aria-current": active ? "page" : void 0,
2368
2434
  className: cn(
@@ -3260,6 +3326,7 @@ function SuiteSettingsMobileNav({
3260
3326
  "button",
3261
3327
  {
3262
3328
  type: "button",
3329
+ id: item.id,
3263
3330
  "data-test": item.testId,
3264
3331
  onClick: () => onSelect(item.href),
3265
3332
  "aria-current": active ? "page" : void 0,
@@ -3472,19 +3539,21 @@ function SuiteSidebar({
3472
3539
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("nav", { "aria-label": "Pages", className: "shrink-0 space-y-0.5", children: [
3473
3540
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn("mb-3", collapsed && "flex justify-center"), children: renderNode(contextSwitcher, collapsed) }),
3474
3541
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "space-y-0.5", children: navItems.map((item) => {
3542
+ var _a;
3475
3543
  const Icon = item.icon;
3476
3544
  const active = Boolean(item.active);
3477
3545
  const link = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3478
3546
  import_link2.default,
3479
3547
  {
3480
3548
  href: item.href,
3481
- "data-test": "nav-link",
3549
+ id: item.id,
3550
+ "data-test": (_a = item.dataTest) != null ? _a : "nav-link",
3482
3551
  "aria-current": active ? "page" : void 0,
3483
3552
  onClick: item.onClick,
3484
3553
  className: cn(
3485
- "group relative flex items-center gap-2.5 rounded-[var(--ph-radius-app)] text-sm font-medium transition-colors",
3554
+ "group relative flex min-h-11 touch-manipulation items-center gap-2.5 rounded-[var(--ph-radius-app)] text-sm font-medium transition-colors",
3486
3555
  active ? "bg-ph-muted" : "text-ph-subtle hover:bg-ph-muted hover:text-ph-ink",
3487
- collapsed ? "mx-auto size-10 shrink-0 justify-center gap-0 px-0 py-0" : "w-full px-2.5 py-2"
3556
+ collapsed ? "mx-auto size-11 shrink-0 justify-center gap-0 px-0 py-0" : "w-full px-2.5 py-2"
3488
3557
  ),
3489
3558
  children: [
3490
3559
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
@@ -3582,7 +3651,7 @@ function SuiteAppLayout({
3582
3651
  {
3583
3652
  "data-test": "app-shell",
3584
3653
  className: cn(
3585
- "suite-app-layout flex min-h-dvh lg:h-screen lg:overflow-hidden",
3654
+ "suite-app-layout flex h-dvh overflow-hidden",
3586
3655
  className
3587
3656
  ),
3588
3657
  children: [