basalt-ui 1.32.0 → 1.33.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 (145) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/MIGRATING.md +228 -20
  3. package/agent/rules/basalt-mantine.md +2 -2
  4. package/agent/rules/basalt-state.md +2 -2
  5. package/agent/rules/basalt-tokens.md +1 -1
  6. package/configs/oxlint-plugin.js +160 -89
  7. package/configs/oxlint-plugin.test.ts +273 -10
  8. package/configs/oxlint.json +2 -2
  9. package/dist/agent/coalesce.d.ts.map +1 -1
  10. package/dist/agent/coalesce.js +1 -2
  11. package/dist/agent/merge.d.ts.map +1 -1
  12. package/dist/agent/merge.js +1 -2
  13. package/dist/agent-chat/relative-time.d.ts +9 -0
  14. package/dist/agent-chat/relative-time.d.ts.map +1 -1
  15. package/dist/agent-chat/relative-time.js +1 -2
  16. package/dist/agent-chat/thread-message.d.ts.map +1 -1
  17. package/dist/agent-chat/thread-message.js +1 -2
  18. package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
  19. package/dist/charts/kinds/BandStrip.js +3 -3
  20. package/dist/charts/kinds/Bars.d.ts.map +1 -1
  21. package/dist/charts/kinds/Bars.js +1 -2
  22. package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
  23. package/dist/charts/kinds/StackedArea.js +1 -2
  24. package/dist/charts/primitives/legend-disclosure.d.ts.map +1 -1
  25. package/dist/cli/audit-allows.d.ts +1 -1
  26. package/dist/cli/audit-allows.d.ts.map +1 -1
  27. package/dist/cli/audit-allows.js +4 -4
  28. package/dist/cli/check-theme.d.ts.map +1 -1
  29. package/dist/cli/check-theme.js +1 -2
  30. package/dist/cli/config.d.ts +197 -0
  31. package/dist/cli/config.d.ts.map +1 -0
  32. package/dist/cli/config.js +20 -0
  33. package/dist/cli/doctor.js +1 -1
  34. package/dist/cli/guard-hook.d.ts.map +1 -1
  35. package/dist/cli/guard-hook.js +2 -8
  36. package/dist/cli/index.d.ts +2 -196
  37. package/dist/cli/index.d.ts.map +1 -1
  38. package/dist/cli/index.js +1 -18
  39. package/dist/commands/define-commands.d.ts.map +1 -1
  40. package/dist/commands/define-commands.js +2 -2
  41. package/dist/commands/define-overlays.d.ts.map +1 -1
  42. package/dist/commands/define-overlays.js +1 -2
  43. package/dist/common/index.d.ts +0 -1
  44. package/dist/common/index.d.ts.map +1 -1
  45. package/dist/common/index.js +0 -2
  46. package/dist/common/validate.d.ts +2 -2
  47. package/dist/common/validate.d.ts.map +1 -1
  48. package/dist/common/validate.js +2 -3
  49. package/dist/content/article-card.d.ts.map +1 -1
  50. package/dist/content/article-card.js +4 -1
  51. package/dist/controls/enum-filter.d.ts.map +1 -1
  52. package/dist/controls/enum-filter.js +3 -13
  53. package/dist/controls/filter-pill.d.ts +8 -0
  54. package/dist/controls/filter-pill.d.ts.map +1 -1
  55. package/dist/controls/filter-pill.js +15 -0
  56. package/dist/controls/multi-select-filter.d.ts.map +1 -1
  57. package/dist/controls/multi-select-filter.js +3 -13
  58. package/dist/controls/number-filter.d.ts +3 -0
  59. package/dist/controls/number-filter.d.ts.map +1 -1
  60. package/dist/controls/number-filter.js +12 -4
  61. package/dist/controls/range-filter.d.ts.map +1 -1
  62. package/dist/controls/range-filter.js +1 -2
  63. package/dist/data/data-table.d.ts +9 -2
  64. package/dist/data/data-table.d.ts.map +1 -1
  65. package/dist/data/data-table.js +2 -3
  66. package/dist/forms/form-layout.d.ts +6 -1
  67. package/dist/forms/form-layout.d.ts.map +1 -1
  68. package/dist/forms/form-layout.module.css +3 -0
  69. package/dist/guard/index.d.ts +18 -4
  70. package/dist/guard/index.d.ts.map +1 -1
  71. package/dist/guard/index.js +67 -31
  72. package/dist/guard/types.d.ts +3 -3
  73. package/dist/guard/types.d.ts.map +1 -1
  74. package/dist/guard/vx-names.d.ts +3 -0
  75. package/dist/guard/vx-names.d.ts.map +1 -0
  76. package/dist/guard/vx-names.js +257 -0
  77. package/dist/notifications/mount-guard.d.ts.map +1 -1
  78. package/dist/notifications/mount-guard.js +1 -2
  79. package/dist/provider/index.d.ts.map +1 -1
  80. package/dist/provider/index.js +2 -3
  81. package/dist/provider/lab-theme.d.ts +5 -4
  82. package/dist/provider/lab-theme.d.ts.map +1 -1
  83. package/dist/provider/lab-theme.js +1 -3
  84. package/dist/router-tanstack/search-store.d.ts +18 -0
  85. package/dist/router-tanstack/search-store.d.ts.map +1 -1
  86. package/dist/router-tanstack/search-store.js +33 -1
  87. package/dist/shell/mobile-nav-model.d.ts.map +1 -1
  88. package/dist/shell/mobile-nav-model.js +3 -4
  89. package/dist/shell/page-bar.d.ts +24 -0
  90. package/dist/shell/page-bar.d.ts.map +1 -1
  91. package/dist/shell/page-bar.js +1 -2
  92. package/dist/surfaces.d.ts +1 -1
  93. package/dist/surfaces.d.ts.map +1 -1
  94. package/dist/surfaces.js +2 -0
  95. package/dist/tokens/index.d.ts +2 -0
  96. package/dist/tokens/index.d.ts.map +1 -1
  97. package/dist/tokens/index.js +10 -0
  98. package/dist/tokens/size-classes.d.ts +13 -0
  99. package/dist/tokens/size-classes.d.ts.map +1 -1
  100. package/dist/tokens/size-classes.js +8 -0
  101. package/llms.txt +2 -2
  102. package/package.json +1 -1
  103. package/src/agent/coalesce.ts +1 -2
  104. package/src/agent/merge.ts +1 -2
  105. package/src/agent-chat/relative-time.ts +1 -2
  106. package/src/agent-chat/thread-message.tsx +2 -3
  107. package/src/charts/kinds/BandStrip.tsx +7 -3
  108. package/src/charts/kinds/Bars.tsx +1 -2
  109. package/src/charts/kinds/StackedArea.tsx +4 -2
  110. package/src/charts/primitives/legend-disclosure.tsx +1 -0
  111. package/src/cli/audit-allows.ts +10 -9
  112. package/src/cli/check-theme.ts +1 -2
  113. package/src/cli/config.ts +209 -0
  114. package/src/cli/doctor.ts +2 -2
  115. package/src/cli/guard-hook.ts +2 -8
  116. package/src/cli/index.ts +2 -206
  117. package/src/commands/define-commands.ts +2 -2
  118. package/src/commands/define-overlays.ts +1 -2
  119. package/src/common/index.ts +0 -1
  120. package/src/common/validate.ts +4 -5
  121. package/src/content/article-card.tsx +1 -0
  122. package/src/controls/enum-filter.tsx +3 -13
  123. package/src/controls/filter-pill.tsx +20 -0
  124. package/src/controls/multi-select-filter.tsx +3 -13
  125. package/src/controls/number-filter.tsx +24 -3
  126. package/src/controls/range-filter.tsx +1 -2
  127. package/src/data/data-table.tsx +11 -5
  128. package/src/forms/form-layout.module.css +3 -0
  129. package/src/forms/form-layout.tsx +6 -1
  130. package/src/guard/index.ts +151 -62
  131. package/src/guard/types.ts +3 -2
  132. package/src/guard/vx-names.ts +257 -0
  133. package/src/notifications/mount-guard.ts +1 -2
  134. package/src/provider/index.tsx +2 -3
  135. package/src/provider/lab-theme.ts +28 -21
  136. package/src/router-tanstack/search-store.ts +73 -1
  137. package/src/shell/mobile-nav-model.ts +3 -5
  138. package/src/shell/page-bar.tsx +25 -4
  139. package/src/surfaces.ts +2 -0
  140. package/src/tokens/index.ts +10 -0
  141. package/src/tokens/size-classes.ts +14 -0
  142. package/dist/common/is-dev.d.ts +0 -3
  143. package/dist/common/is-dev.d.ts.map +0 -1
  144. package/dist/common/is-dev.js +0 -6
  145. package/src/common/is-dev.ts +0 -4
@@ -37,6 +37,16 @@ function assertNoLazyUrlFallback(key, fields) {
37
37
  );
38
38
  }
39
39
  }
40
+ function assertResetsNotOwned(input) {
41
+ const { key, resets, paramOwners } = input;
42
+ for (const param of resets) {
43
+ const owner = paramOwners.get(param);
44
+ if (owner === void 0) continue;
45
+ throw new Error(
46
+ `basalt-ui: createSearchStore('${key}'): \`resets\` names \`${param}\`, which this store's field '${owner}' owns. \`resets\` is for sibling params the store does not own (a \`page\`); a field of the store is reset through \`useReset()\` or its own \`clear()\`.`
47
+ );
48
+ }
49
+ }
40
50
  function isMemoryLane(entry) {
41
51
  return !entry.codec.lane.url && !entry.codec.lane.persist;
42
52
  }
@@ -55,6 +65,15 @@ function buildSearchStore(o) {
55
65
  for (const entry of core.urlEntries) {
56
66
  for (const param of entry.codec.params) paramOwners.set(param, entry.name);
57
67
  }
68
+ const resets = o.resets ?? [];
69
+ assertResetsNotOwned({ key: o.key, resets, paramOwners });
70
+ const resetPatch = Object.fromEntries(
71
+ resets.map((param) => [param, void 0])
72
+ );
73
+ const resetsFor = (entry, prev, next) => {
74
+ const current = core.resolve(entry, prev, core.readRecord());
75
+ return entry.codec.equals(next, current) ? void 0 : resetPatch;
76
+ };
58
77
  const persistedNames = new Set(
59
78
  core.entries.filter((entry) => entry.codec.lane.persist).map((entry) => entry.name)
60
79
  );
@@ -118,8 +137,10 @@ function buildSearchStore(o) {
118
137
  if (!validated) return;
119
138
  navigate({
120
139
  to: ".",
140
+ // Gated like the setter: clearing a field already at its fallback keeps the page.
121
141
  search: (prev) => ({
122
142
  ...prev,
143
+ ...resetsFor(entry, prev, entry.codec.fallback),
123
144
  ...entry.codec.toSearch(entry.codec.fallback)
124
145
  }),
125
146
  replace: true,
@@ -143,8 +164,11 @@ function buildSearchStore(o) {
143
164
  // `patch` FIRST, the field's own params last: a patch is for keys the store does not
144
165
  // own (clearing a sibling `detailDate` with `undefined`), so it must never be able to
145
166
  // overwrite the value this very call is setting.
167
+ // `resets` only when the value moves: a no-op write (a debounced box settling back on
168
+ // what it held) must not throw the reader off the page they are on.
146
169
  search: (prev) => ({
147
170
  ...prev,
171
+ ...resetsFor(entry, prev, next),
148
172
  ...opts?.patch,
149
173
  ...entry.codec.toSearch(next)
150
174
  }),
@@ -224,7 +248,15 @@ function buildSearchStore(o) {
224
248
  }
225
249
  navigate({
226
250
  to: ".",
227
- search: (prev) => ({ ...prev, ...patch }),
251
+ // `resets` only when some field actually moves — the same gate as the setter and
252
+ // `clear()`. A `Reset all` with everything already at its fallback must keep the page:
253
+ // this navigate REPLACES, so a page dropped here could not be got back with Back.
254
+ search: (prev) => {
255
+ const moved = validatedEntries.some(
256
+ (entry) => resetsFor(entry, prev, entry.codec.fallback) !== void 0
257
+ );
258
+ return { ...prev, ...moved ? resetPatch : void 0, ...patch };
259
+ },
228
260
  replace: true,
229
261
  // Same reason as a single field's write above — a `Reset all` pressed from the mobile
230
262
  // sheet must not also scroll the page it was pressed on.
@@ -1 +1 @@
1
- {"version":3,"file":"mobile-nav-model.d.ts","sourceRoot":"","sources":["../../src/shell/mobile-nav-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EACV,eAAe,EAEf,cAAc,EAGd,YAAY,EAEZ,cAAc,EACf,MAAM,aAAa,CAAA;AAGpB,mGAAmG;AACnG,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAA;AAEzC,iGAAiG;AACjG,eAAO,MAAM,eAAe,WAAW,CAAA;AAEvC,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS,CAAA;IACpC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,GAAG,MAAM,CAQjF;AA8VD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,cAAc,EAAE,EAC1B,IAAI,CAAC,EAAE,uBAAuB,GAC7B,cAAc,CA8EhB"}
1
+ {"version":3,"file":"mobile-nav-model.d.ts","sourceRoot":"","sources":["../../src/shell/mobile-nav-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EACV,eAAe,EAEf,cAAc,EAGd,YAAY,EAEZ,cAAc,EACf,MAAM,aAAa,CAAA;AAGpB,mGAAmG;AACnG,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAA;AAEzC,iGAAiG;AACjG,eAAO,MAAM,eAAe,WAAW,CAAA;AAEvC,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS,CAAA;IACpC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,GAAG,MAAM,CAQjF;AA4VD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,cAAc,EAAE,EAC1B,IAAI,CAAC,EAAE,uBAAuB,GAC7B,cAAc,CA8EhB"}
@@ -9,7 +9,6 @@ function blockRowCount(blocks) {
9
9
  return block.kind !== "list" || block.items.length > 0;
10
10
  }).length;
11
11
  }
12
- const DEV = process.env["NODE_ENV"] !== "production";
13
12
  function placementOf(item, sectionHidden) {
14
13
  if (sectionHidden) return "hidden";
15
14
  const mobile = item.mobile;
@@ -149,7 +148,7 @@ function buildCandidates(sections, config, maxTabs, menuMax) {
149
148
  }
150
149
  const tabbable = (item) => {
151
150
  if (!item.disabled) return true;
152
- if (DEV) {
151
+ if (process.env.NODE_ENV !== "production") {
153
152
  console.warn(
154
153
  `[basalt] MobileNav: "${item.key}" asks for a bar slot but is disabled \u2014 a disabled destination never becomes a tab. It still renders, disabled, in the More surface.`
155
154
  );
@@ -169,7 +168,7 @@ function buildCandidates(sections, config, maxTabs, menuMax) {
169
168
  candidates2.push(sectionCandidate(section, menuMax));
170
169
  continue;
171
170
  }
172
- if (DEV) {
171
+ if (process.env.NODE_ENV !== "production") {
173
172
  console.warn(
174
173
  `[basalt] MobileNav: mobileNav.tabs names "${id}", which is neither a destination key nor a visible section label \u2014 ignoring it.`
175
174
  );
@@ -232,7 +231,7 @@ function projectMobileNav(sections, opts) {
232
231
  const limit = needsMore ? maxTabs - 1 : maxTabs;
233
232
  const kept = candidates.slice(0, limit);
234
233
  const dropped = candidates.slice(limit);
235
- if (DEV && dropped.length > 0) {
234
+ if (process.env.NODE_ENV !== "production" && dropped.length > 0) {
236
235
  console.warn(
237
236
  `[basalt] MobileNav: ${candidates.length} slot candidates for ${limit} available slot(s) \u2014 the last ${dropped.length} moved into the More surface: ${dropped.map((candidate) => `"${candidate.key}"`).join(", ")}. Raise mobileNav.maxTabs or drop a mobile: 'tab'.`
238
237
  );
@@ -100,5 +100,29 @@ export type PageBarProps = BasaltProps & SlotStylesProps<PageBarSlot> & {
100
100
  /** One `ViewTabs`. */
101
101
  tabs?: ReactNode;
102
102
  };
103
+ /**
104
+ * The page's control bar — row 1 (title/icon, `actions`, `sync`) and row 2 (`tabs`, `filters`,
105
+ * `filtersEnd`). Inside `BasaltShell` both rows portal into shell chrome; with no shell it renders
106
+ * ONE sticky bar in flow, `title` leading, and needs no `PageBarProvider`.
107
+ *
108
+ * @example
109
+ * // Shell-less (linewatch-shaped): the store is local, the bar is the page's first child.
110
+ * const filters = createLocalStore({ key: 'outages', fields: { q: field.string({ max: 60 }) } })
111
+ *
112
+ * function OutagesPage() {
113
+ * const [q] = filters.field.q.use()
114
+ * return (
115
+ * <>
116
+ * <PageBar
117
+ * title="Outages"
118
+ * actions={{ primary: { key: 'export', label: 'Export', onClick: exportCsv } }}
119
+ * filters={<FilterSet><SearchFilter field={filters.field.q} placeholder="Find a line" /></FilterSet>}
120
+ * classNames={{ root: classes.bleed }} // your gutter bleed — see `PageBarSlot`
121
+ * />
122
+ * <OutageTable query={q} />
123
+ * </>
124
+ * )
125
+ * }
126
+ */
103
127
  export declare function PageBar({ title, icon, actions, sync, filters, filtersEnd, tabs, className, style, classNames, }: PageBarProps): ReactNode;
104
128
  //# sourceMappingURL=page-bar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"page-bar.d.ts","sourceRoot":"","sources":["../../src/shell/page-bar.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAWnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAK9D,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,wBAAwB,CAAA;AAKxD;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,gGAAgG;IAChG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CACzB,CAAA;AAuDD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,aAAa,EACb,QAAQ,GACT,EAAE;IACD,aAAa,EAAE,SAAS,YAAY,EAAE,CAAA;IACtC,QAAQ,EAAE,SAAS,CAAA;CACpB,GAAG,SAAS,CAsDZ;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAGlE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAGtE;AAED,yFAAyF;AACzF,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,IAAI;IACnC,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,IAAI,CAAA;IAC7C,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;CAC3B,CAaA;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;AAElD,MAAM,MAAM,YAAY,GAAG,WAAW,GACpC,eAAe,CAAC,WAAW,CAAC,GAAG;IAC7B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B,qGAAqG;IACrG,IAAI,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;IACrC,6CAA6C;IAC7C,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,sDAAsD;IACtD,UAAU,CAAC,EAAE,SAAS,EAAE,CAAA;IACxB,sBAAsB;IACtB,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB,CAAA;AAmEH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,OAAO,EACP,UAAU,EACV,IAAI,EACJ,SAAS,EACT,KAAK,EACL,UAAU,GACX,EAAE,YAAY,GAAG,SAAS,CAkM1B"}
1
+ {"version":3,"file":"page-bar.d.ts","sourceRoot":"","sources":["../../src/shell/page-bar.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAWnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAK9D,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,wBAAwB,CAAA;AAExD;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,gGAAgG;IAChG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CACzB,CAAA;AAuDD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC9B,aAAa,EACb,QAAQ,GACT,EAAE;IACD,aAAa,EAAE,SAAS,YAAY,EAAE,CAAA;IACtC,QAAQ,EAAE,SAAS,CAAA;CACpB,GAAG,SAAS,CAsDZ;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAGlE;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAGtE;AAED,yFAAyF;AACzF,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,IAAI;IACnC,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,IAAI,CAAA;IAC7C,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;CAC3B,CAaA;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;AAElD,MAAM,MAAM,YAAY,GAAG,WAAW,GACpC,eAAe,CAAC,WAAW,CAAC,GAAG;IAC7B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B,qGAAqG;IACrG,IAAI,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;IACrC,6CAA6C;IAC7C,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,sDAAsD;IACtD,UAAU,CAAC,EAAE,SAAS,EAAE,CAAA;IACxB,sBAAsB;IACtB,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB,CAAA;AAmEH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,OAAO,EACP,UAAU,EACV,IAAI,EACJ,SAAS,EACT,KAAK,EACL,UAAU,GACX,EAAE,YAAY,GAAG,SAAS,CAkM1B"}
@@ -16,7 +16,6 @@ import { useIsomorphicLayoutEffect } from "../common/isomorphic-layout-effect.js
16
16
  import classes from "./page-bar.module.css";
17
17
  import asideClasses from "./page-aside.module.css";
18
18
  const PAGE_BAR_HEIGHT_VAR = "--basalt-page-bar-h";
19
- const DEV = process.env["NODE_ENV"] !== "production";
20
19
  const NO_SLOTS = {
21
20
  target: null,
22
21
  setTarget: () => {
@@ -101,7 +100,7 @@ function useAsidePanelSlot() {
101
100
  setSettled(true);
102
101
  }, []);
103
102
  useEffect(() => {
104
- if (!DEV || !settled || !inShell || panelHost) return;
103
+ if (process.env.NODE_ENV === "production" || !settled || !inShell || panelHost) return;
105
104
  console.warn(
106
105
  "[basalt] PageAside: this page's PageBar renders no row 2 (no `tabs`, no `filters`, no `filtersEnd`), so below `sm` there is no pill to open the aside \u2014 it renders in flow at the bottom of the page instead. Give the bar a row 2, or expect the in-flow form on a phone."
107
106
  );
@@ -203,7 +203,7 @@ export declare const SURFACES: {
203
203
  readonly layer: "headless";
204
204
  readonly rule: "tokens";
205
205
  readonly skill: readonly ["basalt-design", "basalt-charts"];
206
- readonly guardKinds: readonly ["raw-hex", "raw-color-fn", "off-identity-accent", "off-system-surface-var", "raw-font-family", "raw-radius", "raw-surface", "inline-font-size", "css-raw-surface", "surface-shadow-override", "theme-allow-unscoped"];
206
+ readonly guardKinds: readonly ["raw-hex", "raw-color-fn", "off-identity-accent", "off-system-surface-var", "raw-font-family", "raw-radius", "raw-surface", "inline-font-size", "css-raw-surface", "surface-shadow-override", "unknown-vx-token", "theme-allow-unscoped"];
207
207
  readonly pluginRules: readonly ["no-raw-font-size", "raw-size-literal", "token-layer-boundary"];
208
208
  readonly description: "VX token refs, buildPaletteCss, defineSeries, seriesTokens, groupTokens, alpha (Mantine-free)";
209
209
  readonly globs: {
@@ -1 +1 @@
1
- {"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../src/surfaces.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAI9C;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAA;AAE3F;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,+oBA+BtB,CAAA;AAEV,+FAA+F;AAC/F,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE/D;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,eAAe,GAAG,eAAe,CAAA;AAExE;;;;GAIG;AACH,MAAM,MAAM,KAAK,GAAG,iBAAiB,GAAG,UAAU,GAAG,YAAY,GAAG,cAAc,GAAG,eAAe,CAAA;AAEpG;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;IAChC,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,oFAAoF;IACpF,QAAQ,CAAC,WAAW,CAAC,EAAE,IAAI,CAAA;IAC3B,2FAA2F;IAC3F,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAA;CACzB,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;CACrC,CAAA;AAID,KAAK,WAAW,GAAG;IACjB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,gBAAgB,EAAE,SAAS,eAAe,EAAE,CAAA;IACrD,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;IAChD;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;QACnC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;KACjC,CAAA;IACD;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC3C,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG;IACvC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,4FAA4F;IAC5F,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAA;IACzC;;;;;;;;;OASG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,YAAY,EAAE,CAAA;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAC1C,CAAA;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG;IACtC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAA;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,KAAK,CAAA;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAA;CAC9B,CAAA;AAED,kEAAkE;AAClE,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,WAAW,CAAA;AA8BpD;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAod2B,CAAA;AAIhD;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,qBAMiB,CAAA;AAIxC;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,sBAMiB,CAAA;AAIzC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,6BAA6B,EAAE,WAAW,CAAC,MAAM,CAAqC,CAAA;AAEnG;;;;;;;;;;;;GAYG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACzC,OAAO,CAET"}
1
+ {"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../src/surfaces.ts"],"names":[],"mappings":"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"}
package/dist/surfaces.js CHANGED
@@ -160,6 +160,8 @@ const SURFACES = {
160
160
  "inline-font-size",
161
161
  "css-raw-surface",
162
162
  "surface-shadow-override",
163
+ // A `var(--vx-*)` naming a token basalt no longer (or never) emits.
164
+ "unknown-vx-token",
163
165
  // Not a token kind — the kind that judges the ANNOTATION rather than the code. It lands here
164
166
  // because `agent/rules/basalt-tokens.md` is where the `theme-allow` grammar is documented
165
167
  // (said once, on purpose), so this is the header that must name its enforcement.
@@ -16,6 +16,8 @@ export { deriveRadius } from './palette.js';
16
16
  export type { RadiusValues } from './palette.js';
17
17
  export { deriveSpacing } from './palette.js';
18
18
  export type { SpaceValues } from './palette.js';
19
+ export { CONTAINER_CLASSES, CONTAINER_GRID_BREAKPOINTS, resolveContainerClass, SIZE_CLASSES, } from './size-classes.js';
20
+ export type { ContainerClass } from './size-classes.js';
19
21
  /** A per-theme color pair: a hue keeps its identity but shifts shade across schemes. */
20
22
  export type ColorPair = {
21
23
  light: string;
@@ -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,12 @@ import { BP, p } from "./palette.js";
14
14
  import { DEFAULT_DERIVE_CONFIG, deriveTokens, resolveDeriveConfig } from "./derive.js";
15
15
  import { deriveRadius } from "./palette.js";
16
16
  import { deriveSpacing } from "./palette.js";
17
+ import {
18
+ CONTAINER_CLASSES,
19
+ CONTAINER_GRID_BREAKPOINTS,
20
+ resolveContainerClass,
21
+ SIZE_CLASSES as SIZE_CLASSES2
22
+ } from "./size-classes.js";
17
23
  const alpha = (token, a) => `color-mix(in srgb, ${token} ${Math.round(a * 100)}%, transparent)`;
18
24
  const TEXT = {
19
25
  nano: 10,
@@ -671,7 +677,10 @@ ${mobileLadderBlock(space)}`;
671
677
  export {
672
678
  BP,
673
679
  BREAKPOINTS,
680
+ CONTAINER_CLASSES,
681
+ CONTAINER_GRID_BREAKPOINTS,
674
682
  DEFAULT_DERIVE_CONFIG,
683
+ SIZE_CLASSES2 as SIZE_CLASSES,
675
684
  VX,
676
685
  alpha,
677
686
  buildDensityCss,
@@ -686,6 +695,7 @@ export {
686
695
  groupTokens,
687
696
  p,
688
697
  pxRem,
698
+ resolveContainerClass,
689
699
  resolveDeriveConfig,
690
700
  seriesTokens
691
701
  };
@@ -19,6 +19,19 @@ export declare const CONTAINER_CLASSES: {
19
19
  readonly wide: 800;
20
20
  };
21
21
  export type ContainerClass = keyof typeof CONTAINER_CLASSES;
22
+ /**
23
+ * `CONTAINER_CLASSES` as the five-key map `<Grid type="container" breakpoints={…}>` takes (Mantine
24
+ * types it `Record<MantineSize, string>`), so `Grid.Col` keys resolve onto the grid's own width:
25
+ * `xs` opens compact, `sm` regular, `md`/`lg`/`xl` wide. `basalt/raw-breakpoint` trusts this import
26
+ * by name (from `basalt-ui/tokens`) — any other imported map is unreadable to it and flagged.
27
+ */
28
+ export declare const CONTAINER_GRID_BREAKPOINTS: {
29
+ readonly xs: "240px";
30
+ readonly sm: "480px";
31
+ readonly md: "800px";
32
+ readonly lg: "800px";
33
+ readonly xl: "800px";
34
+ };
22
35
  /** The class a MEASURED inline size falls in (`px` is a min-width boundary, so 240 is `compact`). */
23
36
  export declare function resolveContainerClass(px: number): ContainerClass;
24
37
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"size-classes.d.ts","sourceRoot":"","sources":["../../src/tokens/size-classes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,yFAAyF;AACzF,eAAO,MAAM,YAAY;;;;CAAuD,CAAA;AAEhF,2FAA2F;AAC3F,eAAO,MAAM,iBAAiB;;;;;CAA+D,CAAA;AAE7F,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,iBAAiB,CAAA;AAE3D,qGAAqG;AACrG,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,CAKhE;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;;;;CAMzB,CAAA;AAEV,mEAAmE;AACnE,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEvC;AAED,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD"}
1
+ {"version":3,"file":"size-classes.d.ts","sourceRoot":"","sources":["../../src/tokens/size-classes.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,yFAAyF;AACzF,eAAO,MAAM,YAAY;;;;CAAuD,CAAA;AAEhF,2FAA2F;AAC3F,eAAO,MAAM,iBAAiB;;;;;CAA+D,CAAA;AAE7F,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,iBAAiB,CAAA;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B;;;;;;CAM7B,CAAA;AAEV,qGAAqG;AACrG,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,CAKhE;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;;;;CAMzB,CAAA;AAEV,mEAAmE;AACnE,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEvC;AAED,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD"}
@@ -1,5 +1,12 @@
1
1
  const SIZE_CLASSES = { compact: 0, medium: 840, expanded: 1200 };
2
2
  const CONTAINER_CLASSES = { micro: 0, compact: 240, regular: 480, wide: 800 };
3
+ const CONTAINER_GRID_BREAKPOINTS = {
4
+ xs: `${CONTAINER_CLASSES.compact}px`,
5
+ sm: `${CONTAINER_CLASSES.regular}px`,
6
+ md: `${CONTAINER_CLASSES.wide}px`,
7
+ lg: `${CONTAINER_CLASSES.wide}px`,
8
+ xl: `${CONTAINER_CLASSES.wide}px`
9
+ };
3
10
  function resolveContainerClass(px) {
4
11
  if (px >= CONTAINER_CLASSES.wide) return "wide";
5
12
  if (px >= CONTAINER_CLASSES.regular) return "regular";
@@ -21,6 +28,7 @@ function sizeClassMaxEm(minPx) {
21
28
  }
22
29
  export {
23
30
  CONTAINER_CLASSES,
31
+ CONTAINER_GRID_BREAKPOINTS,
24
32
  SIZE_CLASSES,
25
33
  SIZE_CLASS_BREAKPOINTS,
26
34
  resolveContainerClass,
package/llms.txt CHANGED
@@ -1,4 +1,4 @@
1
- # basalt-ui v1.32.0
1
+ # basalt-ui v1.33.0
2
2
  # Opinionated framework for Mantine-based React apps — theme, app shell, visx charts, toolchain presets
3
3
  #
4
4
  # basalt-ui is an opinionated framework for Mantine-based React apps.
@@ -19,7 +19,7 @@
19
19
  # ./tokens.css subpath. Guide: docs/FRAMEWORK-FREE.md in the repo.
20
20
 
21
21
  Package: basalt-ui
22
- Version: 1.32.0
22
+ Version: 1.33.0
23
23
 
24
24
  ## basalt-ui
25
25
  Import: import { ... } from 'basalt-ui'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "basalt-ui",
3
- "version": "1.32.0",
3
+ "version": "1.33.0",
4
4
  "description": "Opinionated framework for Mantine-based React apps — theme, app shell, visx charts, toolchain presets",
5
5
  "keywords": [
6
6
  "charts",
@@ -38,7 +38,6 @@
38
38
  * <PartList parts={coalesceParts(parts)} />
39
39
  */
40
40
  import type { AgentPart, ReasoningPart, TextPart, ToolCallPart } from './parts'
41
- import { isDev } from '../common/is-dev'
42
41
 
43
42
  type TextLike = TextPart | ReasoningPart
44
43
 
@@ -170,7 +169,7 @@ function mergeToolPart(existing: ToolCallPart, next: ToolCallPart): ToolCallPart
170
169
  // and make every field read below a compile error, so the assertion is what makes the
171
170
  // runtime value usable. It asserts nothing tsc has not already proved on the line above.
172
171
  const fallback = unhandled as ToolCallPart
173
- if (isDev()) {
172
+ if (process.env.NODE_ENV !== 'production') {
174
173
  console.warn(
175
174
  `[basalt] coalesceParts: unrecognized tool state ${JSON.stringify(fallback.state)} — kept, merged best-effort`,
176
175
  )
@@ -29,7 +29,6 @@
29
29
  * // parts === [{ id: 'p1', type: 'text', text: 'Hello' }]
30
30
  */
31
31
  import type { ReasoningPart, TextPart } from './parts'
32
- import { isDev } from '../common/is-dev'
33
32
 
34
33
  type TextLike = TextPart | ReasoningPart
35
34
 
@@ -79,7 +78,7 @@ function clampOffset(offset: number, length: number): number {
79
78
  // A non-finite offset would make every slice() return '' and blank the part outright — it is
80
79
  // out of range like any other, and appending is the safe reading of "position unknown".
81
80
  const clamped = Number.isFinite(offset) ? Math.min(Math.max(offset, 0), length) : length
82
- if (clamped !== offset && isDev()) {
81
+ if (clamped !== offset && process.env.NODE_ENV !== 'production') {
83
82
  console.warn(
84
83
  `[basalt] mergePart: text offset ${offset} out of range [0, ${length}] — clamped to ${clamped}`,
85
84
  )
@@ -7,7 +7,6 @@
7
7
  *
8
8
  * Internal to `agent-chat/` — not part of the public barrel.
9
9
  */
10
- import { isDev } from '../common/is-dev'
11
10
 
12
11
  const RELATIVE_TIME_FORMAT = new Intl.RelativeTimeFormat('en', { numeric: 'auto' })
13
12
 
@@ -41,7 +40,7 @@ const RELATIVE_TIME_UNITS: readonly {
41
40
  */
42
41
  export function formatRelativeTime(timestamp: number): string {
43
42
  if (!Number.isFinite(timestamp)) {
44
- if (isDev()) {
43
+ if (process.env.NODE_ENV !== 'production') {
45
44
  console.warn(
46
45
  `[basalt] formatRelativeTime: non-finite timestamp ${String(timestamp)} — rendering empty string`,
47
46
  )
@@ -60,7 +60,6 @@ import { formatRelativeTime } from './relative-time'
60
60
  import { ToolChip } from './tool-chip'
61
61
  import { resolveVirtualize } from './virtualize'
62
62
  import type { VirtualizeOptions, VirtualizeProps } from './virtualize'
63
- import { isDev } from '../common/is-dev'
64
63
 
65
64
  /** The mono, uppercase, letter-spaced micro-label idiom (docs/DESIGN-SPEC.md §3) — shared by the
66
65
  * transcript's role labels and the reasoning/tool-call headers below. */
@@ -189,11 +188,11 @@ function UnknownPartChip({ part }: { part: ForeignPart }): JSX.Element {
189
188
  )
190
189
  }
191
190
 
192
- /** Consulted only when `ThreadTranscript` gets no `fallbackRenderer` prop. `isDev()` reads
191
+ /** Consulted only when `ThreadTranscript` gets no `fallbackRenderer` prop. The gate reads
193
192
  * `process.env.NODE_ENV` (not `import.meta.env` — basalt-ui bans it) INSIDE the render so tests can
194
193
  * flip it. */
195
194
  const DEFAULT_FALLBACK_RENDERER: PartRenderer<ForeignPart> = ({ part }) =>
196
- isDev() ? <UnknownPartChip part={part} /> : null
195
+ process.env.NODE_ENV !== 'production' ? <UnknownPartChip part={part} /> : null
197
196
 
198
197
  // ── Part resolution — the three-step order that is the whole design ───────────
199
198
  //
@@ -17,7 +17,6 @@ import type { ChartState } from '../primitives/ChartPending'
17
17
  import type { ChartLegendConfig, SeriesStyle } from '../series'
18
18
  import { fmtAxisDate } from '../utils/format'
19
19
  import { BandAxisOverlay, BandTooltip, clampFraction } from './band-chrome'
20
- import { isDev } from '../../common/is-dev'
21
20
 
22
21
  /**
23
22
  * A state a strip can draw. Extends `SeriesStyle` rather than `ChartSeries` because a band has no
@@ -266,7 +265,8 @@ function BandStripPlot<T>(props: BandStripPlotProps<T>) {
266
265
  const style = styleByKey.get(span.state)
267
266
  const x = i * step
268
267
  if (style === undefined) {
269
- if (isDev()) throw unknownStateError('BandSpan.state', span.state, styleByKey.keys())
268
+ if (process.env.NODE_ENV !== 'production')
269
+ throw unknownStateError('BandSpan.state', span.state, styleByKey.keys())
270
270
  out.push(
271
271
  <rect
272
272
  key={getX(d)}
@@ -298,7 +298,11 @@ function BandStripPlot<T>(props: BandStripPlotProps<T>) {
298
298
  const hatchWidth = bandWidth - measuredWidth
299
299
  const markerKey = span.marker?.state ?? span.state
300
300
  const markerColor = styleByKey.get(markerKey)?.color
301
- if (span.marker !== undefined && markerColor === undefined && isDev()) {
301
+ if (
302
+ span.marker !== undefined &&
303
+ markerColor === undefined &&
304
+ process.env.NODE_ENV !== 'production'
305
+ ) {
302
306
  throw unknownStateError('BandSpan.marker.state', markerKey, styleByKey.keys())
303
307
  }
304
308
  const inset = span.marker?.inset ?? DEFAULT_MARKER_INSET
@@ -13,7 +13,6 @@ import type { ChartState } from '../primitives/ChartPending'
13
13
  import { curveFor, LINE_OVERLAY_STROKE_WIDTH } from '../series'
14
14
  import type { ChartLegendConfig, ChartSeries, SeriesCurve } from '../series'
15
15
  import { padAutoLower } from '../utils/domain'
16
- import { isDev } from '../../common/is-dev'
17
16
 
18
17
  /**
19
18
  * `T = unknown` is load-bearing, not a shortcut: it keeps a consumer's existing
@@ -196,7 +195,7 @@ function BarsInner<T>(props: BarsProps<T>) {
196
195
  // Stacking sums bar heights via `posOffset`/`negOffset` in yScale units directly — a log axis
197
196
  // has no additive zero, so a stacked total is meaningless on it (`docs/CHARTS-SPEC.md`'s null-gap
198
197
  // + log contract). `grouped` bars only ever read one bar's own scaled value, so they're unaffected.
199
- if (isDev() && barLayout === 'stacked' && y?.scale === 'log') {
198
+ if (process.env.NODE_ENV !== 'production' && barLayout === 'stacked' && y?.scale === 'log') {
200
199
  throw new Error(
201
200
  'Bars: stacked bars cannot use a log axis (y.scale: "log") — the stack sums bar heights, ' +
202
201
  "and a log axis has no additive zero to sum from. Use barLayout: 'grouped' instead.",
@@ -9,7 +9,6 @@ import type { ResponsiveChartHeight } from '../primitives/ChartFrame'
9
9
  import type { ChartState } from '../primitives/ChartPending'
10
10
  import { curveFor } from '../series'
11
11
  import type { ChartLegendConfig, ChartSeries } from '../series'
12
- import { isDev } from '../../common/is-dev'
13
12
 
14
13
  export type StackedAreaProps<T> = BasaltProps & {
15
14
  data: T[]
@@ -113,7 +112,10 @@ function StackedAreaInner<T>(props: StackedAreaProps<T>) {
113
112
 
114
113
  // The stack sums band heights via `getValue` totals directly — a log axis has no additive zero
115
114
  // to sum from (`docs/CHARTS-SPEC.md`'s null-gap + log contract, mirrored from `Bars`' own guard).
116
- if (isDev() && (y as { scale?: string } | undefined)?.scale === 'log') {
115
+ if (
116
+ process.env.NODE_ENV !== 'production' &&
117
+ (y as { scale?: string } | undefined)?.scale === 'log'
118
+ ) {
117
119
  throw new Error(
118
120
  'StackedArea: cannot use a log axis (y.scale: "log") — the stack sums band heights, ' +
119
121
  'and a log axis has no additive zero to sum from.',
@@ -43,6 +43,7 @@ function disclosurePlacement(chip: DOMRect, coarse: boolean): CSSProperties {
43
43
  }
44
44
  }
45
45
  const below = window.innerHeight - chip.bottom
46
+ // theme-allow raw-breakpoint — clamps a fixed panel inside the viewport; a position, not a breakpoint
46
47
  const left = Math.max(8, Math.min(chip.left, window.innerWidth - 248))
47
48
  const base = { left, right: 'auto', minWidth: 200, maxWidth: 'calc(100vw - 16px)' }
48
49
  return below >= 200 || below >= chip.top
@@ -13,8 +13,8 @@ import {
13
13
  unmatchedExemptPatterns,
14
14
  } from '../guard'
15
15
  import type { Finding, GuardConfig, GuardKind } from '../guard'
16
- import type { BasaltConfig, ExemptRuleEntry } from './index'
17
- import { exemptRulePaths, exemptRuleReason, resolveRoots } from './index'
16
+ import { exemptRulePaths, exemptRuleReason, resolveRoots } from './config'
17
+ import type { BasaltConfig, ExemptRuleEntry } from './config'
18
18
 
19
19
  // ── check-theme --audit-allows — every waiver, and whether it still suppresses anything ─────────
20
20
 
@@ -30,7 +30,7 @@ type PluginProbe = {
30
30
  readonly rel: string
31
31
  /** 1-based line of the annotation, as {@link findAllowAnnotations} reports it. */
32
32
  readonly line: number
33
- readonly ids: readonly string[]
33
+ readonly reach: string
34
34
  readonly site: string
35
35
  readonly suffix: string
36
36
  }
@@ -231,14 +231,15 @@ export function auditAllows(
231
231
  waiverLines.push(`${label} suppresses ${[...new Set(revealed)].join(', ')}${suffix}`)
232
232
  continue
233
233
  }
234
- // Nothing in check-theme's reach moved. If the annotation names a PLUGIN rule, the oxlint
235
- // half decides it — a placeholder holds the slot so the report stays in file/line order.
236
- if (site.pluginRules.length > 0 && site.guardKinds.length === 0) {
234
+ // Nothing the guard reaches moved: oxlint decides it (a placeholder keeps the report order).
235
+ if (site.oxlintRules.length > 0) {
237
236
  pluginProbes.push({
238
237
  slot: waiverLines.length,
239
238
  rel,
240
239
  line: site.line,
241
- ids: site.pluginRules,
240
+ reach: site.bare
241
+ ? 'a bare annotation, waiving every oxlint plugin rule on its line'
242
+ : `scoped to ${site.oxlintRules.join(', ')}, which oxlint judges`,
242
243
  site: label,
243
244
  suffix,
244
245
  })
@@ -266,8 +267,8 @@ export function auditAllows(
266
267
  if (revealed === undefined) {
267
268
  outOfReach++
268
269
  waiverLines[probe.slot] =
269
- `${probe.site} scoped to ${probe.ids.join(', ')} — an oxlint plugin rule, and oxlint ` +
270
- `could not be run here, so this audit cannot judge it${probe.suffix}`
270
+ `${probe.site} ${probe.reach} — and oxlint could not be run here, so this audit ` +
271
+ `cannot judge it${probe.suffix}`
271
272
  continue
272
273
  }
273
274
  if (revealed.length > 0) {
@@ -15,15 +15,14 @@ import {
15
15
  } from '../guard'
16
16
  import type { Finding, GuardConfig } from '../guard'
17
17
  import { auditAllows } from './audit-allows'
18
+ import { DEFAULT_ROOTS, resolveRoots } from './config'
18
19
  import {
19
20
  conflictingProfileFlags,
20
21
  declaredProfile,
21
- DEFAULT_ROOTS,
22
22
  hasBasaltKey,
23
23
  readBasaltConfig,
24
24
  resolveExemptRules,
25
25
  resolveProjectDir,
26
- resolveRoots,
27
26
  scannableFiles,
28
27
  SERIES_MODULE_HINT_RE,
29
28
  waiverHintFor,