basalt-ui 1.18.0 → 1.19.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 (92) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +14 -0
  3. package/agent/rules/basalt-mantine.md +71 -6
  4. package/agent/rules/basalt-router.md +129 -30
  5. package/agent/rules/basalt-tokens.md +2 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +8 -0
  9. package/dist/nav/types.d.ts +110 -0
  10. package/dist/nav/types.d.ts.map +1 -0
  11. package/dist/nav/types.js +0 -0
  12. package/dist/router-tanstack/index.d.ts +9 -2
  13. package/dist/router-tanstack/index.d.ts.map +1 -1
  14. package/dist/router-tanstack/index.js +7 -0
  15. package/dist/router-tanstack/nav.d.ts +163 -0
  16. package/dist/router-tanstack/nav.d.ts.map +1 -0
  17. package/dist/router-tanstack/nav.js +38 -0
  18. package/dist/router-tanstack/nav.test.d.ts +2 -0
  19. package/dist/router-tanstack/nav.test.d.ts.map +1 -0
  20. package/dist/router-tanstack/search-param-store.d.ts +19 -9
  21. package/dist/router-tanstack/search-param-store.d.ts.map +1 -1
  22. package/dist/router-tanstack/use-nav.d.ts +30 -0
  23. package/dist/router-tanstack/use-nav.d.ts.map +1 -0
  24. package/dist/router-tanstack/use-nav.js +71 -0
  25. package/dist/shell/app-breadcrumbs.d.ts +7 -9
  26. package/dist/shell/app-breadcrumbs.d.ts.map +1 -1
  27. package/dist/shell/app-breadcrumbs.js +8 -4
  28. package/dist/shell/app-mobile-nav.d.ts +23 -24
  29. package/dist/shell/app-mobile-nav.d.ts.map +1 -1
  30. package/dist/shell/app-mobile-nav.js +291 -69
  31. package/dist/shell/app-mobile-nav.module.css +191 -11
  32. package/dist/shell/app-mobile-nav.module.css.d.ts +11 -2
  33. package/dist/shell/app-mobile-nav.test.d.ts +2 -0
  34. package/dist/shell/app-mobile-nav.test.d.ts.map +1 -0
  35. package/dist/shell/app-sidebar.d.ts +3 -28
  36. package/dist/shell/app-sidebar.d.ts.map +1 -1
  37. package/dist/shell/app-sidebar.js +40 -174
  38. package/dist/shell/app-sidebar.module.css +3 -2
  39. package/dist/shell/app-sidebar.module.css.d.ts +0 -2
  40. package/dist/shell/index.d.ts +22 -65
  41. package/dist/shell/index.d.ts.map +1 -1
  42. package/dist/shell/index.js +38 -76
  43. package/dist/shell/mobile-nav-model.d.ts +41 -0
  44. package/dist/shell/mobile-nav-model.d.ts.map +1 -0
  45. package/dist/shell/mobile-nav-model.js +244 -0
  46. package/dist/shell/mobile-nav-model.test.d.ts +2 -0
  47. package/dist/shell/mobile-nav-model.test.d.ts.map +1 -0
  48. package/dist/shell/nav-count-badge.d.ts +11 -0
  49. package/dist/shell/nav-count-badge.d.ts.map +1 -0
  50. package/dist/shell/nav-count-badge.js +29 -0
  51. package/dist/surfaces.d.ts +1 -1
  52. package/dist/surfaces.js +1 -1
  53. package/dist/theme/index.d.ts.map +1 -1
  54. package/dist/theme/index.js +8 -7
  55. package/dist/theme/nav-link.module.css +4 -2
  56. package/dist/tokens/index.d.ts.map +1 -1
  57. package/dist/tokens/index.js +2 -0
  58. package/dist/tokens/palette.d.ts +15 -0
  59. package/dist/tokens/palette.d.ts.map +1 -1
  60. package/dist/tokens/palette.js +13 -0
  61. package/dist/tokens.css +2 -0
  62. package/llms.txt +3 -3
  63. package/package.json +1 -1
  64. package/src/index.ts +15 -5
  65. package/src/nav/types.ts +115 -0
  66. package/src/router-tanstack/index.ts +21 -2
  67. package/src/router-tanstack/nav.test.ts +111 -0
  68. package/src/router-tanstack/nav.ts +205 -0
  69. package/src/router-tanstack/search-param-store.ts +19 -9
  70. package/src/router-tanstack/use-nav.ts +146 -0
  71. package/src/shell/app-breadcrumbs.tsx +21 -19
  72. package/src/shell/app-mobile-nav.module.css +191 -11
  73. package/src/shell/app-mobile-nav.module.css.d.ts +11 -2
  74. package/src/shell/app-mobile-nav.test.tsx +403 -0
  75. package/src/shell/app-mobile-nav.tsx +449 -104
  76. package/src/shell/app-sidebar.module.css +3 -2
  77. package/src/shell/app-sidebar.module.css.d.ts +0 -2
  78. package/src/shell/app-sidebar.test.tsx +6 -10
  79. package/src/shell/app-sidebar.tsx +49 -206
  80. package/src/shell/index.test.tsx +62 -7
  81. package/src/shell/index.tsx +105 -164
  82. package/src/shell/mobile-nav-model.test.ts +296 -0
  83. package/src/shell/mobile-nav-model.ts +389 -0
  84. package/src/shell/nav-count-badge.tsx +39 -0
  85. package/src/surfaces.ts +1 -1
  86. package/src/theme/density-relations.test.ts +19 -1
  87. package/src/theme/index.ts +8 -7
  88. package/src/theme/nav-link.module.css +4 -2
  89. package/src/theme/spacing.test.ts +11 -0
  90. package/src/tokens/density.test.ts +2 -0
  91. package/src/tokens/index.ts +8 -5
  92. package/src/tokens/palette.ts +16 -0
@@ -1,36 +1,13 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { BrandConfig, SettingsMenuItem, SidebarItem, SidebarSection } from './index.js';
2
+ import type { BrandConfig, SettingsMenuItem } from './index.js';
3
+ import type { SidebarSection } from '../nav/types.js';
3
4
  import type { BasaltAccountProps } from './account-types.js';
4
5
  import type { SidebarSearchConfig } from './sidebar-search.js';
5
- /**
6
- * Renders a single nav item. The consumer's router `Link` lives here; `active` is precomputed.
7
- *
8
- * `opts.close` (item 20) is the mobile "More" drawer's close handle — invoke-safe when absent, a
9
- * no-op on desktop. Call it from the rendered link's own `onClick` (e.g. before/after navigating)
10
- * so tapping a nav row in the mobile drawer also closes it; the built-in fallback `<a>` path does
11
- * this automatically.
12
- *
13
- * `opts.navLinkClassName` (item 18) is the internal `.link` CSS-module class the fallback `<a>`
14
- * path uses for inactive/hover treatment — present whenever `AppSidebar` renders this callback.
15
- * Apply it to the rendered link's `className` to match that styling exactly instead of
16
- * re-deriving it.
17
- */
18
- export type NavLinkRenderer = (item: SidebarItem, opts: {
19
- active: boolean;
20
- close?: (() => void) | undefined;
21
- navLinkClassName?: string | undefined;
22
- }) => ReactNode;
23
6
  export type AppSidebarProps = {
24
7
  brand: BrandConfig;
25
8
  sections: SidebarSection[];
26
9
  collapsed: boolean;
27
10
  onToggleCollapse: () => void;
28
- onClose: () => void;
29
- /**
30
- * Optional consumer link renderer (e.g. a router `<Link>`). Receives the precomputed `active`
31
- * flag. When omitted, items fall back to a plain `<a href>` + `item.onClick`.
32
- */
33
- renderNavLink?: NavLinkRenderer;
34
11
  /**
35
12
  * Footer settings-menu entries (theme switcher, devtools, …) — supplied by the consumer.
36
13
  * The pinned footer "Settings" row renders ONLY when this is a non-empty list — apps that put
@@ -38,8 +15,6 @@ export type AppSidebarProps = {
38
15
  * `brand.version` label renders inside this menu, so it also only shows when the row does.
39
16
  */
40
17
  settingsMenuItems?: SettingsMenuItem[];
41
- /** Extra content appended to the sidebar footer, beside the settings menu (mobile close, etc.). */
42
- footerExtra?: ReactNode;
43
18
  /**
44
19
  * Optional account row rendered below the settings menu in the sidebar footer (see
45
20
  * `SidebarAccount` / `BasaltAccountProps`), separated by its own top hairline. Omitting it
@@ -70,5 +45,5 @@ export type AppSidebarProps = {
70
45
  */
71
46
  navExtra?: ReactNode;
72
47
  };
73
- export declare function AppSidebar({ brand, sections, collapsed, onToggleCollapse, onClose, renderNavLink, settingsMenuItems, footerExtra, account, search, navExtra, }: AppSidebarProps): import("react").JSX.Element;
48
+ export declare function AppSidebar({ brand, sections, collapsed, onToggleCollapse, settingsMenuItems, account, search, navExtra, }: AppSidebarProps): import("react").JSX.Element;
74
49
  //# sourceMappingURL=app-sidebar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../src/shell/app-sidebar.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,OAAO,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAK3D;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,GAAG,CAC5B,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE;IACJ,MAAM,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAA;IAChC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACtC,KACE,SAAS,CAAA;AAEd,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,WAAW,CAAA;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,SAAS,EAAE,OAAO,CAAA;IAClB,gBAAgB,EAAE,MAAM,IAAI,CAAA;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,eAAe,CAAA;IAC/B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACtC,mGAAmG;IACnG,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB;;;;OAIG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B;;;OAGG;IACH,MAAM,CAAC,EAAE,mBAAmB,CAAA;IAC5B;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,CAAA;AAkWD,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,OAAO,EACP,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,OAAO,EACP,MAAM,EACN,QAAQ,GACT,EAAE,eAAe,+BAyLjB"}
1
+ {"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../src/shell/app-sidebar.tsx"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC5D,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,cAAc,CAAA;AAG/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAK3D,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,WAAW,CAAA;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,SAAS,EAAE,OAAO,CAAA;IAClB,gBAAgB,EAAE,MAAM,IAAI,CAAA;IAC5B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACtC;;;;OAIG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B;;;OAGG;IACH,MAAM,CAAC,EAAE,mBAAmB,CAAA;IAC5B;;;;;;;;;;;;;;;;OAgBG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,CAAA;AAqQD,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,OAAO,EACP,MAAM,EACN,QAAQ,GACT,EAAE,eAAe,+BAuJjB"}
@@ -14,7 +14,8 @@ import {
14
14
  UnstyledButton
15
15
  } from "@mantine/core";
16
16
  import { useDisclosure } from "@mantine/hooks";
17
- import { useRef, useState } from "react";
17
+ import { useEffect, useRef, useState } from "react";
18
+ import { NavCountBadge } from "./nav-count-badge.js";
18
19
  import { SidebarAccount } from "./app-sidebar-account.js";
19
20
  import { SidebarSearch } from "./sidebar-search.js";
20
21
  import { VX } from "../tokens/index.js";
@@ -78,69 +79,34 @@ function IconGear() {
78
79
  }
79
80
  );
80
81
  }
81
- function IconClose() {
82
- return /* @__PURE__ */ jsxs(
83
- "svg",
84
- {
85
- width: 18,
86
- height: 18,
87
- viewBox: "0 0 24 24",
88
- fill: "none",
89
- stroke: "currentColor",
90
- strokeWidth: 2,
91
- strokeLinecap: "round",
92
- strokeLinejoin: "round",
93
- "aria-hidden": true,
94
- children: [
95
- /* @__PURE__ */ jsx("path", { d: "M18 6l-12 12" }),
96
- /* @__PURE__ */ jsx("path", { d: "M6 6l12 12" })
97
- ]
98
- }
99
- );
100
- }
101
82
  const HOVER_OPEN_DELAY = 150;
102
83
  const HOVER_CLOSE_DELAY = 200;
103
84
  function hasActiveDescendant(item) {
104
85
  if (item.active) return true;
105
86
  return item.children?.some((c) => hasActiveDescendant(c)) ?? false;
106
87
  }
107
- function NavLinkBody({
108
- item,
109
- active,
110
- renderNavLink,
111
- close
112
- }) {
113
- if (renderNavLink) {
114
- return /* @__PURE__ */ jsx(Fragment, { children: renderNavLink(item, { active, close, navLinkClassName: classes.link }) });
88
+ function NavLinkBody({ item, active }) {
89
+ const Anchor = item.Anchor;
90
+ const shared = {
91
+ classNames: { root: classes.link },
92
+ label: item.label,
93
+ leftSection: item.icon,
94
+ rightSection: item.badge ?? (item.count ? /* @__PURE__ */ jsx(NavCountBadge, { count: item.count }) : void 0),
95
+ active,
96
+ ...item.onClick !== void 0 && { onClick: item.onClick }
97
+ };
98
+ if (Anchor) {
99
+ return /* @__PURE__ */ jsx(NavLink, { component: Anchor, ...shared });
115
100
  }
116
- return /* @__PURE__ */ jsx(
117
- NavLink,
118
- {
119
- classNames: { root: classes.link },
120
- component: "a",
121
- label: item.label,
122
- leftSection: item.icon,
123
- rightSection: item.badge,
124
- active,
125
- ...item.href !== void 0 && { href: item.href },
126
- onClick: (e) => {
127
- item.onClick?.(e);
128
- close?.();
129
- }
130
- }
131
- );
101
+ return /* @__PURE__ */ jsx(NavLink, { component: "a", ...item.href !== void 0 && { href: item.href }, ...shared });
132
102
  }
133
103
  function SectionLabel({ children, flush }) {
134
104
  return /* @__PURE__ */ jsx(Text, { component: "div", px: flush ? 0 : "xs", mb: flush ? 0 : 4, className: classes.sectionLabel, children });
135
105
  }
136
- function NavItemRow({
137
- item,
138
- collapsed,
139
- renderNavLink,
140
- closeMobile
141
- }) {
106
+ function NavItemRow({ item, collapsed }) {
142
107
  const [opened, { open, close }] = useDisclosure(false);
143
108
  const timer = useRef(void 0);
109
+ useEffect(() => () => clearTimeout(timer.current), []);
144
110
  const scheduleOpen = () => {
145
111
  clearTimeout(timer.current);
146
112
  timer.current = setTimeout(() => open(), HOVER_OPEN_DELAY);
@@ -164,28 +130,12 @@ function NavItemRow({
164
130
  ) }) }, item.key);
165
131
  }
166
132
  const active2 = Boolean(item.active);
167
- return /* @__PURE__ */ jsx(Tooltip, { label: item.label, position: "right", withArrow: true, disabled: !collapsed, children: /* @__PURE__ */ jsx(Box, { className: classes.navItem, children: /* @__PURE__ */ jsx(
168
- NavLinkBody,
169
- {
170
- item,
171
- active: active2,
172
- renderNavLink,
173
- close: closeMobile
174
- }
175
- ) }) }, item.key);
133
+ return /* @__PURE__ */ jsx(Tooltip, { label: item.label, position: "right", withArrow: true, disabled: !collapsed, children: /* @__PURE__ */ jsx(Box, { className: classes.navItem, children: /* @__PURE__ */ jsx(NavLinkBody, { item, active: active2 }) }) }, item.key);
176
134
  }
177
135
  const active = Boolean(item.active);
178
136
  if (isExpanded) {
179
137
  return /* @__PURE__ */ jsxs(Box, { children: [
180
- /* @__PURE__ */ jsx(Tooltip, { label: item.label, position: "right", withArrow: true, disabled: !collapsed, children: /* @__PURE__ */ jsx(Box, { className: classes.navItem, children: /* @__PURE__ */ jsx(
181
- NavLinkBody,
182
- {
183
- item,
184
- active,
185
- renderNavLink,
186
- close: closeMobile
187
- }
188
- ) }) }),
138
+ /* @__PURE__ */ jsx(Tooltip, { label: item.label, position: "right", withArrow: true, disabled: !collapsed, children: /* @__PURE__ */ jsx(Box, { className: classes.navItem, children: /* @__PURE__ */ jsx(NavLinkBody, { item, active }) }) }),
189
139
  /* @__PURE__ */ jsx(Stack, { gap: 0, className: classes.childList, children: item.children.map((child) => {
190
140
  if (child.disabled) {
191
141
  return /* @__PURE__ */ jsx(Tooltip, { label: "Coming soon", position: "right", withArrow: true, children: /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
@@ -199,15 +149,7 @@ function NavItemRow({
199
149
  ) }) }, child.key);
200
150
  }
201
151
  const childActive = Boolean(child.active);
202
- return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
203
- NavLinkBody,
204
- {
205
- item: child,
206
- active: childActive,
207
- renderNavLink,
208
- close: closeMobile
209
- }
210
- ) }, child.key);
152
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(NavLinkBody, { item: child, active: childActive }) }, child.key);
211
153
  }) })
212
154
  ] }, item.key);
213
155
  }
@@ -231,15 +173,7 @@ function NavItemRow({
231
173
  onMouseLeave: scheduleClose,
232
174
  onFocus: scheduleOpen,
233
175
  onBlur: scheduleClose,
234
- children: /* @__PURE__ */ jsx(
235
- NavLinkBody,
236
- {
237
- item,
238
- active,
239
- renderNavLink,
240
- close: closeMobile
241
- }
242
- )
176
+ children: /* @__PURE__ */ jsx(NavLinkBody, { item, active })
243
177
  }
244
178
  ) }) }),
245
179
  /* @__PURE__ */ jsx(
@@ -264,41 +198,10 @@ function NavItemRow({
264
198
  ) }) }, child.key);
265
199
  }
266
200
  const childActive = Boolean(child.active);
267
- return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
268
- NavLinkBody,
269
- {
270
- item: child,
271
- active: childActive,
272
- renderNavLink,
273
- close: closeMobile
274
- }
275
- ) }, child.key);
201
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(NavLinkBody, { item: child, active: childActive }) }, child.key);
276
202
  }) })
277
203
  }
278
- ),
279
- isExpanded && /* @__PURE__ */ jsx(Stack, { gap: 0, className: classes.childList, children: item.children.map((child) => {
280
- if (child.disabled) {
281
- return /* @__PURE__ */ jsx(Tooltip, { label: "Coming soon", position: "right", withArrow: true, children: /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
282
- NavLink,
283
- {
284
- classNames: { root: classes.link },
285
- label: child.label,
286
- leftSection: child.icon,
287
- "data-disabled": true
288
- }
289
- ) }) }, child.key);
290
- }
291
- const childActive = Boolean(child.active);
292
- return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
293
- NavLinkBody,
294
- {
295
- item: child,
296
- active: childActive,
297
- renderNavLink,
298
- close: closeMobile
299
- }
300
- ) }, child.key);
301
- }) })
204
+ )
302
205
  ]
303
206
  },
304
207
  item.key
@@ -309,10 +212,7 @@ function AppSidebar({
309
212
  sections,
310
213
  collapsed,
311
214
  onToggleCollapse,
312
- onClose,
313
- renderNavLink,
314
215
  settingsMenuItems,
315
- footerExtra,
316
216
  account,
317
217
  search,
318
218
  navExtra
@@ -321,59 +221,25 @@ function AppSidebar({
321
221
  const [collapsedSections, setCollapsedSections] = useState(
322
222
  () => Object.fromEntries(sections.map((s) => [s.label, Boolean(s.defaultCollapsed)]))
323
223
  );
324
- const renderSectionItems = (section) => section.items.map((item) => /* @__PURE__ */ jsx(
325
- NavItemRow,
326
- {
327
- item,
328
- collapsed,
329
- renderNavLink,
330
- closeMobile: onClose
331
- },
332
- item.key
333
- ));
334
- const mobileControls = /* @__PURE__ */ jsxs(Group, { gap: 2, wrap: "nowrap", hiddenFrom: "sm", children: [
335
- footerExtra,
336
- /* @__PURE__ */ jsx(
337
- ActionIcon,
338
- {
339
- variant: "subtle",
340
- className: classes.ghostIcon,
341
- onClick: onClose,
342
- "aria-label": "Close navigation",
343
- children: /* @__PURE__ */ jsx(IconClose, {})
344
- }
345
- )
346
- ] });
224
+ const renderSectionItems = (section) => section.items.map((item) => /* @__PURE__ */ jsx(NavItemRow, { item, collapsed }, item.key));
347
225
  const hasSettingsMenu = (settingsMenuItems?.length ?? 0) > 0;
348
- const settingsRow = hasSettingsMenu ? /* @__PURE__ */ jsxs(Group, { ...account ? {} : { className: classes.footer }, gap: "xs", wrap: "nowrap", children: [
349
- /* @__PURE__ */ jsxs(Menu, { position: "right-start", withArrow: true, width: step.sidebarSettingsMenuWidth, zIndex: 500, children: [
350
- /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsxs(UnstyledButton, { className: classes.footerBtn, "aria-label": "Settings", children: [
351
- /* @__PURE__ */ jsx(IconGear, {}),
352
- /* @__PURE__ */ jsx(Text, { className: classes.footerText, fz: VX.text.md, children: "Settings" })
353
- ] }) }),
354
- /* @__PURE__ */ jsxs(Menu.Dropdown, { children: [
355
- settingsMenuItems?.map((entry) => /* @__PURE__ */ jsx(Menu.Item, { leftSection: entry.icon, onClick: entry.onClick, children: entry.label }, entry.key)),
356
- brand.version && /* @__PURE__ */ jsxs(Fragment, { children: [
357
- /* @__PURE__ */ jsx(Menu.Divider, {}),
358
- /* @__PURE__ */ jsxs(Menu.Label, { children: [
359
- brand.name,
360
- " v",
361
- brand.version
362
- ] })
226
+ const settingsRow = hasSettingsMenu ? /* @__PURE__ */ jsx(Group, { ...account ? {} : { className: classes.footer }, gap: "xs", wrap: "nowrap", children: /* @__PURE__ */ jsxs(Menu, { position: "right-start", withArrow: true, width: step.sidebarSettingsMenuWidth, zIndex: 500, children: [
227
+ /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsxs(UnstyledButton, { className: classes.footerBtn, "aria-label": "Settings", children: [
228
+ /* @__PURE__ */ jsx(IconGear, {}),
229
+ /* @__PURE__ */ jsx(Text, { className: classes.footerText, fz: VX.text.md, children: "Settings" })
230
+ ] }) }),
231
+ /* @__PURE__ */ jsxs(Menu.Dropdown, { children: [
232
+ settingsMenuItems?.map((entry) => /* @__PURE__ */ jsx(Menu.Item, { leftSection: entry.icon, onClick: entry.onClick, children: entry.label }, entry.key)),
233
+ brand.version && /* @__PURE__ */ jsxs(Fragment, { children: [
234
+ /* @__PURE__ */ jsx(Menu.Divider, {}),
235
+ /* @__PURE__ */ jsxs(Menu.Label, { children: [
236
+ brand.name,
237
+ " v",
238
+ brand.version
363
239
  ] })
364
240
  ] })
365
- ] }),
366
- mobileControls
367
- ] }) : /* @__PURE__ */ jsx(
368
- Group,
369
- {
370
- ...account ? {} : { className: classes.footer },
371
- gap: "xs",
372
- wrap: "nowrap",
373
- hiddenFrom: "sm",
374
- children: mobileControls
375
- }
376
- );
241
+ ] })
242
+ ] }) }) : null;
377
243
  return /* @__PURE__ */ jsxs(Stack, { gap: 0, h: "100%", className: classes.root, "data-collapsed": collapsed || void 0, children: [
378
244
  /* @__PURE__ */ jsxs(Group, { className: classes.brand, gap: "sm", wrap: "nowrap", children: [
379
245
  /* @__PURE__ */ jsxs(Group, { className: classes.brandLead, gap: "sm", wrap: "nowrap", children: [
@@ -395,7 +261,7 @@ function AppSidebar({
395
261
  variant: "subtle",
396
262
  size: 28,
397
263
  visibleFrom: "sm",
398
- className: `${classes.collapseBtn} ${classes.ghostIcon}`,
264
+ className: classes.ghostIcon,
399
265
  onClick: onToggleCollapse,
400
266
  "aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
401
267
  children: /* @__PURE__ */ jsx(IconCollapse, { collapsed })
@@ -8,7 +8,8 @@
8
8
  *
9
9
  * The active tint and icon-accent color live in the Mantine theme
10
10
  * (`NavLink.extend` + `theme/nav-link.module.css`) so they apply to EVERY render path, including a
11
- * consumer's router `<Link>` via `renderNavLink` (which never sees this CSS module). This module
11
+ * consumer's router `<Link>` hosted through `SidebarItem.Anchor` (which never sees this CSS
12
+ * module). This module
12
13
  * owns the shell-local layout (docs/DESIGN-SPEC.md §5) and the INACTIVE state (muted text, faint
13
14
  * icon, ink-6% hover) — the active state is left to the theme.
14
15
  *
@@ -382,7 +383,7 @@
382
383
  }
383
384
 
384
385
  /* Collapse every nav row to its icon. Targets `.navItem` — the wrapper Box present on EVERY render
385
- * path — so it covers the shell's fallback NavLink AND a consumer's `renderNavLink` (e.g. a router
386
+ * path — so it covers the shell's fallback NavLink AND a consumer's `SidebarItem.Anchor` (e.g. a router
386
387
  * <Link>), both of which render a Mantine NavLink inside. Keying off `.link` alone missed consumer
387
388
  * links, so their labels overflowed the 64px rail. */
388
389
  .root[data-collapsed] .navItem :global(.mantine-NavLink-root) {
@@ -2,7 +2,6 @@
2
2
  * Typed CSS-module declaration (the S4 CSS-modules path). Named string props — not an index
3
3
  * signature — so dot access (`classes.link`) stays verbatim under the package's strict flags
4
4
  * (`noUncheckedIndexedAccess`, `noPropertyAccessFromIndexSignature`, `exactOptionalPropertyTypes`).
5
- * `collapseBtn` is referenced by the component for parity with argo though it has no CSS rule.
6
5
  */
7
6
  declare const classes: {
8
7
  readonly root: string
@@ -15,7 +14,6 @@ declare const classes: {
15
14
  readonly navScroll: string
16
15
  readonly navViewport: string
17
16
  readonly nav: string
18
- readonly collapseBtn: string
19
17
  readonly footer: string
20
18
  readonly footerBtn: string
21
19
  readonly footerText: string
@@ -1,45 +1,22 @@
1
1
  import type { MouseEvent, ReactNode } from 'react';
2
- import type { NavLinkRenderer } from './app-sidebar.js';
3
- import type { BreadcrumbLinkRenderer } from './app-breadcrumbs.js';
4
2
  import type { BasaltAccountProps } from './account-types.js';
5
3
  import type { SidebarSearchConfig } from './sidebar-search.js';
6
- export { AppSidebar, type AppSidebarProps, type NavLinkRenderer } from './app-sidebar.js';
4
+ import type { MobileNavConfig, SidebarSection } from '../nav/types.js';
5
+ export { AppSidebar, type AppSidebarProps } from './app-sidebar.js';
6
+ export { NavCountBadge } from './nav-count-badge.js';
7
7
  export { SidebarSearch, type SidebarSearchConfig } from './sidebar-search.js';
8
8
  export { SidebarAccount } from './app-sidebar-account.js';
9
9
  export type { AccountBadgeTone, BasaltIdentity, BasaltRole, BasaltPlan, AccountMenuItem, BasaltAccountState, BasaltAccountActions, BasaltAccountProps, } from './account-types.js';
10
- export { MobileNav, type MobileNavItem, type MobileNavSection, type MobileNavLinkRenderer, } from './app-mobile-nav.js';
11
- export { AppBreadcrumbs, type BreadcrumbLinkRenderer } from './app-breadcrumbs.js';
10
+ export { MobileNav, type MobileNavProps } from './app-mobile-nav.js';
11
+ export { projectMobileNav, type ProjectMobileNavOptions, MOBILE_MAX_TABS_DEFAULT, MOBILE_MENU_MAX_DEFAULT, MOBILE_MORE_KEY, } from './mobile-nav-model.js';
12
+ export { AppBreadcrumbs } from './app-breadcrumbs.js';
12
13
  export { PageHeaderProvider, PageActions, PageActionsOutlet } from './page-header.js';
13
- /** A single sidebar destination. Grounded verbatim in argo's `SidebarItem`. */
14
- export type SidebarItem = {
15
- key: string;
16
- label: string;
17
- /** Short label for the mobile bottom-nav; falls back to `label`. */
18
- short?: string;
19
- /** Whether this destination appears in the mobile bottom-nav. */
20
- mobile?: boolean;
21
- icon: ReactNode;
22
- href?: string;
23
- active?: boolean;
24
- disabled?: boolean;
25
- onClick?: (e: MouseEvent) => void;
26
- badge?: ReactNode;
27
- /** Nested sub-navigation items — surfaced in a hover popover and inline when active. */
28
- children?: SidebarItem[];
29
- };
30
- /** A labelled group of sidebar items. Grounded verbatim in argo's `SidebarSection`. */
31
- export type SidebarSection = {
32
- label: string;
33
- items: SidebarItem[];
34
- /** Group icon, used by the mobile tabs. */
35
- icon?: ReactNode;
36
- /** Desktop: render a clickable group header that collapses its items. */
37
- collapsible?: boolean;
38
- /** Initial collapsed state when `collapsible`. */
39
- defaultCollapsed?: boolean;
40
- /** `false` excludes the section from the primary mobile group tabs. */
41
- mobileTab?: boolean;
42
- };
14
+ /**
15
+ * The shared nav vocabulary lives in `src/nav/types.ts` so the headless router bridge can `import
16
+ * type` it without reaching into the Mantine layer. Re-exported here so `SidebarItem` /
17
+ * `SidebarSection` keep resolving straight from `basalt-ui`, exactly as before.
18
+ */
19
+ export type { NavAnchor, NavAnchorProps, NavMobilePlacement, NavSectionMobile, SidebarItem, SidebarSection, MobileNavConfig, MobileNavGroup, MobileNavModel, MobileNavSlot, MobileNavSurface, } from '../nav/types.js';
43
20
  /** Brand identity shown in the sidebar header (logo + name). */
44
21
  export type BrandConfig = {
45
22
  /** Display name (e.g. "Argo"). */
@@ -61,25 +38,21 @@ export type SettingsMenuItem = {
61
38
  export type BasaltShellProps = {
62
39
  /** Brand identity for the sidebar header. */
63
40
  brand: BrandConfig;
64
- /** Grouped nav sections rendered in the sidebar (and projected to the mobile bottom nav). */
41
+ /** Grouped nav sections — the ONE definition, rendered as the sidebar and projected to the bar. */
65
42
  sections: SidebarSection[];
66
43
  /**
67
- * Optional consumer link renderer (e.g. a router `<Link>`). Receives the precomputed `active`
68
- * flag. When omitted, items fall back to a plain `<a href>` + `item.onClick`. This is the router
69
- * seam — no router primitive is imported by the shell.
44
+ * Mobile bar tuning. Every field optional — the defaults ARE the design, and a nav with nothing
45
+ * configured still produces a working bar (see `projectMobileNav`'s zero-config fallback).
70
46
  */
71
- renderNavLink?: NavLinkRenderer;
47
+ mobileNav?: MobileNavConfig;
72
48
  /** Persistent, shell-owned top-bar slot (timer, refresh, notifications). */
73
49
  globalActions?: ReactNode;
74
- /** Extra content appended to the sidebar footer, beside the settings menu (mobile close, etc.). */
75
- sidebarFooterExtra?: ReactNode;
76
50
  /**
77
- * Arbitrary content appended after `sections` inside the sidebar's nav scroll region (a tree, a
78
- * filter panel, a project list, …). Hidden on the collapsed desktop rail; still present in the
79
- * mobile drawer, which opens at full width — see `AppSidebarProps.navExtra`'s JSDoc for why.
80
- * `AppSidebar` renders once and serves both the desktop rail and the mobile drawer (collapse
81
- * styling is gated behind a `min-width: sm` media query, not a second render), so this slot
82
- * reaches both.
51
+ * DESKTOP ONLY. Arbitrary content appended after `sections` inside the sidebar's nav scroll
52
+ * region (a tree, a filter panel, a project list, …), for anything a set of `SidebarItem`s can't
53
+ * express. Hidden on the collapsed desktop rail; the sidebar itself no longer exists below the
54
+ * `sm` breakpoint, so this slot has no mobile representation — put mobile-reachable extras in
55
+ * `mobileNav.moreExtra` instead.
83
56
  */
84
57
  sidebarNavExtra?: ReactNode;
85
58
  /** Entries appended to the sidebar settings menu. */
@@ -109,24 +82,8 @@ export type BasaltShellProps = {
109
82
  * a no-op when omitted.
110
83
  */
111
84
  onCollapsedChange?: (collapsed: boolean) => void;
112
- /**
113
- * Optional router link renderer for the breadcrumb parent segment. When provided, the parent
114
- * breadcrumb label is rendered through this callback (e.g. a TanStack `<Link>`) instead of a
115
- * plain `<a href>`, enabling client-side navigation.
116
- */
117
- renderBreadcrumbLink?: BreadcrumbLinkRenderer | undefined;
118
85
  /** Page content. */
119
86
  children?: ReactNode;
120
87
  };
121
- /**
122
- * Sidebar nav count badge (docs/DESIGN-SPEC.md §5): mono 10.5px, ink-8% bg, radius 5, height 16,
123
- * padding 0 5px, muted text; `marginLeft: auto` pins it to the row end on any render path.
124
- * `styles` (inline) rather than a token color prop, since none of Mantine's variant/color
125
- * combinations land on the ink-tint idiom. Returns `null` for a zero/empty count so the badge slot
126
- * stays clean ("ink earns its color", DESIGN.md).
127
- */
128
- export declare function NavCountBadge({ count }: {
129
- count: number;
130
- }): import("react").JSX.Element | null;
131
- export declare function BasaltShell({ brand, sections, renderNavLink, globalActions, sidebarFooterExtra, sidebarNavExtra, settingsMenuItems, storageKey, collapsed: collapsedProp, onCollapsedChange, renderBreadcrumbLink, account, search, children, }: BasaltShellProps): import("react").JSX.Element;
88
+ export declare function BasaltShell({ brand, sections, mobileNav, globalActions, sidebarNavExtra, settingsMenuItems, storageKey, collapsed: collapsedProp, onCollapsedChange, account, search, children, }: BasaltShellProps): import("react").JSX.Element;
132
89
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shell/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shell/index.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMlD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAA0B,cAAc,EAAE,MAAM,cAAc,CAAA;AAK3F,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,uBAAuB,EACvB,uBAAuB,EACvB,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAElF;;;;GAIG;AACH,YAAY,EACV,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,aAAa,EACb,gBAAgB,GACjB,MAAM,cAAc,CAAA;AAErB,gEAAgE;AAChE,MAAM,MAAM,WAAW,GAAG;IACxB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,6DAA6D;AAC7D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,6CAA6C;IAC7C,KAAK,EAAE,WAAW,CAAA;IAClB,mGAAmG;IACnG,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,CAAA;IAC3B,4EAA4E;IAC5E,aAAa,CAAC,EAAE,SAAS,CAAA;IACzB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,SAAS,CAAA;IAC3B,qDAAqD;IACrD,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B;;;OAGG;IACH,MAAM,CAAC,EAAE,mBAAmB,CAAA;IAC5B,kGAAkG;IAClG,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAA;IAChD,oBAAoB;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,CAAA;AAgDD,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,SAAS,EACT,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,UAAuC,EACvC,SAAS,EAAE,aAAa,EACxB,iBAAiB,EACjB,OAAO,EACP,MAAM,EACN,QAAQ,GACT,EAAE,gBAAgB,+BAgGlB"}