@marktiderman/genesis-ui 2.11.0 → 2.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/SKILL.md +57 -0
  2. package/dist/AppShell-D5nD0mcL.d.ts +348 -0
  3. package/dist/chunk-424PT5DM.js +21 -0
  4. package/dist/chunk-424PT5DM.js.map +1 -0
  5. package/dist/{chunk-UYI3GLFJ.js → chunk-6N6MUN3T.js} +722 -159
  6. package/dist/chunk-6N6MUN3T.js.map +1 -0
  7. package/dist/chunk-J45FHL7D.js +46 -0
  8. package/dist/chunk-J45FHL7D.js.map +1 -0
  9. package/dist/{chunk-OITWCIG2.js → chunk-PMCUHSZS.js} +3 -3
  10. package/dist/{chunk-OITWCIG2.js.map → chunk-PMCUHSZS.js.map} +1 -1
  11. package/dist/{chunk-5GOQ72WB.js → chunk-STZVZUYO.js} +3 -3
  12. package/dist/{chunk-5GOQ72WB.js.map → chunk-STZVZUYO.js.map} +1 -1
  13. package/dist/chunk-WALJMVEF.js +10 -0
  14. package/dist/chunk-WALJMVEF.js.map +1 -0
  15. package/dist/components/data/index.d.ts +7 -6
  16. package/dist/components/data/index.js +15 -13
  17. package/dist/components/data/index.js.map +1 -1
  18. package/dist/components/layout/dashboard-page.js +1 -0
  19. package/dist/components/layout/detail-page.js +1 -0
  20. package/dist/components/layout/form-page.js +1 -0
  21. package/dist/components/layout/index.d.ts +3 -2
  22. package/dist/components/layout/index.js +4 -2
  23. package/dist/components/layout/settings-page.js +1 -0
  24. package/dist/components/patterns/empty-state.js +1 -0
  25. package/dist/components/patterns/form-field.js +1 -0
  26. package/dist/components/patterns/index.js +1 -0
  27. package/dist/components/patterns/page-loading.js +1 -0
  28. package/dist/components/patterns/settings-row.js +1 -0
  29. package/dist/components/patterns/sortable-list.js +1 -0
  30. package/dist/components/patterns/status-badge.js +1 -0
  31. package/dist/components/patterns/toggle-row.js +1 -0
  32. package/dist/components/patterns/user-avatar.js +1 -0
  33. package/dist/components/rich-text/rich-text-editor.js +2 -1
  34. package/dist/components/rich-text/rich-text-editor.js.map +1 -1
  35. package/dist/components/rich-text/rich-text.js +1 -0
  36. package/dist/components/sheet-grid/sheet-grid.js +1 -0
  37. package/dist/components/sheet-grid/sheet-grid.js.map +1 -1
  38. package/dist/components/ui/accessible-icon.js +1 -0
  39. package/dist/components/ui/accordion.js +1 -0
  40. package/dist/components/ui/alert-dialog.js +1 -0
  41. package/dist/components/ui/alert.js +1 -0
  42. package/dist/components/ui/aspect-ratio.js +1 -0
  43. package/dist/components/ui/avatar.js +1 -0
  44. package/dist/components/ui/badge.js +1 -0
  45. package/dist/components/ui/breadcrumb.js +1 -0
  46. package/dist/components/ui/button-group.js +1 -0
  47. package/dist/components/ui/button.js +1 -0
  48. package/dist/components/ui/calendar.js +1 -0
  49. package/dist/components/ui/card.js +1 -0
  50. package/dist/components/ui/carousel.js +1 -0
  51. package/dist/components/ui/chart.js +1 -0
  52. package/dist/components/ui/checkbox.js +1 -0
  53. package/dist/components/ui/collapsible.js +1 -0
  54. package/dist/components/ui/command-palette.js +1 -0
  55. package/dist/components/ui/command.js +1 -0
  56. package/dist/components/ui/context-menu.js +1 -0
  57. package/dist/components/ui/date-picker.js +1 -0
  58. package/dist/components/ui/dialog.js +1 -0
  59. package/dist/components/ui/drawer.js +1 -0
  60. package/dist/components/ui/dropdown-menu.js +1 -0
  61. package/dist/components/ui/hover-card.js +1 -0
  62. package/dist/components/ui/input-group.js +1 -0
  63. package/dist/components/ui/input-otp.js +1 -0
  64. package/dist/components/ui/input.js +1 -0
  65. package/dist/components/ui/kbd.js +1 -0
  66. package/dist/components/ui/label.js +1 -0
  67. package/dist/components/ui/menubar.js +1 -0
  68. package/dist/components/ui/navigation-menu.js +1 -0
  69. package/dist/components/ui/pagination.js +1 -0
  70. package/dist/components/ui/password-toggle-field.js +1 -0
  71. package/dist/components/ui/popover.js +1 -0
  72. package/dist/components/ui/progress.js +1 -0
  73. package/dist/components/ui/radio-group.js +1 -0
  74. package/dist/components/ui/resizable.js +1 -0
  75. package/dist/components/ui/scroll-area.js +1 -0
  76. package/dist/components/ui/select.js +1 -0
  77. package/dist/components/ui/separator.js +1 -0
  78. package/dist/components/ui/sheet.js +1 -0
  79. package/dist/components/ui/skeleton.js +1 -0
  80. package/dist/components/ui/slider.js +1 -0
  81. package/dist/components/ui/sonner.js +1 -0
  82. package/dist/components/ui/spinner.js +1 -0
  83. package/dist/components/ui/switch.js +1 -0
  84. package/dist/components/ui/table.js +1 -0
  85. package/dist/components/ui/tabs.js +1 -0
  86. package/dist/components/ui/textarea.js +1 -0
  87. package/dist/components/ui/toggle-group.js +1 -0
  88. package/dist/components/ui/toggle.js +1 -0
  89. package/dist/components/ui/toolbar.js +1 -0
  90. package/dist/components/ui/tooltip.js +1 -0
  91. package/dist/components/ui/typography.js +1 -0
  92. package/dist/components/ui/visually-hidden.js +1 -0
  93. package/dist/hooks/index.d.ts +3 -3
  94. package/dist/hooks/index.js +4 -3
  95. package/dist/hooks/use-data-filters.d.ts +1 -1
  96. package/dist/hooks/use-data-filters.js +3 -2
  97. package/dist/hooks/use-keyboard-navigation.js +1 -0
  98. package/dist/hooks/use-mobile.js +1 -0
  99. package/dist/hooks/use-prefetch.js +1 -0
  100. package/dist/hooks/use-resource-page.js +1 -0
  101. package/dist/hooks/use-resource-url-state.d.ts +1 -1
  102. package/dist/hooks/use-resource-url-state.js +1 -0
  103. package/dist/hooks/use-saved-views.js +1 -0
  104. package/dist/hooks/use-view-preference.js +1 -0
  105. package/dist/hooks/use-view-settings.js +1 -0
  106. package/dist/index.d.ts +3 -2
  107. package/dist/index.js +361 -3
  108. package/dist/index.js.map +1 -1
  109. package/dist/navigation-vmFJ6r1m.d.ts +90 -0
  110. package/dist/router/react-router.d.ts +1 -1
  111. package/dist/router/react-router.js +1 -0
  112. package/dist/router/react-router.js.map +1 -1
  113. package/dist/router/tanstack-router.d.ts +1 -1
  114. package/dist/router/tanstack-router.js +2 -1
  115. package/dist/router/tanstack-router.js.map +1 -1
  116. package/dist/status-colors.js +2 -0
  117. package/dist/status-colors.js.map +1 -1
  118. package/dist/{use-resource-table-Dx1OZRne.d.ts → use-resource-table-easmRDQI.d.ts} +2 -2
  119. package/dist/utils.js +1 -0
  120. package/package.json +6 -5
  121. package/dist/AppShell-BVr4V0UK.d.ts +0 -174
  122. package/dist/chunk-7S7LKQBD.js +0 -12
  123. package/dist/chunk-7S7LKQBD.js.map +0 -1
  124. package/dist/chunk-UYI3GLFJ.js.map +0 -1
  125. package/dist/chunk-WGMEVX3Y.js +0 -141
  126. package/dist/chunk-WGMEVX3Y.js.map +0 -1
  127. package/dist/navigation-Bha0R3Fu.d.ts +0 -166
  128. package/dist/slots-tR0wf89f.d.ts +0 -60
package/SKILL.md CHANGED
@@ -327,6 +327,63 @@ const navigation: NavigationNode<NavItem> = {
327
327
  linkComponent={RouterLink}>{children}</AppShell>
328
328
  ```
329
329
 
330
+ **Collapsible sidebar.** On desktop the sidebar collapses to an icon rail (56px;
331
+ `options.collapsedRailWidth: 64` for the wider one): the logo mark, one icon per item (name in a
332
+ tooltip on hover and focus), nested groups in a popover, and the expand button at the bottom.
333
+ The panel button beside the logo toggles it; `options.collapseShortcut: "["` adds an opt-in key
334
+ (skipped while typing, in a listbox/combobox/menu, or with a dialog open). Pass
335
+ `optionsStorageKey` (app-scoped, e.g. `"acme:app-shell"`) to remember the user's choice under
336
+ `${key}:collapsed`. A page asks to open collapsed with `defaultCollapsed: true` on its
337
+ `NavigationNode` (the nearest node in the trail that sets it wins) or `defaultCollapsed` on
338
+ `AppShell`; the user's own toggle always wins once they have used it, and "Reset to defaults" in
339
+ the sidebar options hands it back. `options.defaultCollapsed` is the app-wide default, and
340
+ `collapsed` +
341
+ `onCollapsedChange` make it controlled. The mobile drawer is unaffected.
342
+
343
+ ```tsx
344
+ { id: "builder", path: "/forms/$formId/edit", label: "Form builder", items: [], defaultCollapsed: true }
345
+ ```
346
+
347
+ **Sub-navigation (a page's children).** A node's `items` are the current page's child items: a
348
+ form's Questions / Logic and endings / Responses / Settings. A node's items are `NavItem`s,
349
+ so each needs an `icon`. The hook (`useAppShellSubNav`) and the exported `SubNavTabs` take
350
+ `SubNavItem`s instead: a `NavItem` whose `icon` is optional. Without one, the sidebar and mobile
351
+ navigation show the label's first letter, and `SubNavTabs` shows the label alone. Each has `label`, `to` (a route, or a `?search` / `#hash`; active state follows the URL,
352
+ most specific sibling wins) and an optional `badge` (a count or short status, shown as a chip). Gate by role the same way as other items: filter the list before handing
353
+ it over.
354
+ For live data (badge counts) the page calls `useAppShellSubNav(items, { mode? })`, which
355
+ replaces the node's items while it is mounted, and puts a host chip at the end of the tab row with
356
+ `<AppShellSubNavEnd>…</AppShellSubNavEnd>`. The page's resource header (breadcrumb, title,
357
+ status, actions) goes in `<AppShellPageHeader>…</AppShellPageHeader>`, which the shell renders
358
+ above the tab row (on phones too; at the top of the content when there is no row). Both are
359
+ portals; when a layout and its page both mount one, the page's (innermost) renders, and the same
360
+ rule picks between `useAppShellSubNav` callers. Shell sub-navigation is opt-in through
361
+ `options.subNav`:
362
+
363
+ - `"section"` (default): exactly the pre-sub-nav shell. The children sit in a labelled section
364
+ below the global sidebar items and replace the phone bar, with no back item.
365
+ - `"tabs"`: one row of navigation links across the top of the content, badges as chips, the
366
+ current tab underlined in the brand colour, `aria-current="page"`.
367
+ - `"sidebar"`: nested under the active global item ("Forms"); a flyout from it on the rail.
368
+ - `"off"`: nothing, desktop or phone; draw your own (`SubNavTabs` is exported for that).
369
+
370
+ With `"tabs"` or `"sidebar"`, a page with children swaps the phone bar to a back item to the
371
+ logical parent ("Forms") plus the children and their badges; leaving the page brings the main
372
+ bar back. A node (`subNav` on `NavigationNode`, nearest in the trail wins), the `subNav` prop and
373
+ the page's hook override the option, in that order of strength (hook strongest), so one subtree
374
+ can opt in. With it on, a page's children also win over an app-wide `mobileNavItems` on that page;
375
+ in `"section"` / `"off"`, or on pages without children, `mobileNavItems` applies as before.
376
+
377
+ ```tsx
378
+ useAppShellSubNav([
379
+ { to: `/forms/${id}/edit`, label: "Questions", icon: ListChecks, badge: questions.length, end: true },
380
+ { to: `/forms/${id}/edit/logic`, label: "Logic and endings", icon: GitBranch, badge: rules.length },
381
+ { to: `/forms/${id}/edit/responses`, label: "Responses", icon: Inbox, badge: responseCount },
382
+ { to: `/forms/${id}/edit/settings`, label: "Settings", icon: Settings },
383
+ ]);
384
+ <AppShellSubNavEnd><Badge variant="success">Ready to publish</Badge></AppShellSubNavEnd>
385
+ ```
386
+
330
387
  For chrome outside AppShell, call the same resolver: `resolveNavigation(tree, pathname)` (from
331
388
  `/layout`, `/data` or the root barrel) returns `{ current, parent, items, trail, params }` with
332
389
  every path interpolated from the URL's params.
@@ -0,0 +1,348 @@
1
+ import * as React from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { LucideIcon } from 'lucide-react';
4
+ import { L as LinkComponent } from './navigation-vmFJ6r1m.js';
5
+ import { NavigationNode } from '@marktiderman/genesis-core/navigation';
6
+
7
+ /**
8
+ * How AppShell shows the current page's child items. Sub-navigation is
9
+ * opt-in: the default, `section`, is the shell as it always was.
10
+ * - `section` (default): a labelled section below the global sidebar
11
+ * items; on phones the children replace the bottom bar (no back item).
12
+ * - `tabs`: one row of tabs across the top of the page content.
13
+ * - `sidebar`: nested under the active item in the sidebar; a flyout from
14
+ * that item on the collapsed rail.
15
+ * - `off`: nothing, on desktop or phones; the app draws its own
16
+ * (`SubNavTabs` is exported for it).
17
+ *
18
+ * With `tabs` or `sidebar`, phones switch the bottom bar to a back item to
19
+ * the logical parent plus the children, with their badges.
20
+ *
21
+ * @stability Beta
22
+ */
23
+ type SubNavMode = "section" | "tabs" | "sidebar" | "off";
24
+ /**
25
+ * A sub-navigation item: a `NavItem` whose `icon` is optional (the tab row,
26
+ * the phone bar and the rail show the label's first letter without one).
27
+ * Every `NavItem` is a `SubNavItem`; `NavItem` itself keeps `icon` required.
28
+ *
29
+ * @stability Beta
30
+ */
31
+ interface SubNavItem extends Omit<NavItem, "icon" | "children"> {
32
+ icon?: LucideIcon;
33
+ children?: SubNavItem[];
34
+ }
35
+ /**
36
+ * Props for {@link SubNavTabs}.
37
+ *
38
+ * @stability Beta
39
+ */
40
+ interface SubNavTabsProps {
41
+ items: SubNavItem[];
42
+ /** Current location (`pathname + search + hash`); drives the active tab. */
43
+ activePath?: string;
44
+ linkComponent: LinkComponent;
45
+ isActive?: (to: string, activePath?: string) => boolean;
46
+ /** Right-aligned slot in the row, e.g. a "Ready to publish" chip. */
47
+ end?: ReactNode;
48
+ /** Accessible name of the `<nav>` (default "Page sections"). */
49
+ label?: string;
50
+ className?: string;
51
+ }
52
+ /**
53
+ * A row of navigation tabs: real links (deep links and middle-click work),
54
+ * `aria-current="page"` on the active one, badges as chips, the active tab
55
+ * underlined in the brand colour. AppShell renders it in `tabs` mode; an app
56
+ * using `subNav: "off"` can place it itself.
57
+ *
58
+ * @stability Beta
59
+ */
60
+ declare function SubNavTabs({ items, activePath, linkComponent: LinkComp, isActive, end, label, className, }: SubNavTabsProps): React.JSX.Element;
61
+ /**
62
+ * Options for {@link useAppShellSubNav}.
63
+ *
64
+ * @stability Beta
65
+ */
66
+ interface UseAppShellSubNavOptions {
67
+ /** This page's `subNav` mode; wins over the shell's and the node's. */
68
+ mode?: SubNavMode;
69
+ }
70
+ /**
71
+ * Give the shell this page's child items (sub-navigation) while the page is
72
+ * mounted. They replace the current `NavigationNode`'s `items`; pass
73
+ * `null` / `undefined` to fall back to them (a `mode` still applies). When
74
+ * several components call it (a layout and its page), the innermost wins,
75
+ * for items and for mode separately. Use it when children depend on
76
+ * page data, such as live badge counts. A fresh array each render is fine:
77
+ * the shell only updates when a `to`, label, badge, icon or flag changes.
78
+ *
79
+ * ```tsx
80
+ * useAppShellSubNav([
81
+ * { to: `/forms/${id}/edit`, label: "Questions", icon: ListChecks, badge: questions.length, end: true },
82
+ * { to: `/forms/${id}/edit/logic`, label: "Logic and endings", icon: GitBranch, badge: rules.length },
83
+ * { to: `/forms/${id}/edit/responses`, label: "Responses", icon: Inbox, badge: responses },
84
+ * { to: `/forms/${id}/edit/settings`, label: "Settings", icon: Settings },
85
+ * ]);
86
+ * ```
87
+ *
88
+ * Does nothing outside an `AppShell`.
89
+ *
90
+ * @stability Beta
91
+ */
92
+ declare function useAppShellSubNav(items: SubNavItem[] | null | undefined, options?: UseAppShellSubNavOptions): void;
93
+ /**
94
+ * Render `children` in the right-hand slot of the shell's sub-navigation
95
+ * tab row, e.g. a "Ready to publish" status chip. Rendered through a
96
+ * portal, so it keeps the page's context and state. Renders nothing when
97
+ * the shell shows no tab row (other modes, phones, no children). When
98
+ * several are mounted (a layout's and a page's), the innermost renders.
99
+ *
100
+ * @stability Beta
101
+ */
102
+ declare function AppShellSubNavEnd({ children }: {
103
+ children: ReactNode;
104
+ }): ReactNode;
105
+ /**
106
+ * Render the page's resource header (breadcrumb, title, status, actions) at
107
+ * the top of the shell's content, ABOVE the sub-navigation tab row, where
108
+ * the design puts it. A portal like `AppShellSubNavEnd`, so it keeps the
109
+ * page's state; the innermost mounted one renders. On phones it stays at
110
+ * the top of the content while the bottom bar carries the children. With
111
+ * no tab row (the default `"section"` mode, or a page without children) it
112
+ * simply sits at the top of the content. Mount none and the layout is
113
+ * unchanged.
114
+ *
115
+ * @stability Beta
116
+ */
117
+ declare function AppShellPageHeader({ children }: {
118
+ children: ReactNode;
119
+ }): ReactNode;
120
+
121
+ interface NavItem {
122
+ /** Route, optionally with `?search` / `#hash` (see `isPathActive`). */
123
+ to: string;
124
+ icon: LucideIcon;
125
+ label: string;
126
+ /** Nested items — rendered as a collapsible group when the rail is expanded */
127
+ children?: NavItem[];
128
+ /**
129
+ * A count (`3`) or a short status (`"New"`), shown as a chip: in the
130
+ * sidebar, the sub-navigation tabs and the mobile bar; as a dot on the
131
+ * collapsed rail. It is part of the item's accessible name where the label
132
+ * is hidden.
133
+ */
134
+ badge?: string | number;
135
+ disabled?: boolean;
136
+ /**
137
+ * Exact-match active state (e.g. overview `/`). Exact on the path only, so
138
+ * an `activePath` carrying `?search#hash` still matches.
139
+ */
140
+ end?: boolean;
141
+ }
142
+ /**
143
+ * The "up" link AppShell renders above page content: a real link to the
144
+ * logical parent, never `history.back()`.
145
+ *
146
+ * @stability Beta
147
+ */
148
+ interface ParentNavigation {
149
+ href: string;
150
+ label: string;
151
+ }
152
+ /**
153
+ * Declarative chrome for AppShell — developer defaults + optional
154
+ * in-sidebar user toggles (Notion/Linear “customize chrome” pattern).
155
+ *
156
+ * @stability Beta
157
+ */
158
+ interface AppShellOptions {
159
+ showLogo?: boolean;
160
+ showAppName?: boolean;
161
+ showThemeToggle?: boolean;
162
+ /** Desktop rail collapse control */
163
+ showCollapse?: boolean;
164
+ showUserSlot?: boolean;
165
+ showFooter?: boolean;
166
+ showSecondaryNav?: boolean;
167
+ /** Mobile fixed bottom tab bar */
168
+ showMobileBottomNav?: boolean;
169
+ /**
170
+ * Open the desktop sidebar collapsed (an icon rail, `collapsedRailWidth` wide) when the user hasn't
171
+ * chosen. The app-wide default; a page asks for its own through
172
+ * `AppShellProps.defaultCollapsed` or `NavigationNode.defaultCollapsed`.
173
+ */
174
+ defaultCollapsed?: boolean;
175
+ /**
176
+ * Opt-in key that toggles the desktop sidebar, e.g. `"["` as in Linear and
177
+ * Notion. Off (`false`) by default. It never fires while typing in a field,
178
+ * while a listbox, combobox or menu has focus (Select typeahead), while a
179
+ * dialog is open, with Ctrl/Cmd/Alt held, or when `showCollapse` is off.
180
+ */
181
+ collapseShortcut?: string | false;
182
+ /**
183
+ * Width of the collapsed icon rail in px: `56` (default, as before) or
184
+ * `64` (the Breakthrough design).
185
+ */
186
+ collapsedRailWidth?: 56 | 64;
187
+ /**
188
+ * Shell sub-navigation, opt-in. `"section"` (default) renders a page's
189
+ * children exactly as AppShell always has; `"tabs"` or `"sidebar"` turn
190
+ * sub-navigation on (see `SubNavMode`), and `"off"` hides them. A
191
+ * navigation node, the `subNav` prop or the page
192
+ * (`useAppShellSubNav(items, { mode })`) can override it.
193
+ */
194
+ subNav?: SubNavMode;
195
+ /**
196
+ * Show the in-sidebar Sidebar options popover so users can customize chrome.
197
+ * Default true when collapse / secondary / theme / slots are available.
198
+ */
199
+ configurable?: boolean;
200
+ /**
201
+ * Toggle keys the developer has decided on and users may not override —
202
+ * e.g. hiding `showThemeToggle` for a brand that manages theme elsewhere.
203
+ * Locked keys are dropped from the options popover and any stored user
204
+ * override for them is ignored on resolve.
205
+ */
206
+ lockedOptions?: (keyof AppShellOptions)[];
207
+ /** Comfortable (default) vs compact row padding */
208
+ density?: "comfortable" | "compact";
209
+ /** Expanded rail width in rem-ish tokens: narrow ≈ 13rem, wide ≈ 16rem */
210
+ railWidth?: "narrow" | "wide";
211
+ /**
212
+ * Where page content scrolls.
213
+ * - `container` (default): main panel scrolls — classic app-shell chrome.
214
+ * - `window`: document/window scrolls with a sticky rail so React Router
215
+ * `ScrollRestoration` keeps working (dashboard dogfood).
216
+ */
217
+ scrollRoot?: "container" | "window";
218
+ }
219
+ /**
220
+ * @stability Beta
221
+ */
222
+ interface AppShellProps {
223
+ /** App name shown in sidebar header */
224
+ appName: string;
225
+ /** App logo letter or short text (ignored when `logo` is set) */
226
+ appLogo?: string;
227
+ /** Custom logo node — preferred over `appLogo` letter tile */
228
+ logo?: ReactNode;
229
+ /**
230
+ * Primary navigation items. Optional when `navigation` is set: the tree
231
+ * root's `items` are the global nav then.
232
+ */
233
+ navItems?: NavItem[];
234
+ /**
235
+ * The app's logical navigation hierarchy. AppShell resolves it against
236
+ * `activePath` (see `resolveNavigation`) and derives:
237
+ * - the sidebar's global items from the root's `items` (unless `navItems`),
238
+ * - a contextual section from the current node's `items`, labelled with
239
+ * the node's `label` (`$param` segments in `to` filled from the URL),
240
+ * - the mobile tab bar: the contextual items when there are any, else the
241
+ * global top-level items (unless `mobileNavItems`),
242
+ * - a back link to the current node's logical parent (unless
243
+ * `parentNavigation`).
244
+ *
245
+ * @stability Beta
246
+ */
247
+ navigation?: NavigationNode<NavItem>;
248
+ /**
249
+ * Back-to-parent link rendered in the content header, above `children`, on
250
+ * mobile and desktop. Derived from `navigation` when omitted; `null` hides
251
+ * it. Use this instead of placing a back row inside page content.
252
+ *
253
+ * @stability Beta
254
+ */
255
+ parentNavigation?: ParentNavigation | null;
256
+ /** Secondary nav (e.g. “More”) — rendered below a divider when shown */
257
+ secondaryNavItems?: NavItem[];
258
+ /** Label above secondary nav (default “More”) */
259
+ secondaryNavLabel?: string;
260
+ /**
261
+ * Items for the mobile bottom tab bar. Defaults to top-level `navItems`
262
+ * (no children). Pass a short list for apps with large sidebars; pass `[]`
263
+ * and set `options.showMobileBottomNav: false` to hide.
264
+ */
265
+ mobileNavItems?: NavItem[];
266
+ /** Slot below the logo row (product switcher, workspace picker, …) */
267
+ headerSlot?: ReactNode;
268
+ /**
269
+ * Compact slot shown in the **collapsed** desktop rail, where `headerSlot`
270
+ * is hidden for space. Use it to keep a core affordance reachable without
271
+ * expanding — e.g. an icon-only product switcher. Omit to hide the header
272
+ * region entirely while collapsed.
273
+ */
274
+ collapsedHeaderSlot?: ReactNode;
275
+ /** Footer region above the user slot (version, links) */
276
+ footer?: ReactNode;
277
+ /**
278
+ * User / account block at the bottom of the sidebar. When the rail is
279
+ * collapsed, AppShell hides any descendant carrying the
280
+ * `data-shell-user-detail` attribute (e.g. name/email text) so only a
281
+ * compact element (avatar, initial) remains — tag the detail wrapper you
282
+ * want hidden in the collapsed rail with that attribute.
283
+ */
284
+ userSlot?: ReactNode;
285
+ /** Page content */
286
+ children: ReactNode;
287
+ /**
288
+ * @deprecated Prefer `options.showThemeToggle`. Kept for sample-app
289
+ * back-compat; merges into resolved options when `options` omits it.
290
+ */
291
+ showThemeToggle?: boolean;
292
+ /** Chrome config (developer defaults + optional in-sidebar menu) */
293
+ options?: AppShellOptions;
294
+ /** Persist user sidebar-option overrides + collapse state (localStorage) */
295
+ optionsStorageKey?: string;
296
+ /**
297
+ * Controlled collapse (desktop rail). Overrides the stored user choice and
298
+ * every default.
299
+ */
300
+ collapsed?: boolean;
301
+ /** Called with the new state whenever the user toggles the sidebar. */
302
+ onCollapsedChange?: (collapsed: boolean) => void;
303
+ /**
304
+ * This page's default: open the desktop sidebar collapsed (`true`) or
305
+ * expanded (`false`) until the user toggles it. Reactive, so a layout can
306
+ * pass it per route. Wins over `navigation`'s `defaultCollapsed` and
307
+ * `options.defaultCollapsed`; the user's own choice (persisted under
308
+ * `optionsStorageKey`) wins over all of them.
309
+ *
310
+ * @stability Beta
311
+ */
312
+ defaultCollapsed?: boolean;
313
+ /**
314
+ * This page's sub-navigation mode (see `AppShellOptions.subNav`). Wins
315
+ * over `navigation`'s `subNav` and `options.subNav`; the page's own
316
+ * `useAppShellSubNav(items, { mode })` wins over it.
317
+ *
318
+ * @stability Beta
319
+ */
320
+ subNav?: SubNavMode;
321
+ /**
322
+ * Accessible name of the sub-navigation tab row. Defaults to the current
323
+ * navigation node's label, else "Page sections".
324
+ */
325
+ subNavLabel?: string;
326
+ /**
327
+ * Injectable link component. Defaults to a plain `<a>` (no router). Pass a
328
+ * router adapter — e.g. React Router `({ href, ...p }) => <Link to={href} {...p} />`
329
+ * or Next.js `next/link` — to get client-side navigation.
330
+ */
331
+ linkComponent?: LinkComponent;
332
+ /**
333
+ * Current location used to highlight the active nav item. Pass the full
334
+ * location, `pathname + search + hash` (React Router: `useLocation()`), so
335
+ * items whose `to` names a query or hash (`/admin?tab=users`) can become
336
+ * active. A pathname alone still works for path-only items, `end` included.
337
+ * Omit to disable active highlighting.
338
+ */
339
+ activePath?: string;
340
+ /**
341
+ * Optional custom active-state matcher. Defaults to a prefix match (with `/`
342
+ * treated as exact), mirroring React Router `NavLink`.
343
+ */
344
+ isActive?: (to: string, activePath?: string) => boolean;
345
+ }
346
+ declare function AppShell({ appName, appLogo, logo, navItems: navItemsProp, navigation, parentNavigation: parentNavigationProp, secondaryNavItems, secondaryNavLabel, mobileNavItems, headerSlot, collapsedHeaderSlot, footer, userSlot, children, showThemeToggle: showThemeToggleProp, options: optionsProp, optionsStorageKey, collapsed: collapsedProp, onCollapsedChange, defaultCollapsed: defaultCollapsedProp, subNav: subNavProp, subNavLabel, linkComponent, activePath, isActive, }: AppShellProps): React.JSX.Element;
347
+
348
+ export { AppShell as A, type NavItem as N, type ParentNavigation as P, type SubNavItem as S, type UseAppShellSubNavOptions as U, type AppShellOptions as a, AppShellPageHeader as b, type AppShellProps as c, AppShellSubNavEnd as d, type SubNavMode as e, SubNavTabs as f, type SubNavTabsProps as g, useAppShellSubNav as u };
@@ -0,0 +1,21 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
18
+
19
+ export { __export, __reExport };
20
+ //# sourceMappingURL=chunk-424PT5DM.js.map
21
+ //# sourceMappingURL=chunk-424PT5DM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-424PT5DM.js"}