basalt-ui 1.24.0 → 1.26.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 +25 -0
- package/MIGRATING.md +547 -21
- package/README.md +46 -33
- package/agent/rules/basalt-batteries.md +205 -0
- package/agent/rules/basalt-charts.md +125 -555
- package/agent/rules/basalt-controls.md +155 -0
- package/agent/rules/basalt-mantine.md +146 -439
- package/agent/rules/basalt-state.md +113 -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 +1275 -31
- package/configs/oxlint-plugin.test.ts +947 -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 +30 -0
- package/dist/controls/enum-filter.d.ts.map +1 -0
- package/dist/controls/enum-filter.js +91 -0
- package/dist/controls/filter-context.d.ts +55 -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 +19 -0
- package/dist/controls/index.d.ts.map +1 -0
- package/dist/controls/index.js +44 -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/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 +29 -0
- package/dist/controls/range-filter.d.ts.map +1 -0
- package/dist/controls/range-filter.js +120 -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/query-state.d.ts +1 -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 +44 -9
- package/dist/dashboard/stat-card.d.ts.map +1 -1
- package/dist/dashboard/stat-card.js +80 -48
- package/dist/dashboard/stat-card.module.css +82 -0
- package/dist/dashboard/stat-card.module.css.d.ts +11 -0
- package/dist/data/data-table.d.ts +102 -20
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +166 -65
- package/dist/data/table.d.ts +1 -1
- package/dist/data/table.d.ts.map +1 -1
- 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 +82 -7
- package/dist/guard/types.d.ts +3 -3
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/index.d.ts +12 -2
- 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 +81 -0
- package/dist/router-tanstack/search-store.d.ts.map +1 -0
- package/dist/router-tanstack/search-store.js +187 -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 +392 -0
- package/dist/state/fields.d.ts.map +1 -0
- package/dist/state/fields.js +369 -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 +48 -0
- package/dist/state/persisted.d.ts.map +1 -0
- package/dist/state/persisted.js +105 -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 +155 -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 +37 -0
- package/dist/widget-header/widget-header.d.ts.map +1 -0
- package/dist/widget-header/widget-header.js +77 -0
- package/dist/widget-header/widget-header.module.css +335 -0
- package/dist/widget-header/widget-header.module.css.d.ts +24 -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 +637 -0
- package/src/controls/enum-filter.tsx +159 -0
- package/src/controls/filter-context.tsx +153 -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 +48 -0
- package/src/controls/multi-select-filter.tsx +140 -0
- package/src/controls/peer-boundary.test.ts +85 -0
- package/src/controls/props-contract.test.tsx +106 -0
- package/src/controls/range-filter.tsx +184 -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/query-state.tsx +1 -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 +82 -0
- package/src/dashboard/stat-card.module.css.d.ts +11 -0
- package/src/dashboard/stat-card.test.tsx +67 -1
- package/src/dashboard/stat-card.tsx +209 -68
- package/src/data/data-table.test.tsx +282 -6
- package/src/data/data-table.tsx +429 -94
- package/src/data/table.ts +2 -0
- package/src/guard/check-source.test.ts +126 -13
- package/src/guard/grace.test.ts +149 -0
- package/src/guard/index.ts +172 -29
- package/src/guard/types.ts +4 -2
- package/src/index.ts +46 -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 +31 -0
- package/src/router-tanstack/index.ts +24 -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 +661 -0
- package/src/router-tanstack/search-store.test.ts +418 -0
- package/src/router-tanstack/search-store.ts +380 -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 +258 -0
- package/src/state/fields.ts +892 -0
- package/src/state/persisted.ts +211 -0
- package/src/state.ts +46 -240
- package/src/styles.css +13 -0
- package/src/surfaces.ts +203 -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 +335 -0
- package/src/widget-header/widget-header.module.css.d.ts +24 -0
- package/src/widget-header/widget-header.test.tsx +187 -0
- package/src/widget-header/widget-header.tsx +168 -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 -269
- 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,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The sidebar-block law — every default a `SidebarBlock` leaves unstated, plus the two persisted
|
|
3
|
+
* fold-key grammars.
|
|
4
|
+
*
|
|
5
|
+
* PURE BY CONTRACT, for the same reason `mobile-nav-model.ts` is: three consumers read these
|
|
6
|
+
* defaults and none of them may disagree. `app-sidebar.tsx` decides where a block renders and
|
|
7
|
+
* whether the rail keeps it, `sidebar-blocks.tsx` paints it, and `mobile-nav-model.ts` counts the
|
|
8
|
+
* More-sheet rows it will produce — a count that picks `menu` vs `sheet` before any of it renders.
|
|
9
|
+
* A default re-derived per call site is how the count and the renderer drift apart (see
|
|
10
|
+
* `accountRowCount`'s doc for the same failure with account rows).
|
|
11
|
+
*/
|
|
12
|
+
import type { SidebarBlock } from '../nav/types.js';
|
|
13
|
+
/** Envelope version for a persisted fold flag. Bump only if the value stops being a boolean. */
|
|
14
|
+
export declare const FOLD_VERSION = 1;
|
|
15
|
+
/**
|
|
16
|
+
* `'nav'` renders after the nav sections inside the scroll region; `'bottom'` pins above the
|
|
17
|
+
* settings footer. A progress block is `'bottom'` — it is a pinned status row, not a nav tail.
|
|
18
|
+
*/
|
|
19
|
+
export declare function sidebarBlockPlacement(block: SidebarBlock): 'nav' | 'bottom';
|
|
20
|
+
/**
|
|
21
|
+
* The collapsed-rail projection. A list block earns a dot only when it carries a `count` — a rail
|
|
22
|
+
* icon with no number behind it is a dot that means nothing — and a progress block a ring on the
|
|
23
|
+
* settings row. A `custom` block has no rail representation at all (arbitrary content in ~48px of
|
|
24
|
+
* icon column), which is exactly what `sidebarNavExtra` did before it.
|
|
25
|
+
*/
|
|
26
|
+
export declare function sidebarBlockRail(block: SidebarBlock): 'dot' | 'ring' | 'hidden';
|
|
27
|
+
/**
|
|
28
|
+
* The mobile projection. A list is reachable from More by default — below `sm` the sidebar does
|
|
29
|
+
* not render at all, so a hidden list is unreachable, not merely unshown. A progress row defaults
|
|
30
|
+
* to `'hidden'`: it is ambient status, and every More row costs headroom the menu-vs-sheet
|
|
31
|
+
* threshold is measured against.
|
|
32
|
+
*/
|
|
33
|
+
export declare function sidebarBlockMobile(block: SidebarBlock): 'more' | 'hidden';
|
|
34
|
+
/** Rows a list block paints, honouring `max` — the "Show more" toggle reveals the remainder. */
|
|
35
|
+
export declare function sidebarBlockVisibleCount(itemCount: number, max: number | undefined): number;
|
|
36
|
+
/**
|
|
37
|
+
* A section label as a storage-key segment. Lowercase, every run of non-alphanumerics collapsed to
|
|
38
|
+
* one `-`, no leading/trailing separator — `'Awaiting action'` → `'awaiting-action'`.
|
|
39
|
+
*/
|
|
40
|
+
export declare function slugifyLabel(label: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* `createPersistedState` namespaces every key as `basalt:<key>`, so these return the UNNAMESPACED
|
|
43
|
+
* halves — the real storage keys are `basalt:sidebar-block:<key>` and
|
|
44
|
+
* `basalt:sidebar-section:<label-slug>` (`docs/CONTROLS-SPEC.md` §2.3).
|
|
45
|
+
*/
|
|
46
|
+
export declare function sidebarBlockFoldKey(blockKey: string): string;
|
|
47
|
+
export declare function sidebarSectionFoldKey(label: string): string;
|
|
48
|
+
//# sourceMappingURL=sidebar-block-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar-block-model.d.ts","sourceRoot":"","sources":["../../src/shell/sidebar-block-model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD,gGAAgG;AAChG,eAAO,MAAM,YAAY,IAAI,CAAA;AAE7B;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,KAAK,GAAG,QAAQ,CAG3E;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAS/E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,QAAQ,CAIzE;AAED,gGAAgG;AAChG,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG3F;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3D"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const FOLD_VERSION = 1;
|
|
2
|
+
function sidebarBlockPlacement(block) {
|
|
3
|
+
if (block.kind === "progress") return block.placement ?? "bottom";
|
|
4
|
+
return block.placement ?? "nav";
|
|
5
|
+
}
|
|
6
|
+
function sidebarBlockRail(block) {
|
|
7
|
+
if (block.kind === "custom") return "hidden";
|
|
8
|
+
if (block.kind === "progress") return block.rail ?? "ring";
|
|
9
|
+
if (block.icon === void 0 || block.count === void 0) return "hidden";
|
|
10
|
+
return block.rail ?? "dot";
|
|
11
|
+
}
|
|
12
|
+
function sidebarBlockMobile(block) {
|
|
13
|
+
if (block.kind === "custom") return "hidden";
|
|
14
|
+
if (block.kind === "progress") return block.mobile ?? "hidden";
|
|
15
|
+
return block.mobile ?? "more";
|
|
16
|
+
}
|
|
17
|
+
function sidebarBlockVisibleCount(itemCount, max) {
|
|
18
|
+
if (max === void 0 || max >= itemCount) return itemCount;
|
|
19
|
+
return Math.max(0, max);
|
|
20
|
+
}
|
|
21
|
+
function slugifyLabel(label) {
|
|
22
|
+
return label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
23
|
+
}
|
|
24
|
+
function sidebarBlockFoldKey(blockKey) {
|
|
25
|
+
return `sidebar-block:${blockKey}`;
|
|
26
|
+
}
|
|
27
|
+
function sidebarSectionFoldKey(label) {
|
|
28
|
+
return `sidebar-section:${slugifyLabel(label)}`;
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
FOLD_VERSION,
|
|
32
|
+
sidebarBlockFoldKey,
|
|
33
|
+
sidebarBlockMobile,
|
|
34
|
+
sidebarBlockPlacement,
|
|
35
|
+
sidebarBlockRail,
|
|
36
|
+
sidebarBlockVisibleCount,
|
|
37
|
+
sidebarSectionFoldKey,
|
|
38
|
+
slugifyLabel
|
|
39
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { SidebarBlockTone, SidebarCustomBlock, SidebarListBlock, SidebarProgressBlock } from '../nav/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Fold/expand chevron. Lives here rather than in `app-sidebar.tsx` purely for direction: that
|
|
4
|
+
* module imports this one, so a glyph shared by a collapsible SECTION header and a collapsible
|
|
5
|
+
* BLOCK header has to sit on this side of the edge or the two files cycle.
|
|
6
|
+
*/
|
|
7
|
+
export declare function IconChevron({ open }: {
|
|
8
|
+
open: boolean;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
10
|
+
/**
|
|
11
|
+
* A persisted fold flag (`true` = folded). Exactly one hook call regardless of `key`, so swapping
|
|
12
|
+
* keys mid-life never moves the hook count.
|
|
13
|
+
*
|
|
14
|
+
* Every fold in the sidebar goes through this — block folds at `basalt:sidebar-block:<key>` and
|
|
15
|
+
* nav-section folds at `basalt:sidebar-section:<label-slug>`. Through 1.25.0 the section folds were
|
|
16
|
+
* one `useState` keyed by label, so every reload re-opened a section the user had closed.
|
|
17
|
+
*/
|
|
18
|
+
export declare function usePersistedFold(key: string, initial: boolean): readonly [boolean, (next: boolean) => void];
|
|
19
|
+
/** Status dot — the icon fallback for a toned row. Reads `--vx-status-*` through `data-tone`. */
|
|
20
|
+
export declare function SidebarBlockToneDot({ tone }: {
|
|
21
|
+
tone: SidebarBlockTone;
|
|
22
|
+
}): import("react").JSX.Element;
|
|
23
|
+
/** `value` of `total` as a ring — the collapsed rail's stand-in for a progress block. */
|
|
24
|
+
export declare function SidebarProgressRing({ value, total }: {
|
|
25
|
+
value: number;
|
|
26
|
+
total: number;
|
|
27
|
+
}): import("react").JSX.Element;
|
|
28
|
+
/** One block, whichever kind it is. `AppSidebar` places it; this decides nothing but the paint. */
|
|
29
|
+
export declare function SidebarBlockView({ block, }: {
|
|
30
|
+
block: SidebarListBlock | SidebarProgressBlock | SidebarCustomBlock;
|
|
31
|
+
}): import("react").JSX.Element;
|
|
32
|
+
//# sourceMappingURL=sidebar-blocks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sidebar-blocks.d.ts","sourceRoot":"","sources":["../../src/shell/sidebar-blocks.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAEV,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,cAAc,CAAA;AAYrB;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,+BAgBtD;AAsBD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,GACf,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,CAE7C;AAcD,iGAAiG;AACjG,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,+BAEvE;AAED,yFAAyF;AACzF,wBAAgB,mBAAmB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,+BAwBrF;AA4JD,mGAAmG;AACnG,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,GACN,EAAE;IACD,KAAK,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,kBAAkB,CAAA;CACpE,+BAIA"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Collapse, NavLink, Progress, Text, UnstyledButton } from "@mantine/core";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { NavCountBadge } from "./nav-count-badge.js";
|
|
5
|
+
import { createPersistedState } from "../state.js";
|
|
6
|
+
import {
|
|
7
|
+
FOLD_VERSION,
|
|
8
|
+
sidebarBlockFoldKey,
|
|
9
|
+
sidebarBlockRail,
|
|
10
|
+
sidebarBlockVisibleCount
|
|
11
|
+
} from "./sidebar-block-model.js";
|
|
12
|
+
import { IconSlot } from "../theme/icon-slot.js";
|
|
13
|
+
import classes from "./app-sidebar.module.css";
|
|
14
|
+
function IconChevron({ open }) {
|
|
15
|
+
return /* @__PURE__ */ jsx(
|
|
16
|
+
"svg",
|
|
17
|
+
{
|
|
18
|
+
width: 12,
|
|
19
|
+
height: 12,
|
|
20
|
+
viewBox: "0 0 24 24",
|
|
21
|
+
fill: "none",
|
|
22
|
+
stroke: "currentColor",
|
|
23
|
+
strokeWidth: 2,
|
|
24
|
+
strokeLinecap: "round",
|
|
25
|
+
strokeLinejoin: "round",
|
|
26
|
+
"aria-hidden": true,
|
|
27
|
+
children: open ? /* @__PURE__ */ jsx("path", { d: "M6 9l6 6l6 -6" }) : /* @__PURE__ */ jsx("path", { d: "M9 6l6 6l-6 6" })
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
const foldStores = /* @__PURE__ */ new Map();
|
|
32
|
+
function foldStore(key, initial) {
|
|
33
|
+
const cached = foldStores.get(key);
|
|
34
|
+
if (cached) return cached;
|
|
35
|
+
const store = createPersistedState({ key, version: FOLD_VERSION, initial });
|
|
36
|
+
foldStores.set(key, store);
|
|
37
|
+
return store;
|
|
38
|
+
}
|
|
39
|
+
function usePersistedFold(key, initial) {
|
|
40
|
+
return foldStore(key, initial)();
|
|
41
|
+
}
|
|
42
|
+
function BlockLabel({ children }) {
|
|
43
|
+
return /* @__PURE__ */ jsx(Text, { component: "div", className: classes.sectionLabel, children });
|
|
44
|
+
}
|
|
45
|
+
function SidebarBlockToneDot({ tone }) {
|
|
46
|
+
return /* @__PURE__ */ jsx("span", { className: classes.blockToneDot, "data-tone": tone, "aria-hidden": true });
|
|
47
|
+
}
|
|
48
|
+
function SidebarProgressRing({ value, total }) {
|
|
49
|
+
const CIRCUMFERENCE = 2 * Math.PI * 8;
|
|
50
|
+
const ratio = total > 0 ? Math.min(1, Math.max(0, value / total)) : 0;
|
|
51
|
+
return /* @__PURE__ */ jsx("span", { className: classes.blockRing, "data-basalt-rail-ring": true, children: /* @__PURE__ */ jsxs("svg", { width: 20, height: 20, viewBox: "0 0 20 20", "aria-hidden": true, children: [
|
|
52
|
+
/* @__PURE__ */ jsx("circle", { cx: 10, cy: 10, r: 8, fill: "none", stroke: "var(--vx-divider)", strokeWidth: 2 }),
|
|
53
|
+
/* @__PURE__ */ jsx(
|
|
54
|
+
"circle",
|
|
55
|
+
{
|
|
56
|
+
cx: 10,
|
|
57
|
+
cy: 10,
|
|
58
|
+
r: 8,
|
|
59
|
+
fill: "none",
|
|
60
|
+
stroke: "var(--vx-accent)",
|
|
61
|
+
strokeWidth: 2,
|
|
62
|
+
strokeLinecap: "round",
|
|
63
|
+
strokeDasharray: CIRCUMFERENCE,
|
|
64
|
+
strokeDashoffset: CIRCUMFERENCE * (1 - ratio),
|
|
65
|
+
transform: "rotate(-90 10 10)"
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
] }) });
|
|
69
|
+
}
|
|
70
|
+
function BlockRow({ item }) {
|
|
71
|
+
const rawLead = item.icon ?? (item.tone !== void 0 ? /* @__PURE__ */ jsx(SidebarBlockToneDot, { tone: item.tone }) : void 0);
|
|
72
|
+
const lead = rawLead === void 0 ? void 0 : /* @__PURE__ */ jsx(IconSlot, { children: rawLead });
|
|
73
|
+
const meta = item.meta !== void 0 ? /* @__PURE__ */ jsx(Text, { component: "span", className: classes.blockRowMeta, children: item.meta }) : void 0;
|
|
74
|
+
const interactive = item.Anchor !== void 0 || item.href !== void 0 || item.onClick !== void 0;
|
|
75
|
+
if (!interactive) {
|
|
76
|
+
return /* @__PURE__ */ jsxs("div", { className: `${classes.blockRow} ${classes.blockRowStatic}`, children: [
|
|
77
|
+
lead,
|
|
78
|
+
/* @__PURE__ */ jsx(Text, { component: "span", className: classes.blockRowLabel, children: item.label }),
|
|
79
|
+
meta
|
|
80
|
+
] });
|
|
81
|
+
}
|
|
82
|
+
const shared = {
|
|
83
|
+
classNames: { root: classes.blockRow },
|
|
84
|
+
label: item.label,
|
|
85
|
+
...lead !== void 0 && { leftSection: lead },
|
|
86
|
+
...meta !== void 0 && { rightSection: meta },
|
|
87
|
+
...item.onClick !== void 0 && { onClick: item.onClick }
|
|
88
|
+
};
|
|
89
|
+
const Anchor = item.Anchor;
|
|
90
|
+
if (Anchor) return /* @__PURE__ */ jsx(NavLink, { component: Anchor, ...shared });
|
|
91
|
+
return /* @__PURE__ */ jsx(NavLink, { component: "a", ...item.href !== void 0 && { href: item.href }, ...shared });
|
|
92
|
+
}
|
|
93
|
+
function ListBlock({ block }) {
|
|
94
|
+
const [folded, setFolded] = usePersistedFold(sidebarBlockFoldKey(block.key), false);
|
|
95
|
+
const [showAll, setShowAll] = useState(false);
|
|
96
|
+
const rail = sidebarBlockRail(block);
|
|
97
|
+
const visible = showAll ? block.items.length : sidebarBlockVisibleCount(block.items.length, block.max);
|
|
98
|
+
const hidden = block.items.length - visible;
|
|
99
|
+
const label = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
100
|
+
block.icon !== void 0 && /* @__PURE__ */ jsxs("span", { className: classes.blockIcon, children: [
|
|
101
|
+
block.icon,
|
|
102
|
+
rail === "dot" && /* @__PURE__ */ jsx("span", { className: classes.blockDot, "aria-hidden": true })
|
|
103
|
+
] }),
|
|
104
|
+
/* @__PURE__ */ jsx(BlockLabel, { children: block.label }),
|
|
105
|
+
block.count ? /* @__PURE__ */ jsx(NavCountBadge, { count: block.count }) : null
|
|
106
|
+
] });
|
|
107
|
+
const body = /* @__PURE__ */ jsxs("div", { className: classes.blockItems, children: [
|
|
108
|
+
block.items.slice(0, visible).map((item) => /* @__PURE__ */ jsx(BlockRow, { item }, item.key)),
|
|
109
|
+
hidden > 0 || showAll ? /* @__PURE__ */ jsx(
|
|
110
|
+
UnstyledButton,
|
|
111
|
+
{
|
|
112
|
+
className: classes.blockMore,
|
|
113
|
+
onClick: () => setShowAll(!showAll),
|
|
114
|
+
"aria-expanded": showAll,
|
|
115
|
+
children: showAll ? "Show less" : "Show more"
|
|
116
|
+
}
|
|
117
|
+
) : null
|
|
118
|
+
] });
|
|
119
|
+
return /* @__PURE__ */ jsx("div", { className: classes.block, "data-rail": rail, children: block.collapsible === true ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
120
|
+
/* @__PURE__ */ jsxs(
|
|
121
|
+
UnstyledButton,
|
|
122
|
+
{
|
|
123
|
+
className: `${classes.blockHeader} ${classes.blockHeaderButton}`,
|
|
124
|
+
onClick: () => setFolded(!folded),
|
|
125
|
+
"aria-expanded": !folded,
|
|
126
|
+
children: [
|
|
127
|
+
label,
|
|
128
|
+
/* @__PURE__ */ jsx(IconChevron, { open: !folded })
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
),
|
|
132
|
+
/* @__PURE__ */ jsx(Collapse, { expanded: !folded, children: body })
|
|
133
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
134
|
+
/* @__PURE__ */ jsx("div", { className: classes.blockHeader, children: label }),
|
|
135
|
+
body
|
|
136
|
+
] }) });
|
|
137
|
+
}
|
|
138
|
+
function ProgressBlock({ block }) {
|
|
139
|
+
const percent = block.total > 0 ? Math.min(100, Math.max(0, block.value / block.total * 100)) : 0;
|
|
140
|
+
const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
141
|
+
/* @__PURE__ */ jsxs("div", { className: classes.blockProgressHead, children: [
|
|
142
|
+
/* @__PURE__ */ jsx(BlockLabel, { children: block.label }),
|
|
143
|
+
/* @__PURE__ */ jsxs(Text, { component: "span", className: classes.blockRowMeta, children: [
|
|
144
|
+
block.value,
|
|
145
|
+
" of ",
|
|
146
|
+
block.total
|
|
147
|
+
] })
|
|
148
|
+
] }),
|
|
149
|
+
/* @__PURE__ */ jsx(Progress, { value: percent, size: "xs", "aria-label": block.label })
|
|
150
|
+
] });
|
|
151
|
+
return /* @__PURE__ */ jsx("div", { className: classes.block, "data-rail": sidebarBlockRail(block), children: block.onClick !== void 0 ? /* @__PURE__ */ jsx(UnstyledButton, { className: classes.blockProgress, onClick: block.onClick, children: inner }) : /* @__PURE__ */ jsx("div", { className: classes.blockProgress, children: inner }) });
|
|
152
|
+
}
|
|
153
|
+
function CustomBlock({ block }) {
|
|
154
|
+
return /* @__PURE__ */ jsx("div", { className: classes.block, "data-rail": "hidden", children: block.node });
|
|
155
|
+
}
|
|
156
|
+
function SidebarBlockView({
|
|
157
|
+
block
|
|
158
|
+
}) {
|
|
159
|
+
if (block.kind === "list") return /* @__PURE__ */ jsx(ListBlock, { block });
|
|
160
|
+
if (block.kind === "progress") return /* @__PURE__ */ jsx(ProgressBlock, { block });
|
|
161
|
+
return /* @__PURE__ */ jsx(CustomBlock, { block });
|
|
162
|
+
}
|
|
163
|
+
export {
|
|
164
|
+
IconChevron,
|
|
165
|
+
SidebarBlockToneDot,
|
|
166
|
+
SidebarBlockView,
|
|
167
|
+
SidebarProgressRing,
|
|
168
|
+
usePersistedFold
|
|
169
|
+
};
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
import type { BarAction } from '../controls/actions.js';
|
|
2
|
+
/**
|
|
3
|
+
* The ⌘K row's trailing icon buttons — ONE or TWO, by type (`docs/CONTROLS-SPEC.md` §2.3).
|
|
4
|
+
*
|
|
5
|
+
* The tuple IS the enforcement: a third button pushes the search trigger under the width where its
|
|
6
|
+
* placeholder stays readable, and there is no third thing a sidebar search row is for. Each entry
|
|
7
|
+
* renders icon-only at the `icon` tier (24px, `--ai-size-icon`) with `label` demoted to the
|
|
8
|
+
* accessible name; a `kind: 'menu'` entry becomes an `OverflowMenu` kebab, a `kind: 'custom'` one
|
|
9
|
+
* is mounted verbatim.
|
|
10
|
+
*/
|
|
11
|
+
export type SidebarSearchActions = [BarAction] | [BarAction, BarAction];
|
|
1
12
|
export type SidebarSearchConfig = {
|
|
2
13
|
/** Opens the search palette — e.g. `openSpotlight` from `basalt-ui/commands`. */
|
|
3
14
|
onOpen: () => void;
|
|
@@ -6,7 +17,8 @@ export type SidebarSearchConfig = {
|
|
|
6
17
|
/** Keyboard-shortcut hint shown on the right (e.g. '⌘K'). Auto-detected mac/other when omitted. */
|
|
7
18
|
shortcut?: string;
|
|
8
19
|
};
|
|
9
|
-
export declare function SidebarSearch({ onOpen, placeholder, shortcut, collapsed, }: SidebarSearchConfig & {
|
|
20
|
+
export declare function SidebarSearch({ onOpen, placeholder, shortcut, actions, collapsed, }: SidebarSearchConfig & {
|
|
21
|
+
actions?: SidebarSearchActions;
|
|
10
22
|
collapsed?: boolean;
|
|
11
23
|
}): import("react").JSX.Element;
|
|
12
24
|
//# sourceMappingURL=sidebar-search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar-search.d.ts","sourceRoot":"","sources":["../../src/shell/sidebar-search.tsx"],"names":[],"mappings":"AAYA,MAAM,MAAM,mBAAmB,GAAG;IAChC,iFAAiF;IACjF,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;
|
|
1
|
+
{"version":3,"file":"sidebar-search.d.ts","sourceRoot":"","sources":["../../src/shell/sidebar-search.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAGpD;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;AAEvE,MAAM,MAAM,mBAAmB,GAAG;IAChC,iFAAiF;IACjF,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mGAAmG;IACnG,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAgED,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,WAAuB,EACvB,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE,mBAAmB,GAAG;IAAE,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,+BA6C/E"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ActionIcon, Kbd, Text, UnstyledButton } from "@mantine/core";
|
|
3
|
+
import { OverflowMenu } from "../controls/actions.js";
|
|
3
4
|
import classes from "./sidebar-search.module.css";
|
|
4
5
|
function IconSearch() {
|
|
5
6
|
return /* @__PURE__ */ jsxs(
|
|
@@ -21,10 +22,37 @@ function IconSearch() {
|
|
|
21
22
|
}
|
|
22
23
|
);
|
|
23
24
|
}
|
|
25
|
+
function initial(label) {
|
|
26
|
+
return [...label][0]?.toUpperCase() ?? "?";
|
|
27
|
+
}
|
|
28
|
+
function SearchAction({ action }) {
|
|
29
|
+
if (action.kind === "custom") return action.node;
|
|
30
|
+
if (action.kind === "menu") {
|
|
31
|
+
return /* @__PURE__ */ jsx(OverflowMenu, { actions: action.items, trigger: "kebab", label: action.label });
|
|
32
|
+
}
|
|
33
|
+
const shared = {
|
|
34
|
+
variant: "subtle",
|
|
35
|
+
size: "icon",
|
|
36
|
+
className: classes.actionBtn,
|
|
37
|
+
"aria-label": action.label,
|
|
38
|
+
disabled: action.disabled === true,
|
|
39
|
+
...action.onClick !== void 0 && { onClick: action.onClick }
|
|
40
|
+
};
|
|
41
|
+
const body = action.icon ?? initial(action.label);
|
|
42
|
+
const Anchor = action.Anchor;
|
|
43
|
+
if (Anchor !== void 0) {
|
|
44
|
+
return /* @__PURE__ */ jsx(ActionIcon, { component: Anchor, ...shared, children: body });
|
|
45
|
+
}
|
|
46
|
+
if (action.link !== void 0) {
|
|
47
|
+
return /* @__PURE__ */ jsx(ActionIcon, { component: "a", href: action.link.to, ...shared, children: body });
|
|
48
|
+
}
|
|
49
|
+
return /* @__PURE__ */ jsx(ActionIcon, { ...shared, children: body });
|
|
50
|
+
}
|
|
24
51
|
function SidebarSearch({
|
|
25
52
|
onOpen,
|
|
26
53
|
placeholder = "Search\u2026",
|
|
27
54
|
shortcut,
|
|
55
|
+
actions,
|
|
28
56
|
collapsed
|
|
29
57
|
}) {
|
|
30
58
|
const isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPod|iPad/i.test(navigator.platform);
|
|
@@ -42,7 +70,7 @@ function SidebarSearch({
|
|
|
42
70
|
}
|
|
43
71
|
);
|
|
44
72
|
}
|
|
45
|
-
|
|
73
|
+
const trigger = /* @__PURE__ */ jsxs(
|
|
46
74
|
UnstyledButton,
|
|
47
75
|
{
|
|
48
76
|
type: "button",
|
|
@@ -56,6 +84,11 @@ function SidebarSearch({
|
|
|
56
84
|
]
|
|
57
85
|
}
|
|
58
86
|
);
|
|
87
|
+
if (actions === void 0) return trigger;
|
|
88
|
+
return /* @__PURE__ */ jsxs("div", { className: classes.row, children: [
|
|
89
|
+
trigger,
|
|
90
|
+
actions.map((action) => /* @__PURE__ */ jsx(SearchAction, { action }, action.key))
|
|
91
|
+
] });
|
|
59
92
|
}
|
|
60
93
|
export {
|
|
61
94
|
SidebarSearch
|
|
@@ -5,6 +5,18 @@
|
|
|
5
5
|
* button as a matched pair, so the two must never drift onto different depth tokens.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
/*
|
|
9
|
+
* The row that appears ONLY when `search.actions` is supplied — one or two icon-only buttons beside
|
|
10
|
+
* the trigger. Without actions the trigger stays the row's sole node (no wrapper), so the DOM of
|
|
11
|
+
* every consumer that doesn't use them is untouched.
|
|
12
|
+
*/
|
|
13
|
+
.row {
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
gap: var(--vx-space-sidebar-search-gap);
|
|
17
|
+
min-width: 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
8
20
|
.trigger {
|
|
9
21
|
display: flex;
|
|
10
22
|
align-items: center;
|
|
@@ -74,3 +86,17 @@
|
|
|
74
86
|
background-color: color-mix(in srgb, var(--vx-ink) 6%, transparent) !important;
|
|
75
87
|
color: var(--vx-ink) !important;
|
|
76
88
|
}
|
|
89
|
+
|
|
90
|
+
/* Trailing search-row action — the same ghost treatment as `.ghostIcon` / `.railBtn`, at the `icon`
|
|
91
|
+
* tier (24px) the component asks for explicitly. Never re-points `--ai-size`: unlike `.railBtn`,
|
|
92
|
+
* this button is NOT a second state of the trigger and must not track its height. */
|
|
93
|
+
.actionBtn {
|
|
94
|
+
flex: none;
|
|
95
|
+
color: var(--vx-faint) !important;
|
|
96
|
+
border-radius: var(--vx-radius-ctrl) !important;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.actionBtn:hover {
|
|
100
|
+
background-color: color-mix(in srgb, var(--vx-ink) 6%, transparent) !important;
|
|
101
|
+
color: var(--vx-ink) !important;
|
|
102
|
+
}
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
* (`noUncheckedIndexedAccess`, `noPropertyAccessFromIndexSignature`, `exactOptionalPropertyTypes`).
|
|
5
5
|
*/
|
|
6
6
|
declare const classes: {
|
|
7
|
+
readonly row: string
|
|
7
8
|
readonly trigger: string
|
|
8
9
|
readonly label: string
|
|
9
10
|
readonly railBtn: string
|
|
11
|
+
readonly actionBtn: string
|
|
10
12
|
}
|
|
11
13
|
export default classes
|