@marktiderman/genesis-ui 2.7.0 → 2.9.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.
Files changed (74) hide show
  1. package/EXTENDING.md +40 -1
  2. package/SKILL.md +198 -9
  3. package/dist/{AppShell-CX0M-dfc.d.ts → AppShell-LXQykEqe.d.ts} +47 -5
  4. package/dist/{chunk-M62CHO3N.js → chunk-4C4ESW6O.js} +9 -4
  5. package/dist/chunk-4C4ESW6O.js.map +1 -0
  6. package/dist/chunk-DIV4BYXX.js +58 -0
  7. package/dist/chunk-DIV4BYXX.js.map +1 -0
  8. package/dist/chunk-FUVWKTPL.js +19 -0
  9. package/dist/chunk-FUVWKTPL.js.map +1 -0
  10. package/dist/{chunk-PLIYF6KI.js → chunk-MPI33I4K.js} +2 -2
  11. package/dist/{chunk-PLIYF6KI.js.map → chunk-MPI33I4K.js.map} +1 -1
  12. package/dist/{chunk-JA3ZKULS.js → chunk-OITWCIG2.js} +3 -3
  13. package/dist/chunk-OITWCIG2.js.map +1 -0
  14. package/dist/chunk-PKFDGGZV.js +65 -0
  15. package/dist/chunk-PKFDGGZV.js.map +1 -0
  16. package/dist/{chunk-IXGAEECT.js → chunk-RKPS7ERS.js} +9 -5
  17. package/dist/chunk-RKPS7ERS.js.map +1 -0
  18. package/dist/{chunk-TXOZMKNW.js → chunk-S7NXD37O.js} +27 -26
  19. package/dist/chunk-S7NXD37O.js.map +1 -0
  20. package/dist/{chunk-ZPPLUGLA.js → chunk-UYI3GLFJ.js} +162 -19
  21. package/dist/chunk-UYI3GLFJ.js.map +1 -0
  22. package/dist/{chunk-CDYZRZ6U.js → chunk-WGMEVX3Y.js} +2 -2
  23. package/dist/chunk-WGMEVX3Y.js.map +1 -0
  24. package/dist/chunk-ZDHWNQTR.js +552 -0
  25. package/dist/chunk-ZDHWNQTR.js.map +1 -0
  26. package/dist/components/data/index.d.ts +306 -19
  27. package/dist/components/data/index.js +1177 -284
  28. package/dist/components/data/index.js.map +1 -1
  29. package/dist/components/layout/form-page.d.ts +1 -1
  30. package/dist/components/layout/form-page.js +1 -1
  31. package/dist/components/layout/index.d.ts +2 -2
  32. package/dist/components/layout/index.js +8 -8
  33. package/dist/components/patterns/index.d.ts +1 -1
  34. package/dist/components/patterns/index.js +5 -5
  35. package/dist/components/patterns/sortable-list.js +1 -1
  36. package/dist/components/rich-text/rich-text-editor.d.ts +194 -0
  37. package/dist/components/rich-text/rich-text-editor.js +833 -0
  38. package/dist/components/rich-text/rich-text-editor.js.map +1 -0
  39. package/dist/components/rich-text/rich-text.d.ts +51 -0
  40. package/dist/components/rich-text/rich-text.js +4 -0
  41. package/dist/components/rich-text/rich-text.js.map +1 -0
  42. package/dist/components/ui/alert-dialog.d.ts +12 -1
  43. package/dist/components/ui/alert-dialog.js +1 -1
  44. package/dist/hooks/index.d.ts +4 -3
  45. package/dist/hooks/index.js +5 -4
  46. package/dist/hooks/use-data-filters.d.ts +5 -3
  47. package/dist/hooks/use-data-filters.js +2 -2
  48. package/dist/hooks/use-resource-page.d.ts +2 -1
  49. package/dist/hooks/use-resource-page.js +3 -2
  50. package/dist/hooks/use-resource-url-state.d.ts +68 -0
  51. package/dist/hooks/use-resource-url-state.js +3 -0
  52. package/dist/hooks/use-resource-url-state.js.map +1 -0
  53. package/dist/hooks/use-view-preference.d.ts +17 -2
  54. package/dist/hooks/use-view-preference.js +2 -1
  55. package/dist/index.d.ts +2 -2
  56. package/dist/index.js +32 -32
  57. package/dist/{navigation-DBwcZ6vb.d.ts → navigation-Bha0R3Fu.d.ts} +6 -3
  58. package/dist/rich-text-doc-C54fME2C.d.ts +180 -0
  59. package/dist/router/react-router.d.ts +47 -0
  60. package/dist/router/react-router.js +53 -0
  61. package/dist/router/react-router.js.map +1 -0
  62. package/dist/router/tanstack-router.d.ts +47 -0
  63. package/dist/router/tanstack-router.js +105 -0
  64. package/dist/router/tanstack-router.js.map +1 -0
  65. package/dist/{use-resource-page-Dd2VUv30.d.ts → use-resource-page-BDnnCssE.d.ts} +83 -5
  66. package/package.json +61 -14
  67. package/dist/chunk-CDYZRZ6U.js.map +0 -1
  68. package/dist/chunk-FTTNGGLA.js +0 -20
  69. package/dist/chunk-FTTNGGLA.js.map +0 -1
  70. package/dist/chunk-IXGAEECT.js.map +0 -1
  71. package/dist/chunk-JA3ZKULS.js.map +0 -1
  72. package/dist/chunk-M62CHO3N.js.map +0 -1
  73. package/dist/chunk-TXOZMKNW.js.map +0 -1
  74. package/dist/chunk-ZPPLUGLA.js.map +0 -1
@@ -2,15 +2,15 @@
2
2
  import { ViewToggle, ViewSettings } from './chunk-46TZGMFW.js';
3
3
  import { Collapsible, CollapsibleContent } from './chunk-B2GIBUQD.js';
4
4
  import { Badge } from './chunk-NPNADZHM.js';
5
- import { Popover, PopoverTrigger, PopoverContent } from './chunk-22XB3Q6H.js';
6
5
  import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from './chunk-QJ6P2DW6.js';
7
6
  import { Switch } from './chunk-27ELYTGE.js';
7
+ import { Popover, PopoverTrigger, PopoverContent } from './chunk-22XB3Q6H.js';
8
8
  import { Button } from './chunk-NWSCYLPT.js';
9
9
  import { Label } from './chunk-F47U5KNW.js';
10
10
  import { cn } from './chunk-NZ5WBA4R.js';
11
- import { DefaultLink, isPathActive } from './chunk-CDYZRZ6U.js';
11
+ import { resolveNavigation, DefaultLink, isPathActive } from './chunk-WGMEVX3Y.js';
12
12
  import { useId, useState, useEffect, useMemo, useCallback } from 'react';
13
- import { ListFilter, MoreHorizontal, SlidersHorizontal, Menu, X, PanelLeft, PanelLeftClose, Sun, Moon, ChevronDown } from 'lucide-react';
13
+ import { ListFilter, MoreHorizontal, SlidersHorizontal, Menu, ArrowLeft, X, PanelLeft, PanelLeftClose, Sun, Moon, ChevronDown } from 'lucide-react';
14
14
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
15
15
 
16
16
  // src/option-storage.ts
@@ -38,6 +38,7 @@ function pluralizeEntity(entity, count) {
38
38
  return entity.endsWith("s") ? entity : `${entity}s`;
39
39
  }
40
40
  var OPTION_DEFAULTS = {
41
+ showTitle: true,
41
42
  showIcon: true,
42
43
  showSubtitle: true,
43
44
  showCount: true,
@@ -343,7 +344,14 @@ function PageHeader({
343
344
  ] })
344
345
  ] }) : null
345
346
  ] });
346
- const titleRow = /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
347
+ const titleRow = resolved.showTitle === false ? /* @__PURE__ */ jsx(
348
+ "div",
349
+ {
350
+ "data-testid": "page-header-toolbar",
351
+ className: "flex min-w-0 flex-wrap items-center justify-end gap-2",
352
+ children: actionsCluster
353
+ }
354
+ ) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between", children: [
347
355
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 min-w-0", children: [
348
356
  Icon && resolved.showIcon !== false ? /* @__PURE__ */ jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-xl bg-primary/10", children: /* @__PURE__ */ jsx(Icon, { className: "h-5 w-5 text-primary" }) }) : null,
349
357
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
@@ -416,6 +424,34 @@ function writeStoredCollapsed(key, collapsed) {
416
424
  } catch {
417
425
  }
418
426
  }
427
+ var PARAM = /^\$(.+)$/;
428
+ function fillParams(to, params) {
429
+ const cut = to.search(/[?#]/);
430
+ const path = cut === -1 ? to : to.slice(0, cut);
431
+ const suffix = cut === -1 ? "" : to.slice(cut);
432
+ let missing = false;
433
+ const filled = path.split("/").map((part) => {
434
+ const name = PARAM.exec(part)?.[1];
435
+ if (name == null) return part;
436
+ const value = params[name];
437
+ if (value == null) missing = true;
438
+ return value == null ? part : encodeURIComponent(value);
439
+ }).join("/");
440
+ return missing ? void 0 : filled + suffix;
441
+ }
442
+ function fillItems(items, params) {
443
+ return items.flatMap((item) => {
444
+ const to = fillParams(item.to, params);
445
+ if (to == null) return [];
446
+ return [
447
+ {
448
+ ...item,
449
+ to,
450
+ children: item.children ? fillItems(item.children, params) : void 0
451
+ }
452
+ ];
453
+ });
454
+ }
419
455
  function ThemeToggle({ testId }) {
420
456
  const [dark, setDark] = useState(false);
421
457
  useEffect(() => {
@@ -464,7 +500,8 @@ function NavLinkRow({
464
500
  onNavClick,
465
501
  linkComponent: LinkComp,
466
502
  activePath,
467
- isActive
503
+ isActive,
504
+ notCurrent = false
468
505
  }) {
469
506
  const active = itemIsActive(item, activePath, isActive);
470
507
  const pad = density === "compact" ? "px-2.5 py-1.5" : "px-3 py-2";
@@ -493,7 +530,7 @@ function NavLinkRow({
493
530
  onClick: onNavClick,
494
531
  title: collapsed ? item.label : void 0,
495
532
  "aria-label": collapsed ? item.label : void 0,
496
- "aria-current": active ? "page" : void 0,
533
+ "aria-current": active && !notCurrent ? "page" : void 0,
497
534
  className: cn(
498
535
  "flex items-center gap-3 rounded-lg text-sm font-medium transition-colors",
499
536
  pad,
@@ -517,7 +554,8 @@ function NavGroup({
517
554
  onNavClick,
518
555
  linkComponent,
519
556
  activePath,
520
- isActive
557
+ isActive,
558
+ notCurrent = false
521
559
  }) {
522
560
  const children = item.children ?? [];
523
561
  const childActive = children.some(
@@ -537,7 +575,8 @@ function NavGroup({
537
575
  onNavClick,
538
576
  linkComponent,
539
577
  activePath,
540
- isActive
578
+ isActive,
579
+ notCurrent
541
580
  }
542
581
  );
543
582
  }
@@ -552,7 +591,8 @@ function NavGroup({
552
591
  onNavClick,
553
592
  linkComponent,
554
593
  activePath,
555
- isActive
594
+ isActive,
595
+ notCurrent
556
596
  }
557
597
  );
558
598
  }
@@ -575,7 +615,7 @@ function NavGroup({
575
615
  {
576
616
  href: item.to,
577
617
  onClick: onNavClick,
578
- "aria-current": selfExact ? "page" : void 0,
618
+ "aria-current": selfExact && !notCurrent ? "page" : void 0,
579
619
  className: parentClass,
580
620
  children: [
581
621
  /* @__PURE__ */ jsx(item.icon, { className: "h-4 w-4 shrink-0" }),
@@ -633,7 +673,8 @@ function NavGroup({
633
673
  onNavClick,
634
674
  linkComponent,
635
675
  activePath,
636
- isActive
676
+ isActive,
677
+ notCurrent
637
678
  },
638
679
  child.to + child.label
639
680
  )) }) })
@@ -641,6 +682,8 @@ function NavGroup({
641
682
  }
642
683
  function SidebarNav({
643
684
  navItems,
685
+ contextualNavItems,
686
+ contextualNavLabel,
644
687
  secondaryNavItems,
645
688
  secondaryNavLabel,
646
689
  showSecondary,
@@ -651,6 +694,10 @@ function SidebarNav({
651
694
  activePath,
652
695
  isActive
653
696
  }) {
697
+ const contextualLabelId = useId();
698
+ const contextualActive = Boolean(
699
+ contextualNavItems?.some((item) => itemIsActive(item, activePath, isActive))
700
+ );
654
701
  return /* @__PURE__ */ jsxs(
655
702
  "nav",
656
703
  {
@@ -669,10 +716,47 @@ function SidebarNav({
669
716
  onNavClick,
670
717
  linkComponent,
671
718
  activePath,
672
- isActive
719
+ isActive,
720
+ notCurrent: contextualActive
673
721
  },
674
722
  item.to + item.label
675
723
  )),
724
+ contextualNavItems && contextualNavItems.length > 0 ? /* @__PURE__ */ jsxs(
725
+ "div",
726
+ {
727
+ className: cn(
728
+ "mt-4 space-y-1 border-t border-sidebar-border pt-4",
729
+ collapsed && "mt-2 pt-2"
730
+ ),
731
+ "data-testid": "app-shell-contextual-nav",
732
+ role: "group",
733
+ "aria-labelledby": !collapsed && contextualNavLabel ? contextualLabelId : void 0,
734
+ "aria-label": collapsed ? contextualNavLabel : void 0,
735
+ children: [
736
+ !collapsed && contextualNavLabel ? /* @__PURE__ */ jsx(
737
+ "p",
738
+ {
739
+ id: contextualLabelId,
740
+ className: "mb-2 truncate px-3 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/40",
741
+ children: contextualNavLabel
742
+ }
743
+ ) : null,
744
+ contextualNavItems.map((item) => /* @__PURE__ */ jsx(
745
+ NavGroup,
746
+ {
747
+ item,
748
+ collapsed,
749
+ density,
750
+ onNavClick,
751
+ linkComponent,
752
+ activePath,
753
+ isActive
754
+ },
755
+ item.to + item.label
756
+ ))
757
+ ]
758
+ }
759
+ ) : null,
676
760
  showSecondary && secondaryNavItems && secondaryNavItems.length > 0 ? /* @__PURE__ */ jsxs(
677
761
  "div",
678
762
  {
@@ -729,7 +813,9 @@ function AppShell({
729
813
  appName,
730
814
  appLogo,
731
815
  logo,
732
- navItems,
816
+ navItems: navItemsProp,
817
+ navigation,
818
+ parentNavigation: parentNavigationProp,
733
819
  secondaryNavItems,
734
820
  secondaryNavLabel = "More",
735
821
  mobileNavItems,
@@ -748,6 +834,18 @@ function AppShell({
748
834
  isActive = isPathActive
749
835
  }) {
750
836
  const [mobileOpen, setMobileOpen] = useState(false);
837
+ const derived = useMemo(() => {
838
+ if (!navigation) return void 0;
839
+ const nav = resolveNavigation(navigation, activePath ?? "/");
840
+ const atRoot = nav.trail.length === 1;
841
+ const globalItems = fillItems(navigation.items, nav.params);
842
+ const contextualItems = atRoot ? [] : fillItems(nav.items, nav.params);
843
+ const parent = nav.parent && nav.trail.length > 2 && !nav.parent.path.split("/").some((p) => PARAM.test(p)) ? { href: nav.parent.path, label: nav.parent.label } : void 0;
844
+ return { current: nav.current, globalItems, contextualItems, parent };
845
+ }, [navigation, activePath]);
846
+ const navItems = navItemsProp ?? derived?.globalItems ?? [];
847
+ const contextualNavItems = derived?.contextualItems ?? [];
848
+ const parentNavigation = parentNavigationProp === void 0 ? derived?.parent : parentNavigationProp ?? void 0;
751
849
  const [userOverrides, setUserOverrides] = useState(
752
850
  {}
753
851
  );
@@ -827,11 +925,15 @@ function AppShell({
827
925
  }
828
926
  onCollapsedChange?.(next);
829
927
  };
928
+ const ParentLink = linkComponent;
830
929
  const density = resolved.density ?? "comfortable";
831
930
  const scrollWindow = resolved.scrollRoot === "window";
832
931
  const railExpanded = resolved.railWidth === "wide" ? "md:w-64" : "md:w-52";
833
932
  const railClass = collapsed ? "md:w-14" : railExpanded;
834
- const bottomItems = (mobileNavItems ?? navItems.filter((i) => !i.children || i.children.length === 0)).filter((i) => !i.disabled);
933
+ const leaves = (items) => items.filter((i) => !i.children || i.children.length === 0);
934
+ const contextualLeaves = leaves(contextualNavItems);
935
+ const bottomItems = (mobileNavItems ?? (contextualLeaves.length > 0 ? contextualLeaves : leaves(navItems))).filter((i) => !i.disabled);
936
+ const bottomNotCurrent = !mobileNavItems && contextualLeaves.length === 0 && contextualNavItems.some((i) => itemIsActive(i, activePath, isActive));
835
937
  const toggles = [
836
938
  { key: "showLogo", label: "Logo", available: hasLogo },
837
939
  { key: "showAppName", label: "App name", available: true },
@@ -981,6 +1083,8 @@ function AppShell({
981
1083
  SidebarNav,
982
1084
  {
983
1085
  navItems,
1086
+ contextualNavItems,
1087
+ contextualNavLabel: derived?.current.label,
984
1088
  secondaryNavItems,
985
1089
  secondaryNavLabel,
986
1090
  showSecondary,
@@ -1100,7 +1204,7 @@ function AppShell({
1100
1204
  ]
1101
1205
  }
1102
1206
  ),
1103
- /* @__PURE__ */ jsx(
1207
+ /* @__PURE__ */ jsxs(
1104
1208
  "main",
1105
1209
  {
1106
1210
  className: cn(
@@ -1108,7 +1212,46 @@ function AppShell({
1108
1212
  !scrollWindow && "overflow-y-auto",
1109
1213
  showMobileBottom ? "pb-16 md:pb-0" : "pb-0"
1110
1214
  ),
1111
- children: /* @__PURE__ */ jsx("div", { className: "min-w-0 p-4 sm:p-6 lg:p-8", children })
1215
+ children: [
1216
+ parentNavigation ? /* @__PURE__ */ jsx(
1217
+ "div",
1218
+ {
1219
+ className: "flex min-w-0 items-center px-4 pt-4 sm:px-6 sm:pt-6 lg:px-8 lg:pt-8",
1220
+ "data-testid": "app-shell-parent-nav",
1221
+ children: /* @__PURE__ */ jsx(
1222
+ Button,
1223
+ {
1224
+ asChild: true,
1225
+ variant: "ghost",
1226
+ size: "sm",
1227
+ className: "-ml-3 min-w-0 max-w-full",
1228
+ testID: "app-shell-parent-link",
1229
+ children: /* @__PURE__ */ jsxs(
1230
+ ParentLink,
1231
+ {
1232
+ href: parentNavigation.href,
1233
+ "aria-label": `Back to ${parentNavigation.label}`,
1234
+ children: [
1235
+ /* @__PURE__ */ jsx(ArrowLeft, { "aria-hidden": true }),
1236
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: parentNavigation.label })
1237
+ ]
1238
+ }
1239
+ )
1240
+ }
1241
+ )
1242
+ }
1243
+ ) : null,
1244
+ /* @__PURE__ */ jsx(
1245
+ "div",
1246
+ {
1247
+ className: cn(
1248
+ "min-w-0 p-4 sm:p-6 lg:p-8",
1249
+ parentNavigation && "pt-2 sm:pt-3 lg:pt-4"
1250
+ ),
1251
+ children
1252
+ }
1253
+ )
1254
+ ]
1112
1255
  }
1113
1256
  ),
1114
1257
  showMobileBottom ? /* @__PURE__ */ jsx(
@@ -1125,7 +1268,7 @@ function AppShell({
1125
1268
  href: item.to,
1126
1269
  title: item.label,
1127
1270
  "aria-label": item.label,
1128
- "aria-current": active ? "page" : void 0,
1271
+ "aria-current": active && !bottomNotCurrent ? "page" : void 0,
1129
1272
  className: cn(
1130
1273
  "flex flex-1 flex-col items-center gap-1 py-2 text-xs font-medium transition-colors",
1131
1274
  active ? "text-primary" : "text-muted-foreground"
@@ -1149,5 +1292,5 @@ function AppShell({
1149
1292
  }
1150
1293
 
1151
1294
  export { AppShell, PageHeader };
1152
- //# sourceMappingURL=chunk-ZPPLUGLA.js.map
1153
- //# sourceMappingURL=chunk-ZPPLUGLA.js.map
1295
+ //# sourceMappingURL=chunk-UYI3GLFJ.js.map
1296
+ //# sourceMappingURL=chunk-UYI3GLFJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/option-storage.ts","../src/components/layout/PageHeader.tsx","../src/components/layout/AppShell.tsx"],"names":["readStoredOptions","OPTION_DEFAULTS","useState","useEffect","jsx","jsxs","Fragment","useId","useMemo","useCallback","SlidersHorizontal"],"mappings":"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","file":"chunk-UYI3GLFJ.js","sourcesContent":["/**\n * Generic localStorage-backed persistence for \"customize chrome\" option\n * objects (AppShell, PageHeader, …). SSR-safe (no-ops without `window`) and\n * swallows quota / private-mode errors so a storage failure never breaks\n * rendering.\n *\n * Callers own their own shape validation — this module only handles the\n * JSON <-> localStorage plumbing shared across chrome components.\n */\nexport function readStoredOptions<T extends object>(key: string): Partial<T> {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\") return {};\n return parsed as Partial<T>;\n } catch {\n return {};\n }\n}\n\nexport function writeStoredOptions<T extends object>(\n key: string,\n value: Partial<T>,\n): void {\n if (typeof window === \"undefined\") return;\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota / private mode\n }\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useId, useMemo, useState, type ReactNode } from \"react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { ListFilter, MoreHorizontal, SlidersHorizontal } from \"lucide-react\";\nimport { Badge } from \"../ui/badge\";\nimport { Button } from \"../ui/button\";\nimport { Collapsible, CollapsibleContent } from \"../ui/collapsible\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../ui/popover\";\nimport { Switch } from \"../ui/switch\";\nimport { Label } from \"../ui/label\";\nimport { ViewToggle, type ViewMode } from \"../patterns/view-toggle\";\nimport { ViewSettings } from \"../patterns/view-settings\";\nimport type { Density } from \"../../hooks/use-view-settings\";\nimport { cn } from \"../../utils\";\nimport {\n readStoredOptions as readStoredOptionsRaw,\n writeStoredOptions,\n} from \"../../option-storage\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"../ui/dropdown-menu\";\n\n/**\n * Declarative chrome for PageHeader — developer defaults + optional\n * in-header user toggles (Notion/Linear “customize view” pattern).\n *\n * @stability Beta\n */\nexport interface PageHeaderOptions {\n /**\n * The icon, title and subtitle block. Turn it off where the surrounding\n * page already names the content (a list inside a tab), keeping only the\n * actions row: count, view toggle, filters, create. Default true. A\n * developer setting, not offered in the user's Header options.\n */\n showTitle?: boolean;\n showIcon?: boolean;\n showSubtitle?: boolean;\n showCount?: boolean;\n showViewToggle?: boolean;\n showViewSettings?: boolean;\n showCreate?: boolean;\n /**\n * Stat cards row under the title block. Off by default — a header that\n * receives `stats` still hides them until the developer or the user turns\n * this on, so an existing page gains no new chrome by upgrading.\n */\n showStats?: boolean;\n /** Ghost ListFilter control in the actions cluster */\n showDetailsToggle?: boolean;\n /** Quiet hint beside actions while details are collapsed */\n showDetailsHint?: boolean;\n /** Move subtitle into the details panel (default true when details exist) */\n subtitleInDetails?: boolean;\n defaultDetailsOpen?: boolean;\n detailsLabel?: string;\n /**\n * Show the in-header Header options popover so users can customize chrome.\n * Default true when the header has more than one chrome affordance.\n */\n configurable?: boolean;\n}\n\n/** @stability Beta */\nexport type PageHeaderOptionKey = keyof PageHeaderOptions;\n\n/** Naive English pluralization for the count badge — singular at exactly 1. */\nfunction pluralizeEntity(entity: string, count: number): string {\n if (count === 1) return entity;\n return entity.endsWith(\"s\") ? entity : `${entity}s`;\n}\n\nconst OPTION_DEFAULTS: Required<\n Omit<PageHeaderOptions, \"detailsLabel\" | \"defaultDetailsOpen\" | \"subtitleInDetails\" | \"configurable\">\n> &\n Pick<PageHeaderOptions, \"detailsLabel\" | \"defaultDetailsOpen\" | \"subtitleInDetails\" | \"configurable\"> = {\n showTitle: true,\n showIcon: true,\n showSubtitle: true,\n showCount: true,\n showViewToggle: true,\n showViewSettings: true,\n showCreate: true,\n showStats: false,\n showDetailsToggle: true,\n showDetailsHint: true,\n subtitleInDetails: undefined,\n defaultDetailsOpen: false,\n detailsLabel: \"Details\",\n configurable: undefined,\n};\n\n// `showTitle` is left out on purpose: it is a developer setting, so a stored\n// user override must never hide the title.\nconst BOOLEAN_OPTION_KEYS: PageHeaderOptionKey[] = [\n \"showIcon\",\n \"showSubtitle\",\n \"showCount\",\n \"showViewToggle\",\n \"showViewSettings\",\n \"showCreate\",\n \"showStats\",\n \"showDetailsToggle\",\n \"showDetailsHint\",\n \"subtitleInDetails\",\n \"defaultDetailsOpen\",\n \"configurable\",\n];\nconst STRING_OPTION_KEYS: PageHeaderOptionKey[] = [\"detailsLabel\"];\n\n/**\n * Reads persisted options and keeps only known keys whose stored value has\n * the expected primitive type — a malformed or hand-edited localStorage\n * value can't smuggle in an unexpected key or wrong-typed override.\n */\nfunction readStoredOptions(key: string): Partial<PageHeaderOptions> {\n const raw = readStoredOptionsRaw<PageHeaderOptions>(key);\n const sanitized: Partial<PageHeaderOptions> = {};\n for (const optKey of BOOLEAN_OPTION_KEYS) {\n const value = raw[optKey];\n if (typeof value === \"boolean\") {\n (sanitized as Record<string, boolean>)[optKey] = value;\n }\n }\n for (const optKey of STRING_OPTION_KEYS) {\n const value = raw[optKey];\n if (typeof value === \"string\") {\n (sanitized as Record<string, string>)[optKey] = value;\n }\n }\n return sanitized;\n}\n\n/** One entry in {@link PageHeaderProps.secondaryActions}. */\nexport interface PageHeaderAction {\n label: string;\n onClick: () => void;\n icon?: LucideIcon;\n /** `data-testid` on the menu item, so e2e can drive it. */\n testId?: string;\n disabled?: boolean;\n /** Omits the action entirely — for one gated on data. */\n hidden?: boolean;\n}\n\nexport interface PageHeaderProps {\n title: string;\n subtitle?: string;\n icon?: LucideIcon;\n /**\n * Header chrome config (developer defaults). Merged under user picks from\n * the in-header options menu when `options.configurable` / storage is on.\n */\n options?: PageHeaderOptions;\n /** Persist user header-option overrides (localStorage) */\n optionsStorageKey?: string;\n /** Extra trailing actions (after create); prefer first-class slots below */\n actions?: ReactNode;\n /**\n * Stat cards row, full width, directly under the title block and above\n * `details`. Layout-only: pass `<StatCard>`s (or anything else) and the\n * header positions them. Rendered only when `options.showStats` resolves\n * true — see {@link PageHeaderOptions.showStats}.\n */\n stats?: ReactNode;\n /** Collapsible details region below the title row */\n details?: ReactNode;\n detailsOpen?: boolean;\n onDetailsOpenChange?: (open: boolean) => void;\n detailsActive?: boolean;\n detailsHint?: ReactNode;\n /** Count badge */\n count?: number;\n totalCount?: number;\n /** Singular entity for “N rows” copy when unfiltered */\n entityName?: string;\n countActive?: boolean;\n viewMode?: ViewMode;\n onViewModeChange?: (mode: ViewMode) => void;\n pageSize?: number;\n onPageSizeChange?: (size: number) => void;\n density?: Density;\n onDensityChange?: (density: Density) => void;\n createAction?: ReactNode;\n /**\n * Additional actions, rendered in ONE overflow menu — never as more\n * side-by-side buttons.\n *\n * The budget is the point. A header with three top-level buttons squeezes\n * its own title to an ellipsis at real viewport widths, so a surface that\n * genuinely has four actions needs somewhere to put the other three. Before\n * this existed the only place was a fork of the header, which is exactly\n * what one consumer did.\n *\n * Pass `ReactNode` via `actions` instead when you need arbitrary chrome;\n * this prop is for the ordinary case, and it keeps the budget for you.\n */\n secondaryActions?: PageHeaderAction[];\n}\n\ntype ToggleDef = {\n key: keyof PageHeaderOptions;\n label: string;\n available: boolean;\n};\n\nexport function PageHeader({\n title,\n subtitle,\n icon: Icon,\n options: optionsProp,\n optionsStorageKey,\n actions,\n stats,\n details,\n detailsOpen,\n onDetailsOpenChange,\n detailsActive = false,\n detailsHint,\n count,\n totalCount,\n entityName,\n countActive = false,\n viewMode,\n onViewModeChange,\n pageSize,\n onPageSizeChange,\n density,\n onDensityChange,\n createAction,\n secondaryActions,\n}: PageHeaderProps) {\n const detailsRegionId = useId();\n const hasDetails = details != null;\n const hasStats = stats != null;\n const hasCount = count !== undefined && totalCount !== undefined;\n const hasViewToggle = Boolean(viewMode && onViewModeChange);\n const hasViewSettings = Boolean(onPageSizeChange && onDensityChange);\n const hasCreate = createAction != null;\n // `hidden` is filtered here rather than at the call site: an action gated on\n // data (\"Review drafts\", only when drafts exist) is the common case, and a\n // conditional array at every call site is what makes those call sites drift.\n const visibleSecondary = (secondaryActions ?? []).filter((a) => !a.hidden);\n\n const [userOverrides, setUserOverrides] = useState<Partial<PageHeaderOptions>>(\n {},\n );\n // Tracks which storage key the current overrides were hydrated from, so a\n // key change (routing between pages with distinct keys while this header\n // stays mounted) can't flush the previous key's overrides into the new key\n // before the read effect re-hydrates.\n const [hydratedKey, setHydratedKey] = useState<string | undefined>(\n optionsStorageKey ? undefined : \"\",\n );\n\n useEffect(() => {\n if (!optionsStorageKey) {\n setUserOverrides({});\n setHydratedKey(\"\");\n return;\n }\n setUserOverrides(readStoredOptions(optionsStorageKey));\n setHydratedKey(optionsStorageKey);\n }, [optionsStorageKey]);\n\n useEffect(() => {\n // Persist only once overrides belong to the current key (see hydratedKey).\n if (!optionsStorageKey || hydratedKey !== optionsStorageKey) return;\n writeStoredOptions(optionsStorageKey, userOverrides);\n }, [optionsStorageKey, userOverrides, hydratedKey]);\n\n const resolved = useMemo(() => {\n const merged: PageHeaderOptions = {\n ...OPTION_DEFAULTS,\n ...optionsProp,\n ...userOverrides,\n };\n if (merged.subtitleInDetails === undefined) {\n merged.subtitleInDetails = hasDetails;\n }\n if (merged.configurable === undefined) {\n merged.configurable =\n hasDetails || hasStats || hasCount || hasViewSettings || hasViewToggle;\n }\n return merged;\n }, [\n optionsProp,\n userOverrides,\n hasDetails,\n hasStats,\n hasCount,\n hasViewSettings,\n hasViewToggle,\n ]);\n\n const patchOption = useCallback((key: keyof PageHeaderOptions, value: boolean) => {\n setUserOverrides((prev) => ({ ...prev, [key]: value }));\n }, []);\n\n const moveSubtitle = Boolean(resolved.subtitleInDetails) && hasDetails;\n const showTitleSubtitle =\n Boolean(subtitle) &&\n Boolean(resolved.showSubtitle) &&\n !moveSubtitle;\n\n const [uncontrolledOpen, setUncontrolledOpen] = useState(\n () => optionsProp?.defaultDetailsOpen ?? OPTION_DEFAULTS.defaultDetailsOpen!,\n );\n const isControlled = detailsOpen !== undefined;\n const open = isControlled ? detailsOpen! : uncontrolledOpen;\n\n const setOpen = (next: boolean) => {\n if (!isControlled) setUncontrolledOpen(next);\n onDetailsOpenChange?.(next);\n };\n\n const detailsLabel = resolved.detailsLabel ?? \"Details\";\n const entity = entityName || \"item\";\n\n const toggles: ToggleDef[] = (\n [\n { key: \"showIcon\", label: \"Icon\", available: Boolean(Icon) },\n {\n key: \"showSubtitle\",\n label: \"Subtitle\",\n available: Boolean(subtitle) && !moveSubtitle,\n },\n { key: \"showCount\", label: \"Count\", available: hasCount },\n { key: \"showViewToggle\", label: \"View toggle\", available: hasViewToggle },\n {\n key: \"showViewSettings\",\n label: \"Display settings\",\n available: hasViewSettings,\n },\n { key: \"showCreate\", label: \"Create action\", available: hasCreate },\n { key: \"showStats\", label: \"Stat cards\", available: hasStats },\n {\n key: \"showDetailsToggle\",\n label: \"Filters / details\",\n available: hasDetails,\n },\n {\n key: \"showDetailsHint\",\n label: \"Collapsed hint\",\n available: hasDetails && detailsHint != null,\n },\n ] as const satisfies readonly ToggleDef[]\n ).filter((t) => t.available);\n\n const showDetailsToggle =\n hasDetails && Boolean(resolved.showDetailsToggle);\n const showStats = hasStats && Boolean(resolved.showStats);\n const showHint =\n hasDetails &&\n !open &&\n Boolean(resolved.showDetailsHint) &&\n detailsHint != null;\n\n const actionsCluster = (\n <div className=\"flex items-center gap-1.5 shrink-0\">\n {showHint ? (\n <span className=\"hidden max-w-[14rem] truncate text-xs text-muted-foreground sm:inline\">\n {detailsHint}\n </span>\n ) : null}\n\n {hasCount && resolved.showCount !== false ? (\n <Badge variant=\"secondary\" className=\"text-xs\">\n {countActive\n ? `${count} of ${totalCount}`\n : `${totalCount} ${pluralizeEntity(entity, totalCount!)}`}\n </Badge>\n ) : null}\n\n {hasViewToggle && resolved.showViewToggle !== false ? (\n <ViewToggle viewMode={viewMode!} onViewModeChange={onViewModeChange!} />\n ) : null}\n\n {showDetailsToggle ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\n \"relative h-8 w-8\",\n (open || detailsActive) && \"bg-accent text-accent-foreground\",\n )}\n onClick={() => setOpen(!open)}\n data-testid=\"page-header-details-toggle\"\n title={open ? `Hide ${detailsLabel}` : `Show ${detailsLabel}`}\n aria-label={open ? `Hide ${detailsLabel}` : `Show ${detailsLabel}`}\n aria-expanded={open}\n aria-controls={detailsRegionId}\n testID=\"page-header-details-toggle\"\n >\n <ListFilter className=\"h-4 w-4\" />\n {detailsActive ? (\n <span\n className=\"absolute right-1.5 top-1.5 size-1.5 rounded-full bg-primary\"\n aria-hidden\n />\n ) : null}\n </Button>\n ) : null}\n\n {hasViewSettings && resolved.showViewSettings !== false ? (\n <ViewSettings\n pageSize={pageSize ?? 25}\n onPageSizeChange={onPageSizeChange!}\n density={density ?? \"comfortable\"}\n onDensityChange={onDensityChange!}\n />\n ) : null}\n\n {hasCreate && resolved.showCreate !== false ? createAction : null}\n\n {visibleSecondary.length > 0 ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label=\"More actions\"\n data-testid=\"page-header-more-actions\"\n >\n <MoreHorizontal className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {visibleSecondary.map((action) => {\n const ActionIcon = action.icon;\n return (\n <DropdownMenuItem\n key={action.label}\n onSelect={action.onClick}\n disabled={action.disabled}\n data-testid={action.testId}\n >\n {ActionIcon ? (\n <ActionIcon className=\"mr-2 h-4 w-4\" aria-hidden=\"true\" />\n ) : null}\n {action.label}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n ) : null}\n\n {actions}\n\n {resolved.configurable && toggles.length > 0 ? (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n title=\"Header options\"\n aria-label=\"Header options\"\n data-testid=\"page-header-options\"\n testID=\"page-header-options\"\n >\n <SlidersHorizontal className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className=\"w-64 space-y-3\">\n <div>\n <h4 className=\"text-sm font-semibold\">Header options</h4>\n <p className=\"text-xs text-muted-foreground\">\n Customize this page header. Saved on this device when a storage\n key is set.\n </p>\n </div>\n <ul className=\"space-y-3\">\n {toggles.map((t) => {\n const checked = Boolean(resolved[t.key] ?? true);\n return (\n <li\n key={t.key}\n className=\"flex items-center justify-between gap-3\"\n >\n <Label\n htmlFor={`page-header-opt-${t.key}`}\n className=\"text-sm font-normal\"\n >\n {t.label}\n </Label>\n <Switch\n id={`page-header-opt-${t.key}`}\n checked={checked}\n onCheckedChange={(v) => patchOption(t.key, v)}\n />\n </li>\n );\n })}\n </ul>\n {optionsStorageKey && Object.keys(userOverrides).length > 0 ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-full text-xs\"\n onClick={() => setUserOverrides({})}\n data-testid=\"page-header-options-reset\"\n aria-label=\"Reset header options\"\n testID=\"page-header-options-reset\"\n >\n Reset to defaults\n </Button>\n ) : null}\n </PopoverContent>\n </Popover>\n ) : null}\n </div>\n );\n\n const titleRow = resolved.showTitle === false ? (\n <div\n data-testid=\"page-header-toolbar\"\n className=\"flex min-w-0 flex-wrap items-center justify-end gap-2\"\n >\n {actionsCluster}\n </div>\n ) : (\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-3 min-w-0\">\n {Icon && resolved.showIcon !== false ? (\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-xl bg-primary/10\">\n <Icon className=\"h-5 w-5 text-primary\" />\n </div>\n ) : null}\n <div className=\"min-w-0\">\n <h1\n data-testid=\"page-title\"\n className=\"truncate font-display text-xl font-bold tracking-tight sm:text-2xl\"\n >\n {title}\n </h1>\n {showTitleSubtitle ? (\n <p className=\"truncate text-sm text-muted-foreground\">{subtitle}</p>\n ) : null}\n </div>\n </div>\n {actionsCluster}\n </div>\n );\n\n const statsRow = showStats ? (\n <div\n data-testid=\"page-header-stats\"\n className=\"mt-3 grid gap-3 sm:grid-cols-2 lg:grid-cols-4\"\n >\n {stats}\n </div>\n ) : null;\n\n if (!hasDetails) {\n return (\n <>\n {titleRow}\n {statsRow}\n </>\n );\n }\n\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n {titleRow}\n {statsRow}\n <CollapsibleContent id={detailsRegionId} className=\"mt-3\">\n <div className=\"flex flex-col gap-3 rounded-lg border border-border bg-card/40 p-3 sm:p-4\">\n {moveSubtitle && subtitle && resolved.showSubtitle !== false ? (\n <p className=\"text-sm text-muted-foreground\">{subtitle}</p>\n ) : null}\n {details}\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n}\n","\"use client\";\n\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useState,\n} from \"react\";\nimport {\n Menu,\n X,\n Sun,\n Moon,\n SlidersHorizontal,\n PanelLeftClose,\n PanelLeft,\n ChevronDown,\n ArrowLeft,\n} from \"lucide-react\";\nimport type { LucideIcon } from \"lucide-react\";\nimport { Button } from \"../ui/button\";\nimport { Badge } from \"../ui/badge\";\nimport { Label } from \"../ui/label\";\nimport { Switch } from \"../ui/switch\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../ui/popover\";\nimport { Collapsible, CollapsibleContent } from \"../ui/collapsible\";\nimport { cn } from \"../../utils\";\nimport { readStoredOptions, writeStoredOptions } from \"../../option-storage\";\nimport {\n DefaultLink,\n isPathActive,\n resolveNavigation,\n type LinkComponent,\n type NavigationNode,\n} from \"../../navigation\";\n\nexport interface NavItem {\n to: string;\n icon: LucideIcon;\n label: string;\n /** Nested items — rendered as a collapsible group when the rail is expanded */\n children?: NavItem[];\n badge?: string | number;\n disabled?: boolean;\n /**\n * Exact-match active state (e.g. overview `/`). Exact on the path only, so\n * an `activePath` carrying `?search#hash` still matches.\n */\n end?: boolean;\n}\n\n/**\n * The \"up\" link AppShell renders above page content: a real link to the\n * logical parent, never `history.back()`.\n *\n * @stability Beta\n */\nexport interface ParentNavigation {\n href: string;\n label: string;\n}\n\n/**\n * Declarative chrome for AppShell — developer defaults + optional\n * in-sidebar user toggles (Notion/Linear “customize chrome” pattern).\n *\n * @stability Beta\n */\nexport interface AppShellOptions {\n showLogo?: boolean;\n showAppName?: boolean;\n showThemeToggle?: boolean;\n /** Desktop rail collapse control */\n showCollapse?: boolean;\n showUserSlot?: boolean;\n showFooter?: boolean;\n showSecondaryNav?: boolean;\n /** Mobile fixed bottom tab bar */\n showMobileBottomNav?: boolean;\n defaultCollapsed?: boolean;\n /**\n * Show the in-sidebar Sidebar options popover so users can customize chrome.\n * Default true when collapse / secondary / theme / slots are available.\n */\n configurable?: boolean;\n /**\n * Toggle keys the developer has decided on and users may not override —\n * e.g. hiding `showThemeToggle` for a brand that manages theme elsewhere.\n * Locked keys are dropped from the options popover and any stored user\n * override for them is ignored on resolve.\n */\n lockedOptions?: (keyof AppShellOptions)[];\n /** Comfortable (default) vs compact row padding */\n density?: \"comfortable\" | \"compact\";\n /** Expanded rail width in rem-ish tokens: narrow ≈ 13rem, wide ≈ 16rem */\n railWidth?: \"narrow\" | \"wide\";\n /**\n * Where page content scrolls.\n * - `container` (default): main panel scrolls — classic app-shell chrome.\n * - `window`: document/window scrolls with a sticky rail so React Router\n * `ScrollRestoration` keeps working (dashboard dogfood).\n */\n scrollRoot?: \"container\" | \"window\";\n}\n\nconst OPTION_DEFAULTS: Required<\n Omit<AppShellOptions, \"configurable\" | \"defaultCollapsed\" | \"lockedOptions\">\n> &\n Pick<AppShellOptions, \"configurable\" | \"defaultCollapsed\" | \"lockedOptions\"> = {\n showLogo: true,\n showAppName: true,\n showThemeToggle: true,\n showCollapse: true,\n showUserSlot: true,\n showFooter: true,\n showSecondaryNav: true,\n showMobileBottomNav: true,\n defaultCollapsed: false,\n configurable: undefined,\n density: \"comfortable\",\n railWidth: \"narrow\",\n scrollRoot: \"container\",\n};\n\nfunction readStoredCollapsed(key: string): boolean | undefined {\n if (typeof window === \"undefined\") return undefined;\n try {\n const raw = localStorage.getItem(`${key}:collapsed`);\n if (raw === \"1\") return true;\n if (raw === \"0\") return false;\n return undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writeStoredCollapsed(key: string, collapsed: boolean) {\n if (typeof window === \"undefined\") return;\n try {\n localStorage.setItem(`${key}:collapsed`, collapsed ? \"1\" : \"0\");\n } catch {\n // quota / private mode\n }\n}\n\n/**\n * @stability Beta\n */\nexport interface AppShellProps {\n /** App name shown in sidebar header */\n appName: string;\n /** App logo letter or short text (ignored when `logo` is set) */\n appLogo?: string;\n /** Custom logo node — preferred over `appLogo` letter tile */\n logo?: ReactNode;\n /**\n * Primary navigation items. Optional when `navigation` is set: the tree\n * root's `items` are the global nav then.\n */\n navItems?: NavItem[];\n /**\n * The app's logical navigation hierarchy. AppShell resolves it against\n * `activePath` (see `resolveNavigation`) and derives:\n * - the sidebar's global items from the root's `items` (unless `navItems`),\n * - a contextual section from the current node's `items`, labelled with\n * the node's `label` (`$param` segments in `to` filled from the URL),\n * - the mobile tab bar: the contextual items when there are any, else the\n * global top-level items (unless `mobileNavItems`),\n * - a back link to the current node's logical parent (unless\n * `parentNavigation`).\n *\n * @stability Beta\n */\n navigation?: NavigationNode<NavItem>;\n /**\n * Back-to-parent link rendered in the content header, above `children`, on\n * mobile and desktop. Derived from `navigation` when omitted; `null` hides\n * it. Use this instead of placing a back row inside page content.\n *\n * @stability Beta\n */\n parentNavigation?: ParentNavigation | null;\n /** Secondary nav (e.g. “More”) — rendered below a divider when shown */\n secondaryNavItems?: NavItem[];\n /** Label above secondary nav (default “More”) */\n secondaryNavLabel?: string;\n /**\n * Items for the mobile bottom tab bar. Defaults to top-level `navItems`\n * (no children). Pass a short list for apps with large sidebars; pass `[]`\n * and set `options.showMobileBottomNav: false` to hide.\n */\n mobileNavItems?: NavItem[];\n /** Slot below the logo row (product switcher, workspace picker, …) */\n headerSlot?: ReactNode;\n /**\n * Compact slot shown in the **collapsed** desktop rail, where `headerSlot`\n * is hidden for space. Use it to keep a core affordance reachable without\n * expanding — e.g. an icon-only product switcher. Omit to hide the header\n * region entirely while collapsed.\n */\n collapsedHeaderSlot?: ReactNode;\n /** Footer region above the user slot (version, links) */\n footer?: ReactNode;\n /**\n * User / account block at the bottom of the sidebar. When the rail is\n * collapsed, AppShell hides any descendant carrying the\n * `data-shell-user-detail` attribute (e.g. name/email text) so only a\n * compact element (avatar, initial) remains — tag the detail wrapper you\n * want hidden in the collapsed rail with that attribute.\n */\n userSlot?: ReactNode;\n /** Page content */\n children: ReactNode;\n /**\n * @deprecated Prefer `options.showThemeToggle`. Kept for sample-app\n * back-compat; merges into resolved options when `options` omits it.\n */\n showThemeToggle?: boolean;\n /** Chrome config (developer defaults + optional in-sidebar menu) */\n options?: AppShellOptions;\n /** Persist user sidebar-option overrides + collapse state (localStorage) */\n optionsStorageKey?: string;\n /** Controlled collapse (desktop rail) */\n collapsed?: boolean;\n onCollapsedChange?: (collapsed: boolean) => void;\n /**\n * Injectable link component. Defaults to a plain `<a>` (no router). Pass a\n * router adapter — e.g. React Router `({ href, ...p }) => <Link to={href} {...p} />`\n * or Next.js `next/link` — to get client-side navigation.\n */\n linkComponent?: LinkComponent;\n /**\n * Current location used to highlight the active nav item. Pass the full\n * location, `pathname + search + hash` (React Router: `useLocation()`), so\n * items whose `to` names a query or hash (`/admin?tab=users`) can become\n * active. A pathname alone still works for path-only items, `end` included.\n * Omit to disable active highlighting.\n */\n activePath?: string;\n /**\n * Optional custom active-state matcher. Defaults to a prefix match (with `/`\n * treated as exact), mirroring React Router `NavLink`.\n */\n isActive?: (to: string, activePath?: string) => boolean;\n}\n\nconst PARAM = /^\\$(.+)$/;\n\n/**\n * Fill `$name` path segments from `params`; `undefined` if one is missing. A\n * `?query` / `#hash` on `to` is kept as is.\n */\nfunction fillParams(to: string, params: Record<string, string>): string | undefined {\n const cut = to.search(/[?#]/);\n const path = cut === -1 ? to : to.slice(0, cut);\n const suffix = cut === -1 ? \"\" : to.slice(cut);\n let missing = false;\n const filled = path\n .split(\"/\")\n .map((part) => {\n const name = PARAM.exec(part)?.[1];\n if (name == null) return part;\n const value = params[name];\n if (value == null) missing = true;\n return value == null ? part : encodeURIComponent(value);\n })\n .join(\"/\");\n return missing ? undefined : filled + suffix;\n}\n\n/** Interpolate items (and children); drop any whose path the URL can't fill. */\nfunction fillItems(items: NavItem[], params: Record<string, string>): NavItem[] {\n return items.flatMap((item) => {\n const to = fillParams(item.to, params);\n if (to == null) return [];\n return [\n {\n ...item,\n to,\n children: item.children ? fillItems(item.children, params) : undefined,\n },\n ];\n });\n}\n\nfunction ThemeToggle({ testId }: { testId: string }) {\n const [dark, setDark] = useState(false);\n\n useEffect(() => {\n const stored = localStorage.getItem(\"theme\");\n const prefersDark = window.matchMedia(\n \"(prefers-color-scheme: dark)\",\n ).matches;\n const isDark = stored === \"dark\" || (!stored && prefersDark);\n setDark(isDark);\n document.documentElement.classList.toggle(\"dark\", isDark);\n }, []);\n\n function toggle() {\n const next = !dark;\n setDark(next);\n document.documentElement.classList.toggle(\"dark\", next);\n localStorage.setItem(\"theme\", next ? \"dark\" : \"light\");\n }\n\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={toggle}\n className=\"h-8 w-8\"\n title=\"Toggle theme\"\n aria-label=\"Toggle theme\"\n data-testid={testId}\n testID={testId}\n >\n {dark ? <Sun className=\"h-4 w-4\" /> : <Moon className=\"h-4 w-4\" />}\n </Button>\n );\n}\n\nfunction itemIsActive(\n item: NavItem,\n activePath: string | undefined,\n isActive: (to: string, activePath?: string) => boolean,\n): boolean {\n // `end` is exact on the path but ignores an incidental query/hash, so an\n // `end` item stays active on `/dashboard?page=2`.\n if (item.end) {\n return isPathActive(item.to, activePath, { end: true });\n }\n if (isActive(item.to, activePath)) return true;\n return Boolean(\n item.children?.some((child) => itemIsActive(child, activePath, isActive)),\n );\n}\n\nfunction NavLinkRow({\n item,\n collapsed,\n density,\n onNavClick,\n linkComponent: LinkComp,\n activePath,\n isActive,\n notCurrent = false,\n}: {\n item: NavItem;\n collapsed: boolean;\n density: \"comfortable\" | \"compact\";\n onNavClick?: () => void;\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n /** Highlight as usual but never claim `aria-current` (another section holds it). */\n notCurrent?: boolean;\n}) {\n const active = itemIsActive(item, activePath, isActive);\n const pad = density === \"compact\" ? \"px-2.5 py-1.5\" : \"px-3 py-2\";\n\n if (item.disabled) {\n return (\n <span\n title={item.label}\n className={cn(\n \"flex items-center gap-3 rounded-lg text-sm font-medium opacity-40\",\n pad,\n collapsed && \"justify-center px-2\",\n )}\n aria-disabled\n >\n <item.icon className=\"h-4 w-4 shrink-0\" />\n {!collapsed ? <span className=\"truncate\">{item.label}</span> : null}\n </span>\n );\n }\n\n return (\n <LinkComp\n href={item.to}\n onClick={onNavClick}\n title={collapsed ? item.label : undefined}\n aria-label={collapsed ? item.label : undefined}\n aria-current={active && !notCurrent ? \"page\" : undefined}\n className={cn(\n \"flex items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n pad,\n collapsed && \"justify-center px-2\",\n active\n ? \"bg-sidebar-accent text-sidebar-primary\"\n : \"text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n )}\n >\n <item.icon className=\"h-4 w-4 shrink-0\" />\n {!collapsed ? (\n <>\n <span className=\"min-w-0 flex-1 truncate\">{item.label}</span>\n {item.badge != null ? (\n <Badge variant=\"secondary\" className=\"h-5 shrink-0 px-1.5 text-[10px]\">\n {item.badge}\n </Badge>\n ) : null}\n </>\n ) : null}\n </LinkComp>\n );\n}\n\nfunction NavGroup({\n item,\n collapsed,\n density,\n onNavClick,\n linkComponent,\n activePath,\n isActive,\n notCurrent = false,\n}: {\n item: NavItem;\n collapsed: boolean;\n density: \"comfortable\" | \"compact\";\n onNavClick?: () => void;\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n /** Highlight as usual but never claim `aria-current` (another section holds it). */\n notCurrent?: boolean;\n}) {\n const children = item.children ?? [];\n const childActive = children.some((c) =>\n itemIsActive(c, activePath, isActive),\n );\n const [open, setOpen] = useState(childActive);\n\n useEffect(() => {\n if (childActive) setOpen(true);\n }, [childActive]);\n\n if (children.length === 0) {\n return (\n <NavLinkRow\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n />\n );\n }\n\n // Collapsed rail: only the parent link (or first child if parent is a group stub)\n if (collapsed) {\n const target: NavItem = item.to\n ? { ...item, children: undefined }\n : { ...children[0]!, children: undefined };\n return (\n <NavLinkRow\n item={target}\n collapsed\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n />\n );\n }\n\n // Parent may be its own route (`item.to`) — keep a real link and a separate\n // expand control so groups under an existing page stay navigable + highlightable.\n // Visual highlight may use prefix match; aria-current is exact-only so a child\n // route does not leave two \"page\" currents in the tree (CMT-322-008). Exact\n // means the same path; a query/hash on `activePath` alone doesn't break it.\n const selfExact = Boolean(\n item.to && isPathActive(item.to, activePath, { end: true }),\n );\n const selfActive = item.to\n ? item.end\n ? selfExact\n : isActive(item.to, activePath)\n : false;\n const groupHighlight = selfActive || childActive;\n const pad = density === \"compact\" ? \"px-2.5 py-1.5\" : \"px-3 py-2\";\n const LinkComp = linkComponent;\n const parentClass = cn(\n \"flex min-w-0 flex-1 items-center gap-3 rounded-lg text-sm font-medium transition-colors\",\n pad,\n groupHighlight\n ? \"bg-sidebar-accent/60 text-sidebar-primary\"\n : \"text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n );\n\n return (\n <Collapsible open={open} onOpenChange={setOpen}>\n <div className=\"space-y-0.5\">\n <div className=\"flex items-center gap-0.5\" data-testid={`nav-group-${item.label}`}>\n {item.to && !item.disabled ? (\n <LinkComp\n href={item.to}\n onClick={onNavClick}\n aria-current={selfExact && !notCurrent ? \"page\" : undefined}\n className={parentClass}\n >\n <item.icon className=\"h-4 w-4 shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate text-left\">{item.label}</span>\n </LinkComp>\n ) : (\n <button\n type=\"button\"\n className={parentClass}\n onClick={() => setOpen((o) => !o)}\n aria-expanded={open}\n aria-disabled={item.disabled || undefined}\n disabled={item.disabled}\n >\n <item.icon className=\"h-4 w-4 shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate text-left\">{item.label}</span>\n </button>\n )}\n <button\n type=\"button\"\n className={cn(\n \"shrink-0 rounded-lg p-1.5 text-sidebar-foreground transition-colors hover:bg-sidebar-accent\",\n groupHighlight && \"text-sidebar-primary\",\n item.disabled && \"pointer-events-none opacity-40\",\n )}\n onClick={() => setOpen((o) => !o)}\n aria-expanded={open}\n aria-label={open ? `Collapse ${item.label}` : `Expand ${item.label}`}\n aria-disabled={item.disabled || undefined}\n disabled={item.disabled}\n data-testid={`nav-group-toggle-${item.label}`}\n >\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 opacity-60 transition-transform\",\n open && \"rotate-180\",\n )}\n />\n </button>\n </div>\n <CollapsibleContent>\n <div className=\"ml-3 space-y-0.5 border-l border-sidebar-border pl-2\">\n {children.map((child) => (\n <NavLinkRow\n key={child.to + child.label}\n item={child}\n collapsed={false}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={notCurrent}\n />\n ))}\n </div>\n </CollapsibleContent>\n </div>\n </Collapsible>\n );\n}\n\nfunction SidebarNav({\n navItems,\n contextualNavItems,\n contextualNavLabel,\n secondaryNavItems,\n secondaryNavLabel,\n showSecondary,\n collapsed,\n density,\n onNavClick,\n linkComponent,\n activePath,\n isActive,\n}: {\n navItems: NavItem[];\n contextualNavItems?: NavItem[];\n contextualNavLabel?: string;\n secondaryNavItems?: NavItem[];\n secondaryNavLabel: string;\n showSecondary: boolean;\n collapsed: boolean;\n density: \"comfortable\" | \"compact\";\n onNavClick?: () => void;\n linkComponent: LinkComponent;\n activePath?: string;\n isActive: (to: string, activePath?: string) => boolean;\n}) {\n const contextualLabelId = useId();\n // While a contextual item is the current page, global items keep their\n // highlight (the section you are in) but leave `aria-current` to it, so\n // \"Showcase\" and \"Overview\" are never both the current page.\n const contextualActive = Boolean(\n contextualNavItems?.some((item) => itemIsActive(item, activePath, isActive)),\n );\n return (\n <nav\n className={cn(\n \"flex-1 space-y-1 overflow-y-auto\",\n collapsed ? \"p-2\" : \"p-3\",\n )}\n aria-label=\"Main\"\n >\n {navItems.map((item) => (\n <NavGroup\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n notCurrent={contextualActive}\n />\n ))}\n\n {contextualNavItems && contextualNavItems.length > 0 ? (\n <div\n className={cn(\n \"mt-4 space-y-1 border-t border-sidebar-border pt-4\",\n collapsed && \"mt-2 pt-2\",\n )}\n data-testid=\"app-shell-contextual-nav\"\n role=\"group\"\n aria-labelledby={!collapsed && contextualNavLabel ? contextualLabelId : undefined}\n aria-label={collapsed ? contextualNavLabel : undefined}\n >\n {!collapsed && contextualNavLabel ? (\n <p\n id={contextualLabelId}\n className=\"mb-2 truncate px-3 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/40\"\n >\n {contextualNavLabel}\n </p>\n ) : null}\n {contextualNavItems.map((item) => (\n <NavGroup\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n />\n ))}\n </div>\n ) : null}\n\n {showSecondary && secondaryNavItems && secondaryNavItems.length > 0 ? (\n <div\n className={cn(\n \"mt-4 space-y-1 border-t border-sidebar-border pt-4\",\n collapsed && \"mt-2 pt-2\",\n )}\n >\n {!collapsed ? (\n <p className=\"mb-2 px-3 text-xs font-medium uppercase tracking-wider text-sidebar-foreground/40\">\n {secondaryNavLabel}\n </p>\n ) : null}\n {secondaryNavItems.map((item) => (\n <NavGroup\n key={item.to + item.label}\n item={item}\n collapsed={collapsed}\n density={density}\n onNavClick={onNavClick}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n />\n ))}\n </div>\n ) : null}\n </nav>\n );\n}\n\nfunction SidebarBrand({\n appName,\n appLogo,\n logo,\n showLogo,\n showAppName,\n collapsed,\n}: {\n appName: string;\n appLogo?: string;\n logo?: ReactNode;\n showLogo: boolean;\n showAppName: boolean;\n collapsed: boolean;\n}) {\n if (!showLogo && !showAppName) return null;\n\n return (\n <div\n className={cn(\n \"flex min-w-0 items-center gap-2\",\n collapsed && \"justify-center\",\n )}\n >\n {showLogo ? (\n logo ? (\n <div className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden\">\n {logo}\n </div>\n ) : appLogo ? (\n <div className=\"flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-primary\">\n <span className=\"text-sm font-bold text-primary-foreground\">\n {appLogo}\n </span>\n </div>\n ) : null\n ) : null}\n {showAppName && !collapsed ? (\n <span className=\"truncate font-semibold text-sidebar-foreground\">\n {appName}\n </span>\n ) : null}\n </div>\n );\n}\n\ntype ToggleDef = {\n key: keyof AppShellOptions;\n label: string;\n available: boolean;\n};\n\nexport function AppShell({\n appName,\n appLogo,\n logo,\n navItems: navItemsProp,\n navigation,\n parentNavigation: parentNavigationProp,\n secondaryNavItems,\n secondaryNavLabel = \"More\",\n mobileNavItems,\n headerSlot,\n collapsedHeaderSlot,\n footer,\n userSlot,\n children,\n showThemeToggle: showThemeToggleProp,\n options: optionsProp,\n optionsStorageKey,\n collapsed: collapsedProp,\n onCollapsedChange,\n linkComponent = DefaultLink,\n activePath,\n isActive = isPathActive,\n}: AppShellProps) {\n const [mobileOpen, setMobileOpen] = useState(false);\n\n // Hierarchical nav: resolve the tree against the current location once.\n const derived = useMemo(() => {\n if (!navigation) return undefined;\n const nav = resolveNavigation(navigation, activePath ?? \"/\");\n const atRoot = nav.trail.length === 1;\n const globalItems = fillItems(navigation.items, nav.params);\n const contextualItems = atRoot ? [] : fillItems(nav.items, nav.params);\n // No link up to the root from a top-level page (it is where the global\n // nav already goes), and none whose path the URL couldn't fill.\n const parent =\n nav.parent &&\n nav.trail.length > 2 &&\n !nav.parent.path.split(\"/\").some((p) => PARAM.test(p))\n ? { href: nav.parent.path, label: nav.parent.label }\n : undefined;\n return { current: nav.current, globalItems, contextualItems, parent };\n }, [navigation, activePath]);\n\n const navItems = navItemsProp ?? derived?.globalItems ?? [];\n const contextualNavItems = derived?.contextualItems ?? [];\n const parentNavigation =\n parentNavigationProp === undefined ? derived?.parent : parentNavigationProp ?? undefined;\n\n const [userOverrides, setUserOverrides] = useState<Partial<AppShellOptions>>(\n {},\n );\n // Tracks which storage key the current overrides were hydrated from, so a\n // key change can't flush the previous key's overrides into the new key\n // before the read effect re-hydrates.\n const [hydratedKey, setHydratedKey] = useState<string | undefined>(\n optionsStorageKey ? undefined : \"\",\n );\n\n // Close the drawer on any path change (product switcher, deep links, …).\n useEffect(() => {\n setMobileOpen(false);\n }, [activePath]);\n\n const hasSecondary = Boolean(secondaryNavItems && secondaryNavItems.length);\n const hasUser = userSlot != null;\n const hasFooter = footer != null;\n const hasLogo = Boolean(logo || appLogo);\n\n useEffect(() => {\n if (!optionsStorageKey) {\n setUserOverrides({});\n setHydratedKey(\"\");\n return;\n }\n setUserOverrides(readStoredOptions<AppShellOptions>(optionsStorageKey));\n setHydratedKey(optionsStorageKey);\n }, [optionsStorageKey]);\n\n useEffect(() => {\n // Persist only once overrides belong to the current key (see hydratedKey).\n if (!optionsStorageKey || hydratedKey !== optionsStorageKey) return;\n writeStoredOptions<AppShellOptions>(optionsStorageKey, userOverrides);\n }, [optionsStorageKey, userOverrides, hydratedKey]);\n\n const lockedOptions = optionsProp?.lockedOptions;\n\n const resolved = useMemo(() => {\n const merged: AppShellOptions = {\n ...OPTION_DEFAULTS,\n ...(showThemeToggleProp !== undefined\n ? { showThemeToggle: showThemeToggleProp }\n : {}),\n ...optionsProp,\n ...userOverrides,\n };\n if (merged.configurable === undefined) {\n merged.configurable =\n hasSecondary ||\n hasUser ||\n hasFooter ||\n Boolean(merged.showCollapse) ||\n Boolean(merged.showThemeToggle);\n }\n // Locked keys always resolve to the developer default, never a stored\n // or in-session user override.\n if (lockedOptions?.length) {\n const defaults = OPTION_DEFAULTS as Record<string, unknown>;\n const devOptions = optionsProp as Record<string, unknown> | undefined;\n const target = merged as Record<string, unknown>;\n for (const key of lockedOptions) {\n target[key] = devOptions?.[key] ?? defaults[key];\n }\n }\n return merged;\n }, [\n optionsProp,\n userOverrides,\n showThemeToggleProp,\n hasSecondary,\n hasUser,\n hasFooter,\n lockedOptions,\n ]);\n\n const patchOption = useCallback(\n (key: keyof AppShellOptions, value: boolean) => {\n if (lockedOptions?.includes(key)) return;\n setUserOverrides((prev) => ({ ...prev, [key]: value }));\n },\n [lockedOptions],\n );\n\n const [uncontrolledCollapsed, setUncontrolledCollapsed] = useState(\n () =>\n optionsProp?.defaultCollapsed ?? OPTION_DEFAULTS.defaultCollapsed!,\n );\n\n useEffect(() => {\n if (!optionsStorageKey || collapsedProp !== undefined) return;\n const stored = readStoredCollapsed(optionsStorageKey);\n if (stored !== undefined) setUncontrolledCollapsed(stored);\n }, [optionsStorageKey, collapsedProp]);\n\n const isCollapseControlled = collapsedProp !== undefined;\n const collapsed = isCollapseControlled\n ? collapsedProp!\n : uncontrolledCollapsed;\n\n const setCollapsed = (next: boolean) => {\n if (!isCollapseControlled) {\n setUncontrolledCollapsed(next);\n if (optionsStorageKey) writeStoredCollapsed(optionsStorageKey, next);\n }\n onCollapsedChange?.(next);\n };\n\n const ParentLink = linkComponent;\n const density = resolved.density ?? \"comfortable\";\n const scrollWindow = resolved.scrollRoot === \"window\";\n const railExpanded =\n resolved.railWidth === \"wide\" ? \"md:w-64\" : \"md:w-52\";\n const railClass = collapsed ? \"md:w-14\" : railExpanded;\n\n const leaves = (items: NavItem[]) =>\n items.filter((i) => !i.children || i.children.length === 0);\n const contextualLeaves = leaves(contextualNavItems);\n const bottomItems = (\n mobileNavItems ??\n (contextualLeaves.length > 0 ? contextualLeaves : leaves(navItems))\n ).filter((i) => !i.disabled);\n // Global tabs shown as a fallback keep their highlight, but leave\n // `aria-current` to the contextual item that is the current page (see SidebarNav).\n const bottomNotCurrent =\n !mobileNavItems &&\n contextualLeaves.length === 0 &&\n contextualNavItems.some((i) => itemIsActive(i, activePath, isActive));\n\n const toggles: ToggleDef[] = (\n [\n { key: \"showLogo\", label: \"Logo\", available: hasLogo },\n { key: \"showAppName\", label: \"App name\", available: true },\n {\n key: \"showThemeToggle\",\n label: \"Theme toggle\",\n available: true,\n },\n { key: \"showCollapse\", label: \"Collapse control\", available: true },\n {\n key: \"showSecondaryNav\",\n label: \"Secondary nav\",\n available: hasSecondary,\n },\n { key: \"showFooter\", label: \"Footer\", available: hasFooter },\n { key: \"showUserSlot\", label: \"User block\", available: hasUser },\n {\n key: \"showMobileBottomNav\",\n label: \"Mobile bottom nav\",\n available: bottomItems.length > 0,\n },\n ] as const satisfies readonly ToggleDef[]\n ).filter((t) => t.available && !lockedOptions?.includes(t.key));\n\n const showTheme = resolved.showThemeToggle !== false;\n const showCollapseCtrl = resolved.showCollapse !== false;\n const showSecondary = hasSecondary && resolved.showSecondaryNav !== false;\n const showFooterSlot = hasFooter && resolved.showFooter !== false;\n const showUser = hasUser && resolved.showUserSlot !== false;\n const showMobileBottom =\n bottomItems.length > 0 && resolved.showMobileBottomNav !== false;\n\n const optionsControl =\n resolved.configurable && toggles.length > 0 ? (\n <Popover>\n <PopoverTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n title=\"Sidebar options\"\n aria-label=\"Sidebar options\"\n data-testid=\"app-shell-options\"\n testID=\"app-shell-options\"\n >\n <SlidersHorizontal className=\"h-4 w-4\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent align=\"start\" side=\"top\" className=\"w-64 space-y-3\">\n <div>\n <h4 className=\"text-sm font-semibold\">Sidebar options</h4>\n <p className=\"text-xs text-muted-foreground\">\n Customize this sidebar. Saved on this device when a storage key is\n set.\n </p>\n </div>\n <ul className=\"space-y-3\">\n {toggles.map((t) => {\n const checked = Boolean(resolved[t.key] ?? true);\n return (\n <li\n key={t.key}\n className=\"flex items-center justify-between gap-3\"\n >\n <Label\n htmlFor={`app-shell-opt-${t.key}`}\n className=\"text-sm font-normal\"\n >\n {t.label}\n </Label>\n <Switch\n id={`app-shell-opt-${t.key}`}\n checked={checked}\n onCheckedChange={(v) => patchOption(t.key, v)}\n />\n </li>\n );\n })}\n </ul>\n {optionsStorageKey && Object.keys(userOverrides).length > 0 ? (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-8 w-full text-xs\"\n onClick={() => setUserOverrides({})}\n data-testid=\"app-shell-options-reset\"\n aria-label=\"Reset sidebar options\"\n testID=\"app-shell-options-reset\"\n >\n Reset to defaults\n </Button>\n ) : null}\n </PopoverContent>\n </Popover>\n ) : null;\n\n const sidebarChrome = (opts: { mobile?: boolean }) => (\n <>\n <div\n className={cn(\n \"flex h-14 shrink-0 items-center gap-2 border-b border-sidebar-border\",\n collapsed && !opts.mobile ? \"justify-center px-2\" : \"px-3\",\n )}\n >\n <div className=\"min-w-0 flex-1\">\n <SidebarBrand\n appName={appName}\n appLogo={appLogo}\n logo={logo}\n showLogo={resolved.showLogo !== false}\n showAppName={resolved.showAppName !== false}\n collapsed={collapsed && !opts.mobile}\n />\n </div>\n {opts.mobile ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setMobileOpen(false)}\n aria-label=\"Close navigation\"\n data-testid=\"app-shell-mobile-close\"\n testID=\"app-shell-mobile-close\"\n >\n <X className=\"h-5 w-5\" />\n </Button>\n ) : (\n <div className=\"flex shrink-0 items-center gap-0.5\">\n {showCollapseCtrl ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-8 w-8\"\n onClick={() => setCollapsed(!collapsed)}\n title={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n aria-label={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n aria-pressed={collapsed}\n data-testid=\"app-shell-collapse\"\n testID=\"app-shell-collapse\"\n >\n {collapsed ? (\n <PanelLeft className=\"h-4 w-4\" />\n ) : (\n <PanelLeftClose className=\"h-4 w-4\" />\n )}\n </Button>\n ) : null}\n {!collapsed ? optionsControl : null}\n </div>\n )}\n </div>\n\n {collapsed && !opts.mobile ? (\n collapsedHeaderSlot ? (\n <div className=\"shrink-0 border-b border-sidebar-border p-2\">\n {collapsedHeaderSlot}\n </div>\n ) : null\n ) : headerSlot ? (\n <div className=\"shrink-0 border-b border-sidebar-border\">\n {headerSlot}\n </div>\n ) : null}\n\n <SidebarNav\n navItems={navItems}\n contextualNavItems={contextualNavItems}\n contextualNavLabel={derived?.current.label}\n secondaryNavItems={secondaryNavItems}\n secondaryNavLabel={secondaryNavLabel}\n showSecondary={showSecondary}\n collapsed={collapsed && !opts.mobile}\n density={density}\n onNavClick={opts.mobile ? () => setMobileOpen(false) : undefined}\n linkComponent={linkComponent}\n activePath={activePath}\n isActive={isActive}\n />\n\n {(showFooterSlot || showUser || showTheme || (collapsed && optionsControl)) &&\n !opts.mobile ? (\n <div className=\"mt-auto shrink-0 space-y-2 border-t border-sidebar-border p-2\">\n {showFooterSlot && !collapsed ? footer : null}\n {showUser ? (\n <div\n className={cn(\n collapsed &&\n \"flex justify-center [&_[data-shell-user-detail]]:hidden\",\n )}\n >\n {userSlot}\n </div>\n ) : null}\n <div\n className={cn(\n \"flex items-center gap-1\",\n collapsed ? \"flex-col\" : \"justify-end\",\n )}\n >\n {collapsed ? optionsControl : null}\n {showTheme ? (\n <ThemeToggle testId=\"app-shell-theme-toggle-desktop\" />\n ) : null}\n </div>\n </div>\n ) : null}\n\n {opts.mobile && (showFooterSlot || showUser || showTheme) ? (\n <div className=\"mt-auto shrink-0 space-y-2 border-t border-sidebar-border p-3\">\n {showFooterSlot ? footer : null}\n {showUser ? userSlot : null}\n {showTheme ? (\n <div className=\"flex justify-end\">\n <ThemeToggle testId=\"app-shell-theme-toggle-mobile-drawer\" />\n </div>\n ) : null}\n </div>\n ) : null}\n </>\n );\n\n return (\n <div\n className={cn(\n \"flex\",\n scrollWindow ? \"min-h-screen\" : \"h-screen overflow-hidden\",\n )}\n >\n {/* Desktop sidebar */}\n <aside\n className={cn(\n \"hidden flex-col border-r border-sidebar-border bg-sidebar transition-[width] duration-200 md:flex\",\n scrollWindow && \"sticky top-0 h-screen\",\n railClass,\n )}\n data-collapsed={collapsed || undefined}\n data-testid=\"app-shell-sidebar\"\n >\n {sidebarChrome({})}\n </aside>\n\n {/* Mobile overlay */}\n {mobileOpen ? (\n <div\n className=\"fixed inset-0 z-40 bg-black/50 md:hidden\"\n onClick={() => setMobileOpen(false)}\n aria-hidden\n />\n ) : null}\n\n {/* Mobile sidebar — inert when closed so off-screen links leave tab order */}\n <aside\n className={cn(\n \"fixed inset-y-0 left-0 z-50 flex w-60 flex-col border-r border-sidebar-border bg-sidebar transition-transform md:hidden\",\n mobileOpen ? \"translate-x-0\" : \"-translate-x-full pointer-events-none\",\n )}\n id=\"app-shell-mobile-nav\"\n aria-hidden={!mobileOpen}\n inert={!mobileOpen || undefined}\n >\n {sidebarChrome({ mobile: true })}\n </aside>\n\n {/* Main content */}\n <div\n className={cn(\n \"flex min-w-0 flex-1 flex-col\",\n !scrollWindow && \"overflow-hidden\",\n )}\n >\n <header\n className={cn(\n \"flex h-14 items-center gap-3 border-b px-4 md:hidden\",\n scrollWindow && \"sticky top-0 z-20 bg-background\",\n )}\n >\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setMobileOpen(true)}\n aria-label=\"Open navigation\"\n aria-expanded={mobileOpen}\n aria-controls=\"app-shell-mobile-nav\"\n data-testid=\"app-shell-mobile-open\"\n testID=\"app-shell-mobile-open\"\n >\n <Menu className=\"h-5 w-5\" />\n </Button>\n <span className=\"flex-1 truncate font-semibold\">{appName}</span>\n {showTheme ? (\n <ThemeToggle testId=\"app-shell-theme-toggle-mobile-header\" />\n ) : null}\n </header>\n\n <main\n className={cn(\n \"flex-1\",\n !scrollWindow && \"overflow-y-auto\",\n showMobileBottom ? \"pb-16 md:pb-0\" : \"pb-0\",\n )}\n >\n {parentNavigation ? (\n <div\n className=\"flex min-w-0 items-center px-4 pt-4 sm:px-6 sm:pt-6 lg:px-8 lg:pt-8\"\n data-testid=\"app-shell-parent-nav\"\n >\n {/* -ml-3 lines the arrow up with the content's left edge. */}\n <Button\n asChild\n variant=\"ghost\"\n size=\"sm\"\n className=\"-ml-3 min-w-0 max-w-full\"\n testID=\"app-shell-parent-link\"\n >\n <ParentLink\n href={parentNavigation.href}\n aria-label={`Back to ${parentNavigation.label}`}\n >\n <ArrowLeft aria-hidden />\n <span className=\"truncate\">{parentNavigation.label}</span>\n </ParentLink>\n </Button>\n </div>\n ) : null}\n <div\n className={cn(\n \"min-w-0 p-4 sm:p-6 lg:p-8\",\n parentNavigation && \"pt-2 sm:pt-3 lg:pt-4\",\n )}\n >\n {children}\n </div>\n </main>\n\n {showMobileBottom ? (\n <nav\n className=\"fixed bottom-0 left-0 right-0 z-30 flex border-t bg-background md:hidden\"\n aria-label=\"Primary\"\n >\n {bottomItems.map((item) => {\n const LinkComp = linkComponent;\n const active = itemIsActive(item, activePath, isActive);\n return (\n <LinkComp\n key={item.to + item.label}\n href={item.to}\n title={item.label}\n aria-label={item.label}\n aria-current={active && !bottomNotCurrent ? \"page\" : undefined}\n className={cn(\n \"flex flex-1 flex-col items-center gap-1 py-2 text-xs font-medium transition-colors\",\n active ? \"text-primary\" : \"text-muted-foreground\",\n )}\n >\n <item.icon className=\"h-5 w-5\" />\n <span className=\"max-w-full truncate px-0.5\">\n {item.label}\n </span>\n </LinkComp>\n );\n })}\n </nav>\n ) : null}\n </div>\n </div>\n );\n}\n"]}
@@ -137,5 +137,5 @@ function useBrowserSearchParams() {
137
137
  }
138
138
 
139
139
  export { DefaultLink, defaultNavigate, isPathActive, resolveNavigation, useBrowserSearchParams };
140
- //# sourceMappingURL=chunk-CDYZRZ6U.js.map
141
- //# sourceMappingURL=chunk-CDYZRZ6U.js.map
140
+ //# sourceMappingURL=chunk-WGMEVX3Y.js.map
141
+ //# sourceMappingURL=chunk-WGMEVX3Y.js.map