basalt-ui 1.30.2 → 1.32.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.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +54 -0
- package/MIGRATING.md +256 -12
- package/agent/rules/basalt-controls.md +19 -19
- package/agent/rules/basalt-mantine.md +5 -5
- package/configs/oxlint-plugin.js +371 -4
- package/configs/oxlint-plugin.test.ts +327 -2
- package/configs/oxlint.json +2 -1
- package/dist/agent-chat/composer.d.ts.map +1 -1
- package/dist/agent-chat/composer.js +41 -43
- package/dist/agent-chat/thread-workspace.d.ts +2 -2
- package/dist/agent-chat/thread-workspace.d.ts.map +1 -1
- package/dist/agent-chat/thread-workspace.js +3 -4
- package/dist/agent-chat/use-keyboard-inset.d.ts +2 -0
- package/dist/agent-chat/use-keyboard-inset.d.ts.map +1 -0
- package/dist/agent-chat/use-keyboard-inset.js +34 -0
- package/dist/charts/cursor/touch-pin.d.ts +45 -0
- package/dist/charts/cursor/touch-pin.d.ts.map +1 -0
- package/dist/charts/cursor/touch-pin.js +79 -0
- package/dist/charts/hooks/use-discrete-cursor.d.ts +66 -0
- package/dist/charts/hooks/use-discrete-cursor.d.ts.map +1 -0
- package/dist/charts/hooks/use-discrete-cursor.js +198 -0
- package/dist/charts/hooks/use-hysteresis.d.ts +18 -0
- package/dist/charts/hooks/use-hysteresis.d.ts.map +1 -0
- package/dist/charts/hooks/use-hysteresis.js +12 -0
- package/dist/charts/hooks/useBandPlot.d.ts +7 -0
- package/dist/charts/hooks/useBandPlot.d.ts.map +1 -1
- package/dist/charts/hooks/useBandPlot.js +62 -18
- package/dist/charts/hooks/useChartCursor.d.ts +40 -11
- package/dist/charts/hooks/useChartCursor.d.ts.map +1 -1
- package/dist/charts/hooks/useChartCursor.js +102 -11
- package/dist/charts/index.d.ts +0 -1
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/index.js +0 -10
- package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
- package/dist/charts/kinds/BandStrip.js +47 -82
- package/dist/charts/kinds/Donut.d.ts +9 -3
- package/dist/charts/kinds/Donut.d.ts.map +1 -1
- package/dist/charts/kinds/Donut.js +110 -48
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +138 -145
- package/dist/charts/kinds/Heatmap.d.ts +7 -0
- package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
- package/dist/charts/kinds/Heatmap.js +37 -16
- package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
- package/dist/charts/kinds/MirroredBars.js +68 -111
- package/dist/charts/kinds/band-chrome.d.ts +31 -0
- package/dist/charts/kinds/band-chrome.d.ts.map +1 -0
- package/dist/charts/kinds/band-chrome.js +71 -0
- package/dist/charts/kinds/donut-layout.d.ts +47 -0
- package/dist/charts/kinds/donut-layout.d.ts.map +1 -0
- package/dist/charts/kinds/donut-layout.js +52 -0
- package/dist/charts/layout/auto-margin.d.ts +7 -2
- package/dist/charts/layout/auto-margin.d.ts.map +1 -1
- package/dist/charts/layout/auto-margin.js +12 -3
- package/dist/charts/layout/end-labels.d.ts +64 -0
- package/dist/charts/layout/end-labels.d.ts.map +1 -0
- package/dist/charts/layout/end-labels.js +76 -0
- package/dist/charts/primitives/Axes.d.ts +32 -4
- package/dist/charts/primitives/Axes.d.ts.map +1 -1
- package/dist/charts/primitives/Axes.js +62 -16
- package/dist/charts/primitives/CartesianChart.d.ts +7 -6
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
- package/dist/charts/primitives/CartesianChart.js +264 -145
- package/dist/charts/primitives/ChartCard.d.ts +0 -14
- package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
- package/dist/charts/primitives/ChartCard.js +56 -21
- package/dist/charts/primitives/ChartFrame.d.ts +28 -22
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +116 -34
- package/dist/charts/primitives/ChartLegend.d.ts +19 -15
- package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
- package/dist/charts/primitives/ChartLegend.js +86 -73
- package/dist/charts/primitives/ChartTooltip.d.ts +5 -0
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +20 -4
- package/dist/charts/primitives/Crosshair.js +2 -2
- package/dist/charts/primitives/HoverOverlay.d.ts +29 -9
- package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
- package/dist/charts/primitives/HoverOverlay.js +54 -27
- package/dist/charts/primitives/HoverOverlay.module.css +13 -0
- package/dist/charts/primitives/HoverOverlay.module.css.d.ts +8 -0
- package/dist/charts/primitives/chart-card-context.d.ts +33 -0
- package/dist/charts/primitives/chart-card-context.d.ts.map +1 -0
- package/dist/charts/primitives/chart-card-context.js +18 -0
- package/dist/charts/primitives/chart-frame-layout.d.ts +93 -113
- package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -1
- package/dist/charts/primitives/chart-frame-layout.js +75 -34
- package/dist/charts/primitives/chart-layout.d.ts +112 -0
- package/dist/charts/primitives/chart-layout.d.ts.map +1 -0
- package/dist/charts/primitives/chart-layout.js +175 -0
- package/dist/charts/primitives/chart-tier.d.ts +13 -11
- package/dist/charts/primitives/chart-tier.d.ts.map +1 -1
- package/dist/charts/primitives/chart-tier.js +42 -13
- package/dist/charts/primitives/legend-disclosure.d.ts +27 -0
- package/dist/charts/primitives/legend-disclosure.d.ts.map +1 -0
- package/dist/charts/primitives/legend-disclosure.js +153 -0
- package/dist/charts/series.d.ts +4 -1
- package/dist/charts/series.d.ts.map +1 -1
- package/dist/charts/utils/ticks.d.ts +27 -8
- package/dist/charts/utils/ticks.d.ts.map +1 -1
- package/dist/charts/utils/ticks.js +35 -11
- package/dist/common/errors.d.ts +11 -1
- package/dist/common/errors.d.ts.map +1 -1
- package/dist/common/errors.js +16 -2
- package/dist/common/hit-floor.d.ts +10 -0
- package/dist/common/hit-floor.d.ts.map +1 -0
- package/dist/common/hit-floor.js +6 -0
- package/dist/{shell → common}/isomorphic-layout-effect.d.ts +4 -3
- package/dist/common/isomorphic-layout-effect.d.ts.map +1 -0
- package/dist/common/use-measured-widths.d.ts +37 -0
- package/dist/common/use-measured-widths.d.ts.map +1 -0
- package/dist/common/use-measured-widths.js +51 -0
- package/dist/common/use-media-query.d.ts +6 -0
- package/dist/common/use-media-query.d.ts.map +1 -0
- package/dist/common/use-media-query.js +40 -0
- package/dist/common/validate.d.ts +9 -0
- package/dist/common/validate.d.ts.map +1 -1
- package/dist/common/validate.js +9 -4
- package/dist/content/article-layout.d.ts +4 -2
- package/dist/content/article-layout.d.ts.map +1 -1
- package/dist/content/article-layout.js +43 -3
- package/dist/content/article-layout.module.css +45 -4
- package/dist/content/article-layout.module.css.d.ts +3 -0
- package/dist/content/code-block.d.ts.map +1 -1
- package/dist/content/code-block.js +40 -2
- package/dist/content/code-block.module.css +32 -2
- package/dist/content/prose.module.css +13 -8
- package/dist/controls/actions.d.ts +29 -6
- package/dist/controls/actions.d.ts.map +1 -1
- package/dist/controls/actions.js +158 -27
- package/dist/controls/actions.module.css +14 -1
- package/dist/controls/actions.module.css.d.ts +1 -0
- package/dist/controls/controls.module.css +13 -31
- package/dist/controls/enum-filter.js +2 -2
- package/dist/controls/filter-context.d.ts +10 -0
- package/dist/controls/filter-context.d.ts.map +1 -1
- package/dist/controls/filter-context.js +2 -0
- package/dist/controls/filter-pill.d.ts.map +1 -1
- package/dist/controls/filter-pill.js +1 -0
- package/dist/controls/index.d.ts +1 -1
- package/dist/controls/index.d.ts.map +1 -1
- package/dist/controls/index.js +0 -2
- package/dist/controls/multi-select-filter.js +2 -2
- package/dist/controls/sync-button.module.css +2 -1
- package/dist/dashboard/section.d.ts.map +1 -1
- package/dist/dashboard/section.js +1 -0
- package/dist/dashboard/section.module.css +1 -26
- package/dist/dashboard/stat-card.d.ts +1 -1
- package/dist/dashboard/stat-card.d.ts.map +1 -1
- package/dist/dashboard/stat-card.js +4 -1
- package/dist/dashboard/stat-card.module.css +6 -9
- package/dist/dashboard/stat-group.module.css +33 -66
- package/dist/dashboard/widget-grid.d.ts.map +1 -1
- package/dist/dashboard/widget-grid.module.css +11 -38
- package/dist/dashboard/widget-header.d.ts +14 -4
- package/dist/dashboard/widget-header.d.ts.map +1 -1
- package/dist/dashboard/widget-header.js +23 -6
- package/dist/dashboard/widget-header.module.css +145 -133
- package/dist/dashboard/widget-header.module.css.d.ts +2 -0
- package/dist/data/data-table-state.d.ts +83 -0
- package/dist/data/data-table-state.d.ts.map +1 -0
- package/dist/data/data-table-state.js +139 -0
- package/dist/data/data-table.d.ts +56 -2
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +436 -336
- package/dist/data/data-table.module.css +94 -0
- package/dist/data/data-table.module.css.d.ts +11 -0
- package/dist/data/virtual-list.d.ts.map +1 -1
- package/dist/data/virtual-list.js +10 -0
- package/dist/forms/form-layout.d.ts.map +1 -1
- package/dist/forms/form-layout.js +3 -3
- package/dist/forms/form-layout.module.css +20 -5
- package/dist/forms/form-layout.module.css.d.ts +1 -0
- package/dist/guard/index.d.ts +8 -2
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +68 -2
- package/dist/guard/types.d.ts +3 -3
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/notifications/center.d.ts.map +1 -1
- package/dist/provider/index.d.ts +20 -1
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +30 -8
- package/dist/shell/app-brand.d.ts.map +1 -1
- package/dist/shell/app-brand.js +1 -0
- package/dist/shell/app-brand.module.css +2 -2
- package/dist/shell/app-header.module.css +18 -8
- package/dist/shell/app-main.module.css +54 -3
- package/dist/shell/app-main.module.css.d.ts +1 -0
- package/dist/shell/app-mobile-nav.module.css +16 -4
- package/dist/shell/app-sidebar.module.css +4 -6
- package/dist/shell/aside-docking.d.ts +31 -0
- package/dist/shell/aside-docking.d.ts.map +1 -0
- package/dist/shell/aside-docking.js +19 -0
- package/dist/shell/index.d.ts +1 -0
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +56 -16
- package/dist/shell/mobile-nav-model.d.ts +1 -1
- package/dist/shell/page-aside.d.ts +22 -3
- package/dist/shell/page-aside.d.ts.map +1 -1
- package/dist/shell/page-aside.js +27 -13
- package/dist/shell/page-bar.d.ts.map +1 -1
- package/dist/shell/page-bar.js +10 -5
- package/dist/shell/page-bar.module.css +10 -34
- package/dist/shell/use-breakpoint.d.ts +3 -4
- package/dist/shell/use-breakpoint.d.ts.map +1 -1
- package/dist/shell/use-breakpoint.js +3 -25
- package/dist/shell/use-size-class.d.ts +6 -0
- package/dist/shell/use-size-class.d.ts.map +1 -0
- package/dist/shell/use-size-class.js +19 -0
- package/dist/state/persisted-or-local.d.ts +4 -1
- package/dist/state/persisted-or-local.d.ts.map +1 -1
- package/dist/state/persisted-or-local.js +4 -3
- package/dist/state/persisted.d.ts +10 -0
- package/dist/state/persisted.d.ts.map +1 -1
- package/dist/state/persisted.js +44 -14
- package/dist/styles.css +41 -0
- package/dist/surfaces.d.ts +4 -4
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +11 -3
- package/dist/theme/controls.module.css +7 -0
- package/dist/theme/ctl-theme.d.ts +1 -0
- package/dist/theme/ctl-theme.d.ts.map +1 -1
- package/dist/theme/ctl-theme.js +12 -4
- package/dist/theme/floating.module.css +37 -0
- package/dist/theme/floating.module.css.d.ts +3 -0
- package/dist/theme/index.d.ts +2 -2
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +34 -5
- package/dist/theme/nav-link.module.css +7 -0
- package/dist/theme-lab/derive-controls.d.ts.map +1 -1
- package/dist/tokens/index.d.ts +7 -16
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +23 -28
- package/dist/tokens/palette.d.ts +5 -27
- package/dist/tokens/palette.d.ts.map +1 -1
- package/dist/tokens/palette.js +8 -30
- package/dist/tokens/size-classes.d.ts +40 -0
- package/dist/tokens/size-classes.d.ts.map +1 -0
- package/dist/tokens/size-classes.js +29 -0
- package/dist/tokens.css +8 -4
- package/llms.txt +3 -3
- package/package.json +18 -17
- package/src/agent-chat/composer.tsx +74 -47
- package/src/agent-chat/thread-workspace.tsx +8 -11
- package/src/agent-chat/use-keyboard-inset.ts +68 -0
- package/src/charts/cursor/touch-pin.ts +138 -0
- package/src/charts/hooks/use-discrete-cursor.ts +335 -0
- package/src/charts/hooks/use-hysteresis.ts +26 -0
- package/src/charts/hooks/useBandPlot.ts +90 -27
- package/src/charts/hooks/useChartCursor.ts +211 -26
- package/src/charts/index.ts +0 -8
- package/src/charts/kinds/BandStrip.tsx +25 -61
- package/src/charts/kinds/Donut.tsx +153 -62
- package/src/charts/kinds/DualPanel.tsx +21 -26
- package/src/charts/kinds/Heatmap.tsx +61 -22
- package/src/charts/kinds/MirroredBars.tsx +23 -65
- package/src/charts/kinds/band-chrome.tsx +91 -0
- package/src/charts/kinds/donut-layout.ts +82 -0
- package/src/charts/layout/auto-margin.ts +24 -5
- package/src/charts/layout/end-labels.ts +135 -0
- package/src/charts/primitives/Axes.tsx +112 -21
- package/src/charts/primitives/CartesianChart.tsx +282 -111
- package/src/charts/primitives/ChartCard.tsx +119 -48
- package/src/charts/primitives/ChartFrame.tsx +204 -60
- package/src/charts/primitives/ChartLegend.tsx +115 -78
- package/src/charts/primitives/ChartTooltip.tsx +24 -3
- package/src/charts/primitives/Crosshair.tsx +2 -2
- package/src/charts/primitives/HoverOverlay.module.css +13 -0
- package/src/charts/primitives/HoverOverlay.module.css.d.ts +8 -0
- package/src/charts/primitives/HoverOverlay.tsx +62 -20
- package/src/charts/primitives/chart-card-context.ts +46 -0
- package/src/charts/primitives/chart-frame-layout.ts +207 -182
- package/src/charts/primitives/chart-layout.ts +318 -0
- package/src/charts/primitives/chart-tier.tsx +66 -21
- package/src/charts/primitives/legend-disclosure.tsx +177 -0
- package/src/charts/series.ts +4 -1
- package/src/charts/utils/ticks.ts +95 -19
- package/src/common/errors.ts +25 -1
- package/src/common/hit-floor.ts +9 -0
- package/src/{shell → common}/isomorphic-layout-effect.ts +4 -3
- package/src/common/use-measured-widths.ts +88 -0
- package/src/common/use-media-query.ts +56 -0
- package/src/common/validate.ts +17 -4
- package/src/content/article-layout.module.css +45 -4
- package/src/content/article-layout.module.css.d.ts +3 -0
- package/src/content/article-layout.tsx +60 -5
- package/src/content/code-block.module.css +32 -2
- package/src/content/code-block.tsx +47 -3
- package/src/content/prose.module.css +13 -8
- package/src/controls/actions.module.css +14 -1
- package/src/controls/actions.module.css.d.ts +1 -0
- package/src/controls/actions.tsx +223 -75
- package/src/controls/controls.module.css +13 -31
- package/src/controls/enum-filter.tsx +2 -2
- package/src/controls/filter-context.tsx +11 -0
- package/src/controls/filter-pill.tsx +1 -0
- package/src/controls/index.ts +0 -1
- package/src/controls/multi-select-filter.tsx +2 -2
- package/src/controls/sync-button.module.css +2 -1
- package/src/dashboard/section.module.css +1 -26
- package/src/dashboard/section.tsx +1 -0
- package/src/dashboard/stat-card.module.css +6 -9
- package/src/dashboard/stat-card.tsx +6 -3
- package/src/dashboard/stat-group.module.css +33 -66
- package/src/dashboard/widget-grid.module.css +11 -38
- package/src/dashboard/widget-grid.tsx +7 -6
- package/src/dashboard/widget-header.module.css +145 -133
- package/src/dashboard/widget-header.module.css.d.ts +2 -0
- package/src/dashboard/widget-header.tsx +45 -11
- package/src/data/data-table-state.ts +218 -0
- package/src/data/data-table.module.css +94 -0
- package/src/data/data-table.module.css.d.ts +11 -0
- package/src/data/data-table.tsx +547 -299
- package/src/data/virtual-list.tsx +31 -0
- package/src/forms/form-layout.module.css +20 -5
- package/src/forms/form-layout.module.css.d.ts +1 -0
- package/src/forms/form-layout.tsx +12 -10
- package/src/guard/index.ts +188 -3
- package/src/guard/types.ts +3 -2
- package/src/index.ts +2 -0
- package/src/notifications/center.tsx +3 -0
- package/src/provider/index.tsx +60 -7
- package/src/shell/app-brand.module.css +2 -2
- package/src/shell/app-brand.tsx +1 -0
- package/src/shell/app-header.module.css +18 -8
- package/src/shell/app-main.module.css +54 -3
- package/src/shell/app-main.module.css.d.ts +1 -0
- package/src/shell/app-mobile-nav.module.css +16 -4
- package/src/shell/app-sidebar.module.css +4 -6
- package/src/shell/aside-docking.ts +54 -0
- package/src/shell/index.tsx +178 -129
- package/src/shell/mobile-nav-model.ts +1 -1
- package/src/shell/page-aside.tsx +70 -21
- package/src/shell/page-bar.module.css +10 -34
- package/src/shell/page-bar.tsx +10 -5
- package/src/shell/use-breakpoint.ts +9 -45
- package/src/shell/use-size-class.ts +31 -0
- package/src/state/persisted-or-local.ts +10 -4
- package/src/state/persisted.ts +76 -17
- package/src/styles.css +41 -0
- package/src/surfaces.ts +9 -1
- package/src/theme/controls.module.css +7 -0
- package/src/theme/ctl-theme.tsx +15 -3
- package/src/theme/floating.module.css +37 -0
- package/src/theme/floating.module.css.d.ts +3 -0
- package/src/theme/index.ts +46 -8
- package/src/theme/nav-link.module.css +7 -0
- package/src/theme-lab/derive-controls.tsx +2 -0
- package/src/tokens/index.ts +20 -30
- package/src/tokens/palette.ts +6 -28
- package/src/tokens/size-classes.ts +46 -0
- package/dist/shell/isomorphic-layout-effect.d.ts.map +0 -1
- /package/dist/{shell → common}/isomorphic-layout-effect.js +0 -0
|
@@ -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,
|
|
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"}
|
package/dist/common/errors.js
CHANGED
|
@@ -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"}
|
|
@@ -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
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { useRef } from "react";
|
|
2
|
+
import { useIsomorphicLayoutEffect } from "./isomorphic-layout-effect.js";
|
|
3
|
+
function useMeasuredWidths(options) {
|
|
4
|
+
const { resolveRoot, signature, enabled = true, nonce = 0, extra, onMeasure } = options;
|
|
5
|
+
const boxes = useRef(/* @__PURE__ */ new Map());
|
|
6
|
+
const signatureRef = useRef(signature);
|
|
7
|
+
const remeasureRef = useRef(() => {
|
|
8
|
+
});
|
|
9
|
+
const resolveRef = useRef(resolveRoot);
|
|
10
|
+
resolveRef.current = resolveRoot;
|
|
11
|
+
const extraRef = useRef(extra);
|
|
12
|
+
extraRef.current = extra;
|
|
13
|
+
const onMeasureRef = useRef(onMeasure);
|
|
14
|
+
onMeasureRef.current = onMeasure;
|
|
15
|
+
useIsomorphicLayoutEffect(() => {
|
|
16
|
+
if (signatureRef.current !== signature) {
|
|
17
|
+
signatureRef.current = signature;
|
|
18
|
+
boxes.current.clear();
|
|
19
|
+
}
|
|
20
|
+
if (!enabled) {
|
|
21
|
+
remeasureRef.current = () => {
|
|
22
|
+
};
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const root = resolveRef.current();
|
|
26
|
+
if (root === null) {
|
|
27
|
+
remeasureRef.current = () => {
|
|
28
|
+
};
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const measure = () => {
|
|
32
|
+
onMeasureRef.current(root, boxes);
|
|
33
|
+
};
|
|
34
|
+
remeasureRef.current = measure;
|
|
35
|
+
if (typeof ResizeObserver === "undefined") {
|
|
36
|
+
measure();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const observer = new ResizeObserver(measure);
|
|
40
|
+
observer.observe(root);
|
|
41
|
+
for (const el of extraRef.current?.(root) ?? []) {
|
|
42
|
+
if (el !== null) observer.observe(el);
|
|
43
|
+
}
|
|
44
|
+
measure();
|
|
45
|
+
return () => observer.disconnect();
|
|
46
|
+
}, [enabled, signature, nonce]);
|
|
47
|
+
return { boxes, remeasure: () => remeasureRef.current() };
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
useMeasuredWidths
|
|
51
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** A one-off, non-reactive read — for a dev-only check that runs once inside an effect/callback
|
|
2
|
+
* rather than subscribing for the component's lifetime. Prefer `useMediaQuery` for anything that
|
|
3
|
+
* should re-render on a match change. */
|
|
4
|
+
export declare function readMediaQuery(query: string, fallback: boolean): boolean;
|
|
5
|
+
export declare function useMediaQuery(query: string, serverFallback: boolean): boolean;
|
|
6
|
+
//# sourceMappingURL=use-media-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-media-query.d.ts","sourceRoot":"","sources":["../../src/common/use-media-query.ts"],"names":[],"mappings":"AAgCA;;yCAEyC;AACzC,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAExE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,OAAO,CAgB7E"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useCallback, useSyncExternalStore } from "react";
|
|
2
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
3
|
+
function mediaQueryList(query) {
|
|
4
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return null;
|
|
5
|
+
let byQuery = cache.get(window.matchMedia);
|
|
6
|
+
if (byQuery === void 0) {
|
|
7
|
+
byQuery = /* @__PURE__ */ new Map();
|
|
8
|
+
cache.set(window.matchMedia, byQuery);
|
|
9
|
+
}
|
|
10
|
+
const cached = byQuery.get(query);
|
|
11
|
+
if (cached !== void 0) return cached;
|
|
12
|
+
const list = window.matchMedia(query);
|
|
13
|
+
byQuery.set(query, list);
|
|
14
|
+
return list;
|
|
15
|
+
}
|
|
16
|
+
function readMediaQuery(query, fallback) {
|
|
17
|
+
return mediaQueryList(query)?.matches ?? fallback;
|
|
18
|
+
}
|
|
19
|
+
function useMediaQuery(query, serverFallback) {
|
|
20
|
+
const subscribe = useCallback(
|
|
21
|
+
(onStoreChange) => {
|
|
22
|
+
const list = mediaQueryList(query);
|
|
23
|
+
if (list === null) return () => {
|
|
24
|
+
};
|
|
25
|
+
list.addEventListener("change", onStoreChange);
|
|
26
|
+
return () => list.removeEventListener("change", onStoreChange);
|
|
27
|
+
},
|
|
28
|
+
[query]
|
|
29
|
+
);
|
|
30
|
+
const getSnapshot = useCallback(
|
|
31
|
+
() => mediaQueryList(query)?.matches ?? serverFallback,
|
|
32
|
+
[query, serverFallback]
|
|
33
|
+
);
|
|
34
|
+
const getServerSnapshot = useCallback(() => serverFallback, [serverFallback]);
|
|
35
|
+
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
readMediaQuery,
|
|
39
|
+
useMediaQuery
|
|
40
|
+
};
|
|
@@ -20,6 +20,15 @@ type CheckResult = string | null | undefined | Array<string | null | undefined>;
|
|
|
20
20
|
* )
|
|
21
21
|
*/
|
|
22
22
|
export declare function useValidateProps(component: string, check: () => CheckResult, deps: unknown[]): void;
|
|
23
|
+
/**
|
|
24
|
+
* The same once-per-`(component, message)` dev diagnostic {@link useValidateProps} logs, for a
|
|
25
|
+
* caller that already owns the effect a check would otherwise race — a decision made synchronously
|
|
26
|
+
* inside a `useLayoutEffect` (e.g. `ChartFrame`'s header-slot claim, P2-9) has no business waiting a
|
|
27
|
+
* further render for a REACTIVE check on state that effect itself just set: that state update lags
|
|
28
|
+
* one commit behind the decision, and a passive-effect check racing it warns about instances that
|
|
29
|
+
* are about to win in the very next render.
|
|
30
|
+
*/
|
|
31
|
+
export declare function reportOnce(component: string, message: string): void;
|
|
23
32
|
/** Test seam. The once-per-message Set is module state, so a suite has to be able to clear it. */
|
|
24
33
|
export declare function resetValidatedProps(): void;
|
|
25
34
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/common/validate.ts"],"names":[],"mappings":"AAYA,iGAAiG;AACjG,KAAK,WAAW,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AAU/E;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,WAAW,EACxB,IAAI,EAAE,OAAO,EAAE,GACd,IAAI,
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/common/validate.ts"],"names":[],"mappings":"AAYA,iGAAiG;AACjG,KAAK,WAAW,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAA;AAU/E;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,WAAW,EACxB,IAAI,EAAE,OAAO,EAAE,GACd,IAAI,CAYN;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAMnE;AAED,kGAAkG;AAClG,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,EAClD,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,EAC7C,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GACxD,IAAI,CASN"}
|
package/dist/common/validate.js
CHANGED
|
@@ -9,13 +9,17 @@ function useValidateProps(component, check, deps) {
|
|
|
9
9
|
const messages = Array.isArray(result) ? result : [result];
|
|
10
10
|
for (const raw of messages) {
|
|
11
11
|
if (raw === null || raw === void 0) continue;
|
|
12
|
-
|
|
13
|
-
if (reported.has(key)) continue;
|
|
14
|
-
reported.add(key);
|
|
15
|
-
console.error(raw);
|
|
12
|
+
reportOnce(component, raw);
|
|
16
13
|
}
|
|
17
14
|
}, deps);
|
|
18
15
|
}
|
|
16
|
+
function reportOnce(component, message) {
|
|
17
|
+
if (!isDev()) return;
|
|
18
|
+
const key = `${component} ${message}`;
|
|
19
|
+
if (reported.has(key)) return;
|
|
20
|
+
reported.add(key);
|
|
21
|
+
console.error(message);
|
|
22
|
+
}
|
|
19
23
|
function resetValidatedProps() {
|
|
20
24
|
reported.clear();
|
|
21
25
|
}
|
|
@@ -31,6 +35,7 @@ function assertRequiredProps(component, props, keys, hints) {
|
|
|
31
35
|
}
|
|
32
36
|
export {
|
|
33
37
|
assertRequiredProps,
|
|
38
|
+
reportOnce,
|
|
34
39
|
resetValidatedProps,
|
|
35
40
|
useValidateProps
|
|
36
41
|
};
|
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
* `ReadingProgress`) — it does not reimplement them.
|
|
6
6
|
*
|
|
7
7
|
* The header/content/footer all align to the SAME grid column, so the article body reads as one
|
|
8
|
-
* consistent width whether or not the TOC rail is visible
|
|
9
|
-
*
|
|
8
|
+
* consistent width whether or not the TOC rail is visible. Below the 1200px breakpoint the rail
|
|
9
|
+
* is replaced, not dropped: a sticky "On this page" trigger opens the same `TableOfContents` in a
|
|
10
|
+
* `Popover` (docs/CONTENT-SPEC.md §7's originally-documented behavior, `useSizeClass() !==
|
|
11
|
+
* 'expanded'` — the same numeric threshold, resolved in JS instead of `@media`).
|
|
10
12
|
*
|
|
11
13
|
* @example
|
|
12
14
|
* import { ArticleLayout } from 'basalt-ui/content'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"article-layout.d.ts","sourceRoot":"","sources":["../../src/content/article-layout.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"article-layout.d.ts","sourceRoot":"","sources":["../../src/content/article-layout.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAK3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,4FAA4F;IAC5F,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAA;IACjC,wFAAwF;IACxF,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;IACtB,0FAA0F;IAC1F,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAA;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAA;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAA;IAChC,wFAAwF;IACxF,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,KAAK,SAAS,CAAA;IAC9E,wDAAwD;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAA;IAC/B;0EACsE;IACtE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAC/B,CAAA;AAiCD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,IAAI,EACJ,GAAU,EACV,eAAuB,EACvB,IAAI,EACJ,IAAI,EACJ,UAA8B,EAC9B,OAAmB,EACnB,MAAgB,EAChB,SAAS,EACT,KAAK,GACN,EAAE,kBAAkB,+BAyGpB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useRef } from "react";
|
|
3
|
-
import { ScrollArea } from "@mantine/core";
|
|
2
|
+
import { useRef, useState } from "react";
|
|
3
|
+
import { Button, Popover, ScrollArea } from "@mantine/core";
|
|
4
|
+
import { useSizeClass } from "../shell/use-size-class.js";
|
|
4
5
|
import classes from "./article-layout.module.css";
|
|
5
6
|
import { formatArticleDate } from "./article-model.js";
|
|
6
7
|
import { Prose } from "./prose.js";
|
|
@@ -44,6 +45,13 @@ function ArticleLayout({
|
|
|
44
45
|
const articleRef = useRef(null);
|
|
45
46
|
const rootClass = [classes.root, !toc && classes.noToc, className].filter(Boolean).join(" ");
|
|
46
47
|
const hasMetaRow = meta?.date !== void 0 || meta?.readingTime !== void 0;
|
|
48
|
+
const showTocRail = useSizeClass() === "expanded";
|
|
49
|
+
const [tocOpen, setTocOpen] = useState(false);
|
|
50
|
+
const prevShowTocRailRef = useRef(showTocRail);
|
|
51
|
+
if (prevShowTocRailRef.current !== showTocRail) {
|
|
52
|
+
prevShowTocRailRef.current = showTocRail;
|
|
53
|
+
if (tocOpen) setTocOpen(false);
|
|
54
|
+
}
|
|
47
55
|
return /* @__PURE__ */ jsxs("div", { className: rootClass, ...style !== void 0 && { style }, children: [
|
|
48
56
|
readingProgress && /* @__PURE__ */ jsx(ReadingProgress, { target: articleRef }),
|
|
49
57
|
meta !== void 0 && /* @__PURE__ */ jsxs("header", { className: classes.header, children: [
|
|
@@ -59,7 +67,39 @@ function ArticleLayout({
|
|
|
59
67
|
] })
|
|
60
68
|
] }),
|
|
61
69
|
/* @__PURE__ */ jsx("div", { className: classes.content, ref: articleRef, children: /* @__PURE__ */ jsx(Prose, { density, children }) }),
|
|
62
|
-
toc && /* @__PURE__ */ jsx("div", { className: classes.tocRail, children: /* @__PURE__ */ jsx(ScrollArea.Autosize, { mah: "calc(100vh - 108px)", type: "hover", children: /* @__PURE__ */ jsx(TableOfContents, { containerRef: articleRef }) }) }),
|
|
70
|
+
toc && showTocRail && /* @__PURE__ */ jsx("div", { className: classes.tocRail, children: /* @__PURE__ */ jsx(ScrollArea.Autosize, { mah: "calc(100vh - 108px)", type: "hover", children: /* @__PURE__ */ jsx(TableOfContents, { containerRef: articleRef }) }) }),
|
|
71
|
+
toc && !showTocRail && // `.tocTrigger`'s `grid-row: 2` (article-layout.module.css) is EXPLICIT, matching
|
|
72
|
+
// `.content`'s own row — not left to CSS Grid's auto-placement, which used to land this
|
|
73
|
+
// in its own row below the content instead of at its top (both are `grid-column: 1`, and
|
|
74
|
+
// the auto-placement cursor moves past row 2 once `.content` claims it).
|
|
75
|
+
/* @__PURE__ */ jsxs(
|
|
76
|
+
Popover,
|
|
77
|
+
{
|
|
78
|
+
opened: tocOpen,
|
|
79
|
+
onChange: setTocOpen,
|
|
80
|
+
onDismiss: () => setTocOpen(false),
|
|
81
|
+
position: "bottom-end",
|
|
82
|
+
withinPortal: true,
|
|
83
|
+
shadow: "md",
|
|
84
|
+
radius: "sm",
|
|
85
|
+
trapFocus: true,
|
|
86
|
+
children: [
|
|
87
|
+
/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(
|
|
88
|
+
Button,
|
|
89
|
+
{
|
|
90
|
+
variant: "subtle",
|
|
91
|
+
color: "gray",
|
|
92
|
+
size: "compact-xs",
|
|
93
|
+
className: classes.tocTrigger,
|
|
94
|
+
classNames: { label: classes.tocTriggerLabel },
|
|
95
|
+
onClick: () => setTocOpen((current) => !current),
|
|
96
|
+
children: "On this page"
|
|
97
|
+
}
|
|
98
|
+
) }),
|
|
99
|
+
/* @__PURE__ */ jsx(Popover.Dropdown, { className: classes.tocDropdown, children: /* @__PURE__ */ jsx(ScrollArea.Autosize, { mah: "calc(100vh - 108px)", type: "hover", children: /* @__PURE__ */ jsx(TableOfContents, { containerRef: articleRef, onNavigate: () => setTocOpen(false) }) }) })
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
),
|
|
63
103
|
(prev !== void 0 || next !== void 0) && /* @__PURE__ */ jsxs("footer", { className: classes.footer, children: [
|
|
64
104
|
prev !== void 0 ? /* @__PURE__ */ jsx(NavCell, { target: prev, side: "prev", renderLink }) : /* @__PURE__ */ jsx("span", {}),
|
|
65
105
|
next !== void 0 ? /* @__PURE__ */ jsx(NavCell, { target: next, side: "next", renderLink }) : /* @__PURE__ */ jsx("span", {})
|
|
@@ -17,12 +17,19 @@
|
|
|
17
17
|
grid-template-columns: minmax(0, var(--vx-prose-measure));
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
/* The literal below MUST equal `BREAKPOINTS.article` (src/tokens/index.ts) — a `@media`
|
|
20
|
+
/* The literal below MUST equal `BREAKPOINTS.article - 0.1` (src/tokens/index.ts) — a `@media`
|
|
21
21
|
* condition is resolved before custom properties exist, so `max-width: var(--x)` is invalid CSS
|
|
22
|
-
* and a stylesheet with a responsive rule has no choice but to write the number. The
|
|
23
|
-
*
|
|
22
|
+
* and a stylesheet with a responsive rule has no choice but to write the number. The 0.1px offset
|
|
23
|
+
* is `tokens/size-classes.ts`' own `sizeClassMaxEm` convention (Mantine's own): the JS side
|
|
24
|
+
* (`article-layout.tsx`'s `useSizeClass() === 'expanded'`) reads a plain `min-width: 1200px`,
|
|
25
|
+
* inclusive AT 1200 — writing this query as a bare `max-width: 1200px` would ALSO be inclusive at
|
|
26
|
+
* exactly 1200px, so at that one width both conditions would fire at once: JS renders the rail,
|
|
27
|
+
* and this rule then hides it with `display: none`, leaving neither the rail nor the trigger
|
|
28
|
+
* visible. `1199.9px` makes the two conditions strict complements with no such gap. The token is
|
|
29
|
+
* the readable half; `article-layout.breakpoint.test.ts` asserts the two agree, the same
|
|
24
30
|
* "literal must match the token" idiom as `styles.floor.test.ts`. Change both or neither. */
|
|
25
|
-
|
|
31
|
+
/* theme-allow raw-media-query — deliberate literal pinned to BREAKPOINTS.article, outside shell/** */
|
|
32
|
+
@media (max-width: 1199.9px) {
|
|
26
33
|
.root {
|
|
27
34
|
grid-template-columns: minmax(0, var(--vx-prose-measure));
|
|
28
35
|
}
|
|
@@ -34,6 +41,7 @@
|
|
|
34
41
|
|
|
35
42
|
.header {
|
|
36
43
|
grid-column: 1;
|
|
44
|
+
grid-row: 1;
|
|
37
45
|
display: flex;
|
|
38
46
|
flex-direction: column;
|
|
39
47
|
gap: var(--vx-space-article-header-gap);
|
|
@@ -71,11 +79,13 @@
|
|
|
71
79
|
|
|
72
80
|
.content {
|
|
73
81
|
grid-column: 1;
|
|
82
|
+
grid-row: 2;
|
|
74
83
|
min-width: 0;
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
.tocRail {
|
|
78
87
|
grid-column: 2;
|
|
88
|
+
grid-row: 2;
|
|
79
89
|
position: sticky;
|
|
80
90
|
/* The rail sticks inside whatever scrolls it — `AppShell.Main` in a shell, the document without
|
|
81
91
|
* one — and NOTHING overhangs that box: the app header and `PageBar` row 2's band are both shell
|
|
@@ -87,8 +97,39 @@
|
|
|
87
97
|
align-self: start;
|
|
88
98
|
}
|
|
89
99
|
|
|
100
|
+
/* The rail's below-breakpoint replacement (docs/CONTENT-SPEC.md §7): a small sticky trigger that
|
|
101
|
+
* opens the SAME `TableOfContents` in a `Popover` instead of the rail vanishing. Rendered by JS
|
|
102
|
+
* (`useSizeClass() !== 'expanded'`), never both at once with `.tocRail` — no media query needed
|
|
103
|
+
* here, only the sticky/alignment behaviour for whenever it IS mounted. `grid-row: 2` is EXPLICIT,
|
|
104
|
+
* not left to auto-placement: `.content` also being `grid-column: 1` moves the auto-placement
|
|
105
|
+
* cursor's row on past row 2 by the time this item (also column 1) is placed, landing it in its
|
|
106
|
+
* own row BELOW the content instead of at its top — the whole point of this trigger. */
|
|
107
|
+
.tocTrigger {
|
|
108
|
+
grid-column: 1;
|
|
109
|
+
grid-row: 2;
|
|
110
|
+
justify-self: end;
|
|
111
|
+
align-self: start;
|
|
112
|
+
position: sticky;
|
|
113
|
+
top: var(--vx-space-sticky-header-clearance);
|
|
114
|
+
z-index: 1;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.tocTriggerLabel {
|
|
118
|
+
font-family: var(--basalt-font-mono);
|
|
119
|
+
font-size: var(--vx-text-micro);
|
|
120
|
+
letter-spacing: 0.06em;
|
|
121
|
+
text-transform: uppercase;
|
|
122
|
+
color: var(--vx-faint);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.tocDropdown {
|
|
126
|
+
min-width: 220px;
|
|
127
|
+
max-width: min(320px, calc(100vw - 32px));
|
|
128
|
+
}
|
|
129
|
+
|
|
90
130
|
.footer {
|
|
91
131
|
grid-column: 1;
|
|
132
|
+
grid-row: 3;
|
|
92
133
|
display: grid;
|
|
93
134
|
grid-template-columns: 1fr 1fr;
|
|
94
135
|
gap: var(--vx-space-article-footer-gap);
|
|
@@ -11,6 +11,9 @@ declare const classes: {
|
|
|
11
11
|
readonly metaRow: string
|
|
12
12
|
readonly content: string
|
|
13
13
|
readonly tocRail: string
|
|
14
|
+
readonly tocTrigger: string
|
|
15
|
+
readonly tocTriggerLabel: string
|
|
16
|
+
readonly tocDropdown: string
|
|
14
17
|
readonly footer: string
|
|
15
18
|
readonly navCell: string
|
|
16
19
|
readonly navCellNext: string
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-block.d.ts","sourceRoot":"","sources":["../../src/content/code-block.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"code-block.d.ts","sourceRoot":"","sources":["../../src/content/code-block.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAO1C,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAA;CAC/B,CAAA;AAED,wBAAgB,SAAS,CAAC,EACxB,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,QAAe,EACf,SAAS,EACT,KAAK,GACN,EAAE,cAAc,+BAuFhB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState } from "react";
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { useIsomorphicLayoutEffect } from "../common/isomorphic-layout-effect.js";
|
|
3
4
|
import classes from "./code-block.module.css";
|
|
4
5
|
import { CopyAction } from "./copy-action.js";
|
|
5
6
|
import { highlightCode } from "./highlighter.js";
|
|
@@ -12,6 +13,10 @@ function CodeBlock({
|
|
|
12
13
|
style
|
|
13
14
|
}) {
|
|
14
15
|
const [html, setHtml] = useState(null);
|
|
16
|
+
const bodyRef = useRef(null);
|
|
17
|
+
const setBodyRef = (node) => {
|
|
18
|
+
bodyRef.current = node;
|
|
19
|
+
};
|
|
15
20
|
useEffect(() => {
|
|
16
21
|
if (language === void 0) return;
|
|
17
22
|
let cancelled = false;
|
|
@@ -23,6 +28,23 @@ function CodeBlock({
|
|
|
23
28
|
cancelled = true;
|
|
24
29
|
};
|
|
25
30
|
}, [code, language]);
|
|
31
|
+
const [showOverflowFade, setShowOverflowFade] = useState(false);
|
|
32
|
+
useIsomorphicLayoutEffect(() => {
|
|
33
|
+
const body = bodyRef.current;
|
|
34
|
+
if (!body) return;
|
|
35
|
+
const update = () => {
|
|
36
|
+
const atEnd = body.scrollLeft + body.clientWidth >= body.scrollWidth - 1;
|
|
37
|
+
setShowOverflowFade(body.scrollWidth > body.clientWidth && !atEnd);
|
|
38
|
+
};
|
|
39
|
+
update();
|
|
40
|
+
body.addEventListener("scroll", update, { passive: true });
|
|
41
|
+
const observer = new ResizeObserver(update);
|
|
42
|
+
observer.observe(body);
|
|
43
|
+
return () => {
|
|
44
|
+
body.removeEventListener("scroll", update);
|
|
45
|
+
observer.disconnect();
|
|
46
|
+
};
|
|
47
|
+
}, [html, code]);
|
|
26
48
|
const containerClass = [classes.container, className].filter(Boolean).join(" ");
|
|
27
49
|
return /* @__PURE__ */ jsxs("div", { className: containerClass, ...style !== void 0 && { style }, children: [
|
|
28
50
|
title !== void 0 && /* @__PURE__ */ jsxs("div", { className: classes.header, children: [
|
|
@@ -32,7 +54,23 @@ function CodeBlock({
|
|
|
32
54
|
showCopy && /* @__PURE__ */ jsx(CopyAction, { value: code, ariaLabel: "Copy code" })
|
|
33
55
|
] })
|
|
34
56
|
] }),
|
|
35
|
-
html !== null ? /* @__PURE__ */ jsx(
|
|
57
|
+
html !== null ? /* @__PURE__ */ jsx(
|
|
58
|
+
"div",
|
|
59
|
+
{
|
|
60
|
+
ref: setBodyRef,
|
|
61
|
+
className: classes.body,
|
|
62
|
+
...showOverflowFade && { "data-code-overflow": true },
|
|
63
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
64
|
+
}
|
|
65
|
+
) : /* @__PURE__ */ jsx(
|
|
66
|
+
"pre",
|
|
67
|
+
{
|
|
68
|
+
ref: setBodyRef,
|
|
69
|
+
className: classes.body,
|
|
70
|
+
...showOverflowFade && { "data-code-overflow": true },
|
|
71
|
+
children: /* @__PURE__ */ jsx("code", { children: code })
|
|
72
|
+
}
|
|
73
|
+
),
|
|
36
74
|
title === void 0 && showCopy && /* @__PURE__ */ jsx("div", { className: classes.floatingCopy, children: /* @__PURE__ */ jsx(CopyAction, { value: code, ariaLabel: "Copy code" }) })
|
|
37
75
|
] });
|
|
38
76
|
}
|
|
@@ -56,6 +56,27 @@
|
|
|
56
56
|
overflow-x: auto;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/* Trailing-edge overflow fade (docs/MATURATION-LEDGER.md) — `code-block.tsx` toggles this
|
|
60
|
+
* attribute from a scroll/resize measurement (`scrollWidth > clientWidth`, not yet at the end), so
|
|
61
|
+
* it never decorates a block that already fits and never lingers once scrolled to the end. The mask
|
|
62
|
+
* fades to TRANSPARENT, not to a solid color — what shows through is `.container`'s own translucent
|
|
63
|
+
* background, already identical to what borders the block everywhere else, so the fade reads as a
|
|
64
|
+
* soft edge rather than a hard cut. Reuses the content inset token rather than a new literal; LTR
|
|
65
|
+
* only, matching the rest of this file (no `dir` handling exists here to fade the other edge from).
|
|
66
|
+
*/
|
|
67
|
+
.body[data-code-overflow] {
|
|
68
|
+
mask-image: linear-gradient(
|
|
69
|
+
to right,
|
|
70
|
+
black calc(100% - var(--vx-space-code-block-content-inset-x) * 2),
|
|
71
|
+
transparent 100%
|
|
72
|
+
);
|
|
73
|
+
-webkit-mask-image: linear-gradient(
|
|
74
|
+
to right,
|
|
75
|
+
black calc(100% - var(--vx-space-code-block-content-inset-x) * 2),
|
|
76
|
+
transparent 100%
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
59
80
|
.body :global(pre.shiki) {
|
|
60
81
|
margin: 0;
|
|
61
82
|
padding: 0;
|
|
@@ -77,11 +98,20 @@ html[data-mantine-color-scheme='light'] .body :global(.shiki span) {
|
|
|
77
98
|
position: absolute;
|
|
78
99
|
top: var(--vx-space-code-block-floating-copy-offset);
|
|
79
100
|
right: var(--vx-space-code-block-floating-copy-offset);
|
|
80
|
-
opacity: 0;
|
|
81
101
|
transition: opacity 120ms ease;
|
|
82
102
|
}
|
|
83
103
|
|
|
84
|
-
|
|
104
|
+
/* Hidden-until-hover only where hover exists (pointer tier, docs/DESIGN-CORE.md § Layout). */
|
|
105
|
+
@media (hover: hover) and (pointer: fine) {
|
|
106
|
+
.floatingCopy {
|
|
107
|
+
opacity: 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.container:hover .floatingCopy {
|
|
111
|
+
opacity: 1;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
85
115
|
.container:focus-within .floatingCopy {
|
|
86
116
|
opacity: 1;
|
|
87
117
|
}
|
|
@@ -149,17 +149,22 @@
|
|
|
149
149
|
display: inline-flex;
|
|
150
150
|
vertical-align: middle;
|
|
151
151
|
margin-left: var(--vx-space-prose-heading-anchor-gap);
|
|
152
|
-
opacity: 0;
|
|
153
152
|
transition: opacity 120ms ease;
|
|
154
153
|
}
|
|
155
154
|
|
|
156
|
-
|
|
157
|
-
.
|
|
158
|
-
|
|
159
|
-
.root
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
155
|
+
/* Hidden-until-hover only where hover exists (pointer tier, docs/DESIGN-CORE.md § Layout,
|
|
156
|
+
elevation, shapes); touch shows it. Focus always reveals (the rule below outranks the hidden one). */
|
|
157
|
+
@media (hover: hover) and (pointer: fine) {
|
|
158
|
+
.root :is(h1, h2, h3, h4, h5, h6) .headingAnchor {
|
|
159
|
+
opacity: 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.root :is(h1, h2, h3, h4, h5, h6):hover .headingAnchor {
|
|
163
|
+
opacity: 1;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.root :is(h1, h2, h3, h4, h5, h6) .headingAnchor:focus-within {
|
|
163
168
|
opacity: 1;
|
|
164
169
|
}
|
|
165
170
|
|