basalt-ui 1.25.0 → 1.27.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 +8 -6
- package/CHANGELOG.md +26 -0
- package/MIGRATING.md +815 -23
- package/README.md +45 -32
- package/agent/rules/basalt-batteries.md +205 -0
- package/agent/rules/basalt-charts.md +125 -555
- package/agent/rules/basalt-controls.md +160 -0
- package/agent/rules/basalt-mantine.md +146 -439
- package/agent/rules/basalt-state.md +118 -96
- package/agent/rules/basalt-tokens.md +126 -288
- package/agent/skills/basalt-app/SKILL.md +70 -195
- package/agent/skills/basalt-charts/SKILL.md +54 -234
- package/agent/skills/basalt-design/SKILL.md +56 -248
- package/agent/templates/CLAUDE-block.md.tpl +31 -40
- package/agent/templates/DESIGN.md.tpl +22 -51
- package/configs/oxlint-plugin.js +1465 -36
- package/configs/oxlint-plugin.test.ts +1190 -11
- package/configs/oxlint.json +11 -3
- package/dist/charts/cursor/resolve.d.ts +18 -0
- package/dist/charts/cursor/resolve.d.ts.map +1 -1
- package/dist/charts/cursor/resolve.js +15 -6
- package/dist/charts/cursor/scope.d.ts +6 -3
- package/dist/charts/cursor/scope.d.ts.map +1 -1
- package/dist/charts/cursor/store.d.ts +5 -1
- package/dist/charts/cursor/store.d.ts.map +1 -1
- package/dist/charts/cursor/store.js +4 -4
- package/dist/charts/hooks/useChartCursor.d.ts.map +1 -1
- package/dist/charts/hooks/useChartCursor.js +9 -8
- package/dist/charts/index.d.ts +2 -2
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/primitives/ChartCard.d.ts +34 -9
- package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
- package/dist/charts/primitives/ChartCard.js +29 -114
- package/dist/charts/primitives/ChartCard.test.d.ts +2 -0
- package/dist/charts/primitives/ChartCard.test.d.ts.map +1 -0
- package/dist/charts/sparklines/BarSparkline.d.ts +26 -2
- package/dist/charts/sparklines/BarSparkline.d.ts.map +1 -1
- package/dist/charts/sparklines/BarSparkline.js +18 -4
- package/dist/cli/check-coverage.test.d.ts +2 -0
- package/dist/cli/check-coverage.test.d.ts.map +1 -0
- package/dist/cli/index.d.ts +67 -4
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +225 -7
- package/dist/connectivity/connectivity-indicator.d.ts +4 -1
- package/dist/connectivity/connectivity-indicator.d.ts.map +1 -1
- package/dist/connectivity/connectivity-indicator.js +1 -1
- package/dist/content/index.d.ts +5 -3
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +4 -2
- package/dist/content/prose.module.css +7 -28
- package/dist/controls/actions.d.ts +169 -0
- package/dist/controls/actions.d.ts.map +1 -0
- package/dist/controls/actions.js +287 -0
- package/dist/controls/actions.module.css +62 -0
- package/dist/controls/actions.module.css.d.ts +13 -0
- package/dist/controls/actions.test.d.ts +2 -0
- package/dist/controls/actions.test.d.ts.map +1 -0
- package/dist/controls/actions.type-guard.test.d.ts +2 -0
- package/dist/controls/actions.type-guard.test.d.ts.map +1 -0
- package/dist/controls/compare-filter.d.ts +41 -0
- package/dist/controls/compare-filter.d.ts.map +1 -0
- package/dist/controls/compare-filter.js +23 -0
- package/dist/controls/control-group.d.ts +19 -0
- package/dist/controls/control-group.d.ts.map +1 -0
- package/dist/controls/control-group.js +20 -0
- package/dist/controls/control-group.test.d.ts +2 -0
- package/dist/controls/control-group.test.d.ts.map +1 -0
- package/dist/controls/controls.module.css +542 -0
- package/dist/controls/controls.module.css.d.ts +35 -0
- package/dist/controls/controls.router.test.d.ts +2 -0
- package/dist/controls/controls.router.test.d.ts.map +1 -0
- package/dist/controls/enum-filter.d.ts +39 -0
- package/dist/controls/enum-filter.d.ts.map +1 -0
- package/dist/controls/enum-filter.js +93 -0
- package/dist/controls/filter-context.d.ts +60 -0
- package/dist/controls/filter-context.d.ts.map +1 -0
- package/dist/controls/filter-context.js +69 -0
- package/dist/controls/filter-pill.d.ts +28 -0
- package/dist/controls/filter-pill.d.ts.map +1 -0
- package/dist/controls/filter-pill.js +70 -0
- package/dist/controls/filter-set.d.ts +13 -0
- package/dist/controls/filter-set.d.ts.map +1 -0
- package/dist/controls/filter-set.js +125 -0
- package/dist/controls/filter-set.test.d.ts +2 -0
- package/dist/controls/filter-set.test.d.ts.map +1 -0
- package/dist/controls/filter-sheet.d.ts +117 -0
- package/dist/controls/filter-sheet.d.ts.map +1 -0
- package/dist/controls/filter-sheet.js +146 -0
- package/dist/controls/glyphs.d.ts +27 -0
- package/dist/controls/glyphs.d.ts.map +1 -0
- package/dist/controls/glyphs.js +49 -0
- package/dist/controls/index.d.ts +20 -0
- package/dist/controls/index.d.ts.map +1 -0
- package/dist/controls/index.js +46 -0
- package/dist/controls/multi-select-filter.d.ts +23 -0
- package/dist/controls/multi-select-filter.d.ts.map +1 -0
- package/dist/controls/multi-select-filter.js +89 -0
- package/dist/controls/number-filter.d.ts +26 -0
- package/dist/controls/number-filter.d.ts.map +1 -0
- package/dist/controls/number-filter.js +143 -0
- package/dist/controls/peer-boundary.test.d.ts +2 -0
- package/dist/controls/peer-boundary.test.d.ts.map +1 -0
- package/dist/controls/props-contract.test.d.ts +2 -0
- package/dist/controls/props-contract.test.d.ts.map +1 -0
- package/dist/controls/range-filter.d.ts +43 -0
- package/dist/controls/range-filter.d.ts.map +1 -0
- package/dist/controls/range-filter.js +135 -0
- package/dist/controls/range-filter.type-guard.test.d.ts +2 -0
- package/dist/controls/range-filter.type-guard.test.d.ts.map +1 -0
- package/dist/controls/search-filter.d.ts +10 -0
- package/dist/controls/search-filter.d.ts.map +1 -0
- package/dist/controls/search-filter.js +81 -0
- package/dist/controls/select-filter.d.ts +74 -0
- package/dist/controls/select-filter.d.ts.map +1 -0
- package/dist/controls/select-filter.js +10 -0
- package/dist/controls/sync-button.d.ts +38 -0
- package/dist/controls/sync-button.d.ts.map +1 -0
- package/dist/controls/sync-button.js +119 -0
- package/dist/controls/sync-button.module.css +63 -0
- package/dist/controls/sync-button.module.css.d.ts +11 -0
- package/dist/controls/sync-button.test.d.ts +2 -0
- package/dist/controls/sync-button.test.d.ts.map +1 -0
- package/dist/controls/toggle-filter.d.ts +9 -0
- package/dist/controls/toggle-filter.d.ts.map +1 -0
- package/dist/controls/toggle-filter.js +42 -0
- package/dist/controls/view-tabs.d.ts +23 -0
- package/dist/controls/view-tabs.d.ts.map +1 -0
- package/dist/controls/view-tabs.js +59 -0
- package/dist/controls-dates/date-range-picker.d.ts +4 -0
- package/dist/controls-dates/date-range-picker.d.ts.map +1 -0
- package/dist/controls-dates/date-range-picker.js +18 -0
- package/dist/controls-dates/index.d.ts +9 -0
- package/dist/controls-dates/index.d.ts.map +1 -0
- package/dist/controls-dates/index.js +4 -0
- package/dist/dashboard/delta-badge.d.ts +6 -12
- package/dist/dashboard/delta-badge.d.ts.map +1 -1
- package/dist/dashboard/delta-badge.js +1 -50
- package/dist/dashboard/index.d.ts +1 -1
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +3 -1
- package/dist/dashboard/settings-section.d.ts +6 -4
- package/dist/dashboard/settings-section.d.ts.map +1 -1
- package/dist/dashboard/settings-section.js +23 -16
- package/dist/dashboard/settings-section.module.css +10 -0
- package/dist/dashboard/settings-section.module.css.d.ts +1 -0
- package/dist/dashboard/settings-section.test.d.ts +2 -0
- package/dist/dashboard/settings-section.test.d.ts.map +1 -0
- package/dist/dashboard/stat-card.d.ts +95 -9
- package/dist/dashboard/stat-card.d.ts.map +1 -1
- package/dist/dashboard/stat-card.js +108 -49
- package/dist/dashboard/stat-card.module.css +153 -0
- package/dist/dashboard/stat-card.module.css.d.ts +15 -0
- package/dist/data/data-table.d.ts +37 -15
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +96 -58
- package/dist/guard/grace.test.d.ts +20 -0
- package/dist/guard/grace.test.d.ts.map +1 -0
- package/dist/guard/index.d.ts +66 -3
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +78 -7
- package/dist/guard/types.d.ts +3 -3
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/index.d.ts +13 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -10
- package/dist/nav/types.d.ts +78 -2
- package/dist/nav/types.d.ts.map +1 -1
- package/dist/notifications/bell.d.ts +4 -1
- package/dist/notifications/bell.d.ts.map +1 -1
- package/dist/notifications/index.d.ts +1 -1
- package/dist/router-tanstack/field.d.ts +14 -0
- package/dist/router-tanstack/field.d.ts.map +1 -0
- package/dist/router-tanstack/field.js +4 -0
- package/dist/router-tanstack/index.d.ts +6 -2
- package/dist/router-tanstack/index.d.ts.map +1 -1
- package/dist/router-tanstack/index.js +4 -0
- package/dist/router-tanstack/multi-search-param-store.d.ts +4 -52
- package/dist/router-tanstack/multi-search-param-store.d.ts.map +1 -1
- package/dist/router-tanstack/multi-search-param-store.js +19 -27
- package/dist/router-tanstack/search-param-store.d.ts +3 -87
- package/dist/router-tanstack/search-param-store.d.ts.map +1 -1
- package/dist/router-tanstack/search-param-store.js +16 -45
- package/dist/router-tanstack/search-store.d.ts +84 -0
- package/dist/router-tanstack/search-store.d.ts.map +1 -0
- package/dist/router-tanstack/search-store.js +271 -0
- package/dist/router-tanstack/search-store.router.test.d.ts +2 -0
- package/dist/router-tanstack/search-store.router.test.d.ts.map +1 -0
- package/dist/router-tanstack/search-store.test.d.ts +2 -0
- package/dist/router-tanstack/search-store.test.d.ts.map +1 -0
- package/dist/router-tanstack/use-nav.d.ts +0 -2
- package/dist/router-tanstack/use-nav.d.ts.map +1 -1
- package/dist/router-tanstack/use-nav.js +34 -12
- package/dist/router-tanstack/use-nav.test.d.ts +2 -0
- package/dist/router-tanstack/use-nav.test.d.ts.map +1 -0
- package/dist/section/index.d.ts +2 -0
- package/dist/section/index.d.ts.map +1 -0
- package/dist/section/index.js +4 -0
- package/dist/section/section.d.ts +24 -0
- package/dist/section/section.d.ts.map +1 -0
- package/dist/section/section.js +126 -0
- package/dist/section/section.module.css +104 -0
- package/dist/section/section.module.css.d.ts +11 -0
- package/dist/section/section.test.d.ts +2 -0
- package/dist/section/section.test.d.ts.map +1 -0
- package/dist/shell/app-breadcrumbs.d.ts.map +1 -1
- package/dist/shell/app-breadcrumbs.js +18 -15
- package/dist/shell/app-header.module.css +77 -37
- package/dist/shell/app-header.module.css.d.ts +2 -1
- package/dist/shell/app-mobile-nav.d.ts +9 -2
- package/dist/shell/app-mobile-nav.d.ts.map +1 -1
- package/dist/shell/app-mobile-nav.js +98 -11
- package/dist/shell/app-mobile-nav.module.css +8 -0
- package/dist/shell/app-mobile-nav.module.css.d.ts +1 -0
- package/dist/shell/app-sidebar.d.ts +55 -28
- package/dist/shell/app-sidebar.d.ts.map +1 -1
- package/dist/shell/app-sidebar.js +116 -67
- package/dist/shell/app-sidebar.module.css +303 -20
- package/dist/shell/app-sidebar.module.css.d.ts +19 -1
- package/dist/shell/index.d.ts +55 -21
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +40 -18
- package/dist/shell/mobile-nav-model.d.ts +13 -2
- package/dist/shell/mobile-nav-model.d.ts.map +1 -1
- package/dist/shell/mobile-nav-model.js +15 -1
- package/dist/shell/nav-count-badge.d.ts +1 -1
- package/dist/shell/page-bar.d.ts +51 -0
- package/dist/shell/page-bar.d.ts.map +1 -0
- package/dist/shell/page-bar.js +154 -0
- package/dist/shell/page-bar.module.css +178 -0
- package/dist/shell/page-bar.module.css.d.ts +17 -0
- package/dist/shell/page-bar.test.d.ts +2 -0
- package/dist/shell/page-bar.test.d.ts.map +1 -0
- package/dist/shell/sidebar-block-model.d.ts +48 -0
- package/dist/shell/sidebar-block-model.d.ts.map +1 -0
- package/dist/shell/sidebar-block-model.js +39 -0
- package/dist/shell/sidebar-blocks.d.ts +32 -0
- package/dist/shell/sidebar-blocks.d.ts.map +1 -0
- package/dist/shell/sidebar-blocks.js +169 -0
- package/dist/shell/sidebar-search.d.ts +13 -1
- package/dist/shell/sidebar-search.d.ts.map +1 -1
- package/dist/shell/sidebar-search.js +34 -1
- package/dist/shell/sidebar-search.module.css +26 -0
- package/dist/shell/sidebar-search.module.css.d.ts +2 -0
- package/dist/state/fields.d.ts +565 -0
- package/dist/state/fields.d.ts.map +1 -0
- package/dist/state/fields.js +405 -0
- package/dist/state/fields.test.d.ts +2 -0
- package/dist/state/fields.test.d.ts.map +1 -0
- package/dist/state/persisted.d.ts +60 -0
- package/dist/state/persisted.d.ts.map +1 -0
- package/dist/state/persisted.js +123 -0
- package/dist/state/persisted.test.d.ts +2 -0
- package/dist/state/persisted.test.d.ts.map +1 -0
- package/dist/state.d.ts +11 -56
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +14 -120
- package/dist/styles.css +13 -0
- package/dist/surfaces.d.ts +106 -24
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +156 -19
- package/dist/theme/controls.module.css +16 -1
- package/dist/theme/ctl-theme.d.ts +32 -0
- package/dist/theme/ctl-theme.d.ts.map +1 -0
- package/dist/theme/ctl-theme.js +54 -0
- package/dist/theme/ctl-theme.test.d.ts +2 -0
- package/dist/theme/ctl-theme.test.d.ts.map +1 -0
- package/dist/theme/ctl-tier-coverage.test.d.ts +2 -0
- package/dist/theme/ctl-tier-coverage.test.d.ts.map +1 -0
- package/dist/theme/divider-law.test.d.ts +2 -0
- package/dist/theme/divider-law.test.d.ts.map +1 -0
- package/dist/theme/icon-slot.d.ts +44 -0
- package/dist/theme/icon-slot.d.ts.map +1 -0
- package/dist/theme/icon-slot.js +21 -0
- package/dist/theme/icon-slot.module.css +47 -0
- package/dist/theme/icon-slot.module.css.d.ts +8 -0
- package/dist/theme/icon-slot.test.d.ts +2 -0
- package/dist/theme/icon-slot.test.d.ts.map +1 -0
- package/dist/theme/index.d.ts +1 -0
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +82 -5
- package/dist/theme/layout-rhythm-css.test.d.ts +2 -0
- package/dist/theme/layout-rhythm-css.test.d.ts.map +1 -0
- package/dist/theme/segmented-control.module.css +20 -0
- package/dist/theme/shadow-surfaces.test.d.ts.map +1 -1
- package/dist/tokens/index.d.ts +12 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +38 -8
- package/dist/tokens/palette.d.ts +97 -61
- package/dist/tokens/palette.d.ts.map +1 -1
- package/dist/tokens/palette.js +76 -38
- package/dist/tokens.css +10 -2
- package/dist/widget-header/delta-badge.d.ts +13 -0
- package/dist/widget-header/delta-badge.d.ts.map +1 -0
- package/dist/widget-header/delta-badge.js +29 -0
- package/dist/widget-header/delta-badge.test.d.ts +2 -0
- package/dist/widget-header/delta-badge.test.d.ts.map +1 -0
- package/dist/widget-header/index.d.ts +3 -0
- package/dist/widget-header/index.d.ts.map +1 -0
- package/dist/widget-header/index.js +6 -0
- package/dist/widget-header/no-mantine.test.d.ts +2 -0
- package/dist/widget-header/no-mantine.test.d.ts.map +1 -0
- package/dist/widget-header/widget-header.d.ts +67 -0
- package/dist/widget-header/widget-header.d.ts.map +1 -0
- package/dist/widget-header/widget-header.js +89 -0
- package/dist/widget-header/widget-header.module.css +350 -0
- package/dist/widget-header/widget-header.module.css.d.ts +25 -0
- package/dist/widget-header/widget-header.test.d.ts +2 -0
- package/dist/widget-header/widget-header.test.d.ts.map +1 -0
- package/llms.txt +30 -17
- package/package.json +14 -1
- package/src/charts/cursor/resolve.test.ts +29 -1
- package/src/charts/cursor/resolve.ts +38 -6
- package/src/charts/cursor/scope.tsx +6 -3
- package/src/charts/cursor/store.test.ts +19 -1
- package/src/charts/cursor/store.ts +10 -5
- package/src/charts/hooks/useChartCursor.ts +16 -8
- package/src/charts/index.ts +2 -2
- package/src/charts/primitives/CartesianChart.test.tsx +124 -0
- package/src/charts/primitives/ChartCard.test.tsx +66 -0
- package/src/charts/primitives/ChartCard.tsx +86 -146
- package/src/charts/sparklines/BarSparkline.tsx +43 -5
- package/src/cli/check-coverage.test.ts +297 -0
- package/src/cli/check-theme.test.ts +38 -14
- package/src/cli/index.ts +392 -16
- package/src/cli/init-sync.test.ts +97 -0
- package/src/connectivity/connectivity-indicator.tsx +16 -9
- package/src/content/index.ts +16 -3
- package/src/content/prose.module.css +7 -28
- package/src/content/prose.module.css.test.ts +8 -24
- package/src/controls/actions.module.css +62 -0
- package/src/controls/actions.module.css.d.ts +13 -0
- package/src/controls/actions.test.tsx +252 -0
- package/src/controls/actions.tsx +655 -0
- package/src/controls/actions.type-guard.test.ts +63 -0
- package/src/controls/compare-filter.tsx +64 -0
- package/src/controls/control-group.test.tsx +229 -0
- package/src/controls/control-group.tsx +63 -0
- package/src/controls/controls.module.css +542 -0
- package/src/controls/controls.module.css.d.ts +35 -0
- package/src/controls/controls.router.test.tsx +1053 -0
- package/src/controls/enum-filter.tsx +170 -0
- package/src/controls/filter-context.tsx +158 -0
- package/src/controls/filter-pill.tsx +120 -0
- package/src/controls/filter-set.test.tsx +472 -0
- package/src/controls/filter-set.tsx +225 -0
- package/src/controls/filter-sheet.tsx +285 -0
- package/src/controls/glyphs.tsx +81 -0
- package/src/controls/index.ts +49 -0
- package/src/controls/multi-select-filter.tsx +140 -0
- package/src/controls/number-filter.tsx +291 -0
- package/src/controls/peer-boundary.test.ts +85 -0
- package/src/controls/props-contract.test.tsx +137 -0
- package/src/controls/range-filter.tsx +237 -0
- package/src/controls/range-filter.type-guard.test.tsx +122 -0
- package/src/controls/search-filter.tsx +123 -0
- package/src/controls/select-filter.tsx +89 -0
- package/src/controls/sync-button.module.css +63 -0
- package/src/controls/sync-button.module.css.d.ts +11 -0
- package/src/controls/sync-button.test.tsx +183 -0
- package/src/controls/sync-button.tsx +197 -0
- package/src/controls/toggle-filter.tsx +60 -0
- package/src/controls/view-tabs.tsx +110 -0
- package/src/controls-dates/date-range-picker.tsx +42 -0
- package/src/controls-dates/index.ts +8 -0
- package/src/dashboard/delta-badge.tsx +4 -74
- package/src/dashboard/index.ts +6 -1
- package/src/dashboard/settings-section.module.css +10 -0
- package/src/dashboard/settings-section.module.css.d.ts +1 -0
- package/src/dashboard/settings-section.test.tsx +56 -0
- package/src/dashboard/settings-section.tsx +33 -30
- package/src/dashboard/stat-card.module.css +153 -0
- package/src/dashboard/stat-card.module.css.d.ts +15 -0
- package/src/dashboard/stat-card.test.tsx +298 -1
- package/src/dashboard/stat-card.tsx +289 -67
- package/src/data/data-table.test.tsx +96 -11
- package/src/data/data-table.tsx +228 -84
- package/src/guard/check-source.test.ts +159 -13
- package/src/guard/grace.test.ts +158 -0
- package/src/guard/index.ts +185 -29
- package/src/guard/types.ts +4 -2
- package/src/index.ts +51 -5
- package/src/nav/types.ts +84 -2
- package/src/notifications/bell.tsx +6 -3
- package/src/notifications/index.ts +1 -1
- package/src/router-tanstack/field.ts +35 -0
- package/src/router-tanstack/index.ts +28 -2
- package/src/router-tanstack/multi-search-param-store.test.ts +71 -3
- package/src/router-tanstack/multi-search-param-store.ts +46 -77
- package/src/router-tanstack/search-param-store.ts +42 -159
- package/src/router-tanstack/search-store.router.test.tsx +882 -0
- package/src/router-tanstack/search-store.test.ts +578 -0
- package/src/router-tanstack/search-store.ts +546 -0
- package/src/router-tanstack/use-nav.test.tsx +187 -0
- package/src/router-tanstack/use-nav.ts +72 -14
- package/src/section/index.ts +1 -0
- package/src/section/section.module.css +104 -0
- package/src/section/section.module.css.d.ts +11 -0
- package/src/section/section.test.tsx +204 -0
- package/src/section/section.tsx +220 -0
- package/src/shell/app-breadcrumbs.tsx +44 -31
- package/src/shell/app-header.module.css +77 -37
- package/src/shell/app-header.module.css.d.ts +2 -1
- package/src/shell/app-mobile-nav.module.css +8 -0
- package/src/shell/app-mobile-nav.module.css.d.ts +1 -0
- package/src/shell/app-mobile-nav.tsx +147 -8
- package/src/shell/app-sidebar-account.tsx +2 -2
- package/src/shell/app-sidebar.module.css +303 -20
- package/src/shell/app-sidebar.module.css.d.ts +19 -1
- package/src/shell/app-sidebar.test.tsx +456 -41
- package/src/shell/app-sidebar.tsx +276 -140
- package/src/shell/index.test.tsx +291 -5
- package/src/shell/index.tsx +137 -38
- package/src/shell/mobile-nav-model.test.ts +228 -7
- package/src/shell/mobile-nav-model.ts +53 -3
- package/src/shell/nav-count-badge.tsx +1 -1
- package/src/shell/page-bar.module.css +178 -0
- package/src/shell/page-bar.module.css.d.ts +17 -0
- package/src/shell/page-bar.test.tsx +316 -0
- package/src/shell/page-bar.tsx +315 -0
- package/src/shell/sidebar-block-model.ts +83 -0
- package/src/shell/sidebar-blocks.tsx +301 -0
- package/src/shell/sidebar-search.module.css +26 -0
- package/src/shell/sidebar-search.module.css.d.ts +2 -0
- package/src/shell/sidebar-search.tsx +71 -2
- package/src/state/fields.test.tsx +512 -0
- package/src/state/fields.ts +1150 -0
- package/src/state/persisted.test.ts +91 -0
- package/src/state/persisted.ts +261 -0
- package/src/state.ts +52 -240
- package/src/styles.css +13 -0
- package/src/surfaces.ts +204 -36
- package/src/theme/controls.module.css +16 -1
- package/src/theme/ctl-theme.test.tsx +275 -0
- package/src/theme/ctl-theme.tsx +138 -0
- package/src/theme/ctl-tier-coverage.test.ts +170 -0
- package/src/theme/density-relations.test.ts +106 -51
- package/src/theme/divider-law.test.ts +259 -0
- package/src/theme/icon-slot.module.css +47 -0
- package/src/theme/icon-slot.module.css.d.ts +8 -0
- package/src/theme/icon-slot.test.tsx +275 -0
- package/src/theme/icon-slot.tsx +59 -0
- package/src/theme/index.ts +165 -3
- package/src/theme/layout-rhythm-css.test.ts +72 -0
- package/src/theme/radius.test.ts +11 -1
- package/src/theme/segmented-control.module.css +20 -0
- package/src/theme/shadow-surfaces.test.ts +20 -7
- package/src/theme/spacing.test.ts +75 -27
- package/src/theme/use-basalt-spacing.ts +2 -2
- package/src/tokens/density.test.ts +7 -25
- package/src/tokens/index.ts +48 -8
- package/src/tokens/palette.ts +107 -73
- package/src/widget-header/delta-badge.test.tsx +60 -0
- package/src/widget-header/delta-badge.tsx +57 -0
- package/src/widget-header/index.ts +2 -0
- package/src/widget-header/no-mantine.test.ts +33 -0
- package/src/widget-header/widget-header.module.css +350 -0
- package/src/widget-header/widget-header.module.css.d.ts +25 -0
- package/src/widget-header/widget-header.test.tsx +187 -0
- package/src/widget-header/widget-header.tsx +213 -0
- package/agent/rules/basalt-agent.md +0 -452
- package/agent/rules/basalt-app.md +0 -246
- package/agent/rules/basalt-commands.md +0 -320
- package/agent/rules/basalt-content.md +0 -409
- package/agent/rules/basalt-data.md +0 -329
- package/agent/rules/basalt-forms.md +0 -186
- package/agent/rules/basalt-notifications.md +0 -264
- package/agent/rules/basalt-query.md +0 -187
- package/agent/rules/basalt-router.md +0 -336
- package/dist/content/article-filter-bar.d.ts +0 -40
- package/dist/content/article-filter-bar.d.ts.map +0 -1
- package/dist/content/article-filter-bar.js +0 -56
- package/dist/shell/page-header.d.ts +0 -13
- package/dist/shell/page-header.d.ts.map +0 -1
- package/dist/shell/page-header.js +0 -23
- package/src/content/article-filter-bar.tsx +0 -88
- package/src/shell/page-header.tsx +0 -35
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { SegmentedControl, Select } from "@mantine/core";
|
|
3
|
+
import classes from "./controls.module.css";
|
|
4
|
+
const PHONE_TRACK_MAX = 3;
|
|
5
|
+
function ViewTabs({
|
|
6
|
+
field,
|
|
7
|
+
options,
|
|
8
|
+
label = "View"
|
|
9
|
+
}) {
|
|
10
|
+
const [value, setValue] = field.use();
|
|
11
|
+
const all = options ?? field.options.map((option) => ({ value: option.value, label: option.label }));
|
|
12
|
+
const desktop = all.filter((option) => option.only !== "sm-down");
|
|
13
|
+
const phone = all.filter((option) => option.only !== "sm-up");
|
|
14
|
+
const commit = (next) => {
|
|
15
|
+
setValue(next);
|
|
16
|
+
};
|
|
17
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
18
|
+
/* @__PURE__ */ jsx(
|
|
19
|
+
SegmentedControl,
|
|
20
|
+
{
|
|
21
|
+
"aria-label": label,
|
|
22
|
+
visibleFrom: "sm",
|
|
23
|
+
size: "ctl",
|
|
24
|
+
value,
|
|
25
|
+
data: desktop.map((option) => ({ value: option.value, label: option.label })),
|
|
26
|
+
onChange: commit
|
|
27
|
+
}
|
|
28
|
+
),
|
|
29
|
+
phone.length <= PHONE_TRACK_MAX ? /* @__PURE__ */ jsx(
|
|
30
|
+
SegmentedControl,
|
|
31
|
+
{
|
|
32
|
+
"aria-label": label,
|
|
33
|
+
hiddenFrom: "sm",
|
|
34
|
+
size: "ctl",
|
|
35
|
+
fullWidth: true,
|
|
36
|
+
value,
|
|
37
|
+
data: phone.map((option) => ({ value: option.value, label: option.label })),
|
|
38
|
+
onChange: commit
|
|
39
|
+
}
|
|
40
|
+
) : /* @__PURE__ */ jsx(
|
|
41
|
+
Select,
|
|
42
|
+
{
|
|
43
|
+
"aria-label": label,
|
|
44
|
+
hiddenFrom: "sm",
|
|
45
|
+
size: "ctl",
|
|
46
|
+
className: classes.phoneSelect,
|
|
47
|
+
value,
|
|
48
|
+
allowDeselect: false,
|
|
49
|
+
data: phone.map((option) => ({ value: option.value, label: option.label })),
|
|
50
|
+
onChange: (next) => {
|
|
51
|
+
if (next !== null) commit(next);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
] });
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
ViewTabs
|
|
59
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-range-picker.d.ts","sourceRoot":"","sources":["../../src/controls-dates/date-range-picker.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AAEtE,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,sBAAsB,GAAG,SAAS,CAatF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { DatePicker } from "@mantine/dates";
|
|
3
|
+
function DateRangePicker({ value, onChange }) {
|
|
4
|
+
return /* @__PURE__ */ jsx(
|
|
5
|
+
DatePicker,
|
|
6
|
+
{
|
|
7
|
+
type: "range",
|
|
8
|
+
allowSingleDateInRange: true,
|
|
9
|
+
value: [value.from ?? null, value.to ?? null],
|
|
10
|
+
onChange: ([from, to]) => {
|
|
11
|
+
if (from !== null && to !== null) onChange({ from, to });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
DateRangePicker
|
|
18
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `basalt-ui/controls-dates` — the one export that needs `@mantine/dates`
|
|
3
|
+
* (`docs/CONTROLS-SPEC.md` §3). Split off `./controls` on purpose: `./controls` resolves and renders
|
|
4
|
+
* with no `@mantine/dates` installed, and this subpath is the only place that stops being true.
|
|
5
|
+
* Proven from outside the package by `scripts/pack-test.sh`.
|
|
6
|
+
*/
|
|
7
|
+
export { DateRangePicker } from './date-range-picker.js';
|
|
8
|
+
export type { RangeCustomPickerProps } from '../controls/range-filter.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/controls-dates/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,YAAY,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA"}
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
withGlyph?: boolean;
|
|
8
|
-
/** Optional comparison timeframe rendered directly after the value in a dimmer shade of the same
|
|
9
|
-
* tone (e.g. `MoM`, `WoW`, `YTD`) — states what the delta is measured against without a hover. */
|
|
10
|
-
period?: string | undefined;
|
|
11
|
-
};
|
|
12
|
-
export declare function DeltaBadge({ value, format, withGlyph, period, }: DeltaBadgeProps): import("react").JSX.Element;
|
|
1
|
+
/**
|
|
2
|
+
* `DeltaBadge` moved to `src/widget-header/` (docs/CONTROLS-SPEC.md §2.2) so `WidgetHeader` can
|
|
3
|
+
* compose it Mantine-free. Re-exported here unchanged so this deep import path — and `StatCard`'s
|
|
4
|
+
* own `./delta-badge` import — keep working without a wave-3 edit.
|
|
5
|
+
*/
|
|
6
|
+
export { DeltaBadge, type DeltaBadgeProps } from '../widget-header/delta-badge.js';
|
|
13
7
|
//# sourceMappingURL=delta-badge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delta-badge.d.ts","sourceRoot":"","sources":["../../src/dashboard/delta-badge.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"delta-badge.d.ts","sourceRoot":"","sources":["../../src/dashboard/delta-badge.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAA"}
|
|
@@ -1,53 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Badge } from "@mantine/core";
|
|
3
|
-
import { alpha, VX } from "../tokens/index.js";
|
|
4
|
-
const defaultFormat = (value) => `${Math.abs(value).toFixed(1)}%`;
|
|
5
|
-
function DeltaBadge({
|
|
6
|
-
value,
|
|
7
|
-
format = defaultFormat,
|
|
8
|
-
withGlyph = true,
|
|
9
|
-
period
|
|
10
|
-
}) {
|
|
11
|
-
const tone = value > 0 ? VX.status.good : value < 0 ? VX.status.bad : VX.faint;
|
|
12
|
-
const glyph = value > 0 ? "\u25B2" : value < 0 ? "\u25BC" : void 0;
|
|
13
|
-
const showGlyph = withGlyph && glyph !== void 0;
|
|
14
|
-
return /* @__PURE__ */ jsxs(
|
|
15
|
-
Badge,
|
|
16
|
-
{
|
|
17
|
-
styles: {
|
|
18
|
-
root: {
|
|
19
|
-
backgroundColor: alpha(tone, 0.13),
|
|
20
|
-
padding: "var(--vx-space-badge-inset-y) var(--vx-space-badge-inset-x)",
|
|
21
|
-
height: "auto"
|
|
22
|
-
},
|
|
23
|
-
label: {
|
|
24
|
-
display: "inline-flex",
|
|
25
|
-
// theme-allow inline-display — a Badge `styles.label` part, not a layout node Flex could replace
|
|
26
|
-
alignItems: "center",
|
|
27
|
-
gap: 3,
|
|
28
|
-
// theme-allow inline-spacing — sub-scale glyph-to-label gap, below the smallest scale stop
|
|
29
|
-
fontFamily: "var(--basalt-font-mono)",
|
|
30
|
-
fontSize: VX.text.xs,
|
|
31
|
-
fontWeight: 600,
|
|
32
|
-
textTransform: "none",
|
|
33
|
-
letterSpacing: "normal",
|
|
34
|
-
color: tone
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
children: [
|
|
38
|
-
showGlyph && /* @__PURE__ */ jsx("span", { style: { fontSize: "0.8em" }, children: glyph }),
|
|
39
|
-
format(value),
|
|
40
|
-
period && /* @__PURE__ */ jsx(
|
|
41
|
-
"span",
|
|
42
|
-
{
|
|
43
|
-
style: { marginLeft: 4, fontWeight: 500, opacity: 0.6 },
|
|
44
|
-
children: period
|
|
45
|
-
}
|
|
46
|
-
)
|
|
47
|
-
]
|
|
48
|
-
}
|
|
49
|
-
);
|
|
50
|
-
}
|
|
1
|
+
import { DeltaBadge } from "../widget-header/delta-badge.js";
|
|
51
2
|
export {
|
|
52
3
|
DeltaBadge
|
|
53
4
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { DeltaBadge, type DeltaBadgeProps } from './delta-badge.js';
|
|
2
|
-
export { StatCard, type StatCardProps, type StatCardTone } from './stat-card.js';
|
|
2
|
+
export { StatCard, type StatCardBreakdownRow, type StatCardProps, type StatCardTone, } from './stat-card.js';
|
|
3
3
|
export { EmptyState, type EmptyStateProps } from './empty-state.js';
|
|
4
4
|
export { SettingsSection, type SettingsSectionProps, SettingsRow, type SettingsRowProps, DangerZone, type DangerZoneProps, } from './settings-section.js';
|
|
5
5
|
export { QueryState, type QueryStateProps, type QueryStateLike, type QueryStateVariant, type QueryEmptyCopy, LoadingState, type LoadingStateProps, ErrorState, type ErrorStateProps, } from './query-state.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,EACL,QAAQ,EACR,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAChE,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,EACzB,WAAW,EACX,KAAK,gBAAgB,EACrB,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,UAAU,EACV,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,YAAY,EACZ,KAAK,iBAAiB,EACtB,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,eAAe,CAAA"}
|
package/dist/dashboard/index.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
export type SettingsSectionProps = {
|
|
3
|
-
/** Head-font section title
|
|
3
|
+
/** Head-font section title, rendered via `WidgetHeader tier="section"`. */
|
|
4
4
|
title: string;
|
|
5
5
|
/** Optional 13px muted description below the title. */
|
|
6
|
-
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
/** Header-right slot — wrapped in `CtlSlot` (C1/C5). */
|
|
8
|
+
actions?: ReactNode;
|
|
7
9
|
/** Section body — typically a stack of `SettingsRow`s. */
|
|
8
10
|
children: ReactNode;
|
|
9
11
|
};
|
|
10
|
-
export declare function SettingsSection({ title,
|
|
12
|
+
export declare function SettingsSection({ title, subtitle, actions, children }: SettingsSectionProps): import("react").JSX.Element;
|
|
11
13
|
export type SettingsRowProps = {
|
|
12
14
|
/** 13px ink label on the left. */
|
|
13
15
|
label: string;
|
|
@@ -20,5 +22,5 @@ export type SettingsRowProps = {
|
|
|
20
22
|
};
|
|
21
23
|
export declare function SettingsRow({ label, description, control, children }: SettingsRowProps): import("react").JSX.Element;
|
|
22
24
|
export type DangerZoneProps = SettingsSectionProps;
|
|
23
|
-
export declare function DangerZone({ title,
|
|
25
|
+
export declare function DangerZone({ title, subtitle, actions, children }: DangerZoneProps): import("react").JSX.Element;
|
|
24
26
|
//# sourceMappingURL=settings-section.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-section.d.ts","sourceRoot":"","sources":["../../src/dashboard/settings-section.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"settings-section.d.ts","sourceRoot":"","sources":["../../src/dashboard/settings-section.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAetC,MAAM,MAAM,oBAAoB,GAAG;IACjC,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAA;IACb,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,0DAA0D;IAC1D,QAAQ,EAAE,SAAS,CAAA;CACpB,CAAA;AAED,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,oBAAoB,+BAc3F;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mDAAmD;IACnD,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB,CAAA;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,gBAAgB,+BAYtF;AAED,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAA;AAElD,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,eAAe,+BAoBjF"}
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Card, Stack } from "@mantine/core";
|
|
3
|
+
import { WidgetHeader } from "../widget-header/index.js";
|
|
4
|
+
import { CtlSlot } from "../theme/index.js";
|
|
3
5
|
import { alpha, VX } from "../tokens/index.js";
|
|
4
6
|
import classes from "./settings-section.module.css";
|
|
5
|
-
const titleStyle = {
|
|
6
|
-
fontFamily: "var(--basalt-font-head)",
|
|
7
|
-
fontStretch: "88%",
|
|
8
|
-
fontSize: VX.text.md,
|
|
9
|
-
fontWeight: 550,
|
|
10
|
-
color: VX.ink
|
|
11
|
-
};
|
|
12
7
|
const eyebrowStyle = {
|
|
13
8
|
fontFamily: "var(--basalt-font-mono)",
|
|
14
9
|
fontSize: VX.text.micro,
|
|
@@ -17,12 +12,17 @@ const eyebrowStyle = {
|
|
|
17
12
|
textTransform: "uppercase",
|
|
18
13
|
color: VX.status.bad
|
|
19
14
|
};
|
|
20
|
-
function SettingsSection({ title,
|
|
15
|
+
function SettingsSection({ title, subtitle, actions, children }) {
|
|
21
16
|
return /* @__PURE__ */ jsxs(Card, { style: { padding: "var(--mantine-spacing-xs) var(--mantine-spacing-sm)" }, children: [
|
|
22
|
-
/* @__PURE__ */
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
/* @__PURE__ */ jsx("div", { className: classes.header, children: /* @__PURE__ */ jsx(
|
|
18
|
+
WidgetHeader,
|
|
19
|
+
{
|
|
20
|
+
tier: "section",
|
|
21
|
+
title,
|
|
22
|
+
...subtitle !== void 0 && { subtitle },
|
|
23
|
+
...actions !== void 0 && { actions: /* @__PURE__ */ jsx(CtlSlot, { children: actions }) }
|
|
24
|
+
}
|
|
25
|
+
) }),
|
|
26
26
|
/* @__PURE__ */ jsx("div", { className: classes.rows, children })
|
|
27
27
|
] });
|
|
28
28
|
}
|
|
@@ -35,7 +35,7 @@ function SettingsRow({ label, description, control, children }) {
|
|
|
35
35
|
/* @__PURE__ */ jsx("div", { className: classes.control, children: control ?? children })
|
|
36
36
|
] });
|
|
37
37
|
}
|
|
38
|
-
function DangerZone({ title,
|
|
38
|
+
function DangerZone({ title, subtitle, actions, children }) {
|
|
39
39
|
return /* @__PURE__ */ jsxs(
|
|
40
40
|
Card,
|
|
41
41
|
{
|
|
@@ -44,10 +44,17 @@ function DangerZone({ title, description, children }) {
|
|
|
44
44
|
boxShadow: `${VX.shadowCard}, 0 0 0 1px ${alpha(VX.status.bad, 0.25)}`
|
|
45
45
|
},
|
|
46
46
|
children: [
|
|
47
|
-
/* @__PURE__ */ jsxs(
|
|
47
|
+
/* @__PURE__ */ jsxs("div", { className: classes.header, children: [
|
|
48
48
|
/* @__PURE__ */ jsx("span", { style: eyebrowStyle, children: "Danger Zone" }),
|
|
49
|
-
/* @__PURE__ */ jsx(
|
|
50
|
-
|
|
49
|
+
/* @__PURE__ */ jsx(
|
|
50
|
+
WidgetHeader,
|
|
51
|
+
{
|
|
52
|
+
tier: "section",
|
|
53
|
+
title,
|
|
54
|
+
...subtitle !== void 0 && { subtitle },
|
|
55
|
+
...actions !== void 0 && { actions: /* @__PURE__ */ jsx(CtlSlot, { children: actions }) }
|
|
56
|
+
}
|
|
57
|
+
)
|
|
51
58
|
] }),
|
|
52
59
|
/* @__PURE__ */ jsx("div", { className: classes.rows, children })
|
|
53
60
|
]
|
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
* vertical padding and a 1px `--vx-divider` rule below it, EXCEPT the last row in the section —
|
|
4
4
|
* `:not(:last-child)` strips the divider there so the section doesn't end on a trailing line.
|
|
5
5
|
*/
|
|
6
|
+
|
|
7
|
+
/* The WidgetHeader block (plus DangerZone's eyebrow, when present) sits above `.rows` with the
|
|
8
|
+
* same gap the old inline `Stack gap={2} mb="sm"` produced. */
|
|
9
|
+
.header {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
gap: 2px;
|
|
13
|
+
margin-bottom: var(--mantine-spacing-sm);
|
|
14
|
+
}
|
|
15
|
+
|
|
6
16
|
.rows > * {
|
|
7
17
|
padding: var(--vx-space-settings-row-inset-y) 0;
|
|
8
18
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-section.test.d.ts","sourceRoot":"","sources":["../../src/dashboard/settings-section.test.tsx"],"names":[],"mappings":""}
|
|
@@ -1,25 +1,111 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
/** A threshold verdict on the card's value. `undefined` is never tinted — see the module docblock. */
|
|
3
3
|
export type StatCardTone = 'good' | 'warn' | 'bad';
|
|
4
|
+
/**
|
|
5
|
+
* One row of a {@link StatCardProps.breakdown} — the two or three parts a hero number is made of.
|
|
6
|
+
*
|
|
7
|
+
* `value` is a pre-formatted `string` for the same reason the hero's is: the card cannot know the
|
|
8
|
+
* locale, the currency or the precision the number was measured at. `tone` marks ONE row as past a
|
|
9
|
+
* threshold and is the same vocabulary as the card's own `tone`, so a row saying `bad` and a rail
|
|
10
|
+
* saying `bad` are the same claim at two scales; omitting it is untinted, never `'good'`.
|
|
11
|
+
*/
|
|
12
|
+
export type StatCardBreakdownRow = {
|
|
13
|
+
readonly label: string;
|
|
14
|
+
readonly value: string;
|
|
15
|
+
readonly tone?: StatCardTone;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The measured box a `sparkline` render prop receives.
|
|
19
|
+
*
|
|
20
|
+
* A `LineSparkline`/`BarSparkline` takes `width`/`height` as NUMBERS (they are SVG attributes — an
|
|
21
|
+
* svg cannot size itself from CSS and then scale its scales), so "full bleed" was never expressible
|
|
22
|
+
* as a `ReactNode`: the caller had to guess a pixel width, or write its own `useChartSize` wrapper
|
|
23
|
+
* component. Four consumers wrote that wrapper; two of them hardcoded a width and drew a sparkline
|
|
24
|
+
* that stopped short of the card edge on every viewport but the one they built on.
|
|
25
|
+
*/
|
|
26
|
+
export type StatCardSparklineSize = {
|
|
27
|
+
width: number;
|
|
28
|
+
height: number;
|
|
29
|
+
};
|
|
4
30
|
export type StatCardProps = {
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
/**
|
|
31
|
+
/** Head-font title, rendered via `WidgetHeader tier="widget"`. */
|
|
32
|
+
title: string;
|
|
33
|
+
/** Optional leading icon, forwarded to `WidgetHeader`. */
|
|
34
|
+
icon?: ReactNode;
|
|
35
|
+
/** Muted line under the hero row, forwarded to `WidgetHeader` — the unit or basis a
|
|
36
|
+
* pre-formatted `value` cannot carry (`per day`, `of 40 planned`). Not a second metric. */
|
|
37
|
+
subtitle?: string;
|
|
38
|
+
/** Info tooltip beside the title, forwarded to `WidgetHeader` — how the number is computed. Never
|
|
39
|
+
* part of the heading's accessible name; see `WidgetHeaderProps.info`. */
|
|
40
|
+
info?: string;
|
|
41
|
+
/** Pre-formatted KPI value string (mono ~24px, weight 600, ink) — the hero-row value. */
|
|
8
42
|
value: string;
|
|
43
|
+
/** The value's unit, muted and mono at `--vx-text-sm`, immediately after it on the hero row —
|
|
44
|
+
* forwarded to `WidgetHeader`. `412` + `TSS`, not `"412 TSS"`: a unit painted at the hero's 24px
|
|
45
|
+
* reads as a second numeral. The BASIS (`7-day rolling`) is still `subtitle`; see
|
|
46
|
+
* `WidgetHeaderProps.unit`. */
|
|
47
|
+
unit?: string;
|
|
48
|
+
/**
|
|
49
|
+
* The parts the hero number is made of — compact rows under it, one line each, no hairlines.
|
|
50
|
+
*
|
|
51
|
+
* It exists because three consumers wanted a KPI card that also SPLITS its number (revenue by
|
|
52
|
+
* channel, uptime by probe) and the only shapes basalt offered were a `subtitle` (one muted line,
|
|
53
|
+
* no second column) and a table. Both hand-rolled a card instead — which is the fork
|
|
54
|
+
* `shadow-basalt-export` reports as a `HeroCard`.
|
|
55
|
+
*
|
|
56
|
+
* Deliberately not a table and deliberately unruled: the divider law puts a hairline between
|
|
57
|
+
* OPTION rows and nowhere else (`docs/CONTROLS-SPEC.md` §2.1), and a KPI card that draws three
|
|
58
|
+
* of them stops reading as one card. Keep it to two or three rows — past that the card is a
|
|
59
|
+
* table, and a table is `BasaltDataTable` in a `Section`.
|
|
60
|
+
*/
|
|
61
|
+
breakdown?: readonly StatCardBreakdownRow[];
|
|
9
62
|
/** Signed delta rendered via `DeltaBadge`; omit to hide the trend chip entirely. */
|
|
10
63
|
delta?: number;
|
|
11
64
|
/** Optional comparison timeframe shown after the delta (e.g. `MoM`) — forwarded to `DeltaBadge`. */
|
|
12
65
|
deltaPeriod?: string;
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Formats `delta` into the chip's label — forwarded to `WidgetHeader` and on to `DeltaBadge`.
|
|
68
|
+
* Defaults to `${Math.abs(delta).toFixed(1)}%`.
|
|
69
|
+
*
|
|
70
|
+
* A delta is not always a percentage, and the default silently claimed it was: a pace card's trend
|
|
71
|
+
* (`0:12 /km`) and a speed card's (`0.3 km/h`) both rendered as `0.3%` — a wrong unit on a KPI is
|
|
72
|
+
* the one failure worse than no chip, and it is why the consumer that needed it kept the card
|
|
73
|
+
* hand-rolled instead (the `HeroCard` fork `shadow-basalt-export` reports).
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* // An absolute delta that prints its own sign — no percent, no glyph saying it twice.
|
|
77
|
+
* <StatCard title="Pace" value="5:31" unit="/km" delta={-12}
|
|
78
|
+
* deltaFormat={(s) => `${s < 0 ? '−' : '+'}0:${String(Math.abs(s)).padStart(2, '0')} /km`}
|
|
79
|
+
* deltaGlyph={false} />
|
|
80
|
+
*/
|
|
81
|
+
deltaFormat?: (delta: number) => string;
|
|
82
|
+
/** Render the ▲/▼ glyph on the delta chip. Defaults to `true`; a zero delta never shows one. Pass
|
|
83
|
+
* `false` when `deltaFormat` prints the sign itself. */
|
|
84
|
+
deltaGlyph?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Optional trend visual. Either a node, or a RENDER PROP receiving the slot's measured box.
|
|
87
|
+
*
|
|
88
|
+
* Prefer the render prop for anything from `basalt-ui/charts`: those take numeric `width`/`height`
|
|
89
|
+
* (SVG attributes), so a plain node has to hardcode a width, and a hardcoded width is not
|
|
90
|
+
* full-bleed on any viewport but the one it was typed on. With `sparklinePlacement="bleed"` the
|
|
91
|
+
* measured width is the card's own inner width including the bled inset; with `'right'` it is the
|
|
92
|
+
* fixed 72×26 slot (see {@link SPARKLINE_RIGHT_WIDTH} for why that one is not measured).
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* sparkline={({ width, height }) => <BarSparkline data={history} width={width} height={height} />}
|
|
96
|
+
*/
|
|
97
|
+
sparkline?: ReactNode | ((size: StatCardSparklineSize) => ReactNode);
|
|
98
|
+
/** Where `sparkline` sits. `'bleed'` (default) is today's full-width row bled to the card edges;
|
|
99
|
+
* `'right'` sits it beside the hero value row. Collapses to `'bleed'` below `sm`. */
|
|
100
|
+
sparklinePlacement?: 'bleed' | 'right';
|
|
101
|
+
/** Header-right slot (e.g. a ghost "..." menu trigger) — wrapped in `CtlSlot tier="widget"`, so a
|
|
102
|
+
* raw `ActionIcon` with no `size` lands on the 24px step the 28px header row holds (C1/C5). */
|
|
103
|
+
actions?: ReactNode;
|
|
18
104
|
/** Threshold verdict — draws an accent rail down the card's leading edge and announces itself to
|
|
19
105
|
* assistive tech. Omitting it is NOT `'good'`: omitted covers a reading that is fine AND one that
|
|
20
106
|
* is absent, and stays untinted so a card with nothing measured can never render green. Pass
|
|
21
107
|
* `'good'` only to assert a measured value that has earned the verdict. */
|
|
22
108
|
tone?: StatCardTone;
|
|
23
109
|
};
|
|
24
|
-
export declare function StatCard({
|
|
110
|
+
export declare function StatCard({ title, icon, subtitle, info, value, unit, breakdown, delta, deltaPeriod, deltaFormat, deltaGlyph, sparkline, sparklinePlacement, actions, tone, }: StatCardProps): import("react").JSX.Element;
|
|
25
111
|
//# sourceMappingURL=stat-card.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stat-card.d.ts","sourceRoot":"","sources":["../../src/dashboard/stat-card.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stat-card.d.ts","sourceRoot":"","sources":["../../src/dashboard/stat-card.tsx"],"names":[],"mappings":"AA6FA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAA;AAMrD,sGAAsG;AACtG,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;AAElD;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAA;CAC7B,CAAA;AAcD;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAkDD,MAAM,MAAM,aAAa,GAAG;IAC1B,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAA;IACb,0DAA0D;IAC1D,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;+FAC2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;8EAC0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,yFAAyF;IACzF,KAAK,EAAE,MAAM,CAAA;IACb;;;mCAG+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAA;IAC3C,oFAAoF;IACpF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oGAAoG;IACpG,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACvC;4DACwD;IACxD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE,qBAAqB,KAAK,SAAS,CAAC,CAAA;IACpE;yFACqF;IACrF,kBAAkB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAA;IACtC;mGAC+F;IAC/F,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB;;;+EAG2E;IAC3E,IAAI,CAAC,EAAE,YAAY,CAAA;CACpB,CAAA;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,SAAS,EACT,KAAK,EACL,WAAW,EACX,WAAW,EACX,UAAU,EACV,SAAS,EACT,kBAA4B,EAC5B,OAAO,EACP,IAAI,GACL,EAAE,aAAa,+BA4Hf"}
|