basalt-ui 1.19.1 → 1.21.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 (129) hide show
  1. package/AGENTS.md +19 -1
  2. package/CHANGELOG.md +39 -0
  3. package/MIGRATING.md +326 -0
  4. package/README.md +87 -9
  5. package/agent/rules/basalt-app.md +84 -0
  6. package/agent/rules/basalt-charts.md +32 -17
  7. package/agent/rules/basalt-content.md +4 -0
  8. package/agent/rules/basalt-mantine.md +25 -10
  9. package/agent/rules/basalt-router.md +79 -15
  10. package/agent/rules/basalt-state.md +21 -3
  11. package/agent/rules/basalt-tokens.md +132 -6
  12. package/agent/skills/basalt-app/SKILL.md +45 -6
  13. package/agent/skills/basalt-charts/SKILL.md +5 -3
  14. package/agent/templates/CLAUDE-block.md.tpl +11 -5
  15. package/configs/check.yml +11 -4
  16. package/configs/lefthook.yml +59 -7
  17. package/configs/oxlint-plugin.js +633 -30
  18. package/configs/oxlint-plugin.test.ts +594 -15
  19. package/configs/oxlint.json +10 -1
  20. package/dist/agent/stick-to-bottom.js +1 -1
  21. package/dist/agent-chat/thread-detail-panel.js +1 -1
  22. package/dist/agent-chat/thread-message.js +2 -2
  23. package/dist/agent-chat/tool-chip.js +1 -1
  24. package/dist/charts/kinds/Bars.d.ts +1 -1
  25. package/dist/charts/kinds/Bars.d.ts.map +1 -1
  26. package/dist/charts/kinds/Donut.d.ts +1 -1
  27. package/dist/charts/kinds/Donut.d.ts.map +1 -1
  28. package/dist/charts/kinds/Donut.js +1 -1
  29. package/dist/charts/kinds/DualPanel.d.ts +1 -1
  30. package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
  31. package/dist/charts/kinds/Heatmap.d.ts +1 -1
  32. package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
  33. package/dist/charts/kinds/MultiLine.d.ts +1 -1
  34. package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
  35. package/dist/charts/kinds/StackedArea.d.ts +1 -1
  36. package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
  37. package/dist/charts/kinds/ZonedLine.d.ts +1 -1
  38. package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
  39. package/dist/charts/primitives/ChartLegend.js +2 -2
  40. package/dist/charts/primitives/ChartTooltip.js +1 -1
  41. package/dist/cli/index.d.ts +146 -20
  42. package/dist/cli/index.d.ts.map +1 -1
  43. package/dist/cli/index.js +901 -101
  44. package/dist/cli/toolchain-wiring.test.d.ts +2 -0
  45. package/dist/cli/toolchain-wiring.test.d.ts.map +1 -0
  46. package/dist/cli/waiver-audit.test.d.ts +2 -0
  47. package/dist/cli/waiver-audit.test.d.ts.map +1 -0
  48. package/dist/dashboard/delta-badge.js +2 -2
  49. package/dist/dashboard/stat-card.js +1 -1
  50. package/dist/data/virtual-list.js +5 -5
  51. package/dist/guard/index.d.ts +101 -2
  52. package/dist/guard/index.d.ts.map +1 -1
  53. package/dist/guard/index.js +474 -62
  54. package/dist/guard/types.d.ts +25 -5
  55. package/dist/guard/types.d.ts.map +1 -1
  56. package/dist/register.d.ts +25 -0
  57. package/dist/register.d.ts.map +1 -1
  58. package/dist/router-tanstack/multi-search-param-store.d.ts +13 -0
  59. package/dist/router-tanstack/multi-search-param-store.d.ts.map +1 -1
  60. package/dist/router-tanstack/multi-search-param-store.js +4 -1
  61. package/dist/router-tanstack/search-param-store.d.ts +29 -5
  62. package/dist/router-tanstack/search-param-store.d.ts.map +1 -1
  63. package/dist/router-tanstack/search-param-store.js +31 -3
  64. package/dist/router-tanstack/search-param-store.test.d.ts +2 -0
  65. package/dist/router-tanstack/search-param-store.test.d.ts.map +1 -0
  66. package/dist/shell/app-mobile-nav.module.css +11 -3
  67. package/dist/shell/index.d.ts +12 -5
  68. package/dist/shell/index.d.ts.map +1 -1
  69. package/dist/shell/index.js +24 -6
  70. package/dist/surfaces.d.ts +1 -1
  71. package/dist/surfaces.js +1 -1
  72. package/dist/tokens/index.d.ts +5 -3
  73. package/dist/tokens/index.d.ts.map +1 -1
  74. package/dist/tokens/index.js +7 -1
  75. package/dist/tokens/palette.d.ts +35 -27
  76. package/dist/tokens/palette.d.ts.map +1 -1
  77. package/dist/tokens/palette.js +24 -18
  78. package/dist/tokens/text-scale.test.d.ts +2 -0
  79. package/dist/tokens/text-scale.test.d.ts.map +1 -0
  80. package/dist/tokens.css +21 -17
  81. package/dist/vite-color-mix.js +2 -2
  82. package/dist/vite.d.ts +24 -2
  83. package/dist/vite.d.ts.map +1 -1
  84. package/dist/vite.js +54 -13
  85. package/llms.txt +3 -3
  86. package/package.json +4 -3
  87. package/src/agent/stick-to-bottom.tsx +1 -1
  88. package/src/agent-chat/thread-detail-panel.tsx +1 -1
  89. package/src/agent-chat/thread-message.tsx +3 -3
  90. package/src/agent-chat/tool-chip.tsx +1 -1
  91. package/src/charts/kinds/Bars.tsx +1 -1
  92. package/src/charts/kinds/Donut.tsx +3 -2
  93. package/src/charts/kinds/DualPanel.tsx +2 -2
  94. package/src/charts/kinds/Heatmap.tsx +1 -1
  95. package/src/charts/kinds/MultiLine.tsx +1 -1
  96. package/src/charts/kinds/StackedArea.tsx +1 -1
  97. package/src/charts/kinds/ZonedLine.tsx +1 -1
  98. package/src/charts/primitives/ChartLegend.tsx +2 -2
  99. package/src/charts/primitives/ChartTooltip.tsx +1 -1
  100. package/src/cli/index.ts +1614 -164
  101. package/src/cli/init-sync.test.ts +21 -3
  102. package/src/cli/template-ledger.test.ts +1 -1
  103. package/src/cli/tokens-css.test.ts +27 -14
  104. package/src/cli/toolchain-wiring.test.ts +856 -0
  105. package/src/cli/waiver-audit.test.ts +131 -0
  106. package/src/dashboard/delta-badge.tsx +3 -3
  107. package/src/dashboard/stat-card.tsx +1 -1
  108. package/src/data/virtual-list.tsx +8 -8
  109. package/src/guard/check-source.test.ts +1104 -12
  110. package/src/guard/index.ts +1106 -103
  111. package/src/guard/types.ts +29 -4
  112. package/src/register.ts +32 -0
  113. package/src/router-tanstack/multi-search-param-store.ts +16 -1
  114. package/src/router-tanstack/search-param-store.test.ts +135 -0
  115. package/src/router-tanstack/search-param-store.ts +90 -8
  116. package/src/shell/app-mobile-nav.module.css +11 -3
  117. package/src/shell/app-mobile-nav.tsx +1 -1
  118. package/src/shell/index.test.tsx +52 -0
  119. package/src/shell/index.tsx +64 -13
  120. package/src/surfaces.ts +1 -1
  121. package/src/theme/density-relations.test.ts +8 -5
  122. package/src/theme/spacing.test.ts +2 -0
  123. package/src/theme-toggle/index.tsx +2 -2
  124. package/src/tokens/index.ts +28 -3
  125. package/src/tokens/palette.ts +24 -18
  126. package/src/tokens/text-scale.test.ts +51 -0
  127. package/src/vite-color-mix.ts +2 -2
  128. package/src/vite.test.ts +125 -6
  129. package/src/vite.ts +148 -20
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Guard types — Mantine-free, dependency-free (zero imports beyond TS types).
3
3
  *
4
- * GuardKind is the closed set of 20 violation kinds the theme guard can emit.
4
+ * GuardKind is the closed set of 25 violation kinds the theme guard can emit.
5
5
  * Finding is the structured result per violation, replacing the old `Violation` shape.
6
6
  * GuardConfig is the per-run configuration that drives checkSource.
7
7
  */
8
- /** The 20 theme-guard violation kinds. */
9
- export type GuardKind = 'raw-hex' | 'raw-color-fn' | 'localstorage-theme' | 'off-identity-accent' | 'mantine-shade-index' | 'raw-spacing' | 'raw-radius' | 'raw-surface' | 'card-with-border' | 'off-system-surface-var' | 'raw-html-layout' | 'inline-spacing' | 'inline-display' | 'raw-visx-axis' | 'raw-motion-value' | 'unframed-chart' | 'chart-missing-aria-label' | 'raw-form-control' | 'sub-16-input-font' | 'raw-font-family';
8
+ /** The 25 theme-guard violation kinds. */
9
+ export type GuardKind = 'raw-hex' | 'raw-color-fn' | 'localstorage-theme' | 'off-identity-accent' | 'mantine-shade-index' | 'raw-spacing' | 'raw-radius' | 'raw-surface' | 'card-with-border' | 'off-system-surface-var' | 'raw-html-layout' | 'inline-spacing' | 'inline-display' | 'raw-visx-axis' | 'raw-motion-value' | 'unframed-chart' | 'chart-missing-aria-label' | 'raw-form-control' | 'sub-16-input-font' | 'raw-font-family' | 'theme-allow-unscoped' | 'surface-shadow-override' | 'css-raw-surface' | 'inline-font-size' | 'hidden-inline-style';
10
10
  /**
11
11
  * How hard a finding lands. `error` fails the build; `warn` reports and passes.
12
12
  *
@@ -127,10 +127,30 @@ export type GuardConfig = {
127
127
  */
128
128
  readonly sub16InputFont: boolean;
129
129
  /**
130
- * Allow-comment policy: a line containing this substring is skipped entirely.
131
- * Default 'theme-allow'. Pure-comment lines (// * /\*) are always skipped.
130
+ * Allow-comment policy. The token that opens an exception annotation inside a COMMENT, on the
131
+ * finding's own line or the line directly above it (matching the oxlint plugin's placement, and
132
+ * surviving an `oxfmt` reflow that moves the comment off the offending line). Default
133
+ * `'theme-allow'`.
134
+ *
135
+ * The accountable form is `theme-allow <rule-id>[, <rule-id>] — <reason>`: the rule ids scope the
136
+ * exception to those kinds only, and the reason says why. A `theme-allow` missing either half
137
+ * still suppresses (so an upgrade never breaks a build over it) but reports
138
+ * {@link GuardKind} `theme-allow-unscoped` on its own line.
132
139
  */
133
140
  readonly allowComment: string;
141
+ /**
142
+ * Which kinds apply to this consumer. `'mantine'` (default) is the full framework guard.
143
+ *
144
+ * `'tokens-only'` is for a consumer that installs the TOKEN LAYER and nothing else — no
145
+ * `@mantine/core`, often no React (`basalt-ui tokens:css` + `basalt-ui/tokens`). Every kind whose
146
+ * remedy is a Mantine component or prop is disabled there, because "use `TextInput` from
147
+ * `@mantine/core`" is not advice, it is a dependency the consumer deliberately does not have.
148
+ * The color/typography kinds stay on — those are the tokens, which is the whole surface they DO
149
+ * consume. See `TOKENS_ONLY_DISABLED_KINDS` in `./index` for the exact set.
150
+ *
151
+ * Optional so a caller built before this field existed keeps compiling; absent means `'mantine'`.
152
+ */
153
+ readonly profile?: 'mantine' | 'tokens-only';
134
154
  /**
135
155
  * Per-rule, per-path exemptions — complements whole-file `exempt` (BasaltConfig, which skips
136
156
  * ALL rules for a file) and code-level `appliesTo` (hardcoded per-kind path scoping, e.g.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/guard/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,0CAA0C;AAC1C,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,cAAc,GACd,oBAAoB,GACpB,qBAAqB,GACrB,qBAAqB,GACrB,aAAa,GACb,YAAY,GACZ,aAAa,GACb,kBAAkB,GAClB,wBAAwB,GACxB,iBAAiB,GACjB,gBAAgB,GAChB,gBAAgB,GAChB,eAAe,GACf,kBAAkB,GAClB,gBAAgB,GAChB,0BAA0B,GAC1B,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB,CAAA;AAErB;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,CAAA;AAE5C;;;;;;;GAOG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAA;CACjC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,wGAAwG;IACxG,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,uEAAuE;IACvE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5C;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAA;IACnC,iGAAiG;IACjG,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC,2GAA2G;IAC3G,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;IACrC,sGAAsG;IACtG,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,4FAA4F;IAC5F,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,yFAAyF;IACzF,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,kGAAkG;IAClG,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAA;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;IAC1D;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAA;CAC7D,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/guard/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,0CAA0C;AAC1C,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,cAAc,GACd,oBAAoB,GACpB,qBAAqB,GACrB,qBAAqB,GACrB,aAAa,GACb,YAAY,GACZ,aAAa,GACb,kBAAkB,GAClB,wBAAwB,GACxB,iBAAiB,GACjB,gBAAgB,GAChB,gBAAgB,GAChB,eAAe,GACf,kBAAkB,GAClB,gBAAgB,GAChB,0BAA0B,GAC1B,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB,GACjB,sBAAsB,GACtB,yBAAyB,GACzB,iBAAiB,GACjB,kBAAkB,GAClB,qBAAqB,CAAA;AAEzB;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,OAAO,CAAA;AAE5C;;;;;;;GAOG;AACH,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAA;CACjC,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,wGAAwG;IACxG,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,uEAAuE;IACvE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5C;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAA;IACnC,iGAAiG;IACjG,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC,2GAA2G;IAC3G,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;IACrC,sGAAsG;IACtG,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,8EAA8E;IAC9E,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,4FAA4F;IAC5F,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,yFAAyF;IACzF,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,kGAAkG;IAClG,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAA;IACvC;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;IAChC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,aAAa,CAAA;IAC5C;;;;;;;;;;;;;;;;;;;OAmBG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;IAC1D;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAA;CAC7D,CAAA"}
@@ -136,4 +136,29 @@ export declare namespace StandardSchemaV1 {
136
136
  type InferInput<T extends StandardSchemaV1> = NonNullable<T['~standard']['types']>['input'];
137
137
  type InferOutput<T extends StandardSchemaV1> = NonNullable<T['~standard']['types']>['output'];
138
138
  }
139
+ declare global {
140
+ /**
141
+ * The app's version string, injected as a build-time constant by basalt's own Vite preset —
142
+ * `basaltViteConfig` defines it from `BUILD_VERSION`, falling back to the app package.json
143
+ * `version` (see `../vite`, the `define` block).
144
+ *
145
+ * Declared HERE rather than beside the define because a consumer's `src/**` never loads
146
+ * `basalt-ui/vite`'s types (that subpath is imported from `vite.config.ts`, which most apps keep
147
+ * in a separate tsconfig project). This file is re-exported from the root barrel, so an app that
148
+ * imports from `'basalt-ui'` at all has it in scope with no `/// <reference>` and no
149
+ * `src/vite-env.d.ts` entry — which is the point: basalt shipped the define and no declaration,
150
+ * so every consumer hand-wrote this block, one of them needing an `oxlint-disable` in a file that
151
+ * existed only because basalt asked for it.
152
+ *
153
+ * A consumer importing ONLY a subpath (`basalt-ui/tokens`, `basalt-ui/charts`) does not load this
154
+ * file and does not get the global. That gap is the same set as the applicability gap: reaching
155
+ * for the root barrel is what `BasaltProvider` requires, and an app that never does is not on
156
+ * basalt's Vite preset either, so there is no `__APP_VERSION__` to declare.
157
+ *
158
+ * Precondition: only defined when your Vite config actually goes through `basaltViteConfig` (or
159
+ * you define it yourself). An app that hand-rolls its Vite config and reads this gets a
160
+ * ReferenceError at runtime — TypeScript is trusting the preset, not proving it.
161
+ */
162
+ const __APP_VERSION__: string;
163
+ }
139
164
  //# sourceMappingURL=register.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAIzC;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc;CAAG;AAElC;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,UAAU,IAAI,cAAc,SAAS;KACrE,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,UAAU;CACrC,GACG,CAAC,GACD,EAAE,CAAA;AAEN,uEAAuE;AACvE,MAAM,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;AAE9C;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,CAAA;AAIrD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IAC/B;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAA;AAEnD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAE/C;AAID;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,gBAAgB,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;IAC/D,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;CAC5D;AAED,yBAAiB,gBAAgB,CAAC;IAChC,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QACpD,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;QACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;QAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;KAClD;IAED,KAAY,MAAM,CAAC,MAAM,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,aAAa,CAAA;IAElE,UAAiB,aAAa,CAAC,MAAM;QACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;QACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;KAC5B;IAED,UAAiB,aAAa;QAC5B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,CAAA;KACtC;IAED,UAAiB,KAAK;QACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,SAAS,CAAA;KACrE;IAED,UAAiB,WAAW;QAC1B,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAA;KAC1B;IAED,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QACpD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KACxB;IAED,KAAY,UAAU,CAAC,CAAC,SAAS,gBAAgB,IAAI,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;IAClG,KAAY,WAAW,CAAC,CAAC,SAAS,gBAAgB,IAAI,WAAW,CAC/D,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CACxB,CAAC,QAAQ,CAAC,CAAA;CACZ"}
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@
8
8
  * 2. `useStore` — React hook: `const [values, persist] = store.useStore()`.
9
9
  * Call `persist(next)` alongside `navigate` so the selection survives navigation.
10
10
  * 3. `readStored` — plain function for non-React contexts (tests, guards).
11
+ * 4. `linkSearch` — the click-time `search:` thunk for a nav link, ready-made.
11
12
  *
12
13
  * Headless — no Mantine, no JSX. Same tier as `createSearchParamStore`.
13
14
  *
@@ -73,6 +74,18 @@ export type MultiSearchParamStore<T extends string, P extends string = string> =
73
74
  useStore: () => readonly [readonly T[], (next: readonly T[]) => void];
74
75
  /** Plain read — for use outside React (tests, guards, fallback reads). */
75
76
  readStored: () => readonly T[] | null;
77
+ /**
78
+ * The click-time `search:` thunk for a nav link — `() => ({ [param]: readStored() ?? fallback })`.
79
+ * Pass it BY REFERENCE (`search: store.linkSearch`), never call it; see `createSearchParamStore`
80
+ * for why a module-scope literal silently defeats the store.
81
+ *
82
+ * No dev warning rides on this one, unlike the single-value store: an empty array in the URL is
83
+ * indistinguishable from an absent param here (`validateSearch` falls back to storage for both),
84
+ * so a link declaring `{ tags: [] }` restores correctly and there is no broken state to detect.
85
+ */
86
+ linkSearch: () => {
87
+ [K in P]: readonly T[];
88
+ };
76
89
  };
77
90
  export declare function createMultiSearchParamStore<const T extends string, const P extends string>(opts: MultiSearchParamStoreOptions<T, P>): MultiSearchParamStore<T, P>;
78
91
  //# sourceMappingURL=multi-search-param-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"multi-search-param-store.d.ts","sourceRoot":"","sources":["../../src/router-tanstack/multi-search-param-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAMH,MAAM,MAAM,4BAA4B,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IACtF,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAA;IACX,6DAA6D;IAC7D,KAAK,EAAE,CAAC,CAAA;IACR,0FAA0F;IAC1F,MAAM,EAAE,SAAS,CAAC,EAAE,CAAA;IACpB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,SAAS,CAAC,EAAE,CAAA;IACvB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAC/E;;;OAGG;IACH,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK;SAAG,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE;KAAE,CAAA;IAC/E;;;OAGG;IACH,QAAQ,EAAE,MAAM,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,CAAA;IACrE,0EAA0E;IAC1E,UAAU,EAAE,MAAM,SAAS,CAAC,EAAE,GAAG,IAAI,CAAA;CACtC,CAAA;AAID,wBAAgB,2BAA2B,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,MAAM,EACxF,IAAI,EAAE,4BAA4B,CAAC,CAAC,EAAE,CAAC,CAAC,GACvC,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,CAoC7B"}
1
+ {"version":3,"file":"multi-search-param-store.d.ts","sourceRoot":"","sources":["../../src/router-tanstack/multi-search-param-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAMH,MAAM,MAAM,4BAA4B,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IACtF,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAA;IACX,6DAA6D;IAC7D,KAAK,EAAE,CAAC,CAAA;IACR,0FAA0F;IAC1F,MAAM,EAAE,SAAS,CAAC,EAAE,CAAA;IACpB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,SAAS,CAAC,EAAE,CAAA;IACvB,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAC/E;;;OAGG;IACH,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK;SAAG,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE;KAAE,CAAA;IAC/E;;;OAGG;IACH,QAAQ,EAAE,MAAM,SAAS,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,CAAA;IACrE,0EAA0E;IAC1E,UAAU,EAAE,MAAM,SAAS,CAAC,EAAE,GAAG,IAAI,CAAA;IACrC;;;;;;;;OAQG;IACH,UAAU,EAAE,MAAM;SAAG,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE;KAAE,CAAA;CAC7C,CAAA;AAID,wBAAgB,2BAA2B,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,MAAM,EACxF,IAAI,EAAE,4BAA4B,CAAC,CAAC,EAAE,CAAC,CAAC,GACvC,qBAAqB,CAAC,CAAC,EAAE,CAAC,CAAC,CAwC7B"}
@@ -16,6 +16,9 @@ function createMultiSearchParamStore(opts) {
16
16
  if (!Array.isArray(raw)) return null;
17
17
  return normalize(raw);
18
18
  };
19
+ const linkSearch = () => {
20
+ return { [opts.param]: readStored() ?? fallback };
21
+ };
19
22
  const validateSearch = (search) => {
20
23
  const fromUrl = normalize(search[opts.param]);
21
24
  if (fromUrl.length > 0) {
@@ -28,7 +31,7 @@ function createMultiSearchParamStore(opts) {
28
31
  version,
29
32
  initial: fallback
30
33
  });
31
- return { validateSearch, useStore, readStored };
34
+ return { validateSearch, useStore, readStored, linkSearch };
32
35
  }
33
36
  export {
34
37
  createMultiSearchParamStore
@@ -9,6 +9,19 @@
9
9
  * Call `persist(next)` alongside `navigate` so the selection survives
10
10
  * navigation away from and back to the route.
11
11
  * 3. `readStored` — plain function for non-React contexts (tests, guards).
12
+ * 4. `linkSearch` — the click-time `search:` thunk a nav link needs, ready-made.
13
+ *
14
+ * ## The half that is easy to skip
15
+ *
16
+ * `validateSearch` restores the value when you navigate TO the route with no param. It cannot do
17
+ * anything about a nav link that declares the param itself — and a link written as
18
+ * `search: { range: '30d' }` at module scope pins the fallback on every click, which silently
19
+ * defeats the whole store. The reference consumer shipped exactly that: three features adopted the
20
+ * persistence, the reader had ZERO call sites, and "remember my window" had never once worked.
21
+ *
22
+ * `linkSearch` exists so that failure is unreachable from the API rather than only warned about in
23
+ * this comment — the mistake is made while typing `search:`, so the remedy has to be something
24
+ * autocomplete offers at that keystroke. The JSDoc was already here when it happened.
12
25
  *
13
26
  * Headless — no Mantine, no JSX. Same tier as `useBasaltNav` and
14
27
  * `useRouterBreadcrumbs`.
@@ -51,17 +64,18 @@
51
64
  *
52
65
  * **5. Nav links** — carry the param across sub-pages, set per destination in
53
66
  * the nav definition so only the dashboard sub-tree inherits it and every
54
- * other link stays clean. Use a CLICK-TIME THUNK over `readStored`:
55
- *
56
- * const dashSearch = () => ({ range: dashboardRange.readStored() ?? '30d' })
67
+ * other link stays clean. Pass `linkSearch` BY REFERENCE — it is the click-time thunk:
57
68
  *
58
69
  * navGroup({ id: 'dash', label: 'Dashboard' }, [
59
70
  * { id: 'dash-overview', label: 'Overview', icon: <IconHome />,
60
- * link: linkOptions({ to: '/dashboard', search: dashSearch }) },
71
+ * link: linkOptions({ to: '/dashboard', search: dashboardRange.linkSearch }) },
61
72
  * { id: 'dash-activity', label: 'Activity', icon: <IconPulse />,
62
- * link: linkOptions({ to: '/dashboard/activity', search: dashSearch }) },
73
+ * link: linkOptions({ to: '/dashboard/activity', search: dashboardRange.linkSearch }) },
63
74
  * ])
64
75
  *
76
+ * `linkSearch` IS that thunk (`() => ({ [param]: readStored() ?? fallback })`) — hand-rolling it
77
+ * over `readStored` still works and is what you need when the link also carries other params.
78
+ *
65
79
  * NOT `search: true`. That flag means "keep the current search" and TanStack
66
80
  * only offers it where the target's search is OPTIONAL — a route wired to a
67
81
  * store's `validateSearch` always returns the param, so the router requires a
@@ -97,6 +111,16 @@ export type SearchParamStore<T extends string, P extends string = string> = {
97
111
  useStore: () => readonly [T, (next: T) => void];
98
112
  /** Plain read — for use outside React (tests, guards, fallback reads). */
99
113
  readStored: () => T | null;
114
+ /**
115
+ * The click-time `search:` thunk for a nav link — `() => ({ [param]: readStored() ?? fallback })`.
116
+ *
117
+ * Pass it BY REFERENCE (`search: store.linkSearch`), never call it: `<Link>` re-evaluates the
118
+ * thunk on every click, so arriving from outside the sub-tree restores the last selection,
119
+ * whereas a value computed once at module scope goes stale immediately and pins the fallback.
120
+ */
121
+ linkSearch: () => {
122
+ [K in P]: T;
123
+ };
100
124
  };
101
125
  export declare function createSearchParamStore<const T extends string, const P extends string>(opts: SearchParamStoreOptions<T, P>): SearchParamStore<T, P>;
102
126
  //# sourceMappingURL=search-param-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search-param-store.d.ts","sourceRoot":"","sources":["../../src/router-tanstack/search-param-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AAMH,MAAM,MAAM,uBAAuB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IACjF,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAA;IACX,mEAAmE;IACnE,KAAK,EAAE,CAAC,CAAA;IACR,2DAA2D;IAC3D,MAAM,EAAE,SAAS,CAAC,EAAE,CAAA;IACpB,kEAAkE;IAClE,QAAQ,EAAE,CAAC,CAAA;IACX,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAC1E;;;OAGG;IACH,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK;SAAG,CAAC,IAAI,CAAC,GAAG,CAAC;KAAE,CAAA;IACpE;;;OAGG;IACH,QAAQ,EAAE,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,CAAA;IAC/C,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;CAC3B,CAAA;AAID,wBAAgB,sBAAsB,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,MAAM,EACnF,IAAI,EAAE,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,GAClC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAyBxB"}
1
+ {"version":3,"file":"search-param-store.d.ts","sourceRoot":"","sources":["../../src/router-tanstack/search-param-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AAMH,MAAM,MAAM,uBAAuB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IACjF,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAA;IACX,mEAAmE;IACnE,KAAK,EAAE,CAAC,CAAA;IACR,2DAA2D;IAC3D,MAAM,EAAE,SAAS,CAAC,EAAE,CAAA;IACpB,kEAAkE;IAClE,QAAQ,EAAE,CAAC,CAAA;IACX,kFAAkF;IAClF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAC1E;;;OAGG;IACH,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK;SAAG,CAAC,IAAI,CAAC,GAAG,CAAC;KAAE,CAAA;IACpE;;;OAGG;IACH,QAAQ,EAAE,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,CAAA;IAC/C,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;IAC1B;;;;;;OAMG;IACH,UAAU,EAAE,MAAM;SAAG,CAAC,IAAI,CAAC,GAAG,CAAC;KAAE,CAAA;CAClC,CAAA;AAgCD,wBAAgB,sBAAsB,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,CAAC,CAAC,SAAS,MAAM,EACnF,IAAI,EAAE,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,GAClC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAyDxB"}
@@ -1,25 +1,53 @@
1
1
  import { createPersistedState, readPersistedValue } from "../state.js";
2
+ function warnLinkPinsFallback(input) {
3
+ const { key, param, urlValue, storedValue } = input;
4
+ console.warn(
5
+ `[basalt-ui] createSearchParamStore('${key}'): the URL pinned \`${param}=${urlValue}\` (the fallback) while '${storedValue}' was persisted, and nothing has read this store back. A nav link is almost certainly declaring \`search: { ${param}: '${urlValue}' }\` at module scope, which overrides the stored value on every click \u2014 pass the store's own reader instead: \`search: <store>.linkSearch\`. (dev only)`
6
+ );
7
+ }
2
8
  function createSearchParamStore(opts) {
3
9
  const version = opts.version ?? 1;
4
- const readStored = () => {
10
+ let readerWired = false;
11
+ let warned = false;
12
+ const read = () => {
5
13
  const raw = readPersistedValue(opts.key, version);
6
14
  if (typeof raw !== "string") return null;
7
15
  if (opts.values.includes(raw)) return raw;
8
16
  return null;
9
17
  };
18
+ const readStored = () => {
19
+ readerWired = true;
20
+ return read();
21
+ };
22
+ const linkSearch = () => {
23
+ readerWired = true;
24
+ return { [opts.param]: read() ?? opts.fallback };
25
+ };
10
26
  const validateSearch = (search) => {
11
27
  const raw = search[opts.param];
12
28
  if (typeof raw === "string" && opts.values.includes(raw)) {
29
+ if (!warned && !readerWired && raw === opts.fallback && process.env["NODE_ENV"] !== "production") {
30
+ const stored = read();
31
+ if (stored !== null && stored !== raw) {
32
+ warned = true;
33
+ warnLinkPinsFallback({
34
+ key: opts.key,
35
+ param: opts.param,
36
+ urlValue: raw,
37
+ storedValue: stored
38
+ });
39
+ }
40
+ }
13
41
  return { [opts.param]: raw };
14
42
  }
15
- return { [opts.param]: readStored() ?? opts.fallback };
43
+ return { [opts.param]: read() ?? opts.fallback };
16
44
  };
17
45
  const useStore = createPersistedState({
18
46
  key: opts.key,
19
47
  version,
20
48
  initial: opts.fallback
21
49
  });
22
- return { validateSearch, useStore, readStored };
50
+ return { validateSearch, useStore, readStored, linkSearch };
23
51
  }
24
52
  export {
25
53
  createSearchParamStore
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-param-store.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-param-store.test.d.ts","sourceRoot":"","sources":["../../src/router-tanstack/search-param-store.test.ts"],"names":[],"mappings":""}
@@ -46,9 +46,17 @@
46
46
  display: inline-flex;
47
47
  align-items: center;
48
48
  justify-content: center;
49
- /* Deliberately sub-scale: the active pill hugs a 24px glyph, so it is a shape inset rather than
50
- * layout spacing — the xs..xl scale has no step this tight. */
51
- padding: 2px 12px; /* theme-allow */
49
+ /* This span IS the active pill, so its box may not depend on what it contains: shipping no icon
50
+ * dependency is a supported configuration, and an empty span collapsed the pill to a 24x4px
51
+ * dash. The floor is the icon box PLUS its inset — everything is border-box under Mantine's
52
+ * reset — so the pill renders identically with and without a glyph, at every density. */
53
+ min-width: calc(
54
+ var(--vx-space-mobile-nav-icon-size) + 2 * var(--vx-space-mobile-nav-tab-inset-x)
55
+ );
56
+ min-height: calc(
57
+ var(--vx-space-mobile-nav-icon-size) + 2 * var(--vx-space-mobile-nav-tab-inset-y)
58
+ );
59
+ padding: var(--vx-space-mobile-nav-tab-inset-y) var(--vx-space-mobile-nav-tab-inset-x);
52
60
  border-radius: var(--vx-radius-ctrl);
53
61
  transition: transform 140ms cubic-bezier(0.32, 0.72, 0, 1);
54
62
  }
@@ -67,13 +67,20 @@ export type BasaltShellProps = {
67
67
  * `onOpen`, e.g. `() => openSpotlight()` from basalt-ui/commands.
68
68
  */
69
69
  search?: SidebarSearchConfig;
70
- /** localStorage key for the persisted sidebar-collapsed flag. Ignored when `collapsed` is set. */
70
+ /**
71
+ * localStorage key for the persisted sidebar-collapsed flag. Ignored when `collapsed` is set.
72
+ *
73
+ * Persisted through basalt's own `createPersistedState`, so the real storage key is
74
+ * `basalt:<storageKey>` and the value is the versioned `{ v, value }` envelope. A consumer
75
+ * mirroring this state reads it with `readPersistedValue(storageKey, 1)` from `basalt-ui/state`
76
+ * — never with a bare `localStorage.getItem`, which is what the pre-1.20.1 shell forced.
77
+ */
71
78
  storageKey?: string;
72
79
  /**
73
- * Controlled desktop-collapse value. When provided, the shell no longer owns the
74
- * `useLocalStorage`-persisted collapse state — the consumer does (e.g. to drive it from its own
75
- * `Cmd+B` hotkey). Pair with `onCollapsedChange` to receive toggle events; omitting both
76
- * reproduces today's internal, persisted collapse behavior unchanged.
80
+ * Controlled desktop-collapse value. When provided, the shell no longer owns the persisted
81
+ * collapse state — the consumer does (e.g. to drive it from its own `Cmd+B` hotkey), and should
82
+ * own it through `createPersistedState` too. Pair with `onCollapsedChange` to receive toggle
83
+ * events; omitting both reproduces today's internal, persisted collapse behavior unchanged.
77
84
  */
78
85
  collapsed?: boolean;
79
86
  /**
@@ -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":"AAqBA,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;AAM3F,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;;;;;;;OAOG;IACH,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;AAgGD,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,+BA4FlB"}
@@ -1,6 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { AppShell } from "@mantine/core";
3
- import { useLocalStorage } from "@mantine/hooks";
4
3
  import { useMemo } from "react";
5
4
  import { AppSidebar } from "./app-sidebar.js";
6
5
  import { MobileNav, accountRowCount } from "./app-mobile-nav.js";
@@ -8,6 +7,7 @@ import { projectMobileNav } from "./mobile-nav-model.js";
8
7
  import { AppBreadcrumbs } from "./app-breadcrumbs.js";
9
8
  import { PageActionsOutlet, PageHeaderProvider } from "./page-header.js";
10
9
  import { useBasaltSpacing } from "../theme/index.js";
10
+ import { createPersistedState } from "../state.js";
11
11
  import headerClasses from "./app-header.module.css";
12
12
  import mobileNavClasses from "./app-mobile-nav.module.css";
13
13
  import { AppSidebar as AppSidebar2 } from "./app-sidebar.js";
@@ -47,6 +47,28 @@ function findActiveWithParent(items, parentLabel, parentAnchor, parentHref) {
47
47
  }
48
48
  return void 0;
49
49
  }
50
+ const COLLAPSE_VERSION = 1;
51
+ const collapseStores = /* @__PURE__ */ new Map();
52
+ function migrateLegacyCollapse(key) {
53
+ try {
54
+ if (window.localStorage.getItem(`basalt:${key}`) !== null) return;
55
+ const legacy = window.localStorage.getItem(key);
56
+ if (legacy !== "true" && legacy !== "false") return;
57
+ window.localStorage.setItem(
58
+ `basalt:${key}`,
59
+ JSON.stringify({ v: COLLAPSE_VERSION, value: legacy === "true" })
60
+ );
61
+ } catch {
62
+ }
63
+ }
64
+ function collapseStore(key) {
65
+ const cached = collapseStores.get(key);
66
+ if (cached) return cached;
67
+ if (typeof window !== "undefined") migrateLegacyCollapse(key);
68
+ const store = createPersistedState({ key, version: COLLAPSE_VERSION, initial: false });
69
+ collapseStores.set(key, store);
70
+ return store;
71
+ }
50
72
  function BasaltShell({
51
73
  brand,
52
74
  sections,
@@ -62,11 +84,7 @@ function BasaltShell({
62
84
  children
63
85
  }) {
64
86
  const { step } = useBasaltSpacing();
65
- const [storedCollapsed, setStoredCollapsed] = useLocalStorage({
66
- key: storageKey,
67
- defaultValue: false,
68
- getInitialValueInEffect: false
69
- });
87
+ const [storedCollapsed, setStoredCollapsed] = collapseStore(storageKey)();
70
88
  const isCollapseControlled = collapsedProp !== void 0;
71
89
  const collapsed = isCollapseControlled ? collapsedProp : storedCollapsed;
72
90
  const toggleCollapse = () => {
@@ -344,7 +344,7 @@ export declare const SURFACES: {
344
344
  readonly './tokens.css': {
345
345
  readonly kind: "tooling";
346
346
  readonly layer: "non-js-asset";
347
- readonly description: "Prebuilt --vx-* token stylesheet — the default buildPaletteCss() output as a plain file, for a consumer with no bundler, no React and no Mantine; retune the selector or trim the spacing set with `basalt-ui tokens:css`";
347
+ readonly description: "Prebuilt --vx-* token stylesheet — the default buildPaletteCss() output as a plain file, for a consumer that has a bundler to resolve the subpath but no React and no Mantine; with no bundler, emit a file you own via `basalt-ui tokens:css`";
348
348
  readonly forbiddenImports: readonly [];
349
349
  };
350
350
  readonly './configs/*': {
package/dist/surfaces.js CHANGED
@@ -284,7 +284,7 @@ const SURFACES = {
284
284
  "./tokens.css": {
285
285
  kind: "tooling",
286
286
  layer: "non-js-asset",
287
- description: "Prebuilt --vx-* token stylesheet \u2014 the default buildPaletteCss() output as a plain file, for a consumer with no bundler, no React and no Mantine; retune the selector or trim the spacing set with `basalt-ui tokens:css`",
287
+ description: "Prebuilt --vx-* token stylesheet \u2014 the default buildPaletteCss() output as a plain file, for a consumer that has a bundler to resolve the subpath but no React and no Mantine; with no bundler, emit a file you own via `basalt-ui tokens:css`",
288
288
  forbiddenImports: []
289
289
  },
290
290
  "./configs/*": {
@@ -40,6 +40,7 @@ export declare const VX: {
40
40
  readonly legendGap: number;
41
41
  readonly legendFontSize: 13.5;
42
42
  readonly text: {
43
+ readonly nano: 10;
43
44
  readonly micro: 11;
44
45
  readonly xs: 12.5;
45
46
  readonly sm: 13.5;
@@ -49,6 +50,7 @@ export declare const VX: {
49
50
  readonly h2: 21;
50
51
  readonly kpi: 24;
51
52
  readonly h1: 26;
53
+ readonly display: 30;
52
54
  };
53
55
  readonly radiusCard: "var(--vx-radius-card)";
54
56
  readonly radiusCtrl: "var(--vx-radius-ctrl)";
@@ -234,13 +236,13 @@ export type BuildPaletteOpts = {
234
236
  */
235
237
  mediaFallback?: boolean;
236
238
  /**
237
- * How much of the SPACING set to emit. Default: `'all'` (every one of the 104 `--vx-space-*`
239
+ * How much of the SPACING set to emit. Default: `'all'` (every one of the 108 `--vx-space-*`
238
240
  * declarations the framework's own components read).
239
241
  *
240
242
  * `'core'` keeps the 9 generic anchors — the stack rhythm, the two control heights, the row
241
- * insets — and drops the 95 named for a specific basalt component
243
+ * insets — and drops the 99 named for a specific basalt component
242
244
  * (`--vx-space-agent-transcript-inset`, `--vx-space-toc-sub-indent`, …), taking the emitted set
243
- * from 197 variables to 102. Nothing outside basalt's own React components reads those, so a
245
+ * from 204 variables to 105. Nothing outside basalt's own React components reads those, so a
244
246
  * framework-free consumer is carrying them for nothing.
245
247
  *
246
248
  * This is a SPACING filter only: color, radius, shadow, type and status variables are identical
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tokens/index.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,8 @@ import { deriveRadius } from "./palette.js";
14
14
  import { deriveSpacing } from "./palette.js";
15
15
  const alpha = (token, a) => `color-mix(in srgb, ${token} ${Math.round(a * 100)}%, transparent)`;
16
16
  const TEXT = {
17
+ nano: 10,
18
+ // engraved/graphic label INSIDE a drawn object (a plate face, a dial, a chip) — never UI copy or prose
17
19
  micro: 11,
18
20
  // mono uppercase micro-label (table th, Menu.Label, sidebar/section headers, axis ticks)
19
21
  xs: 12.5,
@@ -30,8 +32,10 @@ const TEXT = {
30
32
  // article-density Prose h2 (docs/CONTENT-SPEC.md §5)
31
33
  kpi: 24,
32
34
  // the StatCard hero numeral (density pass: 31 → 24, tighter/less shouty)
33
- h1: 26
35
+ h1: 26,
34
36
  // article-density Prose h1 (docs/CONTENT-SPEC.md §5)
37
+ display: 30
38
+ // a numeral read at arm's length (a keypad readout, a timer, a kiosk figure) — not a heading
35
39
  };
36
40
  const VX = {
37
41
  // Non-color sizing constants
@@ -358,6 +362,8 @@ function spaceDecls(space) {
358
362
  decl("space-app-header-mobile-actions-height", `${space.step.appHeaderMobileActionsHeight}px`),
359
363
  decl("space-mobile-nav-tab-gap", `${space.step.mobileNavTabGap}px`),
360
364
  decl("space-mobile-nav-icon-size", `${space.step.mobileNavIconSize}px`),
365
+ decl("space-mobile-nav-tab-inset-y", `${space.step.mobileNavTabInsetY}px`),
366
+ decl("space-mobile-nav-tab-inset-x", `${space.step.mobileNavTabInsetX}px`),
361
367
  decl("space-mobile-nav-row-height", `${space.step.mobileNavRowHeight}px`),
362
368
  decl("space-agent-rail-inset-x", `${space.step.agentRailInsetX}px`),
363
369
  decl("space-agent-part-gap-top", `${space.step.agentPartGapTop}px`),