basalt-ui 1.30.2 → 1.31.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 (334) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +31 -0
  3. package/MIGRATING.md +172 -12
  4. package/agent/rules/basalt-controls.md +19 -19
  5. package/agent/rules/basalt-mantine.md +1 -1
  6. package/configs/oxlint-plugin.js +254 -4
  7. package/configs/oxlint-plugin.test.ts +145 -2
  8. package/configs/oxlint.json +2 -1
  9. package/dist/agent-chat/composer.d.ts.map +1 -1
  10. package/dist/agent-chat/composer.js +41 -43
  11. package/dist/agent-chat/thread-workspace.d.ts +2 -2
  12. package/dist/agent-chat/thread-workspace.d.ts.map +1 -1
  13. package/dist/agent-chat/thread-workspace.js +3 -4
  14. package/dist/agent-chat/use-keyboard-inset.d.ts +2 -0
  15. package/dist/agent-chat/use-keyboard-inset.d.ts.map +1 -0
  16. package/dist/agent-chat/use-keyboard-inset.js +34 -0
  17. package/dist/charts/cursor/touch-pin.d.ts +45 -0
  18. package/dist/charts/cursor/touch-pin.d.ts.map +1 -0
  19. package/dist/charts/cursor/touch-pin.js +79 -0
  20. package/dist/charts/hooks/use-discrete-cursor.d.ts +66 -0
  21. package/dist/charts/hooks/use-discrete-cursor.d.ts.map +1 -0
  22. package/dist/charts/hooks/use-discrete-cursor.js +198 -0
  23. package/dist/charts/hooks/use-hysteresis.d.ts +18 -0
  24. package/dist/charts/hooks/use-hysteresis.d.ts.map +1 -0
  25. package/dist/charts/hooks/use-hysteresis.js +12 -0
  26. package/dist/charts/hooks/useBandPlot.d.ts +7 -0
  27. package/dist/charts/hooks/useBandPlot.d.ts.map +1 -1
  28. package/dist/charts/hooks/useBandPlot.js +62 -18
  29. package/dist/charts/hooks/useChartCursor.d.ts +40 -11
  30. package/dist/charts/hooks/useChartCursor.d.ts.map +1 -1
  31. package/dist/charts/hooks/useChartCursor.js +102 -11
  32. package/dist/charts/index.d.ts +0 -1
  33. package/dist/charts/index.d.ts.map +1 -1
  34. package/dist/charts/index.js +0 -10
  35. package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
  36. package/dist/charts/kinds/BandStrip.js +54 -41
  37. package/dist/charts/kinds/Donut.d.ts +9 -3
  38. package/dist/charts/kinds/Donut.d.ts.map +1 -1
  39. package/dist/charts/kinds/Donut.js +110 -48
  40. package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
  41. package/dist/charts/kinds/DualPanel.js +145 -131
  42. package/dist/charts/kinds/Heatmap.d.ts +7 -0
  43. package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
  44. package/dist/charts/kinds/Heatmap.js +37 -16
  45. package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
  46. package/dist/charts/kinds/MirroredBars.js +83 -68
  47. package/dist/charts/kinds/donut-layout.d.ts +47 -0
  48. package/dist/charts/kinds/donut-layout.d.ts.map +1 -0
  49. package/dist/charts/kinds/donut-layout.js +52 -0
  50. package/dist/charts/layout/auto-margin.d.ts +7 -2
  51. package/dist/charts/layout/auto-margin.d.ts.map +1 -1
  52. package/dist/charts/layout/auto-margin.js +12 -3
  53. package/dist/charts/layout/end-labels.d.ts +64 -0
  54. package/dist/charts/layout/end-labels.d.ts.map +1 -0
  55. package/dist/charts/layout/end-labels.js +76 -0
  56. package/dist/charts/primitives/Axes.d.ts +32 -4
  57. package/dist/charts/primitives/Axes.d.ts.map +1 -1
  58. package/dist/charts/primitives/Axes.js +62 -16
  59. package/dist/charts/primitives/CartesianChart.d.ts +7 -6
  60. package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
  61. package/dist/charts/primitives/CartesianChart.js +271 -125
  62. package/dist/charts/primitives/ChartCard.d.ts +0 -14
  63. package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
  64. package/dist/charts/primitives/ChartCard.js +74 -21
  65. package/dist/charts/primitives/ChartFrame.d.ts +28 -22
  66. package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
  67. package/dist/charts/primitives/ChartFrame.js +133 -34
  68. package/dist/charts/primitives/ChartLegend.d.ts +19 -15
  69. package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
  70. package/dist/charts/primitives/ChartLegend.js +212 -71
  71. package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
  72. package/dist/charts/primitives/ChartTooltip.js +4 -3
  73. package/dist/charts/primitives/Crosshair.js +2 -2
  74. package/dist/charts/primitives/HoverOverlay.d.ts +6 -1
  75. package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
  76. package/dist/charts/primitives/HoverOverlay.js +37 -26
  77. package/dist/charts/primitives/HoverOverlay.module.css +13 -0
  78. package/dist/charts/primitives/HoverOverlay.module.css.d.ts +8 -0
  79. package/dist/charts/primitives/chart-card-context.d.ts +29 -0
  80. package/dist/charts/primitives/chart-card-context.d.ts.map +1 -0
  81. package/dist/charts/primitives/chart-card-context.js +13 -0
  82. package/dist/charts/primitives/chart-frame-layout.d.ts +93 -113
  83. package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -1
  84. package/dist/charts/primitives/chart-frame-layout.js +76 -29
  85. package/dist/charts/primitives/chart-layout.d.ts +112 -0
  86. package/dist/charts/primitives/chart-layout.d.ts.map +1 -0
  87. package/dist/charts/primitives/chart-layout.js +175 -0
  88. package/dist/charts/primitives/chart-tier.d.ts +13 -11
  89. package/dist/charts/primitives/chart-tier.d.ts.map +1 -1
  90. package/dist/charts/primitives/chart-tier.js +42 -13
  91. package/dist/charts/series.d.ts +4 -1
  92. package/dist/charts/series.d.ts.map +1 -1
  93. package/dist/charts/utils/ticks.d.ts +27 -8
  94. package/dist/charts/utils/ticks.d.ts.map +1 -1
  95. package/dist/charts/utils/ticks.js +35 -11
  96. package/dist/common/errors.d.ts +11 -1
  97. package/dist/common/errors.d.ts.map +1 -1
  98. package/dist/common/errors.js +16 -2
  99. package/dist/common/hit-floor.d.ts +10 -0
  100. package/dist/common/hit-floor.d.ts.map +1 -0
  101. package/dist/common/hit-floor.js +6 -0
  102. package/dist/{shell → common}/isomorphic-layout-effect.d.ts +4 -3
  103. package/dist/common/isomorphic-layout-effect.d.ts.map +1 -0
  104. package/dist/common/use-measured-widths.d.ts +37 -0
  105. package/dist/common/use-measured-widths.d.ts.map +1 -0
  106. package/dist/common/use-measured-widths.js +51 -0
  107. package/dist/common/use-media-query.d.ts +6 -0
  108. package/dist/common/use-media-query.d.ts.map +1 -0
  109. package/dist/common/use-media-query.js +40 -0
  110. package/dist/common/validate.d.ts +9 -0
  111. package/dist/common/validate.d.ts.map +1 -1
  112. package/dist/common/validate.js +9 -4
  113. package/dist/content/article-layout.d.ts +4 -2
  114. package/dist/content/article-layout.d.ts.map +1 -1
  115. package/dist/content/article-layout.js +43 -3
  116. package/dist/content/article-layout.module.css +45 -4
  117. package/dist/content/article-layout.module.css.d.ts +3 -0
  118. package/dist/content/code-block.d.ts.map +1 -1
  119. package/dist/content/code-block.js +40 -2
  120. package/dist/content/code-block.module.css +32 -2
  121. package/dist/content/prose.module.css +13 -8
  122. package/dist/controls/actions.d.ts +29 -6
  123. package/dist/controls/actions.d.ts.map +1 -1
  124. package/dist/controls/actions.js +158 -27
  125. package/dist/controls/actions.module.css +14 -1
  126. package/dist/controls/actions.module.css.d.ts +1 -0
  127. package/dist/controls/controls.module.css +8 -31
  128. package/dist/controls/enum-filter.js +2 -2
  129. package/dist/controls/filter-context.d.ts +10 -0
  130. package/dist/controls/filter-context.d.ts.map +1 -1
  131. package/dist/controls/filter-context.js +2 -0
  132. package/dist/controls/filter-pill.d.ts.map +1 -1
  133. package/dist/controls/filter-pill.js +1 -0
  134. package/dist/controls/index.d.ts +1 -1
  135. package/dist/controls/index.d.ts.map +1 -1
  136. package/dist/controls/index.js +0 -2
  137. package/dist/controls/multi-select-filter.js +2 -2
  138. package/dist/controls/sync-button.module.css +1 -1
  139. package/dist/dashboard/section.d.ts.map +1 -1
  140. package/dist/dashboard/section.js +1 -0
  141. package/dist/dashboard/section.module.css +1 -26
  142. package/dist/dashboard/stat-card.d.ts +1 -1
  143. package/dist/dashboard/stat-card.d.ts.map +1 -1
  144. package/dist/dashboard/stat-card.js +4 -1
  145. package/dist/dashboard/stat-card.module.css +6 -9
  146. package/dist/dashboard/stat-group.module.css +16 -4
  147. package/dist/dashboard/widget-grid.d.ts.map +1 -1
  148. package/dist/dashboard/widget-header.d.ts +14 -4
  149. package/dist/dashboard/widget-header.d.ts.map +1 -1
  150. package/dist/dashboard/widget-header.js +23 -6
  151. package/dist/dashboard/widget-header.module.css +145 -133
  152. package/dist/dashboard/widget-header.module.css.d.ts +2 -0
  153. package/dist/data/data-table.d.ts +23 -0
  154. package/dist/data/data-table.d.ts.map +1 -1
  155. package/dist/data/data-table.js +339 -141
  156. package/dist/data/data-table.module.css +94 -0
  157. package/dist/data/data-table.module.css.d.ts +11 -0
  158. package/dist/data/virtual-list.d.ts.map +1 -1
  159. package/dist/data/virtual-list.js +10 -0
  160. package/dist/forms/form-layout.d.ts.map +1 -1
  161. package/dist/forms/form-layout.js +3 -3
  162. package/dist/forms/form-layout.module.css +30 -5
  163. package/dist/forms/form-layout.module.css.d.ts +1 -0
  164. package/dist/guard/index.d.ts +8 -2
  165. package/dist/guard/index.d.ts.map +1 -1
  166. package/dist/guard/index.js +67 -2
  167. package/dist/guard/types.d.ts +3 -3
  168. package/dist/guard/types.d.ts.map +1 -1
  169. package/dist/index.d.ts +1 -1
  170. package/dist/index.d.ts.map +1 -1
  171. package/dist/index.js +3 -1
  172. package/dist/provider/index.d.ts +20 -1
  173. package/dist/provider/index.d.ts.map +1 -1
  174. package/dist/provider/index.js +22 -2
  175. package/dist/shell/app-brand.d.ts.map +1 -1
  176. package/dist/shell/app-brand.js +1 -0
  177. package/dist/shell/app-brand.module.css +2 -2
  178. package/dist/shell/app-header.module.css +18 -8
  179. package/dist/shell/app-main.module.css +54 -3
  180. package/dist/shell/app-main.module.css.d.ts +1 -0
  181. package/dist/shell/app-mobile-nav.module.css +16 -4
  182. package/dist/shell/app-sidebar.module.css +4 -6
  183. package/dist/shell/index.d.ts +12 -0
  184. package/dist/shell/index.d.ts.map +1 -1
  185. package/dist/shell/index.js +57 -16
  186. package/dist/shell/mobile-nav-model.d.ts +1 -1
  187. package/dist/shell/page-aside.d.ts +22 -3
  188. package/dist/shell/page-aside.d.ts.map +1 -1
  189. package/dist/shell/page-aside.js +27 -13
  190. package/dist/shell/page-bar.d.ts.map +1 -1
  191. package/dist/shell/page-bar.js +10 -5
  192. package/dist/shell/page-bar.module.css +10 -34
  193. package/dist/shell/use-breakpoint.d.ts +3 -4
  194. package/dist/shell/use-breakpoint.d.ts.map +1 -1
  195. package/dist/shell/use-breakpoint.js +3 -25
  196. package/dist/shell/use-size-class.d.ts +6 -0
  197. package/dist/shell/use-size-class.d.ts.map +1 -0
  198. package/dist/shell/use-size-class.js +19 -0
  199. package/dist/state/persisted-or-local.d.ts +4 -1
  200. package/dist/state/persisted-or-local.d.ts.map +1 -1
  201. package/dist/state/persisted-or-local.js +4 -3
  202. package/dist/state/persisted.d.ts +10 -0
  203. package/dist/state/persisted.d.ts.map +1 -1
  204. package/dist/state/persisted.js +44 -14
  205. package/dist/styles.css +41 -0
  206. package/dist/surfaces.d.ts +4 -4
  207. package/dist/surfaces.d.ts.map +1 -1
  208. package/dist/surfaces.js +11 -3
  209. package/dist/theme/controls.module.css +7 -0
  210. package/dist/theme/ctl-theme.d.ts +1 -0
  211. package/dist/theme/ctl-theme.d.ts.map +1 -1
  212. package/dist/theme/ctl-theme.js +12 -4
  213. package/dist/theme/floating.module.css +36 -0
  214. package/dist/theme/floating.module.css.d.ts +3 -0
  215. package/dist/theme/index.d.ts +2 -2
  216. package/dist/theme/index.d.ts.map +1 -1
  217. package/dist/theme/index.js +34 -5
  218. package/dist/theme/nav-link.module.css +7 -0
  219. package/dist/tokens/index.d.ts +7 -16
  220. package/dist/tokens/index.d.ts.map +1 -1
  221. package/dist/tokens/index.js +23 -28
  222. package/dist/tokens/palette.d.ts +5 -27
  223. package/dist/tokens/palette.d.ts.map +1 -1
  224. package/dist/tokens/palette.js +8 -30
  225. package/dist/tokens/size-classes.d.ts +40 -0
  226. package/dist/tokens/size-classes.d.ts.map +1 -0
  227. package/dist/tokens/size-classes.js +29 -0
  228. package/dist/tokens.css +8 -4
  229. package/llms.txt +3 -3
  230. package/package.json +17 -17
  231. package/src/agent-chat/composer.tsx +74 -47
  232. package/src/agent-chat/thread-workspace.tsx +8 -11
  233. package/src/agent-chat/use-keyboard-inset.ts +68 -0
  234. package/src/charts/cursor/touch-pin.ts +138 -0
  235. package/src/charts/hooks/use-discrete-cursor.ts +335 -0
  236. package/src/charts/hooks/use-hysteresis.ts +26 -0
  237. package/src/charts/hooks/useBandPlot.ts +90 -27
  238. package/src/charts/hooks/useChartCursor.ts +211 -26
  239. package/src/charts/index.ts +0 -8
  240. package/src/charts/kinds/BandStrip.tsx +11 -1
  241. package/src/charts/kinds/Donut.tsx +153 -62
  242. package/src/charts/kinds/DualPanel.tsx +19 -4
  243. package/src/charts/kinds/Heatmap.tsx +61 -22
  244. package/src/charts/kinds/MirroredBars.tsx +15 -3
  245. package/src/charts/kinds/donut-layout.ts +82 -0
  246. package/src/charts/layout/auto-margin.ts +24 -5
  247. package/src/charts/layout/end-labels.ts +135 -0
  248. package/src/charts/primitives/Axes.tsx +112 -21
  249. package/src/charts/primitives/CartesianChart.tsx +282 -68
  250. package/src/charts/primitives/ChartCard.tsx +141 -48
  251. package/src/charts/primitives/ChartFrame.tsx +243 -60
  252. package/src/charts/primitives/ChartLegend.tsx +257 -73
  253. package/src/charts/primitives/ChartTooltip.tsx +8 -3
  254. package/src/charts/primitives/Crosshair.tsx +2 -2
  255. package/src/charts/primitives/HoverOverlay.module.css +13 -0
  256. package/src/charts/primitives/HoverOverlay.module.css.d.ts +8 -0
  257. package/src/charts/primitives/HoverOverlay.tsx +15 -4
  258. package/src/charts/primitives/chart-card-context.ts +37 -0
  259. package/src/charts/primitives/chart-frame-layout.ts +214 -177
  260. package/src/charts/primitives/chart-layout.ts +318 -0
  261. package/src/charts/primitives/chart-tier.tsx +66 -21
  262. package/src/charts/series.ts +4 -1
  263. package/src/charts/utils/ticks.ts +95 -19
  264. package/src/common/errors.ts +25 -1
  265. package/src/common/hit-floor.ts +9 -0
  266. package/src/{shell → common}/isomorphic-layout-effect.ts +4 -3
  267. package/src/common/use-measured-widths.ts +88 -0
  268. package/src/common/use-media-query.ts +56 -0
  269. package/src/common/validate.ts +17 -4
  270. package/src/content/article-layout.module.css +45 -4
  271. package/src/content/article-layout.module.css.d.ts +3 -0
  272. package/src/content/article-layout.tsx +60 -5
  273. package/src/content/code-block.module.css +32 -2
  274. package/src/content/code-block.tsx +47 -3
  275. package/src/content/prose.module.css +13 -8
  276. package/src/controls/actions.module.css +14 -1
  277. package/src/controls/actions.module.css.d.ts +1 -0
  278. package/src/controls/actions.tsx +223 -75
  279. package/src/controls/controls.module.css +8 -31
  280. package/src/controls/enum-filter.tsx +2 -2
  281. package/src/controls/filter-context.tsx +11 -0
  282. package/src/controls/filter-pill.tsx +1 -0
  283. package/src/controls/index.ts +0 -1
  284. package/src/controls/multi-select-filter.tsx +2 -2
  285. package/src/controls/sync-button.module.css +1 -1
  286. package/src/dashboard/section.module.css +1 -26
  287. package/src/dashboard/section.tsx +1 -0
  288. package/src/dashboard/stat-card.module.css +6 -9
  289. package/src/dashboard/stat-card.tsx +6 -3
  290. package/src/dashboard/stat-group.module.css +16 -4
  291. package/src/dashboard/widget-grid.tsx +7 -6
  292. package/src/dashboard/widget-header.module.css +145 -133
  293. package/src/dashboard/widget-header.module.css.d.ts +2 -0
  294. package/src/dashboard/widget-header.tsx +45 -11
  295. package/src/data/data-table.module.css +94 -0
  296. package/src/data/data-table.module.css.d.ts +11 -0
  297. package/src/data/data-table.tsx +503 -164
  298. package/src/data/virtual-list.tsx +31 -0
  299. package/src/forms/form-layout.module.css +30 -5
  300. package/src/forms/form-layout.module.css.d.ts +1 -0
  301. package/src/forms/form-layout.tsx +12 -10
  302. package/src/guard/index.ts +183 -3
  303. package/src/guard/types.ts +3 -2
  304. package/src/index.ts +2 -0
  305. package/src/provider/index.tsx +53 -1
  306. package/src/shell/app-brand.module.css +2 -2
  307. package/src/shell/app-brand.tsx +1 -0
  308. package/src/shell/app-header.module.css +18 -8
  309. package/src/shell/app-main.module.css +54 -3
  310. package/src/shell/app-main.module.css.d.ts +1 -0
  311. package/src/shell/app-mobile-nav.module.css +16 -4
  312. package/src/shell/app-sidebar.module.css +4 -6
  313. package/src/shell/index.tsx +200 -129
  314. package/src/shell/mobile-nav-model.ts +1 -1
  315. package/src/shell/page-aside.tsx +70 -21
  316. package/src/shell/page-bar.module.css +10 -34
  317. package/src/shell/page-bar.tsx +10 -5
  318. package/src/shell/use-breakpoint.ts +9 -45
  319. package/src/shell/use-size-class.ts +31 -0
  320. package/src/state/persisted-or-local.ts +10 -4
  321. package/src/state/persisted.ts +76 -17
  322. package/src/styles.css +41 -0
  323. package/src/surfaces.ts +9 -1
  324. package/src/theme/controls.module.css +7 -0
  325. package/src/theme/ctl-theme.tsx +15 -3
  326. package/src/theme/floating.module.css +36 -0
  327. package/src/theme/floating.module.css.d.ts +3 -0
  328. package/src/theme/index.ts +46 -8
  329. package/src/theme/nav-link.module.css +7 -0
  330. package/src/tokens/index.ts +20 -30
  331. package/src/tokens/palette.ts +6 -28
  332. package/src/tokens/size-classes.ts +46 -0
  333. package/dist/shell/isomorphic-layout-effect.d.ts.map +0 -1
  334. /package/dist/{shell → common}/isomorphic-layout-effect.js +0 -0
@@ -0,0 +1,175 @@
1
+ import { resolveContainerClass } from "../../tokens/size-classes.js";
2
+ import { VX } from "../../tokens/index.js";
3
+ import { measureText } from "../utils/measure-text.js";
4
+ import {
5
+ entriesWithinChipRows,
6
+ entriesWithinDotRows,
7
+ entriesWithinRows,
8
+ orderEntries
9
+ } from "./chart-frame-layout.js";
10
+ const HEIGHT_RATIO = { micro: 0.5, compact: 0.62, regular: 0.5, wide: 0.4 };
11
+ const HEIGHT_MIN = 160;
12
+ const HEIGHT_MAX = 420;
13
+ const COARSE_VIEWPORT_SHARE = 0.45;
14
+ const UNMEASURED_WIDTH = { micro: 200, compact: 360, regular: 640, wide: 960 };
15
+ const TICK_SPACING = 44;
16
+ const COMPACT_LABEL_CHARS = 4;
17
+ const X_LABEL_GAP = 8;
18
+ const LEGEND_ROWS = { header: 1, band: 2 };
19
+ const CONTAINER_CLASS_OF_SIZE_CLASS = {
20
+ compact: "compact",
21
+ medium: "regular",
22
+ expanded: "wide"
23
+ };
24
+ function containerClassFromSizeClass(sizeClass) {
25
+ return CONTAINER_CLASS_OF_SIZE_CLASS[sizeClass];
26
+ }
27
+ const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
28
+ function resolveHeight(input, containerClass) {
29
+ const override = input.override?.height;
30
+ const width = input.frameW > 0 ? input.frameW : UNMEASURED_WIDTH[containerClass];
31
+ const derived = override ?? clamp(Math.round(width * HEIGHT_RATIO[containerClass]), HEIGHT_MIN, HEIGHT_MAX);
32
+ if (!input.coarse || input.viewportH <= 0) return derived;
33
+ return Math.min(derived, Math.round(input.viewportH * COARSE_VIEWPORT_SHARE));
34
+ }
35
+ function rollUp(total, fitted) {
36
+ const visible = total - fitted < 2 ? total : fitted;
37
+ return { visible, overflow: total - visible };
38
+ }
39
+ function resolveLegend(input, containerClass) {
40
+ const total = input.legendItems.length;
41
+ if (containerClass === "micro" || total === 0) return { mode: "none" };
42
+ const where = input.slotW > 0 ? "header" : "band";
43
+ const width = where === "header" ? input.slotW : input.frameW;
44
+ if (width <= 0) return { mode: "chips", where, visible: total, overflow: 0 };
45
+ const { entries: ordered, dividerAfter } = orderEntries(input.legendItems, input.groups === true);
46
+ const chipFit = entriesWithinRows(ordered, width, LEGEND_ROWS[where]);
47
+ const allChipsFit = chipFit >= total;
48
+ const wantsDots = where === "header" && !allChipsFit && (input.cardShort === true || containerClass === "compact");
49
+ if (!wantsDots) {
50
+ const fitted = allChipsFit ? chipFit : entriesWithinChipRows(ordered, width, LEGEND_ROWS[where]);
51
+ const { visible: visible2, overflow: overflow2 } = rollUp(total, fitted);
52
+ return { mode: "chips", where, visible: visible2, overflow: overflow2 };
53
+ }
54
+ const dotFit = entriesWithinDotRows(ordered, width, LEGEND_ROWS[where], dividerAfter);
55
+ const { visible, overflow } = rollUp(total, dotFit);
56
+ return { mode: "dots", where, visible, overflow };
57
+ }
58
+ function isTightClass(containerClass) {
59
+ return containerClass === "compact" || containerClass === "micro";
60
+ }
61
+ function resolveYPlacement(containerClass, opts = {}) {
62
+ const { hasLeftAxis = true, marginOverrideLeft } = opts;
63
+ if (!isTightClass(containerClass) || !hasLeftAxis || marginOverrideLeft !== void 0)
64
+ return "outside";
65
+ return containerClass === "micro" ? "none" : "inside";
66
+ }
67
+ const INSIDE_Y_FLOOR = 4;
68
+ function resolveMarginFloor(yPlacement, tierMargin) {
69
+ return yPlacement === "outside" ? tierMargin : { ...tierMargin, left: INSIDE_Y_FLOOR };
70
+ }
71
+ const COMPACT_UNITS = [
72
+ [1e12, "T"],
73
+ [1e9, "B"],
74
+ [1e6, "M"],
75
+ [1e3, "k"]
76
+ ];
77
+ const roundTenth = (value) => Math.round(value * 10) / 10;
78
+ function compactNumber(value) {
79
+ const abs = Math.abs(value);
80
+ if (!Number.isFinite(value) || abs < 1e3) return null;
81
+ let index = COMPACT_UNITS.findIndex(([unit]) => abs >= unit);
82
+ let scaled = roundTenth(abs / COMPACT_UNITS[index][0]);
83
+ if (scaled >= 1e3 && index > 0) {
84
+ index -= 1;
85
+ scaled = roundTenth(abs / COMPACT_UNITS[index][0]);
86
+ }
87
+ return `${value < 0 ? "-" : ""}${scaled}${COMPACT_UNITS[index][1]}`;
88
+ }
89
+ function shouldCompactYLabels(labels) {
90
+ return labels.some((label) => label.length > COMPACT_LABEL_CHARS);
91
+ }
92
+ function yTickCount(plotHeight) {
93
+ if (plotHeight < VX.minPlotHeight) return 2;
94
+ return clamp(Math.round(plotHeight / TICK_SPACING), 2, 6);
95
+ }
96
+ function wrapLabel(label, maxPx, fontPx) {
97
+ const words = label.split(/\s+/).filter((word) => word !== "");
98
+ const lines = [];
99
+ let current = "";
100
+ for (const word of words) {
101
+ const candidate = current === "" ? word : `${current} ${word}`;
102
+ if (current !== "" && measureText(candidate, fontPx) > maxPx) {
103
+ lines.push(current);
104
+ current = word;
105
+ continue;
106
+ }
107
+ current = candidate;
108
+ }
109
+ if (current !== "") lines.push(current);
110
+ return lines.length > 0 ? lines : [label];
111
+ }
112
+ function planXLabels(input) {
113
+ const { labels, plotWidth, fontPx, categorical } = input;
114
+ const count = labels.length;
115
+ const widest = labels.reduce((max, label) => Math.max(max, measureText(label, fontPx)), 0);
116
+ const flatPx = widest + X_LABEL_GAP;
117
+ const fit = plotWidth > 0 && widest > 0 ? Math.floor(plotWidth / flatPx) : count;
118
+ const flat = {
119
+ wrap: false,
120
+ rotate: 0,
121
+ lines: 1,
122
+ labelPx: flatPx,
123
+ wrapPx: 0
124
+ };
125
+ if (!categorical || count <= fit || plotWidth <= 0) return flat;
126
+ const widestWord = labels.reduce(
127
+ (max, label) => Math.max(max, ...label.split(/\s+/).map((word) => measureText(word, fontPx))),
128
+ 0
129
+ );
130
+ const wrapPx = Math.min(widest, Math.max(widestWord, Math.floor(plotWidth / count) - X_LABEL_GAP));
131
+ const wrapped = labels.map((label) => wrapLabel(label, wrapPx, fontPx));
132
+ const lines = wrapped.reduce((max, parts) => Math.max(max, parts.length), 1);
133
+ if (lines === 1) {
134
+ return count > 2 * Math.max(fit, 1) ? { ...flat, rotate: 45 } : flat;
135
+ }
136
+ const wrappedWidest = wrapped.reduce(
137
+ (max, parts) => Math.max(max, ...parts.map((part) => measureText(part, fontPx))),
138
+ 0
139
+ );
140
+ const wrappedFit = Math.max(Math.floor(plotWidth / (wrappedWidest + X_LABEL_GAP)), 1);
141
+ if (wrappedFit >= count) {
142
+ return {
143
+ wrap: true,
144
+ rotate: 0,
145
+ lines,
146
+ labelPx: wrappedWidest + X_LABEL_GAP,
147
+ wrapPx
148
+ };
149
+ }
150
+ return count > 2 * wrappedFit ? { ...flat, rotate: 45 } : flat;
151
+ }
152
+ function resolveFrameClass(input) {
153
+ return input.frameW > 0 ? resolveContainerClass(input.frameW) : containerClassFromSizeClass(input.sizeClass);
154
+ }
155
+ function resolveChartLayout(input) {
156
+ const containerClass = resolveFrameClass(input);
157
+ return {
158
+ containerClass,
159
+ height: resolveHeight(input, containerClass),
160
+ legend: resolveLegend(input, containerClass)
161
+ };
162
+ }
163
+ export {
164
+ INSIDE_Y_FLOOR,
165
+ compactNumber,
166
+ isTightClass,
167
+ planXLabels,
168
+ resolveChartLayout,
169
+ resolveFrameClass,
170
+ resolveMarginFloor,
171
+ resolveYPlacement,
172
+ shouldCompactYLabels,
173
+ wrapLabel,
174
+ yTickCount
175
+ };
@@ -1,16 +1,18 @@
1
1
  import type { ReactNode } from 'react';
2
- import { chartTierMetrics, resolveChartTier } from './chart-frame-layout.js';
3
- import type { ChartTier, ChartTierMetrics } from './chart-frame-layout.js';
2
+ import type { ContainerClass } from '../../tokens/size-classes.js';
3
+ import type { ChartTierMetrics } from './chart-frame-layout.js';
4
4
  export type ChartTierProviderProps = {
5
- tier: ChartTier;
5
+ containerClass: ContainerClass;
6
6
  children: ReactNode;
7
7
  };
8
- /** Publishes a resolved tier to the subtree. Mounted once, by `ChartFrame`. */
9
- export declare function ChartTierProvider({ tier, children }: ChartTierProviderProps): ReactNode;
10
- /** The tier of the nearest measured `ChartFrame`, or `'desktop'` outside one. */
11
- export declare function useChartTier(): ChartTier;
12
- /** The resolved sizes for the ambient tier — the form every primitive actually wants. */
13
- export declare function useChartTierMetrics(): ChartTierMetrics;
14
- export { chartTierMetrics, resolveChartTier };
15
- export type { ChartTier, ChartTierMetrics };
8
+ /** Publishes a resolved container class to the subtree. Mounted once, by `ChartFrame`. */
9
+ export declare function ChartTierProvider({ containerClass, children }: ChartTierProviderProps): ReactNode;
10
+ /** The ambient container class (`'regular'` outside a `ChartFrame`). Internal. */
11
+ export declare function useChartContainerClass(): ContainerClass;
12
+ /** The resolved sizes for the ambient container class — what every internal primitive wants. */
13
+ export declare function useChartMetrics(): ChartTierMetrics;
14
+ /** Whether the primary pointer is coarse. Server snapshot `false`: hydration agrees, then updates. */
15
+ export declare function useCoarsePointer(): boolean;
16
+ /** Viewport height in px (`0` on the server). Only the coarse-pointer height clamp reads it. */
17
+ export declare function useViewportHeight(): number;
16
18
  //# sourceMappingURL=chart-tier.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-tier.d.ts","sourceRoot":"","sources":["../../../src/charts/primitives/chart-tier.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAYvE,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,SAAS,CAAA;IACf,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,sBAAsB,GAAG,SAAS,CAEvF;AAED,iFAAiF;AACjF,wBAAgB,YAAY,IAAI,SAAS,CAExC;AAED,yFAAyF;AACzF,wBAAgB,mBAAmB,IAAI,gBAAgB,CAEtD;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAA;AAC7C,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,CAAA"}
1
+ {"version":3,"file":"chart-tier.d.ts","sourceRoot":"","sources":["../../../src/charts/primitives/chart-tier.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAE/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAa5D,MAAM,MAAM,sBAAsB,GAAG;IACnC,cAAc,EAAE,cAAc,CAAA;IAC9B,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,sBAAsB,GAAG,SAAS,CAMjG;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,IAAI,cAAc,CAEvD;AAED,gGAAgG;AAChG,wBAAgB,eAAe,IAAI,gBAAgB,CAElD;AAID,sGAAsG;AACtG,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AA+BD,gGAAgG;AAChG,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
@@ -1,20 +1,49 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { createContext, useContext } from "react";
3
- import { chartTierMetrics, resolveChartTier } from "./chart-frame-layout.js";
4
- const ChartTierContext = createContext("desktop");
5
- function ChartTierProvider({ tier, children }) {
6
- return /* @__PURE__ */ jsx(ChartTierContext.Provider, { value: tier, children });
2
+ import { createContext, useContext, useSyncExternalStore } from "react";
3
+ import { useMediaQuery } from "../../common/use-media-query.js";
4
+ import { chartMetrics } from "./chart-frame-layout.js";
5
+ const ChartContainerClassContext = createContext("regular");
6
+ function ChartTierProvider({ containerClass, children }) {
7
+ return /* @__PURE__ */ jsx(ChartContainerClassContext.Provider, { value: containerClass, children });
7
8
  }
8
- function useChartTier() {
9
- return useContext(ChartTierContext);
9
+ function useChartContainerClass() {
10
+ return useContext(ChartContainerClassContext);
10
11
  }
11
- function useChartTierMetrics() {
12
- return chartTierMetrics(useContext(ChartTierContext));
12
+ function useChartMetrics() {
13
+ return chartMetrics(useChartContainerClass());
14
+ }
15
+ const subscribeNothing = () => () => {
16
+ };
17
+ function useCoarsePointer() {
18
+ return useMediaQuery("(pointer: coarse)", false);
19
+ }
20
+ const VIEWPORT_H_STEP = 50;
21
+ const viewportHListeners = /* @__PURE__ */ new Set();
22
+ let viewportHListenerAttached = false;
23
+ function ensureViewportHListener() {
24
+ if (viewportHListenerAttached || typeof window === "undefined") return;
25
+ viewportHListenerAttached = true;
26
+ window.addEventListener("resize", () => {
27
+ for (const listener of viewportHListeners) listener();
28
+ });
29
+ }
30
+ function subscribeViewportH(onChange) {
31
+ if (typeof window === "undefined") return subscribeNothing();
32
+ ensureViewportHListener();
33
+ viewportHListeners.add(onChange);
34
+ return () => viewportHListeners.delete(onChange);
35
+ }
36
+ function readViewportH() {
37
+ if (typeof window === "undefined") return 0;
38
+ return Math.round(window.innerHeight / VIEWPORT_H_STEP) * VIEWPORT_H_STEP;
39
+ }
40
+ function useViewportHeight() {
41
+ return useSyncExternalStore(subscribeViewportH, readViewportH, () => 0);
13
42
  }
14
43
  export {
15
44
  ChartTierProvider,
16
- chartTierMetrics,
17
- resolveChartTier,
18
- useChartTier,
19
- useChartTierMetrics
45
+ useChartContainerClass,
46
+ useChartMetrics,
47
+ useCoarsePointer,
48
+ useViewportHeight
20
49
  };
@@ -59,7 +59,10 @@ export type ChartLegendConfig = {
59
59
  placement?: LegendPlacement;
60
60
  /** Visually separate role: series | overlay | reference. */
61
61
  groups?: boolean;
62
- /** Wrap cap → "+N more" rollup at high cardinality. */
62
+ /**
63
+ * @deprecated Removed in 1.32.0 — the legend fits by measured width and folds overflow into an
64
+ * `All N` disclosure on its own. An explicit value still wins this release (entry count).
65
+ */
63
66
  maxRows?: number;
64
67
  /** Clicking an entry hides that series. Default: on whenever there is more than one entry. */
65
68
  toggle?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"series.d.ts","sourceRoot":"","sources":["../../src/charts/series.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"series.d.ts","sourceRoot":"","sources":["../../src/charts/series.ts"],"names":[],"mappings":"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"}
@@ -6,27 +6,46 @@ import type { ChartTier } from '../primitives/chart-frame-layout.js';
6
6
  * `useBandPlot` and `DualPanel` — the three call sites that used to reimplement this formula.
7
7
  *
8
8
  * `fontPx` defaults to `VX.axisFont`; a phone-tier chart passes its own smaller tick font
9
- * (`chartTierMetrics().axisFont`) so the spacing is derived from the size actually painted.
9
+ * (`chartMetrics().axisFont`) so the spacing is derived from the size actually painted.
10
10
  */
11
11
  export declare function xLabelPxFor(labels: string[], fontPx?: number): number;
12
+ /**
13
+ * The horizontal room one 45°-rotated x label takes: its projected box (`cos 45°` of the width plus
14
+ * one line box) plus the gap. A tilted label still competes with its neighbour for this much, so
15
+ * thinning by the bare `VX.minPxPerTick` floor let two of them touch as soon as the plot widened.
16
+ */
17
+ export declare function rotatedXLabelPx(labels: string[], fontPx?: number): number;
12
18
  /**
13
19
  * Pick evenly-spaced tick values that fit the available width.
14
20
  *
15
21
  * `labelPx` is the width one formatted label actually needs (measured, plus the gap it wants from
16
- * its neighbour) and overrides the `VX.minPxPerTick` floor whenever it is wider. Without it the
17
- * spacing came from that constant alone regardless of what was painted, so a `formatX` returning
18
- * `Mar 08 14:00` overlapped at every width — the one side of the chart that did not follow §1's
19
- * "measure what you paint" law. Omit it and nothing moves.
22
+ * its neighbour) and REPLACES the `VX.minPxPerTick` constant whenever it is supplied, in either
23
+ * direction — a wide label needs more room than the constant assumed (a `formatX` returning
24
+ * `Mar 08 14:00` used to overlap at every width, the one side of the chart that did not follow
25
+ * §1's "measure what you paint" law), and a narrow one (single-digit band labels) can pack in
26
+ * MORE ticks than the constant would allow, which the floor used to suppress (R2C-11). Omit it and
27
+ * the constant is what governs, same as before.
20
28
  *
21
29
  * The final key is still appended when the step misses the last index — a thinned axis would
22
30
  * otherwise paint no label at the right edge at all — but it no longer prints ON TOP of its
23
31
  * neighbour. An appended tick lands a PARTIAL step from the last one on the grid, so at any tick
24
32
  * count wide enough labels overlap there; measured at `/charts-stress` block (f1), `Mar 13 14:00`
25
33
  * and `Mar 14 14:00` printed over each other at 1440px. When that gap is narrower than one label,
26
- * the grid tick before it is dropped instead. Index 0 is never dropped: the left edge is the one
27
- * label a reader orients from.
34
+ * the grid tick before it is dropped instead.
35
+ *
36
+ * `anchorTerminals` (default false) mirrors the SAME flag `autoMargin`/`Axes.tsx` take: when the
37
+ * axis anchors index 0 and the last index at their TEXT edge rather than their centre
38
+ * (`terminalAnchor`), each reaches a FULL label's width toward its neighbour instead of half, so
39
+ * the plain per-tick pitch above (sized for two centred labels) isn't enough at either boundary —
40
+ * `Bars` with 30 daily "Jan DD HH:MM" keys overlapped there at phone width even though the interior
41
+ * pitch was fine (R2C-6). The SAME rule then applies, symmetrically, to the tick right after
42
+ * index 0. 1.5× is a deliberately generous (cheap, simple) stand-in for "one label plus half a
43
+ * label" rather than measuring the split precisely; it's skipped when `labelPx` is only the bare
44
+ * `VX.minPxPerTick` floor, which has no relationship to how wide a label actually is. Index 0
45
+ * always survives (never the one dropped here) and `last` is always (re-)added below, so dropping
46
+ * any OTHER index never breaks the "at least 2 ticks" floor.
28
47
  */
29
- export declare function smartTicks(dates: string[], xMax: number, labelPx?: number): string[];
48
+ export declare function smartTicks(dates: string[], xMax: number, labelPx?: number, anchorTerminals?: boolean): string[];
30
49
  /**
31
50
  * Which of a BAND axis's category labels may be painted so that no two neighbours overlap — the
32
51
  * same measured law {@link smartTicks} applies to a point axis, for a chart that lays its labels
@@ -1 +1 @@
1
- {"version":3,"file":"ticks.d.ts","sourceRoot":"","sources":["../../../src/charts/utils/ticks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAMjE;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,GAAE,MAAoB,GAAG,MAAM,CAElF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBpF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,GAAG,CAAC,MAAM,CAAC,CAkBb;AAED,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKxE;AAaD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,IAAI,EAAE,SAAS,CAAA;IACf,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAA;IACf;qEACiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,CAAC,GAAG,EAAE,CAST"}
1
+ {"version":3,"file":"ticks.d.ts","sourceRoot":"","sources":["../../../src/charts/utils/ticks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAMjE;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,GAAE,MAAoB,GAAG,MAAM,CAElF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,GAAE,MAAoB,GAAG,MAAM,CAItF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,EAChB,eAAe,UAAQ,GACtB,MAAM,EAAE,CAoEV;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,GAAG,CAAC,MAAM,CAAC,CAkBb;AAED,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKxE;AAaD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,IAAI,EAAE,SAAS,CAAA;IACf,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAA;IACf;qEACiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,CAAC,GAAG,EAAE,CAST"}
@@ -4,21 +4,44 @@ const X_TICK_LABEL_GAP = 8;
4
4
  function xLabelPxFor(labels, fontPx = VX.axisFont) {
5
5
  return maxTextWidth(labels, fontPx) + X_TICK_LABEL_GAP;
6
6
  }
7
- function smartTicks(dates, xMax, labelPx) {
7
+ function rotatedXLabelPx(labels, fontPx = VX.axisFont) {
8
+ return Math.ceil(COS_45 * (maxTextWidth(labels, fontPx) + Math.ceil(fontPx * 1.35))) + X_TICK_LABEL_GAP;
9
+ }
10
+ function smartTicks(dates, xMax, labelPx, anchorTerminals = false) {
8
11
  if (dates.length === 0) return [];
9
- const perTick = Math.max(VX.minPxPerTick, labelPx ?? 0);
12
+ const perTick = labelPx !== void 0 && labelPx > 0 ? labelPx : VX.minPxPerTick;
10
13
  const maxTicks = Math.max(2, Math.floor(xMax / perTick));
11
- if (dates.length <= maxTicks) return dates;
12
- const step = Math.ceil(dates.length / maxTicks);
13
14
  const last = dates.length - 1;
15
+ const pxPerIndex = dates.length > 0 ? xMax / dates.length : 0;
16
+ const anchored = anchorTerminals && labelPx !== void 0 && labelPx > 0;
14
17
  const keep = /* @__PURE__ */ new Set();
15
- for (let i = 0; i <= last; i += step) keep.add(i);
16
- const lastOnGrid = Math.floor(last / step) * step;
17
- if (lastOnGrid !== last) {
18
- const pxPerIndex = dates.length > 0 ? xMax / dates.length : 0;
19
- const gapPx = (last - lastOnGrid) * pxPerIndex;
20
- if (lastOnGrid > 0 && gapPx > 0 && gapPx < perTick) keep.delete(lastOnGrid);
21
- keep.add(last);
18
+ if (dates.length <= maxTicks) {
19
+ for (let i = 0; i <= last; i += 1) keep.add(i);
20
+ } else {
21
+ const step = Math.ceil(dates.length / maxTicks);
22
+ for (let i = 0; i <= last; i += step) keep.add(i);
23
+ const BOUNDARY_FACTOR = 1.5;
24
+ const boundaryPx = anchored ? perTick * BOUNDARY_FACTOR : perTick;
25
+ const lastOnGrid = Math.floor(last / step) * step;
26
+ if (lastOnGrid !== last) {
27
+ const gapPx = (last - lastOnGrid) * pxPerIndex;
28
+ if (lastOnGrid > 0 && gapPx > 0 && gapPx < boundaryPx) keep.delete(lastOnGrid);
29
+ keep.add(last);
30
+ }
31
+ }
32
+ if (anchored && keep.size > 1) {
33
+ const BOUNDARY_FACTOR = 1.5;
34
+ const boundaryPx = perTick * BOUNDARY_FACTOR;
35
+ const sorted = [...keep].toSorted((a, b) => a - b);
36
+ const second = sorted[1];
37
+ if (second !== void 0 && second !== last && second * pxPerIndex < boundaryPx) {
38
+ keep.delete(second);
39
+ }
40
+ const afterHead = [...keep].toSorted((a, b) => a - b);
41
+ const secondLast = afterHead[afterHead.length - 2];
42
+ if (secondLast !== void 0 && secondLast !== 0 && (last - secondLast) * pxPerIndex < boundaryPx) {
43
+ keep.delete(secondLast);
44
+ }
22
45
  }
23
46
  return dates.filter((_, i) => keep.has(i));
24
47
  }
@@ -61,6 +84,7 @@ function autoXLabelRotate(input) {
61
84
  }
62
85
  export {
63
86
  autoXLabelRotate,
87
+ rotatedXLabelPx,
64
88
  smartTicks,
65
89
  smartTicksEvery,
66
90
  thinLabels,
@@ -22,7 +22,7 @@ export declare function oneOf(component: string, prop: string, allowed: readonly
22
22
  * A prop still shipped and still working, with a named successor and the version it goes away in.
23
23
  * Majors are banned here, so the deprecation notice IS the migration channel.
24
24
  */
25
- export declare function deprecatedProp(component: string, oldProp: string, newProp: string, removeIn: string): string;
25
+ export declare function deprecatedProp(component: string, oldProp: string, newProp: string, removeIn: string, note?: string): string;
26
26
  /**
27
27
  * A prop the component ACCEPTS, reads nothing from, and cannot report as wrong — because a SECOND
28
28
  * prop it was passed alongside decides the same thing and won.
@@ -34,6 +34,12 @@ export declare function deprecatedProp(component: string, oldProp: string, newPr
34
34
  * constants and a whole `compact` branch changed no pixel.
35
35
  */
36
36
  export declare function ignoredProp(component: string, prop: string, because: string): string;
37
+ /**
38
+ * A numeric `height` the caller stated that, once the legend band is taken out, leaves the plot
39
+ * under the floor. The frame keeps the plot at the floor and grows past the number, so the chart
40
+ * is taller than the caller asked for and nothing else says why.
41
+ */
42
+ export declare function plotBelowFloor(component: string, height: number, floor: number): string;
37
43
  /**
38
44
  * An imperative call needs a layer that is not there — the optional peer is not installed, or the
39
45
  * mount that subscribes to its event bus is disabled. Both halves are named because the remedy
@@ -42,6 +48,10 @@ export declare function ignoredProp(component: string, prop: string, because: st
42
48
  export declare function missingLayer(component: string, layer: string, remedy: string): string;
43
49
  /** A single-mount component found a second instance alive (`BasaltProvider`, `Notifications`). */
44
50
  export declare function duplicateMount(component: string): string;
51
+ /** Two frames inside one `ChartCard` both want the header legend slot (`docs/waves/PLAN.md` wave
52
+ * 3, P2-9) — only the first to mount keeps it, every later one falls back to its own band legend
53
+ * rather than silently overwriting the portal. */
54
+ export declare function legendSlotContention(component: string): string;
45
55
  /**
46
56
  * The HTTP status behind a thrown envelope (Eden Treaty's `{ status, value }`, a `Response`-shaped
47
57
  * throw), when there is one. Use it to BRANCH — 404 → "not found" copy — rather than to build a
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/common/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,yDAAyD;AACzD,eAAO,MAAM,aAAa,aAAa,CAAA;AAMvC;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,oEAAoE;AACpE,wBAAgB,KAAK,CACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,GAAG,EAAE,OAAO,GACX,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,MAAM,CAKR;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKxD;AAOD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAI5D;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,SAAwB,GAAG,MAAM,CAKrF"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/common/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,yDAAyD;AACzD,eAAO,MAAM,aAAa,aAAa,CAAA;AAMvC;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED,oEAAoE;AACpE,wBAAgB,KAAK,CACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,GAAG,EAAE,OAAO,GACX,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,GACZ,MAAM,CAKR;AAED;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMvF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED;;kDAEkD;AAClD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAK9D;AAOD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAI5D;AAqBD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,SAAwB,GAAG,MAAM,CAKrF"}
@@ -11,15 +11,21 @@ function oneOf(component, prop, allowed, got) {
11
11
  `prop "${prop}" must be one of ${allowed.map((value) => `'${value}'`).join(" | ")} \u2014 got ${JSON.stringify(got)}.`
12
12
  );
13
13
  }
14
- function deprecatedProp(component, oldProp, newProp, removeIn) {
14
+ function deprecatedProp(component, oldProp, newProp, removeIn, note) {
15
15
  return message(
16
16
  component,
17
- `prop "${oldProp}" is deprecated \u2014 use "${newProp}" instead. "${oldProp}" is removed in ${removeIn}.`
17
+ `prop "${oldProp}" is deprecated \u2014 use "${newProp}" instead. "${oldProp}" is removed in ${removeIn}.${note === void 0 ? "" : ` ${note}`}`
18
18
  );
19
19
  }
20
20
  function ignoredProp(component, prop, because) {
21
21
  return message(component, `prop "${prop}" is ignored because ${because}`);
22
22
  }
23
+ function plotBelowFloor(component, height, floor) {
24
+ return message(
25
+ component,
26
+ `prop "height" (${height}) leaves less than the ${floor}px plot floor once the legend band is subtracted, so the frame grows past it. Raise the height or drop the legend.`
27
+ );
28
+ }
23
29
  function missingLayer(component, layer, remedy) {
24
30
  return message(component, `needs ${layer}, which is not available \u2014 ${remedy}.`);
25
31
  }
@@ -29,6 +35,12 @@ function duplicateMount(component) {
29
35
  "more than one instance is mounted at once \u2014 mount exactly one, at the app root."
30
36
  );
31
37
  }
38
+ function legendSlotContention(component) {
39
+ return message(
40
+ component,
41
+ "more than one chart in this ChartCard wants the header legend slot \u2014 only the first keeps it, the rest fall back to their own band legend."
42
+ );
43
+ }
32
44
  function errorStatus(err) {
33
45
  if (err === null || typeof err !== "object") return void 0;
34
46
  const status = err.status;
@@ -61,8 +73,10 @@ export {
61
73
  duplicateMount,
62
74
  errorStatus,
63
75
  ignoredProp,
76
+ legendSlotContention,
64
77
  missingLayer,
65
78
  oneOf,
79
+ plotBelowFloor,
66
80
  requiredProp,
67
81
  toErrorMessage
68
82
  };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The pointer-tier hit floors, in px — WCAG 2.5.8 Target Size Minimum (24) and 2.5.5 Target Size
3
+ * Enhanced (44). One home for the number `--vx-hit` resolves to under `(pointer: coarse)` and for
4
+ * the components that compare a MEASURED px against it (a virtual list's row height, a column-fold
5
+ * toggle's width, the chart legend's dot pitch). Deliberately not re-exported through
6
+ * `common/index.ts`: a CSS-var's numeric value is not a public symbol.
7
+ */
8
+ export declare const HIT_FINE = 24;
9
+ export declare const HIT_COARSE = 44;
10
+ //# sourceMappingURL=hit-floor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hit-floor.d.ts","sourceRoot":"","sources":["../../src/common/hit-floor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,KAAK,CAAA;AAC1B,eAAO,MAAM,UAAU,KAAK,CAAA"}
@@ -0,0 +1,6 @@
1
+ const HIT_FINE = 24;
2
+ const HIT_COARSE = 44;
3
+ export {
4
+ HIT_COARSE,
5
+ HIT_FINE
6
+ };
@@ -5,9 +5,10 @@
5
5
  * nothing on the server" warning. The branch reads a global that cannot change between renders, so
6
6
  * the hook identity is stable across every render of every caller.
7
7
  *
8
- * One module rather than one `const` per file: `page-bar.tsx` and `page-aside.tsx` declared the
9
- * same line with the same doc, and the second copy's doc already said "see `page-bar.tsx`'s copy".
10
- * Not exported from any barrel — this is a shell-internal utility, not a published hook.
8
+ * Lives in `common/` rather than beside the shell because both halves use it — the shell chrome, the
9
+ * provider, and the Mantine-free measured-fold core — and `common/` is the one module both may
10
+ * import from. One module rather than one `const` per file. Not exported from any barrel; import it
11
+ * by path.
11
12
  */
12
13
  import { useEffect } from 'react';
13
14
  export declare const useIsomorphicLayoutEffect: typeof useEffect;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isomorphic-layout-effect.d.ts","sourceRoot":"","sources":["../../src/common/isomorphic-layout-effect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,SAAS,EAAmB,MAAM,OAAO,CAAA;AAElD,eAAO,MAAM,yBAAyB,kBAA8D,CAAA"}
@@ -0,0 +1,37 @@
1
+ import type { MutableRefObject } from 'react';
2
+ /** One measured element's box, cached while it was still visible (a folded child is gone from the DOM). */
3
+ export type MeasuredBox = {
4
+ width: number;
5
+ height: number;
6
+ };
7
+ export interface UseMeasuredWidthsOptions {
8
+ /** The box to observe, resolved on each effect run. */
9
+ resolveRoot: () => HTMLElement | null;
10
+ /** Change this string to drop every cached box — a folded child cannot report its unfolded width. */
11
+ signature: string;
12
+ /** Skip measuring entirely (the feature is off). Default true. */
13
+ enabled?: boolean;
14
+ /** Bump to re-measure on demand beyond a resize (a post-reset commit). */
15
+ nonce?: number;
16
+ /** Extra descendants to observe besides the root (an inner table whose min-content can move). */
17
+ extra?: (root: HTMLElement) => (Element | null)[];
18
+ /** Read the current boxes from `root`, fill the cache, and plan — runs on every measure. */
19
+ onMeasure: (root: HTMLElement, boxes: MutableRefObject<Map<string, MeasuredBox>>) => void;
20
+ }
21
+ export interface UseMeasuredWidthsResult {
22
+ boxes: MutableRefObject<Map<string, MeasuredBox>>;
23
+ /** Re-run the measurement by hand (a web font settling changes every width without a resize). */
24
+ remeasure: () => void;
25
+ }
26
+ /**
27
+ * The measured-fold core every fold planner shares: caches each measured box while it is visible,
28
+ * re-reads on a `ResizeObserver` of the root (plus {@link UseMeasuredWidthsOptions.extra}), and
29
+ * clears the cache when the {@link UseMeasuredWidthsOptions.signature} changes. The caller keeps its
30
+ * own element reading and pure plan function in `onMeasure`.
31
+ *
32
+ * A folded child is gone from the DOM but its cached box survives, so a resize never needs it back
33
+ * on screen; the caller's `onMeasure` decides which boxes to cache (e.g. skip an item that is
34
+ * currently folded, whose painted width is the collapsed one).
35
+ */
36
+ export declare function useMeasuredWidths(options: UseMeasuredWidthsOptions): UseMeasuredWidthsResult;
37
+ //# sourceMappingURL=use-measured-widths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-measured-widths.d.ts","sourceRoot":"","sources":["../../src/common/use-measured-widths.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA;AAG7C,2GAA2G;AAC3G,MAAM,MAAM,WAAW,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3D,MAAM,WAAW,wBAAwB;IACvC,uDAAuD;IACvD,WAAW,EAAE,MAAM,WAAW,GAAG,IAAI,CAAA;IACrC,qGAAqG;IACrG,SAAS,EAAE,MAAM,CAAA;IACjB,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iGAAiG;IACjG,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAA;IACjD,4FAA4F;IAC5F,SAAS,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,KAAK,IAAI,CAAA;CAC1F;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;IACjD,iGAAiG;IACjG,SAAS,EAAE,MAAM,IAAI,CAAA;CACtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,uBAAuB,CAiD5F"}