basalt-ui 1.26.0 → 1.28.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 +23 -23
- package/CHANGELOG.md +67 -0
- package/MIGRATING.md +896 -37
- package/README.md +33 -3
- package/agent/rules/basalt-batteries.md +25 -10
- package/agent/rules/basalt-controls.md +73 -43
- package/agent/rules/basalt-mantine.md +17 -6
- package/agent/rules/basalt-state.md +5 -0
- package/agent/rules/basalt-tokens.md +1 -1
- package/configs/oxlint-plugin.js +1286 -73
- package/configs/oxlint-plugin.test.ts +1338 -29
- package/configs/oxlint.json +12 -5
- package/dist/agent/coalesce.d.ts.map +1 -1
- package/dist/agent/coalesce.js +2 -1
- package/dist/agent/merge.d.ts.map +1 -1
- package/dist/agent/merge.js +2 -1
- package/dist/agent/part-list.d.ts.map +1 -1
- package/dist/agent/part-list.js +2 -0
- package/dist/agent/stick-to-bottom.d.ts +3 -6
- package/dist/agent/stick-to-bottom.d.ts.map +1 -1
- package/dist/agent/stick-to-bottom.js +6 -3
- package/dist/agent-chat/composer.d.ts +6 -2
- package/dist/agent-chat/composer.d.ts.map +1 -1
- package/dist/agent-chat/composer.js +49 -33
- package/dist/agent-chat/relative-time.d.ts +0 -9
- package/dist/agent-chat/relative-time.d.ts.map +1 -1
- package/dist/agent-chat/relative-time.js +2 -1
- package/dist/agent-chat/thread-detail-panel.d.ts +3 -2
- package/dist/agent-chat/thread-detail-panel.d.ts.map +1 -1
- package/dist/agent-chat/thread-detail-panel.js +8 -5
- package/dist/agent-chat/thread-feed-row.d.ts +2 -1
- package/dist/agent-chat/thread-feed-row.d.ts.map +1 -1
- package/dist/agent-chat/thread-feed-row.js +92 -92
- package/dist/agent-chat/thread-feed.d.ts +3 -2
- package/dist/agent-chat/thread-feed.d.ts.map +1 -1
- package/dist/agent-chat/thread-feed.js +8 -3
- package/dist/agent-chat/thread-message.d.ts +4 -3
- package/dist/agent-chat/thread-message.d.ts.map +1 -1
- package/dist/agent-chat/thread-message.js +70 -31
- package/dist/agent-chat/thread-outcome-card.d.ts +3 -2
- package/dist/agent-chat/thread-outcome-card.d.ts.map +1 -1
- package/dist/agent-chat/thread-outcome-card.js +9 -2
- package/dist/agent-chat/thread-workspace.d.ts +7 -2
- package/dist/agent-chat/thread-workspace.d.ts.map +1 -1
- package/dist/agent-chat/thread-workspace.js +62 -29
- package/dist/agent-chat/tool-chip.d.ts +3 -2
- package/dist/agent-chat/tool-chip.d.ts.map +1 -1
- package/dist/agent-chat/tool-chip.js +7 -2
- package/dist/charts/hooks/useBandPlot.d.ts.map +1 -1
- package/dist/charts/hooks/useBandPlot.js +15 -8
- package/dist/charts/index.d.ts +8 -7
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/index.js +45 -5
- package/dist/charts/kinds/BandStrip.d.ts +10 -7
- package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
- package/dist/charts/kinds/BandStrip.js +12 -7
- package/dist/charts/kinds/Bars.d.ts +12 -6
- package/dist/charts/kinds/Bars.d.ts.map +1 -1
- package/dist/charts/kinds/Bars.js +37 -11
- package/dist/charts/kinds/Donut.d.ts +6 -5
- package/dist/charts/kinds/Donut.d.ts.map +1 -1
- package/dist/charts/kinds/Donut.js +19 -2
- package/dist/charts/kinds/DualPanel.d.ts +6 -5
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +36 -8
- package/dist/charts/kinds/Heatmap.d.ts +10 -6
- package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
- package/dist/charts/kinds/Heatmap.js +58 -31
- package/dist/charts/kinds/MirroredBars.d.ts +6 -5
- package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
- package/dist/charts/kinds/MirroredBars.js +9 -2
- package/dist/charts/kinds/MultiLine.d.ts +11 -6
- package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
- package/dist/charts/kinds/MultiLine.js +24 -15
- package/dist/charts/kinds/StackedArea.d.ts +18 -8
- package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
- package/dist/charts/kinds/StackedArea.js +29 -4
- package/dist/charts/kinds/ZonedLine.d.ts +12 -8
- package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
- package/dist/charts/kinds/ZonedLine.js +33 -23
- package/dist/charts/layout/auto-margin.d.ts +65 -8
- package/dist/charts/layout/auto-margin.d.ts.map +1 -1
- package/dist/charts/layout/auto-margin.js +45 -10
- package/dist/charts/layout/log-ticks.d.ts +27 -0
- package/dist/charts/layout/log-ticks.d.ts.map +1 -0
- package/dist/charts/layout/log-ticks.js +42 -0
- package/dist/charts/primitives/Axes.d.ts +11 -2
- package/dist/charts/primitives/Axes.d.ts.map +1 -1
- package/dist/charts/primitives/Axes.js +15 -5
- package/dist/charts/primitives/CartesianChart.d.ts +45 -7
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
- package/dist/charts/primitives/CartesianChart.js +86 -28
- package/dist/charts/primitives/ChartCard.d.ts +27 -2
- package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
- package/dist/charts/primitives/ChartCard.js +37 -17
- package/dist/charts/primitives/ChartFrame.d.ts +30 -4
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +45 -15
- package/dist/charts/primitives/ChartLegend.d.ts +13 -2
- package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
- package/dist/charts/primitives/ChartLegend.js +33 -13
- package/dist/charts/primitives/ChartPending.d.ts +77 -4
- package/dist/charts/primitives/ChartPending.d.ts.map +1 -1
- package/dist/charts/primitives/ChartPending.js +100 -6
- package/dist/charts/primitives/ChartTooltip.d.ts +7 -0
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +18 -5
- package/dist/charts/primitives/Crosshair.d.ts +3 -0
- package/dist/charts/primitives/Crosshair.d.ts.map +1 -1
- package/dist/charts/primitives/Crosshair.js +3 -1
- package/dist/charts/primitives/chart-frame-layout.d.ts +95 -0
- package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -0
- package/dist/charts/primitives/chart-frame-layout.js +89 -0
- package/dist/charts/primitives/chart-tier.d.ts +16 -0
- package/dist/charts/primitives/chart-tier.d.ts.map +1 -0
- package/dist/charts/primitives/chart-tier.js +20 -0
- package/dist/charts/series.d.ts +55 -1
- package/dist/charts/series.d.ts.map +1 -1
- package/dist/charts/series.js +27 -1
- package/dist/charts/sparklines/BarSparkline.d.ts +3 -3
- package/dist/charts/sparklines/BarSparkline.d.ts.map +1 -1
- package/dist/charts/sparklines/BarSparkline.js +9 -3
- package/dist/charts/sparklines/LineSparkline.d.ts +3 -3
- package/dist/charts/sparklines/LineSparkline.d.ts.map +1 -1
- package/dist/charts/sparklines/LineSparkline.js +15 -3
- package/dist/charts/sparklines/index.d.ts +2 -2
- package/dist/charts/sparklines/index.d.ts.map +1 -1
- package/dist/charts/utils/format.d.ts +92 -2
- package/dist/charts/utils/format.d.ts.map +1 -1
- package/dist/charts/utils/format.js +64 -1
- package/dist/charts/utils/ticks.d.ts +81 -2
- package/dist/charts/utils/ticks.d.ts.map +1 -1
- package/dist/charts/utils/ticks.js +54 -4
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/commands/ShortcutsHelp.d.ts +3 -2
- package/dist/commands/ShortcutsHelp.d.ts.map +1 -1
- package/dist/commands/ShortcutsHelp.js +8 -2
- package/dist/commands/define-commands.d.ts.map +1 -1
- package/dist/commands/define-commands.js +2 -2
- package/dist/commands/define-overlays.d.ts +102 -0
- package/dist/commands/define-overlays.d.ts.map +1 -1
- package/dist/commands/define-overlays.js +102 -2
- package/dist/commands/index.d.ts +10 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +3 -1
- package/dist/commands/overlays-mount.d.ts +13 -6
- package/dist/commands/overlays-mount.d.ts.map +1 -1
- package/dist/commands/overlays-mount.js +23 -14
- package/dist/common/errors.d.ts +34 -0
- package/dist/common/errors.d.ts.map +1 -0
- package/dist/common/errors.js +36 -0
- package/dist/common/index.d.ts +15 -0
- package/dist/common/index.d.ts.map +1 -0
- package/dist/common/index.js +29 -0
- package/dist/common/props.d.ts +63 -0
- package/dist/common/props.d.ts.map +1 -0
- package/dist/common/props.js +6 -0
- package/dist/common/query-state-like.d.ts +43 -0
- package/dist/common/query-state-like.d.ts.map +1 -0
- package/dist/common/query-state-like.js +20 -0
- package/dist/common/refs.d.ts +29 -0
- package/dist/common/refs.d.ts.map +1 -0
- package/dist/common/refs.js +29 -0
- package/dist/common/scroll-parent.d.ts +23 -0
- package/dist/common/scroll-parent.d.ts.map +1 -0
- package/dist/common/scroll-parent.js +21 -0
- package/dist/common/validate.d.ts +38 -0
- package/dist/common/validate.d.ts.map +1 -0
- package/dist/common/validate.js +36 -0
- package/dist/connectivity/connectivity-indicator.d.ts +3 -1
- package/dist/connectivity/connectivity-indicator.d.ts.map +1 -1
- package/dist/connectivity/connectivity-indicator.js +3 -1
- package/dist/connectivity/connectivity-provider.d.ts.map +1 -1
- package/dist/connectivity/connectivity-provider.js +4 -1
- package/dist/connectivity/index.d.ts +1 -0
- package/dist/connectivity/index.d.ts.map +1 -1
- package/dist/connectivity/types.d.ts +2 -2
- package/dist/connectivity/types.d.ts.map +1 -1
- package/dist/connectivity/use-connectivity.d.ts.map +1 -1
- package/dist/content/article-layout.module.css +11 -4
- package/dist/content/callout.d.ts +8 -4
- package/dist/content/callout.d.ts.map +1 -1
- package/dist/content/callout.js +15 -8
- package/dist/content/guide.d.ts +5 -4
- package/dist/content/guide.d.ts.map +1 -1
- package/dist/content/guide.js +13 -4
- package/dist/content/heading-anchor.d.ts +24 -2
- package/dist/content/heading-anchor.d.ts.map +1 -1
- package/dist/content/heading-anchor.js +23 -9
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/markdown.d.ts.map +1 -1
- package/dist/content/markdown.js +2 -0
- package/dist/content/prose.module.css +9 -7
- package/dist/content/reading-progress.d.ts +10 -4
- package/dist/content/reading-progress.d.ts.map +1 -1
- package/dist/content/reading-progress.js +26 -10
- package/dist/content/slug.d.ts +4 -0
- package/dist/content/slug.d.ts.map +1 -1
- package/dist/content/toc.d.ts +11 -0
- package/dist/content/toc.d.ts.map +1 -1
- package/dist/content/toc.js +23 -10
- package/dist/controls/actions.d.ts +49 -6
- package/dist/controls/actions.d.ts.map +1 -1
- package/dist/controls/actions.js +39 -8
- package/dist/controls/compare-filter.d.ts +3 -2
- package/dist/controls/compare-filter.d.ts.map +1 -1
- package/dist/controls/compare-filter.js +17 -2
- package/dist/controls/control-group.d.ts +3 -3
- package/dist/controls/control-group.d.ts.map +1 -1
- package/dist/controls/control-group.js +9 -2
- package/dist/controls/controls.module.css +169 -186
- package/dist/controls/controls.module.css.d.ts +9 -11
- package/dist/controls/enum-filter.d.ts +13 -3
- package/dist/controls/enum-filter.d.ts.map +1 -1
- package/dist/controls/enum-filter.js +32 -15
- package/dist/controls/filter-context.d.ts +15 -6
- package/dist/controls/filter-context.d.ts.map +1 -1
- package/dist/controls/filter-pill.d.ts +3 -3
- package/dist/controls/filter-pill.d.ts.map +1 -1
- package/dist/controls/filter-pill.js +4 -1
- package/dist/controls/filter-set.d.ts +3 -2
- package/dist/controls/filter-set.d.ts.map +1 -1
- package/dist/controls/filter-set.js +66 -41
- package/dist/controls/filter-sheet.d.ts +20 -80
- package/dist/controls/filter-sheet.d.ts.map +1 -1
- package/dist/controls/filter-sheet.js +9 -95
- package/dist/controls/index.d.ts +3 -0
- package/dist/controls/index.d.ts.map +1 -1
- package/dist/controls/index.js +6 -0
- package/dist/controls/multi-select-filter.d.ts +18 -2
- package/dist/controls/multi-select-filter.d.ts.map +1 -1
- package/dist/controls/multi-select-filter.js +124 -22
- package/dist/controls/number-filter.d.ts +28 -0
- package/dist/controls/number-filter.d.ts.map +1 -0
- package/dist/controls/number-filter.js +172 -0
- package/dist/controls/panel-row.d.ts +132 -0
- package/dist/controls/panel-row.d.ts.map +1 -0
- package/dist/controls/panel-row.js +173 -0
- package/dist/controls/panel-row.module.css +86 -0
- package/dist/controls/panel-row.module.css.d.ts +13 -0
- package/dist/controls/range-filter.d.ts +20 -5
- package/dist/controls/range-filter.d.ts.map +1 -1
- package/dist/controls/range-filter.js +75 -38
- package/dist/controls/search-filter.d.ts +3 -2
- package/dist/controls/search-filter.d.ts.map +1 -1
- package/dist/controls/search-filter.js +26 -11
- package/dist/controls/select-filter.d.ts +2 -1
- package/dist/controls/select-filter.d.ts.map +1 -1
- package/dist/controls/select-filter.js +4 -0
- package/dist/controls/slider-control.d.ts +36 -0
- package/dist/controls/slider-control.d.ts.map +1 -0
- package/dist/controls/slider-control.js +64 -0
- package/dist/controls/sync-button.d.ts +3 -2
- package/dist/controls/sync-button.d.ts.map +1 -1
- package/dist/controls/sync-button.js +16 -3
- package/dist/controls/toggle-filter.d.ts +3 -2
- package/dist/controls/toggle-filter.d.ts.map +1 -1
- package/dist/controls/toggle-filter.js +29 -12
- package/dist/controls/view-tabs.d.ts +3 -2
- package/dist/controls/view-tabs.d.ts.map +1 -1
- package/dist/controls/view-tabs.js +43 -11
- package/dist/controls-dates/date-range-picker.d.ts +1 -1
- package/dist/controls-dates/date-range-picker.d.ts.map +1 -1
- package/dist/controls-dates/date-range-picker.js +6 -1
- package/dist/dashboard/delta-badge.d.ts +5 -1
- package/dist/dashboard/delta-badge.d.ts.map +1 -1
- package/dist/dashboard/empty-state.d.ts +10 -3
- package/dist/dashboard/empty-state.d.ts.map +1 -1
- package/dist/dashboard/empty-state.js +37 -6
- package/dist/dashboard/index.d.ts +6 -4
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +10 -2
- package/dist/dashboard/query-state.d.ts +48 -27
- package/dist/dashboard/query-state.d.ts.map +1 -1
- package/dist/dashboard/query-state.js +111 -57
- package/dist/dashboard/settings-section.d.ts +19 -9
- package/dist/dashboard/settings-section.d.ts.map +1 -1
- package/dist/dashboard/settings-section.js +74 -25
- package/dist/dashboard/stat-card.d.ts +76 -19
- package/dist/dashboard/stat-card.d.ts.map +1 -1
- package/dist/dashboard/stat-card.js +78 -38
- package/dist/dashboard/stat-card.module.css +112 -26
- package/dist/dashboard/stat-card.module.css.d.ts +5 -0
- package/dist/dashboard/stat-group.d.ts +41 -0
- package/dist/dashboard/stat-group.d.ts.map +1 -0
- package/dist/dashboard/stat-group.js +30 -0
- package/dist/dashboard/stat-group.module.css +66 -0
- package/dist/dashboard/stat-group.module.css.d.ts +8 -0
- package/dist/dashboard/widget-grid.d.ts +27 -0
- package/dist/dashboard/widget-grid.d.ts.map +1 -0
- package/dist/dashboard/widget-grid.js +41 -0
- package/dist/dashboard/widget-grid.module.css +53 -0
- package/dist/dashboard/widget-grid.module.css.d.ts +9 -0
- package/dist/data/data-table.d.ts +151 -12
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +392 -138
- package/dist/data/data-table.module.css +64 -0
- package/dist/data/data-table.module.css.d.ts +11 -0
- package/dist/data/index.d.ts +2 -2
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +24 -2
- package/dist/data/query-branch.d.ts +28 -0
- package/dist/data/query-branch.d.ts.map +1 -0
- package/dist/data/query-branch.js +10 -0
- package/dist/data/table.d.ts +2 -2
- package/dist/data/table.d.ts.map +1 -1
- package/dist/data/virtual-list.d.ts +65 -6
- package/dist/data/virtual-list.d.ts.map +1 -1
- package/dist/data/virtual-list.js +89 -38
- package/dist/data/virtual.d.ts +1 -1
- package/dist/data/virtual.d.ts.map +1 -1
- package/dist/forms/FormErrorSummary.d.ts +4 -3
- package/dist/forms/FormErrorSummary.d.ts.map +1 -1
- package/dist/forms/FormErrorSummary.js +6 -4
- package/dist/forms/create-form.d.ts +2 -2
- package/dist/forms/field.d.ts +46 -6
- package/dist/forms/field.d.ts.map +1 -1
- package/dist/forms/field.js +10 -5
- package/dist/forms/form-layout.d.ts +142 -0
- package/dist/forms/form-layout.d.ts.map +1 -0
- package/dist/forms/form-layout.js +110 -0
- package/dist/forms/form-layout.module.css +145 -0
- package/dist/forms/form-layout.module.css.d.ts +20 -0
- package/dist/forms/form-state.d.ts +42 -0
- package/dist/forms/form-state.d.ts.map +1 -0
- package/dist/forms/form-state.js +26 -0
- package/dist/forms/index.d.ts +22 -6
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +19 -3
- package/dist/forms/use-field-array.d.ts +60 -0
- package/dist/forms/use-field-array.d.ts.map +1 -0
- package/dist/forms/use-field-array.js +20 -0
- package/dist/forms/use-form-draft.d.ts +25 -10
- package/dist/forms/use-form-draft.d.ts.map +1 -1
- package/dist/forms/use-form-draft.js +55 -18
- package/dist/forms/use-form-submit.d.ts +88 -0
- package/dist/forms/use-form-submit.d.ts.map +1 -0
- package/dist/forms/use-form-submit.js +63 -0
- package/dist/guard/index.d.ts +1 -1
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +27 -11
- package/dist/index.d.ts +10 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -4
- package/dist/nav/types.d.ts +15 -6
- package/dist/nav/types.d.ts.map +1 -1
- package/dist/notifications/bell.d.ts +3 -2
- package/dist/notifications/bell.d.ts.map +1 -1
- package/dist/notifications/bell.js +73 -56
- package/dist/notifications/center.d.ts +15 -4
- package/dist/notifications/center.d.ts.map +1 -1
- package/dist/notifications/center.js +5 -2
- package/dist/notifications/define-notifications.d.ts +56 -14
- package/dist/notifications/define-notifications.d.ts.map +1 -1
- package/dist/notifications/define-notifications.js +2 -1
- package/dist/notifications/index.d.ts +6 -2
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +5 -1
- package/dist/notifications/mount-guard.d.ts +8 -0
- package/dist/notifications/mount-guard.d.ts.map +1 -0
- package/dist/notifications/mount-guard.js +19 -0
- package/dist/notifications/notify.d.ts +58 -1
- package/dist/notifications/notify.d.ts.map +1 -1
- package/dist/notifications/notify.js +46 -2
- package/dist/notifications/overlay.d.ts.map +1 -1
- package/dist/notifications/overlay.js +2 -0
- package/dist/notifications/store.d.ts +7 -0
- package/dist/notifications/store.d.ts.map +1 -1
- package/dist/provider/index.d.ts +37 -5
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +66 -28
- package/dist/provider/lab-theme.d.ts.map +1 -1
- package/dist/provider/lab-theme.js +2 -1
- package/dist/query/devtools.d.ts.map +1 -1
- package/dist/query/devtools.js +1 -0
- package/dist/router-tanstack/field.d.ts +1 -1
- package/dist/router-tanstack/field.d.ts.map +1 -1
- package/dist/router-tanstack/index.d.ts +1 -1
- package/dist/router-tanstack/index.d.ts.map +1 -1
- package/dist/router-tanstack/search-store.d.ts +4 -1
- package/dist/router-tanstack/search-store.d.ts.map +1 -1
- package/dist/router-tanstack/search-store.js +92 -8
- package/dist/router-tanstack/use-nav.d.ts.map +1 -1
- package/dist/router-tanstack/use-nav.js +1 -1
- package/dist/section/index.d.ts +1 -1
- package/dist/section/index.d.ts.map +1 -1
- package/dist/section/section.d.ts +36 -2
- package/dist/section/section.d.ts.map +1 -1
- package/dist/section/section.js +49 -57
- package/dist/section/section.module.css +11 -0
- package/dist/shell/account-types.d.ts +5 -2
- package/dist/shell/account-types.d.ts.map +1 -1
- package/dist/shell/app-brand.d.ts +13 -0
- package/dist/shell/app-brand.d.ts.map +1 -0
- package/dist/shell/app-brand.js +94 -0
- package/dist/shell/app-brand.module.css +109 -0
- package/dist/shell/app-brand.module.css.d.ts +14 -0
- package/dist/shell/app-breadcrumbs.d.ts +4 -2
- package/dist/shell/app-breadcrumbs.d.ts.map +1 -1
- package/dist/shell/app-breadcrumbs.js +33 -22
- package/dist/shell/app-header.module.css +10 -5
- package/dist/shell/app-main.module.css +107 -0
- package/dist/shell/app-main.module.css.d.ts +11 -0
- package/dist/shell/app-mobile-nav.d.ts +3 -2
- package/dist/shell/app-mobile-nav.d.ts.map +1 -1
- package/dist/shell/app-mobile-nav.js +29 -15
- package/dist/shell/app-mobile-nav.module.css +48 -27
- package/dist/shell/app-mobile-nav.module.css.d.ts +0 -1
- package/dist/shell/app-sidebar-account.d.ts +2 -1
- package/dist/shell/app-sidebar-account.d.ts.map +1 -1
- package/dist/shell/app-sidebar-account.js +57 -22
- package/dist/shell/app-sidebar.d.ts +9 -3
- package/dist/shell/app-sidebar.d.ts.map +1 -1
- package/dist/shell/app-sidebar.js +55 -109
- package/dist/shell/app-sidebar.module.css +53 -96
- package/dist/shell/app-sidebar.module.css.d.ts +0 -5
- package/dist/shell/index.d.ts +14 -6
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +47 -12
- package/dist/shell/isomorphic-layout-effect.d.ts +14 -0
- package/dist/shell/isomorphic-layout-effect.d.ts.map +1 -0
- package/dist/shell/isomorphic-layout-effect.js +5 -0
- package/dist/shell/mobile-nav-model.d.ts.map +1 -1
- package/dist/shell/mobile-nav-model.js +27 -6
- package/dist/shell/nav-count-badge.d.ts +5 -3
- package/dist/shell/nav-count-badge.d.ts.map +1 -1
- package/dist/shell/nav-count-badge.js +3 -1
- package/dist/shell/page-aside.d.ts +43 -0
- package/dist/shell/page-aside.d.ts.map +1 -0
- package/dist/shell/page-aside.js +202 -0
- package/dist/shell/page-aside.module.css +174 -0
- package/dist/shell/page-aside.module.css.d.ts +14 -0
- package/dist/shell/page-bar.d.ts +55 -15
- package/dist/shell/page-bar.d.ts.map +1 -1
- package/dist/shell/page-bar.js +130 -41
- package/dist/shell/page-bar.module.css +107 -13
- package/dist/shell/page-bar.module.css.d.ts +4 -1
- package/dist/shell/sidebar-search.d.ts +4 -2
- package/dist/shell/sidebar-search.d.ts.map +1 -1
- package/dist/shell/sidebar-search.js +9 -4
- package/dist/shell/sidebar-search.module.css +1 -1
- package/dist/state/fields.d.ts +227 -34
- package/dist/state/fields.d.ts.map +1 -1
- package/dist/state/fields.js +77 -30
- package/dist/state/persisted-or-local.d.ts +9 -0
- package/dist/state/persisted-or-local.d.ts.map +1 -0
- package/dist/state/persisted-or-local.js +24 -0
- package/dist/state/persisted.d.ts +12 -0
- package/dist/state/persisted.d.ts.map +1 -1
- package/dist/state/persisted.js +36 -18
- package/dist/state.d.ts +1 -1
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +2 -6
- package/dist/surfaces.d.ts +12 -11
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +43 -12
- package/dist/theme/ctl-theme.d.ts.map +1 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +102 -17
- package/dist/theme/nav-link.module.css +37 -26
- package/dist/theme/segmented-control.module.css +22 -0
- package/dist/theme/segmented-control.module.css.d.ts +1 -0
- package/dist/theme-lab/boot.d.ts +66 -0
- package/dist/theme-lab/boot.d.ts.map +1 -0
- package/dist/theme-lab/boot.js +82 -0
- package/dist/theme-lab/index.d.ts +4 -43
- package/dist/theme-lab/index.d.ts.map +1 -1
- package/dist/theme-lab/index.js +9 -69
- package/dist/theme-toggle/index.d.ts +3 -2
- package/dist/theme-toggle/index.d.ts.map +1 -1
- package/dist/theme-toggle/index.js +8 -2
- package/dist/tokens/index.d.ts +42 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +35 -6
- package/dist/tokens/palette.d.ts +45 -25
- package/dist/tokens/palette.d.ts.map +1 -1
- package/dist/tokens/palette.js +31 -14
- package/dist/tokens.css +4 -5
- package/dist/utils/is-dev.d.ts +3 -0
- package/dist/utils/is-dev.d.ts.map +1 -0
- package/dist/utils/is-dev.js +6 -0
- package/dist/widget-header/delta-badge.d.ts +7 -1
- package/dist/widget-header/delta-badge.d.ts.map +1 -1
- package/dist/widget-header/delta-badge.js +8 -1
- package/dist/widget-header/index.d.ts +2 -2
- package/dist/widget-header/index.d.ts.map +1 -1
- package/dist/widget-header/index.js +3 -1
- package/dist/widget-header/widget-header.d.ts +99 -4
- package/dist/widget-header/widget-header.d.ts.map +1 -1
- package/dist/widget-header/widget-header.js +45 -18
- package/dist/widget-header/widget-header.module.css +87 -7
- package/dist/widget-header/widget-header.module.css.d.ts +1 -0
- package/llms.txt +6 -6
- package/package.json +49 -25
- package/src/agent/coalesce.ts +2 -1
- package/src/agent/merge.ts +2 -1
- package/src/agent/part-list.tsx +2 -0
- package/src/agent/stick-to-bottom.tsx +9 -11
- package/src/agent-chat/composer.tsx +124 -103
- package/src/agent-chat/relative-time.ts +2 -1
- package/src/agent-chat/thread-detail-panel.tsx +9 -5
- package/src/agent-chat/thread-feed-row.tsx +17 -9
- package/src/agent-chat/thread-feed.tsx +9 -3
- package/src/agent-chat/thread-message.tsx +48 -13
- package/src/agent-chat/thread-outcome-card.tsx +9 -1
- package/src/agent-chat/thread-workspace.tsx +72 -33
- package/src/agent-chat/tool-chip.tsx +8 -2
- package/src/charts/hooks/useBandPlot.ts +26 -8
- package/src/charts/index.ts +39 -4
- package/src/charts/kinds/BandStrip.tsx +36 -14
- package/src/charts/kinds/Bars.tsx +67 -16
- package/src/charts/kinds/Donut.tsx +30 -3
- package/src/charts/kinds/DualPanel.tsx +56 -10
- package/src/charts/kinds/Heatmap.tsx +90 -33
- package/src/charts/kinds/MirroredBars.tsx +21 -3
- package/src/charts/kinds/MultiLine.tsx +61 -18
- package/src/charts/kinds/StackedArea.tsx +77 -6
- package/src/charts/kinds/ZonedLine.tsx +71 -31
- package/src/charts/layout/auto-margin.ts +134 -21
- package/src/charts/layout/log-ticks.ts +90 -0
- package/src/charts/primitives/Axes.tsx +33 -5
- package/src/charts/primitives/CartesianChart.tsx +194 -41
- package/src/charts/primitives/ChartCard.tsx +66 -25
- package/src/charts/primitives/ChartFrame.tsx +107 -26
- package/src/charts/primitives/ChartLegend.tsx +43 -13
- package/src/charts/primitives/ChartPending.tsx +185 -7
- package/src/charts/primitives/ChartTooltip.tsx +37 -5
- package/src/charts/primitives/Crosshair.tsx +6 -3
- package/src/charts/primitives/chart-frame-layout.ts +212 -0
- package/src/charts/primitives/chart-tier.tsx +37 -0
- package/src/charts/series.ts +77 -1
- package/src/charts/sparklines/BarSparkline.tsx +11 -3
- package/src/charts/sparklines/LineSparkline.tsx +18 -4
- package/src/charts/sparklines/index.ts +2 -2
- package/src/charts/utils/format.ts +163 -2
- package/src/charts/utils/ticks.ts +149 -4
- package/src/cli/index.ts +8 -3
- package/src/commands/ShortcutsHelp.tsx +10 -3
- package/src/commands/define-commands.ts +2 -2
- package/src/commands/define-overlays.ts +216 -1
- package/src/commands/index.ts +12 -0
- package/src/commands/overlays-mount.tsx +60 -26
- package/src/common/errors.ts +73 -0
- package/src/common/index.ts +21 -0
- package/src/common/props.ts +71 -0
- package/src/common/query-state-like.ts +64 -0
- package/src/common/refs.ts +58 -0
- package/src/common/scroll-parent.ts +42 -0
- package/src/common/validate.ts +94 -0
- package/src/connectivity/connectivity-indicator.tsx +6 -1
- package/src/connectivity/connectivity-provider.tsx +4 -1
- package/src/connectivity/index.ts +1 -0
- package/src/connectivity/types.ts +5 -2
- package/src/connectivity/use-connectivity.ts +3 -2
- package/src/content/article-layout.module.css +11 -4
- package/src/content/callout.tsx +13 -7
- package/src/content/guide.tsx +14 -4
- package/src/content/heading-anchor.tsx +14 -3
- package/src/content/index.ts +2 -0
- package/src/content/markdown.tsx +2 -0
- package/src/content/prose.module.css +9 -7
- package/src/content/reading-progress.tsx +40 -15
- package/src/content/slug.ts +4 -0
- package/src/content/toc.tsx +47 -10
- package/src/controls/actions.tsx +89 -9
- package/src/controls/compare-filter.tsx +20 -3
- package/src/controls/control-group.tsx +11 -4
- package/src/controls/controls.module.css +169 -186
- package/src/controls/controls.module.css.d.ts +9 -11
- package/src/controls/enum-filter.tsx +46 -19
- package/src/controls/filter-context.tsx +21 -8
- package/src/controls/filter-pill.tsx +6 -3
- package/src/controls/filter-set.tsx +32 -13
- package/src/controls/filter-sheet.tsx +44 -194
- package/src/controls/index.ts +8 -0
- package/src/controls/multi-select-filter.tsx +179 -29
- package/src/controls/number-filter.tsx +329 -0
- package/src/controls/panel-row.module.css +86 -0
- package/src/controls/panel-row.module.css.d.ts +13 -0
- package/src/controls/panel-row.tsx +392 -0
- package/src/controls/range-filter.tsx +133 -43
- package/src/controls/search-filter.tsx +31 -13
- package/src/controls/select-filter.tsx +11 -1
- package/src/controls/slider-control.tsx +159 -0
- package/src/controls/sync-button.tsx +13 -3
- package/src/controls/toggle-filter.tsx +37 -17
- package/src/controls/view-tabs.tsx +63 -11
- package/src/controls-dates/date-range-picker.tsx +8 -1
- package/src/dashboard/delta-badge.tsx +5 -1
- package/src/dashboard/empty-state.tsx +72 -25
- package/src/dashboard/index.ts +19 -2
- package/src/dashboard/query-state.tsx +154 -84
- package/src/dashboard/settings-section.tsx +87 -31
- package/src/dashboard/stat-card.module.css +112 -26
- package/src/dashboard/stat-card.module.css.d.ts +5 -0
- package/src/dashboard/stat-card.tsx +207 -68
- package/src/dashboard/stat-group.module.css +66 -0
- package/src/dashboard/stat-group.module.css.d.ts +8 -0
- package/src/dashboard/stat-group.tsx +74 -0
- package/src/dashboard/widget-grid.module.css +53 -0
- package/src/dashboard/widget-grid.module.css.d.ts +9 -0
- package/src/dashboard/widget-grid.tsx +127 -0
- package/src/data/data-table.module.css +64 -0
- package/src/data/data-table.module.css.d.ts +11 -0
- package/src/data/data-table.tsx +927 -346
- package/src/data/index.ts +30 -2
- package/src/data/query-branch.ts +53 -0
- package/src/data/table.ts +5 -0
- package/src/data/virtual-list.tsx +189 -55
- package/src/data/virtual.ts +5 -1
- package/src/forms/FormErrorSummary.tsx +13 -6
- package/src/forms/create-form.ts +2 -2
- package/src/forms/field.ts +60 -11
- package/src/forms/form-layout.module.css +145 -0
- package/src/forms/form-layout.module.css.d.ts +20 -0
- package/src/forms/form-layout.tsx +305 -0
- package/src/forms/form-state.tsx +94 -0
- package/src/forms/index.ts +38 -7
- package/src/forms/use-field-array.ts +94 -0
- package/src/forms/use-form-draft.ts +145 -53
- package/src/forms/use-form-submit.ts +199 -0
- package/src/guard/index.ts +91 -23
- package/src/index.ts +79 -10
- package/src/nav/types.ts +15 -6
- package/src/notifications/bell.tsx +18 -4
- package/src/notifications/center.tsx +18 -5
- package/src/notifications/define-notifications.ts +64 -18
- package/src/notifications/index.ts +12 -1
- package/src/notifications/mount-guard.ts +41 -0
- package/src/notifications/notify.tsx +122 -3
- package/src/notifications/overlay.tsx +2 -0
- package/src/notifications/store.ts +7 -0
- package/src/provider/index.tsx +101 -13
- package/src/provider/lab-theme.ts +2 -1
- package/src/query/devtools.tsx +1 -0
- package/src/router-tanstack/field.ts +5 -0
- package/src/router-tanstack/index.ts +4 -0
- package/src/router-tanstack/search-store.ts +171 -12
- package/src/router-tanstack/use-nav.ts +18 -13
- package/src/section/index.ts +1 -1
- package/src/section/section.module.css +11 -0
- package/src/section/section.tsx +163 -96
- package/src/shell/account-types.ts +5 -2
- package/src/shell/app-brand.module.css +109 -0
- package/src/shell/app-brand.module.css.d.ts +14 -0
- package/src/shell/app-brand.tsx +140 -0
- package/src/shell/app-breadcrumbs.tsx +19 -9
- package/src/shell/app-header.module.css +10 -5
- package/src/shell/app-main.module.css +107 -0
- package/src/shell/app-main.module.css.d.ts +11 -0
- package/src/shell/app-mobile-nav.module.css +48 -27
- package/src/shell/app-mobile-nav.module.css.d.ts +0 -1
- package/src/shell/app-mobile-nav.tsx +43 -11
- package/src/shell/app-sidebar-account.tsx +29 -6
- package/src/shell/app-sidebar.module.css +53 -96
- package/src/shell/app-sidebar.module.css.d.ts +0 -5
- package/src/shell/app-sidebar.tsx +40 -113
- package/src/shell/index.tsx +156 -65
- package/src/shell/isomorphic-layout-effect.ts +14 -0
- package/src/shell/mobile-nav-model.ts +66 -10
- package/src/shell/nav-count-badge.tsx +6 -1
- package/src/shell/page-aside.module.css +174 -0
- package/src/shell/page-aside.module.css.d.ts +14 -0
- package/src/shell/page-aside.tsx +377 -0
- package/src/shell/page-bar.module.css +107 -13
- package/src/shell/page-bar.module.css.d.ts +4 -1
- package/src/shell/page-bar.tsx +294 -94
- package/src/shell/sidebar-search.module.css +1 -1
- package/src/shell/sidebar-search.tsx +13 -4
- package/src/state/fields.ts +360 -69
- package/src/state/persisted-or-local.ts +50 -0
- package/src/state/persisted.ts +76 -26
- package/src/state.ts +4 -7
- package/src/surfaces.ts +43 -12
- package/src/theme/ctl-theme.tsx +10 -0
- package/src/theme/index.ts +129 -16
- package/src/theme/nav-link.module.css +37 -26
- package/src/theme/segmented-control.module.css +22 -0
- package/src/theme/segmented-control.module.css.d.ts +1 -0
- package/src/theme-lab/boot.ts +140 -0
- package/src/theme-lab/index.tsx +21 -112
- package/src/theme-toggle/index.tsx +10 -3
- package/src/tokens/index.ts +50 -6
- package/src/tokens/palette.ts +58 -30
- package/src/utils/is-dev.ts +4 -0
- package/src/widget-header/delta-badge.tsx +25 -5
- package/src/widget-header/index.ts +10 -2
- package/src/widget-header/widget-header.module.css +87 -7
- package/src/widget-header/widget-header.module.css.d.ts +1 -0
- package/src/widget-header/widget-header.tsx +166 -42
- package/dist/agent/adapter.test.d.ts +0 -2
- package/dist/agent/adapter.test.d.ts.map +0 -1
- package/dist/agent/ai-sdk-transport.test.d.ts +0 -2
- package/dist/agent/ai-sdk-transport.test.d.ts.map +0 -1
- package/dist/agent/coalesce.test.d.ts +0 -2
- package/dist/agent/coalesce.test.d.ts.map +0 -1
- package/dist/agent/foreign.test.d.ts +0 -2
- package/dist/agent/foreign.test.d.ts.map +0 -1
- package/dist/agent/id.test.d.ts +0 -2
- package/dist/agent/id.test.d.ts.map +0 -1
- package/dist/agent/merge.test.d.ts +0 -2
- package/dist/agent/merge.test.d.ts.map +0 -1
- package/dist/agent/part-list.test.d.ts +0 -2
- package/dist/agent/part-list.test.d.ts.map +0 -1
- package/dist/agent/parts.test.d.ts +0 -2
- package/dist/agent/parts.test.d.ts.map +0 -1
- package/dist/agent/thread.test.d.ts +0 -2
- package/dist/agent/thread.test.d.ts.map +0 -1
- package/dist/agent/transport.test.d.ts +0 -2
- package/dist/agent/transport.test.d.ts.map +0 -1
- package/dist/agent/use-agent-stream.test.d.ts +0 -2
- package/dist/agent/use-agent-stream.test.d.ts.map +0 -1
- package/dist/agent/use-agent-thread-runs.foreign.test.d.ts +0 -2
- package/dist/agent/use-agent-thread-runs.foreign.test.d.ts.map +0 -1
- package/dist/agent/use-agent-thread-runs.resume.test.d.ts +0 -2
- package/dist/agent/use-agent-thread-runs.resume.test.d.ts.map +0 -1
- package/dist/agent/use-agent-thread-runs.test.d.ts +0 -2
- package/dist/agent/use-agent-thread-runs.test.d.ts.map +0 -1
- package/dist/agent/use-agent-thread-runs.wedge.test.d.ts +0 -2
- package/dist/agent/use-agent-thread-runs.wedge.test.d.ts.map +0 -1
- package/dist/agent-chat/composer.test.d.ts +0 -2
- package/dist/agent-chat/composer.test.d.ts.map +0 -1
- package/dist/agent-chat/relative-time.test.d.ts +0 -2
- package/dist/agent-chat/relative-time.test.d.ts.map +0 -1
- package/dist/agent-chat/thread-feed-row.test.d.ts +0 -2
- package/dist/agent-chat/thread-feed-row.test.d.ts.map +0 -1
- package/dist/agent-chat/thread-feed.test.d.ts +0 -2
- package/dist/agent-chat/thread-feed.test.d.ts.map +0 -1
- package/dist/agent-chat/thread-message.test.d.ts +0 -2
- package/dist/agent-chat/thread-message.test.d.ts.map +0 -1
- package/dist/agent-chat/thread-workspace.test.d.ts +0 -2
- package/dist/agent-chat/thread-workspace.test.d.ts.map +0 -1
- package/dist/agent-chat/tool-chip.test.d.ts +0 -2
- package/dist/agent-chat/tool-chip.test.d.ts.map +0 -1
- package/dist/agent-chat/virtualize.type-guard.test.d.ts +0 -2
- package/dist/agent-chat/virtualize.type-guard.test.d.ts.map +0 -1
- package/dist/charts/cursor/resolve.test.d.ts +0 -2
- package/dist/charts/cursor/resolve.test.d.ts.map +0 -1
- package/dist/charts/cursor/store.test.d.ts +0 -2
- package/dist/charts/cursor/store.test.d.ts.map +0 -1
- package/dist/charts/kinds/BandStrip.test.d.ts +0 -2
- package/dist/charts/kinds/BandStrip.test.d.ts.map +0 -1
- package/dist/charts/kinds/Bars.test.d.ts +0 -2
- package/dist/charts/kinds/Bars.test.d.ts.map +0 -1
- package/dist/charts/kinds/DualPanel.test.d.ts +0 -2
- package/dist/charts/kinds/DualPanel.test.d.ts.map +0 -1
- package/dist/charts/kinds/MirroredBars.test.d.ts +0 -2
- package/dist/charts/kinds/MirroredBars.test.d.ts.map +0 -1
- package/dist/charts/kinds/MultiLine.test.d.ts +0 -2
- package/dist/charts/kinds/MultiLine.test.d.ts.map +0 -1
- package/dist/charts/kinds/StackedArea.test.d.ts +0 -2
- package/dist/charts/kinds/StackedArea.test.d.ts.map +0 -1
- package/dist/charts/kinds/ZonedLine.test.d.ts +0 -2
- package/dist/charts/kinds/ZonedLine.test.d.ts.map +0 -1
- package/dist/charts/layout/auto-margin.test.d.ts +0 -2
- package/dist/charts/layout/auto-margin.test.d.ts.map +0 -1
- package/dist/charts/primitives/CartesianChart.test.d.ts +0 -2
- package/dist/charts/primitives/CartesianChart.test.d.ts.map +0 -1
- package/dist/charts/primitives/ChartCard.test.d.ts +0 -2
- package/dist/charts/primitives/ChartCard.test.d.ts.map +0 -1
- package/dist/charts/primitives/ChartFrame.test.d.ts +0 -2
- package/dist/charts/primitives/ChartFrame.test.d.ts.map +0 -1
- package/dist/charts/primitives/ChartLegend.test.d.ts +0 -2
- package/dist/charts/primitives/ChartLegend.test.d.ts.map +0 -1
- package/dist/charts/primitives/ChartTooltip.test.d.ts +0 -2
- package/dist/charts/primitives/ChartTooltip.test.d.ts.map +0 -1
- package/dist/charts/primitives/XZoneRects.test.d.ts +0 -2
- package/dist/charts/primitives/XZoneRects.test.d.ts.map +0 -1
- package/dist/charts/series.test.d.ts +0 -2
- package/dist/charts/series.test.d.ts.map +0 -1
- package/dist/charts/utils/domain.test.d.ts +0 -2
- package/dist/charts/utils/domain.test.d.ts.map +0 -1
- package/dist/charts/utils/measure-text.test.d.ts +0 -2
- package/dist/charts/utils/measure-text.test.d.ts.map +0 -1
- package/dist/cli/check-coverage.test.d.ts +0 -2
- package/dist/cli/check-coverage.test.d.ts.map +0 -1
- package/dist/cli/check-theme.test.d.ts +0 -2
- package/dist/cli/check-theme.test.d.ts.map +0 -1
- package/dist/cli/help.test.d.ts +0 -2
- package/dist/cli/help.test.d.ts.map +0 -1
- package/dist/cli/init-sync.test.d.ts +0 -2
- package/dist/cli/init-sync.test.d.ts.map +0 -1
- package/dist/cli/placement-engine.test.d.ts +0 -2
- package/dist/cli/placement-engine.test.d.ts.map +0 -1
- package/dist/cli/shipped-versions.test.d.ts +0 -2
- package/dist/cli/shipped-versions.test.d.ts.map +0 -1
- package/dist/cli/tarball-parity.test.d.ts +0 -2
- package/dist/cli/tarball-parity.test.d.ts.map +0 -1
- package/dist/cli/template-format.test.d.ts +0 -2
- package/dist/cli/template-format.test.d.ts.map +0 -1
- package/dist/cli/template-ledger.test.d.ts +0 -2
- package/dist/cli/template-ledger.test.d.ts.map +0 -1
- package/dist/cli/tokens-css.test.d.ts +0 -2
- package/dist/cli/tokens-css.test.d.ts.map +0 -1
- package/dist/cli/toolchain-wiring.test.d.ts +0 -2
- package/dist/cli/toolchain-wiring.test.d.ts.map +0 -1
- package/dist/cli/waiver-audit.test.d.ts +0 -2
- package/dist/cli/waiver-audit.test.d.ts.map +0 -1
- package/dist/content/article-actions.test.d.ts +0 -2
- package/dist/content/article-actions.test.d.ts.map +0 -1
- package/dist/content/article-model.test.d.ts +0 -2
- package/dist/content/article-model.test.d.ts.map +0 -1
- package/dist/content/block-split.test.d.ts +0 -2
- package/dist/content/block-split.test.d.ts.map +0 -1
- package/dist/content/heading-components.test.d.ts +0 -2
- package/dist/content/heading-components.test.d.ts.map +0 -1
- package/dist/content/markdown.test.d.ts +0 -2
- package/dist/content/markdown.test.d.ts.map +0 -1
- package/dist/content/prose.module.css.test.d.ts +0 -2
- package/dist/content/prose.module.css.test.d.ts.map +0 -1
- package/dist/content/sanitize.test.d.ts +0 -2
- package/dist/content/sanitize.test.d.ts.map +0 -1
- package/dist/content/slug.test.d.ts +0 -2
- package/dist/content/slug.test.d.ts.map +0 -1
- package/dist/controls/actions.test.d.ts +0 -2
- package/dist/controls/actions.test.d.ts.map +0 -1
- package/dist/controls/actions.type-guard.test.d.ts +0 -2
- package/dist/controls/actions.type-guard.test.d.ts.map +0 -1
- package/dist/controls/control-group.test.d.ts +0 -2
- package/dist/controls/control-group.test.d.ts.map +0 -1
- package/dist/controls/controls.router.test.d.ts +0 -2
- package/dist/controls/controls.router.test.d.ts.map +0 -1
- package/dist/controls/filter-set.test.d.ts +0 -2
- package/dist/controls/filter-set.test.d.ts.map +0 -1
- package/dist/controls/peer-boundary.test.d.ts +0 -2
- package/dist/controls/peer-boundary.test.d.ts.map +0 -1
- package/dist/controls/props-contract.test.d.ts +0 -2
- package/dist/controls/props-contract.test.d.ts.map +0 -1
- package/dist/controls/sync-button.test.d.ts +0 -2
- package/dist/controls/sync-button.test.d.ts.map +0 -1
- package/dist/dashboard/query-state.test.d.ts +0 -2
- package/dist/dashboard/query-state.test.d.ts.map +0 -1
- package/dist/dashboard/settings-section.test.d.ts +0 -2
- package/dist/dashboard/settings-section.test.d.ts.map +0 -1
- package/dist/dashboard/stat-card.test.d.ts +0 -2
- package/dist/dashboard/stat-card.test.d.ts.map +0 -1
- package/dist/data/data-table.test.d.ts +0 -2
- package/dist/data/data-table.test.d.ts.map +0 -1
- package/dist/guard/check-source.test.d.ts +0 -2
- package/dist/guard/check-source.test.d.ts.map +0 -1
- package/dist/guard/grace.test.d.ts +0 -20
- package/dist/guard/grace.test.d.ts.map +0 -1
- package/dist/guard/guard-hook.test.d.ts +0 -2
- package/dist/guard/guard-hook.test.d.ts.map +0 -1
- package/dist/provider/index.test.d.ts +0 -2
- package/dist/provider/index.test.d.ts.map +0 -1
- package/dist/provider/lab-theme.test.d.ts +0 -2
- package/dist/provider/lab-theme.test.d.ts.map +0 -1
- package/dist/query/error-message.test.d.ts +0 -2
- package/dist/query/error-message.test.d.ts.map +0 -1
- package/dist/router-tanstack/multi-search-param-store.test.d.ts +0 -2
- package/dist/router-tanstack/multi-search-param-store.test.d.ts.map +0 -1
- package/dist/router-tanstack/nav.test.d.ts +0 -2
- package/dist/router-tanstack/nav.test.d.ts.map +0 -1
- package/dist/router-tanstack/search-param-store.test.d.ts +0 -2
- package/dist/router-tanstack/search-param-store.test.d.ts.map +0 -1
- package/dist/router-tanstack/search-store.router.test.d.ts +0 -2
- package/dist/router-tanstack/search-store.router.test.d.ts.map +0 -1
- package/dist/router-tanstack/search-store.test.d.ts +0 -2
- package/dist/router-tanstack/search-store.test.d.ts.map +0 -1
- package/dist/router-tanstack/use-nav.test.d.ts +0 -2
- package/dist/router-tanstack/use-nav.test.d.ts.map +0 -1
- package/dist/section/section.test.d.ts +0 -2
- package/dist/section/section.test.d.ts.map +0 -1
- package/dist/shell/app-mobile-nav.test.d.ts +0 -2
- package/dist/shell/app-mobile-nav.test.d.ts.map +0 -1
- package/dist/shell/app-sidebar.test.d.ts +0 -2
- package/dist/shell/app-sidebar.test.d.ts.map +0 -1
- package/dist/shell/index.test.d.ts +0 -2
- package/dist/shell/index.test.d.ts.map +0 -1
- package/dist/shell/mobile-nav-model.test.d.ts +0 -2
- package/dist/shell/mobile-nav-model.test.d.ts.map +0 -1
- package/dist/shell/page-bar.test.d.ts +0 -2
- package/dist/shell/page-bar.test.d.ts.map +0 -1
- package/dist/state/fields.test.d.ts +0 -2
- package/dist/state/fields.test.d.ts.map +0 -1
- package/dist/styles.floor.test.d.ts +0 -2
- package/dist/styles.floor.test.d.ts.map +0 -1
- package/dist/theme/border-coverage.test.d.ts +0 -18
- package/dist/theme/border-coverage.test.d.ts.map +0 -1
- package/dist/theme/contrast.test.d.ts +0 -2
- package/dist/theme/contrast.test.d.ts.map +0 -1
- package/dist/theme/ctl-theme.test.d.ts +0 -2
- package/dist/theme/ctl-theme.test.d.ts.map +0 -1
- package/dist/theme/ctl-tier-coverage.test.d.ts +0 -2
- package/dist/theme/ctl-tier-coverage.test.d.ts.map +0 -1
- package/dist/theme/density-option.test.d.ts +0 -2
- package/dist/theme/density-option.test.d.ts.map +0 -1
- package/dist/theme/density-relations.test.d.ts +0 -2
- package/dist/theme/density-relations.test.d.ts.map +0 -1
- package/dist/theme/derive-theme.test.d.ts +0 -2
- package/dist/theme/derive-theme.test.d.ts.map +0 -1
- package/dist/theme/divider-law.test.d.ts +0 -2
- package/dist/theme/divider-law.test.d.ts.map +0 -1
- package/dist/theme/fonts-option.test.d.ts +0 -2
- package/dist/theme/fonts-option.test.d.ts.map +0 -1
- package/dist/theme/icon-slot.test.d.ts +0 -2
- package/dist/theme/icon-slot.test.d.ts.map +0 -1
- package/dist/theme/layout-rhythm-css.test.d.ts +0 -2
- package/dist/theme/layout-rhythm-css.test.d.ts.map +0 -1
- package/dist/theme/radius-option.test.d.ts +0 -2
- package/dist/theme/radius-option.test.d.ts.map +0 -1
- package/dist/theme/radius.test.d.ts +0 -2
- package/dist/theme/radius.test.d.ts.map +0 -1
- package/dist/theme/shadow-surfaces.test.d.ts +0 -26
- package/dist/theme/shadow-surfaces.test.d.ts.map +0 -1
- package/dist/theme/spacing.test.d.ts +0 -2
- package/dist/theme/spacing.test.d.ts.map +0 -1
- package/dist/theme/use-basalt-spacing.test.d.ts +0 -2
- package/dist/theme/use-basalt-spacing.test.d.ts.map +0 -1
- package/dist/theme-lab/derive-controls.test.d.ts +0 -2
- package/dist/theme-lab/derive-controls.test.d.ts.map +0 -1
- package/dist/theme-lab/derive-state.test.d.ts +0 -2
- package/dist/theme-lab/derive-state.test.d.ts.map +0 -1
- package/dist/theme-lab/theme-lab.test.d.ts +0 -2
- package/dist/theme-lab/theme-lab.test.d.ts.map +0 -1
- package/dist/tokens/build-fonts-css.test.d.ts +0 -2
- package/dist/tokens/build-fonts-css.test.d.ts.map +0 -1
- package/dist/tokens/build-radius-css.test.d.ts +0 -2
- package/dist/tokens/build-radius-css.test.d.ts.map +0 -1
- package/dist/tokens/chart-margin.test.d.ts +0 -2
- package/dist/tokens/chart-margin.test.d.ts.map +0 -1
- package/dist/tokens/density.test.d.ts +0 -2
- package/dist/tokens/density.test.d.ts.map +0 -1
- package/dist/tokens/derive-radius.test.d.ts +0 -2
- package/dist/tokens/derive-radius.test.d.ts.map +0 -1
- package/dist/tokens/derive.test.d.ts +0 -2
- package/dist/tokens/derive.test.d.ts.map +0 -1
- package/dist/tokens/palette.test.d.ts +0 -2
- package/dist/tokens/palette.test.d.ts.map +0 -1
- package/dist/tokens/text-scale.test.d.ts +0 -2
- package/dist/tokens/text-scale.test.d.ts.map +0 -1
- package/dist/vite-color-mix.test.d.ts +0 -2
- package/dist/vite-color-mix.test.d.ts.map +0 -1
- package/dist/vite.test.d.ts +0 -2
- package/dist/vite.test.d.ts.map +0 -1
- package/dist/widget-header/delta-badge.test.d.ts +0 -2
- package/dist/widget-header/delta-badge.test.d.ts.map +0 -1
- package/dist/widget-header/no-mantine.test.d.ts +0 -2
- package/dist/widget-header/no-mantine.test.d.ts.map +0 -1
- package/dist/widget-header/widget-header.test.d.ts +0 -2
- package/dist/widget-header/widget-header.test.d.ts.map +0 -1
- package/src/agent/adapter.test.ts +0 -1640
- package/src/agent/ai-sdk-transport.test.ts +0 -658
- package/src/agent/coalesce.test.ts +0 -387
- package/src/agent/foreign.test.ts +0 -51
- package/src/agent/id.test.ts +0 -169
- package/src/agent/merge.test.ts +0 -206
- package/src/agent/part-list.test.tsx +0 -112
- package/src/agent/parts.test.ts +0 -720
- package/src/agent/thread.test.ts +0 -220
- package/src/agent/transport.test.ts +0 -70
- package/src/agent/use-agent-stream.test.tsx +0 -287
- package/src/agent/use-agent-thread-runs.foreign.test.tsx +0 -138
- package/src/agent/use-agent-thread-runs.resume.test.tsx +0 -294
- package/src/agent/use-agent-thread-runs.test.tsx +0 -1120
- package/src/agent/use-agent-thread-runs.wedge.test.tsx +0 -387
- package/src/agent-chat/composer.test.tsx +0 -924
- package/src/agent-chat/relative-time.test.ts +0 -95
- package/src/agent-chat/thread-feed-row.test.tsx +0 -510
- package/src/agent-chat/thread-feed.test.tsx +0 -241
- package/src/agent-chat/thread-message.test.tsx +0 -1285
- package/src/agent-chat/thread-workspace.test.tsx +0 -169
- package/src/agent-chat/tool-chip.test.tsx +0 -139
- package/src/agent-chat/virtualize.type-guard.test.ts +0 -49
- package/src/charts/cursor/resolve.test.ts +0 -151
- package/src/charts/cursor/store.test.ts +0 -64
- package/src/charts/kinds/BandStrip.test.tsx +0 -282
- package/src/charts/kinds/Bars.test.tsx +0 -183
- package/src/charts/kinds/DualPanel.test.tsx +0 -527
- package/src/charts/kinds/MirroredBars.test.tsx +0 -232
- package/src/charts/kinds/MultiLine.test.tsx +0 -218
- package/src/charts/kinds/StackedArea.test.tsx +0 -114
- package/src/charts/kinds/ZonedLine.test.tsx +0 -147
- package/src/charts/layout/auto-margin.test.ts +0 -42
- package/src/charts/primitives/CartesianChart.test.tsx +0 -647
- package/src/charts/primitives/ChartCard.test.tsx +0 -66
- package/src/charts/primitives/ChartFrame.test.tsx +0 -142
- package/src/charts/primitives/ChartLegend.test.tsx +0 -78
- package/src/charts/primitives/ChartTooltip.test.tsx +0 -44
- package/src/charts/primitives/XZoneRects.test.tsx +0 -123
- package/src/charts/series.test.ts +0 -112
- package/src/charts/utils/domain.test.ts +0 -54
- package/src/charts/utils/measure-text.test.ts +0 -36
- package/src/cli/check-coverage.test.ts +0 -297
- package/src/cli/check-theme.test.ts +0 -837
- package/src/cli/help.test.ts +0 -170
- package/src/cli/init-sync.test.ts +0 -343
- package/src/cli/placement-engine.test.ts +0 -298
- package/src/cli/shipped-versions.test.ts +0 -83
- package/src/cli/tarball-parity.test.ts +0 -44
- package/src/cli/template-format.test.ts +0 -64
- package/src/cli/template-ledger.test.ts +0 -219
- package/src/cli/tokens-css.test.ts +0 -249
- package/src/cli/toolchain-wiring.test.ts +0 -1358
- package/src/cli/waiver-audit.test.ts +0 -215
- package/src/content/article-actions.test.ts +0 -78
- package/src/content/article-model.test.ts +0 -119
- package/src/content/block-split.test.ts +0 -75
- package/src/content/heading-components.test.tsx +0 -65
- package/src/content/markdown.test.tsx +0 -603
- package/src/content/prose.module.css.test.ts +0 -39
- package/src/content/sanitize.test.ts +0 -659
- package/src/content/slug.test.ts +0 -62
- package/src/controls/actions.test.tsx +0 -252
- package/src/controls/actions.type-guard.test.ts +0 -63
- package/src/controls/control-group.test.tsx +0 -229
- package/src/controls/controls.router.test.tsx +0 -637
- package/src/controls/filter-set.test.tsx +0 -472
- package/src/controls/peer-boundary.test.ts +0 -85
- package/src/controls/props-contract.test.tsx +0 -106
- package/src/controls/sync-button.test.tsx +0 -183
- package/src/dashboard/query-state.test.tsx +0 -152
- package/src/dashboard/settings-section.test.tsx +0 -56
- package/src/dashboard/stat-card.test.tsx +0 -154
- package/src/data/data-table.test.tsx +0 -434
- package/src/guard/check-source.test.ts +0 -3355
- package/src/guard/grace.test.ts +0 -149
- package/src/guard/guard-hook.test.ts +0 -203
- package/src/provider/index.test.tsx +0 -101
- package/src/provider/lab-theme.test.ts +0 -147
- package/src/query/error-message.test.ts +0 -67
- package/src/router-tanstack/multi-search-param-store.test.ts +0 -124
- package/src/router-tanstack/nav.test.ts +0 -111
- package/src/router-tanstack/search-param-store.test.ts +0 -135
- package/src/router-tanstack/search-store.router.test.tsx +0 -661
- package/src/router-tanstack/search-store.test.ts +0 -418
- package/src/router-tanstack/use-nav.test.tsx +0 -187
- package/src/section/section.test.tsx +0 -204
- package/src/shell/app-mobile-nav.test.tsx +0 -403
- package/src/shell/app-sidebar.test.tsx +0 -509
- package/src/shell/index.test.tsx +0 -428
- package/src/shell/mobile-nav-model.test.ts +0 -517
- package/src/shell/page-bar.test.tsx +0 -316
- package/src/state/fields.test.tsx +0 -258
- package/src/styles.floor.test.ts +0 -36
- package/src/theme/border-coverage.test.ts +0 -272
- package/src/theme/contrast.test.ts +0 -354
- package/src/theme/ctl-theme.test.tsx +0 -275
- package/src/theme/ctl-tier-coverage.test.ts +0 -170
- package/src/theme/density-option.test.ts +0 -96
- package/src/theme/density-relations.test.ts +0 -506
- package/src/theme/derive-theme.test.ts +0 -101
- package/src/theme/divider-law.test.ts +0 -259
- package/src/theme/fonts-option.test.ts +0 -75
- package/src/theme/icon-slot.test.tsx +0 -275
- package/src/theme/layout-rhythm-css.test.ts +0 -72
- package/src/theme/radius-option.test.ts +0 -86
- package/src/theme/radius.test.ts +0 -142
- package/src/theme/shadow-surfaces.test.ts +0 -488
- package/src/theme/spacing.test.ts +0 -495
- package/src/theme/use-basalt-spacing.test.tsx +0 -55
- package/src/theme-lab/derive-controls.test.ts +0 -94
- package/src/theme-lab/derive-state.test.ts +0 -71
- package/src/theme-lab/theme-lab.test.ts +0 -46
- package/src/tokens/build-fonts-css.test.ts +0 -52
- package/src/tokens/build-radius-css.test.ts +0 -25
- package/src/tokens/chart-margin.test.ts +0 -39
- package/src/tokens/density.test.ts +0 -259
- package/src/tokens/derive-radius.test.ts +0 -62
- package/src/tokens/derive.test.ts +0 -30
- package/src/tokens/palette.test.ts +0 -114
- package/src/tokens/text-scale.test.ts +0 -51
- package/src/vite-color-mix.test.ts +0 -46
- package/src/vite.test.ts +0 -423
- package/src/widget-header/delta-badge.test.tsx +0 -60
- package/src/widget-header/no-mantine.test.ts +0 -33
- package/src/widget-header/widget-header.test.tsx +0 -187
|
@@ -1,472 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `FilterSet`'s four owned behaviours (`docs/CONTROLS-SPEC.md` §2.1/§3), each asserted against real
|
|
3
|
-
* children bound to a real `createSearchStore`: the DERIVED active count, `Reset all` reaching every
|
|
4
|
-
* registered filter, the mobile `inline` budget, and the measured desktop fold.
|
|
5
|
-
*
|
|
6
|
-
* The fold is the one behaviour that needs the DOM stubbed rather than driven — happy-dom lays
|
|
7
|
-
* nothing out, so `offsetWidth`/`clientWidth` are 0 for every element and the no-op
|
|
8
|
-
* `ResizeObserver` from `tests/setup/dom.ts` never fires. Both are replaced here (restored in
|
|
9
|
-
* `afterEach`), which is what lets the fold arithmetic be tested at all instead of only in a
|
|
10
|
-
* browser.
|
|
11
|
-
*/
|
|
12
|
-
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
|
|
13
|
-
import { readFileSync } from 'node:fs'
|
|
14
|
-
import { join } from 'node:path'
|
|
15
|
-
import type { ReactNode } from 'react'
|
|
16
|
-
import { MantineProvider } from '@mantine/core'
|
|
17
|
-
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'
|
|
18
|
-
import {
|
|
19
|
-
Outlet,
|
|
20
|
-
RouterProvider,
|
|
21
|
-
createMemoryHistory,
|
|
22
|
-
createRootRoute,
|
|
23
|
-
createRoute,
|
|
24
|
-
createRouter,
|
|
25
|
-
} from '@tanstack/react-router'
|
|
26
|
-
import { field } from '../router-tanstack/field'
|
|
27
|
-
import { createSearchStore } from '../router-tanstack/search-store'
|
|
28
|
-
import { FilterSet } from './filter-set'
|
|
29
|
-
import { SelectFilter } from './select-filter'
|
|
30
|
-
import { ToggleFilter } from './toggle-filter'
|
|
31
|
-
|
|
32
|
-
type Router = { state: { status: string; location: { search: unknown } } }
|
|
33
|
-
|
|
34
|
-
const store = createSearchStore({
|
|
35
|
-
key: 'fs',
|
|
36
|
-
fields: {
|
|
37
|
-
currency: field.enum(['USD', 'EUR'], 'USD'),
|
|
38
|
-
region: field.enum(['all', 'eu', 'us'], 'all'),
|
|
39
|
-
tier: field.enum(['any', 'pro'], 'any'),
|
|
40
|
-
errorsOnly: field.boolean(false),
|
|
41
|
-
},
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
async function mountSet(entry: string, inline?: number): Promise<Router> {
|
|
45
|
-
const rootRoute = createRootRoute({ component: () => <Outlet /> })
|
|
46
|
-
const pageRoute = createRoute({
|
|
47
|
-
getParentRoute: () => rootRoute,
|
|
48
|
-
path: '/dashboard',
|
|
49
|
-
validateSearch: store.validateSearch,
|
|
50
|
-
component: () => (
|
|
51
|
-
<FilterSet {...(inline !== undefined && { inline })}>
|
|
52
|
-
<SelectFilter field={store.field.currency} label="Currency" />
|
|
53
|
-
<SelectFilter field={store.field.region} label="Region" />
|
|
54
|
-
<SelectFilter field={store.field.tier} label="Tier" />
|
|
55
|
-
<ToggleFilter field={store.field.errorsOnly} label="Errors only" />
|
|
56
|
-
</FilterSet>
|
|
57
|
-
),
|
|
58
|
-
})
|
|
59
|
-
const router = createRouter({
|
|
60
|
-
routeTree: rootRoute.addChildren([pageRoute]),
|
|
61
|
-
history: createMemoryHistory({ initialEntries: [entry] }),
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
render(
|
|
65
|
-
<MantineProvider>
|
|
66
|
-
<RouterProvider router={router} />
|
|
67
|
-
</MantineProvider>,
|
|
68
|
-
)
|
|
69
|
-
await waitFor(() => {
|
|
70
|
-
expect(router.state.status).toBe('idle')
|
|
71
|
-
})
|
|
72
|
-
return router as unknown as Router
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function slots(): HTMLElement[] {
|
|
76
|
-
return [...document.querySelectorAll<HTMLElement>('[data-filter-slot]')]
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function row(): HTMLElement {
|
|
80
|
-
const node = document.querySelector<HTMLElement>('[data-filter-row]')
|
|
81
|
-
if (node === null) throw new Error('no filter row rendered')
|
|
82
|
-
return node
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** The stubbed layout: every element's width is whatever the test wrote to `data-test-width`. */
|
|
86
|
-
function widthFromData(this: HTMLElement): number {
|
|
87
|
-
return Number(this.dataset['testWidth'] ?? '0')
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
beforeEach(() => {
|
|
91
|
-
localStorage.clear()
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
describe('the active count is derived from the children, never passed', () => {
|
|
95
|
-
test('no filter is off its default → the sheet pill states no count', async () => {
|
|
96
|
-
await mountSet('/dashboard')
|
|
97
|
-
expect(screen.getByRole('button', { name: 'Filters' })).toBeDefined()
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
test('two non-default fields on a deep link → Filters (2), with nothing told to FilterSet', async () => {
|
|
101
|
-
await mountSet('/dashboard?currency=EUR&errorsOnly=true')
|
|
102
|
-
await waitFor(() => {
|
|
103
|
-
expect(screen.getByRole('button', { name: 'Filters (2)' })).toBeDefined()
|
|
104
|
-
})
|
|
105
|
-
})
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
describe('Reset all reaches every registered filter, including the folded and the inline ones', () => {
|
|
109
|
-
test('one press writes every field back to its fallback', async () => {
|
|
110
|
-
const router = await mountSet('/dashboard?currency=EUR®ion=eu&errorsOnly=true')
|
|
111
|
-
await waitFor(() => {
|
|
112
|
-
expect(screen.getByRole('button', { name: 'Filters (3)' })).toBeDefined()
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
await act(async () => {
|
|
116
|
-
fireEvent.click(screen.getByRole('button', { name: 'Filters (3)' }))
|
|
117
|
-
})
|
|
118
|
-
await act(async () => {
|
|
119
|
-
fireEvent.click(screen.getByRole('button', { name: 'Reset all', hidden: true }))
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
await waitFor(() => {
|
|
123
|
-
const search = router.state.location.search as Record<string, unknown>
|
|
124
|
-
expect(search['currency']).toBe('USD')
|
|
125
|
-
expect(search['region']).toBe('all')
|
|
126
|
-
expect(search['errorsOnly']).toBe(false)
|
|
127
|
-
})
|
|
128
|
-
expect(screen.getByRole('button', { name: 'Filters' })).toBeDefined()
|
|
129
|
-
})
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
describe('the mobile inline budget is per-slot data, not a second mount', () => {
|
|
133
|
-
test('inline defaults to 1 — the first slot only', async () => {
|
|
134
|
-
await mountSet('/dashboard')
|
|
135
|
-
expect(slots().map((slot) => slot.hasAttribute('data-inline'))).toEqual([
|
|
136
|
-
true,
|
|
137
|
-
false,
|
|
138
|
-
false,
|
|
139
|
-
false,
|
|
140
|
-
])
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
test('inline={2} keeps the first two', async () => {
|
|
144
|
-
await mountSet('/dashboard', 2)
|
|
145
|
-
expect(slots().map((slot) => slot.hasAttribute('data-inline'))).toEqual([
|
|
146
|
-
true,
|
|
147
|
-
true,
|
|
148
|
-
false,
|
|
149
|
-
false,
|
|
150
|
-
])
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
test('every child stays mounted regardless of the budget — the row is the whole census', async () => {
|
|
154
|
-
await mountSet('/dashboard')
|
|
155
|
-
expect(slots()).toHaveLength(4)
|
|
156
|
-
})
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
describe('the desktop fold is measured, and it never scrolls', () => {
|
|
160
|
-
const offsetWidth = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetWidth')
|
|
161
|
-
const clientWidth = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'clientWidth')
|
|
162
|
-
let observers: (() => void)[] = []
|
|
163
|
-
|
|
164
|
-
function stubLayout(): void {
|
|
165
|
-
observers = []
|
|
166
|
-
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
|
|
167
|
-
configurable: true,
|
|
168
|
-
get: widthFromData,
|
|
169
|
-
})
|
|
170
|
-
Object.defineProperty(HTMLElement.prototype, 'clientWidth', {
|
|
171
|
-
configurable: true,
|
|
172
|
-
get: widthFromData,
|
|
173
|
-
})
|
|
174
|
-
class ResizeObserverStub {
|
|
175
|
-
constructor(callback: () => void) {
|
|
176
|
-
observers.push(callback)
|
|
177
|
-
}
|
|
178
|
-
observe(): void {}
|
|
179
|
-
unobserve(): void {}
|
|
180
|
-
disconnect(): void {}
|
|
181
|
-
}
|
|
182
|
-
window.ResizeObserver = ResizeObserverStub as unknown as typeof ResizeObserver
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
afterEach(() => {
|
|
186
|
-
if (offsetWidth !== undefined) {
|
|
187
|
-
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', offsetWidth)
|
|
188
|
-
}
|
|
189
|
-
if (clientWidth !== undefined) {
|
|
190
|
-
Object.defineProperty(HTMLElement.prototype, 'clientWidth', clientWidth)
|
|
191
|
-
}
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
async function resizeTo(available: number, perSlot: number): Promise<void> {
|
|
195
|
-
row().dataset['testWidth'] = String(available)
|
|
196
|
-
for (const slot of slots()) slot.dataset['testWidth'] = String(perSlot)
|
|
197
|
-
await act(async () => {
|
|
198
|
-
for (const notify of observers) notify()
|
|
199
|
-
})
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
test('four 100px pills in 250px: the tail folds into +3, and the row keeps one', async () => {
|
|
203
|
-
stubLayout()
|
|
204
|
-
await mountSet('/dashboard')
|
|
205
|
-
await resizeTo(250, 100)
|
|
206
|
-
|
|
207
|
-
expect(slots().map((slot) => slot.hasAttribute('data-folded'))).toEqual([
|
|
208
|
-
false,
|
|
209
|
-
true,
|
|
210
|
-
true,
|
|
211
|
-
true,
|
|
212
|
-
])
|
|
213
|
-
const fold = screen.getByRole('button', { name: '3 more filters' })
|
|
214
|
-
expect(fold.hasAttribute('data-shown')).toBe(true)
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
test('slots of DIFFERENT widths fold at the right index, not at a uniform one', async () => {
|
|
218
|
-
// The uniform-100px case can be satisfied by arithmetic that ignores which slot is which. Here
|
|
219
|
-
// the widths are 40/40/300/40: the wide third pill is what pushes the row over, so the fold has
|
|
220
|
-
// to land at 2 rather than at some average-derived index.
|
|
221
|
-
stubLayout()
|
|
222
|
-
await mountSet('/dashboard')
|
|
223
|
-
row().dataset['testWidth'] = '250'
|
|
224
|
-
const widths = ['40', '40', '300', '40']
|
|
225
|
-
slots().forEach((slot, index) => {
|
|
226
|
-
slot.dataset['testWidth'] = widths[index] ?? '40'
|
|
227
|
-
})
|
|
228
|
-
await act(async () => {
|
|
229
|
-
for (const notify of observers) notify()
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
expect(slots().map((slot) => slot.hasAttribute('data-folded'))).toEqual([
|
|
233
|
-
false,
|
|
234
|
-
false,
|
|
235
|
-
true,
|
|
236
|
-
true,
|
|
237
|
-
])
|
|
238
|
-
expect(screen.getByRole('button', { name: '2 more filters' }).hasAttribute('data-shown')).toBe(
|
|
239
|
-
true,
|
|
240
|
-
)
|
|
241
|
-
})
|
|
242
|
-
|
|
243
|
-
test('the same four pills in 900px: nothing folds and the +N pill stays unshown', async () => {
|
|
244
|
-
stubLayout()
|
|
245
|
-
await mountSet('/dashboard')
|
|
246
|
-
await resizeTo(900, 100)
|
|
247
|
-
|
|
248
|
-
expect(slots().some((slot) => slot.hasAttribute('data-folded'))).toBe(false)
|
|
249
|
-
expect(screen.getByRole('button', { name: '0 more filters' }).hasAttribute('data-shown')).toBe(
|
|
250
|
-
false,
|
|
251
|
-
)
|
|
252
|
-
})
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
describe('a folded filter is still operable from inside the +N dropdown', () => {
|
|
256
|
-
const offsetWidth = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetWidth')
|
|
257
|
-
const clientWidth = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'clientWidth')
|
|
258
|
-
|
|
259
|
-
afterEach(() => {
|
|
260
|
-
if (offsetWidth !== undefined) {
|
|
261
|
-
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', offsetWidth)
|
|
262
|
-
}
|
|
263
|
-
if (clientWidth !== undefined) {
|
|
264
|
-
Object.defineProperty(HTMLElement.prototype, 'clientWidth', clientWidth)
|
|
265
|
-
}
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
test('opening +N and changing a folded field writes the URL, and +N stays open', async () => {
|
|
269
|
-
// The regression this pins: rendering the fold body in PILL form gave each folded filter its own
|
|
270
|
-
// `withinPortal` Popover, whose mousedown is outside the +N dropdown's `composedPath()` — so +N
|
|
271
|
-
// closed, the pill unmounted, and the click never landed. The sheet form has no nested overlay.
|
|
272
|
-
let observers: (() => void)[] = []
|
|
273
|
-
Object.defineProperty(HTMLElement.prototype, 'offsetWidth', {
|
|
274
|
-
configurable: true,
|
|
275
|
-
get: widthFromData,
|
|
276
|
-
})
|
|
277
|
-
Object.defineProperty(HTMLElement.prototype, 'clientWidth', {
|
|
278
|
-
configurable: true,
|
|
279
|
-
get: widthFromData,
|
|
280
|
-
})
|
|
281
|
-
class ResizeObserverStub {
|
|
282
|
-
constructor(callback: () => void) {
|
|
283
|
-
observers.push(callback)
|
|
284
|
-
}
|
|
285
|
-
observe(): void {}
|
|
286
|
-
unobserve(): void {}
|
|
287
|
-
disconnect(): void {}
|
|
288
|
-
}
|
|
289
|
-
window.ResizeObserver = ResizeObserverStub as unknown as typeof ResizeObserver
|
|
290
|
-
|
|
291
|
-
const router = await mountSet('/dashboard')
|
|
292
|
-
row().dataset['testWidth'] = '250'
|
|
293
|
-
for (const slot of slots()) slot.dataset['testWidth'] = '100'
|
|
294
|
-
await act(async () => {
|
|
295
|
-
for (const notify of observers) notify()
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
await act(async () => {
|
|
299
|
-
fireEvent.click(screen.getByRole('button', { name: '3 more filters' }))
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
// The folded children render their sheet form — a named option list, no second pill. `group`,
|
|
303
|
-
// not `radiogroup`: the sheet form is a `<fieldset>` of native radios (`SheetOptionList`), which
|
|
304
|
-
// is the grouping role a fieldset carries. `Radio.Group` is the POPOVER form's shape.
|
|
305
|
-
const group = screen.getByRole('group', { name: 'Region', hidden: true })
|
|
306
|
-
expect(group).toBeDefined()
|
|
307
|
-
|
|
308
|
-
await act(async () => {
|
|
309
|
-
fireEvent.click(screen.getByRole('radio', { name: 'eu', hidden: true }))
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
await waitFor(() => {
|
|
313
|
-
expect((router.state.location.search as Record<string, unknown>)['region']).toBe('eu')
|
|
314
|
-
})
|
|
315
|
-
// Still open: the write did not tear its own container down.
|
|
316
|
-
expect(screen.getByRole('group', { name: 'Region', hidden: true })).toBeDefined()
|
|
317
|
-
observers = []
|
|
318
|
-
})
|
|
319
|
-
})
|
|
320
|
-
|
|
321
|
-
describe('the sheet names every control it holds', () => {
|
|
322
|
-
test('the option lists and the Switch row carry the filter name, not the pill text', async () => {
|
|
323
|
-
await mountSet('/dashboard?currency=EUR')
|
|
324
|
-
await act(async () => {
|
|
325
|
-
fireEvent.click(screen.getByRole('button', { name: 'Filters (1)' }))
|
|
326
|
-
})
|
|
327
|
-
|
|
328
|
-
// `Currency`, not `EUR` — the pill reads the VALUE once set, which names the selection rather
|
|
329
|
-
// than the filter. Each `<fieldset>` points at its own visible SheetField heading.
|
|
330
|
-
for (const name of ['Currency', 'Region', 'Tier']) {
|
|
331
|
-
expect(screen.getByRole('group', { name, hidden: true })).toBeDefined()
|
|
332
|
-
}
|
|
333
|
-
expect(screen.getByRole('switch', { name: 'Errors only', hidden: true })).toBeDefined()
|
|
334
|
-
})
|
|
335
|
-
})
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* The 44px touch target, asserted at the SOURCE. Neither half is checkable in the DOM here:
|
|
339
|
-
* happy-dom lays nothing out (so no bounding box), and a `.module.css` import resolves to `undefined`
|
|
340
|
-
* under `bun test` (so the emitted `class` attribute carries only Mantine's own names). What IS
|
|
341
|
-
* checkable is the pair that produces it — the CSS stretching the body and label to the row, and
|
|
342
|
-
* every row-rendering control actually passing those classes. A row whose height sits on a
|
|
343
|
-
* non-interactive wrapper is C15's number without C15's behaviour, which is the defect this pins.
|
|
344
|
-
*/
|
|
345
|
-
describe('sheet rows are tappable across their full height (C15)', () => {
|
|
346
|
-
const css = readFileSync(join(import.meta.dir, 'controls.module.css'), 'utf8')
|
|
347
|
-
|
|
348
|
-
function block(selector: string): string {
|
|
349
|
-
const start = css.indexOf(`${selector} {`)
|
|
350
|
-
expect(start).toBeGreaterThan(-1)
|
|
351
|
-
return css.slice(start, css.indexOf('}', start))
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
test('both row primitives pin the height to the sheet-row token, not a literal', () => {
|
|
355
|
-
expect(block('.sheetRow')).toContain('var(--vx-space-sheet-row-height')
|
|
356
|
-
expect(block('.sheetOption')).toContain('var(--vx-space-sheet-row-height')
|
|
357
|
-
})
|
|
358
|
-
|
|
359
|
-
test('the option row IS the hit target — the height sits on the label, never on a wrapper', () => {
|
|
360
|
-
// `.sheetOption` is the `<label>` (and, in a disclosure, the `<button>`) itself, so the 44px is
|
|
361
|
-
// on the interactive element by construction rather than by a classNames hand-off.
|
|
362
|
-
const rule = block('.sheetOption')
|
|
363
|
-
expect(rule).toContain('width: 100%')
|
|
364
|
-
expect(rule).toContain('cursor: pointer')
|
|
365
|
-
})
|
|
366
|
-
|
|
367
|
-
test('.sheetRowBody and .sheetRowLabel stretch the interactive element to that height', () => {
|
|
368
|
-
for (const selector of ['.sheetRowBody', '.sheetRowLabel']) {
|
|
369
|
-
const rule = block(selector)
|
|
370
|
-
expect(rule).toContain('flex: 1')
|
|
371
|
-
expect(rule).toContain('min-height: inherit')
|
|
372
|
-
}
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
test('every control that renders a sheet row goes through a 44px row primitive', () => {
|
|
376
|
-
// Two primitives, one law. `ToggleFilter` renders a Mantine `Switch` AS the row, so it needs
|
|
377
|
-
// `sheetRowClassNames` to stretch the control's own `<label>` across the 44px. The enum/multi/
|
|
378
|
-
// range filters render `SheetOptionList`, which owns the `<label>`-per-row box itself — the
|
|
379
|
-
// classNames escape exists for controls basalt does not draw the row for.
|
|
380
|
-
expect(readFileSync(join(import.meta.dir, 'toggle-filter.tsx'), 'utf8')).toContain(
|
|
381
|
-
'sheetRowClassNames',
|
|
382
|
-
)
|
|
383
|
-
for (const file of ['enum-filter.tsx', 'multi-select-filter.tsx', 'range-filter.tsx']) {
|
|
384
|
-
const source = readFileSync(join(import.meta.dir, file), 'utf8')
|
|
385
|
-
expect(source).toContain('SheetOptionList')
|
|
386
|
-
}
|
|
387
|
-
})
|
|
388
|
-
|
|
389
|
-
test('no control wraps its sheet row in a plain div — the height must sit on the label', () => {
|
|
390
|
-
// `SheetRow` puts `min-height` on a non-interactive wrapper, which is exactly the 20px-strip
|
|
391
|
-
// defect. It stays exported for a future non-interactive row; no filter may use it.
|
|
392
|
-
for (const file of ['enum-filter.tsx', 'multi-select-filter.tsx', 'toggle-filter.tsx']) {
|
|
393
|
-
const source = readFileSync(join(import.meta.dir, file), 'utf8')
|
|
394
|
-
expect(source).not.toContain('<SheetRow>')
|
|
395
|
-
}
|
|
396
|
-
})
|
|
397
|
-
})
|
|
398
|
-
|
|
399
|
-
describe('an empty home renders nothing (C14)', () => {
|
|
400
|
-
test('no children → no row, so no route pays for a reserved bar', async () => {
|
|
401
|
-
const rootRoute = createRootRoute({ component: () => <Outlet /> })
|
|
402
|
-
const pageRoute = createRoute({
|
|
403
|
-
getParentRoute: () => rootRoute,
|
|
404
|
-
path: '/dashboard',
|
|
405
|
-
component: (): ReactNode => <FilterSet>{null}</FilterSet>,
|
|
406
|
-
})
|
|
407
|
-
const router = createRouter({
|
|
408
|
-
routeTree: rootRoute.addChildren([pageRoute]),
|
|
409
|
-
history: createMemoryHistory({ initialEntries: ['/dashboard'] }),
|
|
410
|
-
})
|
|
411
|
-
render(
|
|
412
|
-
<MantineProvider>
|
|
413
|
-
<RouterProvider router={router} />
|
|
414
|
-
</MantineProvider>,
|
|
415
|
-
)
|
|
416
|
-
await waitFor(() => {
|
|
417
|
-
expect(router.state.status).toBe('idle')
|
|
418
|
-
})
|
|
419
|
-
|
|
420
|
-
expect(document.querySelector('[data-filter-row]')).toBeNull()
|
|
421
|
-
})
|
|
422
|
-
})
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* The `Filters (n)` pill is the mobile SHEET TRIGGER, and the sheet only ever holds what the
|
|
426
|
-
* `inline` budget folded away. With nothing folded it opens a drawer showing a copy of the pills
|
|
427
|
-
* already on screen — while costing the mobile row the width of a pill to say so.
|
|
428
|
-
*/
|
|
429
|
-
describe('the mobile sheet trigger appears only when a child is folded', () => {
|
|
430
|
-
async function mountOne(inline?: number): Promise<void> {
|
|
431
|
-
const rootRoute = createRootRoute({ component: () => <Outlet /> })
|
|
432
|
-
const pageRoute = createRoute({
|
|
433
|
-
getParentRoute: () => rootRoute,
|
|
434
|
-
path: '/dashboard',
|
|
435
|
-
validateSearch: store.validateSearch,
|
|
436
|
-
component: (): ReactNode => (
|
|
437
|
-
<FilterSet {...(inline !== undefined && { inline })}>
|
|
438
|
-
<SelectFilter field={store.field.currency} label="Currency" />
|
|
439
|
-
</FilterSet>
|
|
440
|
-
),
|
|
441
|
-
})
|
|
442
|
-
const router = createRouter({
|
|
443
|
-
routeTree: rootRoute.addChildren([pageRoute]),
|
|
444
|
-
history: createMemoryHistory({ initialEntries: ['/dashboard'] }),
|
|
445
|
-
})
|
|
446
|
-
render(
|
|
447
|
-
<MantineProvider>
|
|
448
|
-
<RouterProvider router={router} />
|
|
449
|
-
</MantineProvider>,
|
|
450
|
-
)
|
|
451
|
-
await waitFor(() => {
|
|
452
|
-
expect(router.state.status).toBe('idle')
|
|
453
|
-
})
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
test('one child at the default budget → no Filters pill at all', async () => {
|
|
457
|
-
await mountOne()
|
|
458
|
-
expect(screen.queryByRole('button', { name: 'Filters' })).toBeNull()
|
|
459
|
-
// …and the filter itself is still there, inline.
|
|
460
|
-
expect(slots()).toHaveLength(1)
|
|
461
|
-
})
|
|
462
|
-
|
|
463
|
-
test('inline={0} folds that same child → the pill is back', async () => {
|
|
464
|
-
await mountOne(0)
|
|
465
|
-
expect(screen.getByRole('button', { name: 'Filters' })).toBeDefined()
|
|
466
|
-
})
|
|
467
|
-
|
|
468
|
-
test('four children at the default budget keep the pill', async () => {
|
|
469
|
-
await mountSet('/dashboard')
|
|
470
|
-
expect(screen.getByRole('button', { name: 'Filters' })).toBeDefined()
|
|
471
|
-
})
|
|
472
|
-
})
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The packaging invariant `./controls` and `./controls-dates` exist to express
|
|
3
|
-
* (`docs/CONTROLS-SPEC.md` §3): `@mantine/dates` is an OPTIONAL peer, so `basalt-ui/controls` must
|
|
4
|
-
* resolve for a consumer who has never installed it.
|
|
5
|
-
*
|
|
6
|
-
* Source-level, and deliberately so: `scripts/pack-test.sh` proves the same thing from the PACKED
|
|
7
|
-
* tarball with the peer genuinely absent, which is the stronger claim — but it runs in CI, on a
|
|
8
|
-
* built artifact, minutes later. This file fails in the unit loop, on the line that broke it, which
|
|
9
|
-
* is what makes the invariant cheap enough to hold. Both, not either.
|
|
10
|
-
*
|
|
11
|
-
* The second half is the direction of the dependency: `./controls-dates` may reach INTO `./controls`
|
|
12
|
-
* (for the `RangeCustomPickerProps` contract, type-only), never the reverse — a runtime import back
|
|
13
|
-
* would put `@mantine/dates` in `./controls`' graph through the side door, which is exactly the
|
|
14
|
-
* failure a lazy `import()` would also cause and the reason `RangeFilter` takes the picker as a prop.
|
|
15
|
-
*/
|
|
16
|
-
import { describe, expect, test } from 'bun:test'
|
|
17
|
-
import { readFileSync } from 'node:fs'
|
|
18
|
-
import { join } from 'node:path'
|
|
19
|
-
|
|
20
|
-
const SRC = join(import.meta.dir, '..')
|
|
21
|
-
|
|
22
|
-
const BLOCK_COMMENT = /\/\*[\s\S]*?\*\//g
|
|
23
|
-
const LINE_COMMENT = /\/\/.*$/gm
|
|
24
|
-
|
|
25
|
-
/** Every static or dynamic reference to `spec` that survives to runtime. Type-only forms excluded. */
|
|
26
|
-
function runtimeReferences(source: string, spec: string): boolean {
|
|
27
|
-
const code = source.replace(BLOCK_COMMENT, '').replace(LINE_COMMENT, '')
|
|
28
|
-
const quoted = `['"]${spec.replace(/[/*]/g, (c) => `\\${c}`)}['"]`
|
|
29
|
-
const staticForm = new RegExp(
|
|
30
|
-
`^(?:import|export)\\s+(?!type\\b)[^\\n]*from\\s+${quoted}|^import\\s+(?!type\\b)${quoted}`,
|
|
31
|
-
'm',
|
|
32
|
-
)
|
|
33
|
-
const dynamicForm = new RegExp(`import\\s*\\(\\s*${quoted}`)
|
|
34
|
-
return staticForm.test(code) || dynamicForm.test(code)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function filesUnder(dir: string): string[] {
|
|
38
|
-
const glob = new Bun.Glob('**/*.{ts,tsx}')
|
|
39
|
-
return [...glob.scanSync({ cwd: join(SRC, dir) })].map((rel) => join(SRC, dir, rel))
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
describe('./controls never reaches @mantine/dates', () => {
|
|
43
|
-
const files = filesUnder('controls')
|
|
44
|
-
|
|
45
|
-
test('the walk found files to scan', () => {
|
|
46
|
-
expect(files.length).toBeGreaterThan(5)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test('no file under src/controls imports @mantine/dates, statically or lazily', () => {
|
|
50
|
-
const violations = files
|
|
51
|
-
.filter((file) => runtimeReferences(readFileSync(file, 'utf8'), '@mantine/dates'))
|
|
52
|
-
.map((file) => file.slice(SRC.length + 1))
|
|
53
|
-
expect(violations).toEqual([])
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
describe('the dependency points one way', () => {
|
|
58
|
-
test('no file under src/controls imports src/controls-dates', () => {
|
|
59
|
-
const violations = filesUnder('controls')
|
|
60
|
-
.filter((file) => /from\s+['"]\.\.\/controls-dates/.test(readFileSync(file, 'utf8')))
|
|
61
|
-
.map((file) => file.slice(SRC.length + 1))
|
|
62
|
-
expect(violations).toEqual([])
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
test('src/controls-dates reaches ../controls for TYPES only — a runtime edge would leak the peer', () => {
|
|
66
|
-
const violations = filesUnder('controls-dates')
|
|
67
|
-
.filter((file) => {
|
|
68
|
-
const source = readFileSync(file, 'utf8')
|
|
69
|
-
return /from\s+['"]\.\.\/controls/.test(
|
|
70
|
-
source
|
|
71
|
-
.replace(/export\s+type\s+\{[^}]*\}\s+from\s+['"][^'"]*['"]/g, '')
|
|
72
|
-
.replace(/import\s+type\s+\{[^}]*\}\s+from\s+['"][^'"]*['"]/g, ''),
|
|
73
|
-
)
|
|
74
|
-
})
|
|
75
|
-
.map((file) => file.slice(SRC.length + 1))
|
|
76
|
-
expect(violations).toEqual([])
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
test('@mantine/dates is reached from exactly one place — src/controls-dates', () => {
|
|
80
|
-
const importers = filesUnder('controls-dates')
|
|
81
|
-
.filter((file) => runtimeReferences(readFileSync(file, 'utf8'), '@mantine/dates'))
|
|
82
|
-
.map((file) => file.slice(SRC.length + 1))
|
|
83
|
-
expect(importers).toEqual(['controls-dates/date-range-picker.tsx'])
|
|
84
|
-
})
|
|
85
|
-
})
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* C2 and C5 as COMPILER assertions. The claim "a basalt filter has no `value`/`onChange`/`size`" is
|
|
3
|
-
* only worth making if writing one fails the build, so each `@ts-expect-error` below is the actual
|
|
4
|
-
* enforcement: `bunx tsc --noEmit` fails if any of them stops being an error, which is what happens
|
|
5
|
-
* the moment someone widens a prop type back open.
|
|
6
|
-
*
|
|
7
|
-
* `tsc` covers `src/**` including test files, so this file is checked by the ordinary typecheck —
|
|
8
|
-
* there is nothing extra to run and nothing to remember.
|
|
9
|
-
*/
|
|
10
|
-
import { describe, expect, test } from 'bun:test'
|
|
11
|
-
import type { ReactNode } from 'react'
|
|
12
|
-
import { createLocalStore, field } from '../state'
|
|
13
|
-
import { CompareFilter } from './compare-filter'
|
|
14
|
-
import { MultiSelectFilter } from './multi-select-filter'
|
|
15
|
-
import { RangeFilter } from './range-filter'
|
|
16
|
-
import { SearchFilter } from './search-filter'
|
|
17
|
-
import { SelectFilter } from './select-filter'
|
|
18
|
-
import { ToggleFilter } from './toggle-filter'
|
|
19
|
-
import { ViewTabs } from './view-tabs'
|
|
20
|
-
|
|
21
|
-
const local = createLocalStore({
|
|
22
|
-
key: 'props-contract',
|
|
23
|
-
fields: {
|
|
24
|
-
currency: field.enum(['USD', 'EUR'], 'USD'),
|
|
25
|
-
compare: field.enum(['none', 'previous', 'year'] as const, 'none'),
|
|
26
|
-
channels: field.multi(['web', 'email'], []),
|
|
27
|
-
range: field.range({ presets: ['7d', '30d'], fallback: '30d', custom: true }),
|
|
28
|
-
errorsOnly: field.boolean(false),
|
|
29
|
-
q: field.string(),
|
|
30
|
-
},
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
/** A runtime catalogue — the shape both `options` props take (`FilterOption[]`). */
|
|
34
|
-
const PROJECTS = [
|
|
35
|
-
{ value: 'argo', label: 'Argo' },
|
|
36
|
-
{ value: 'linewatch', label: 'Linewatch', disabled: true },
|
|
37
|
-
]
|
|
38
|
-
const CHANNELS = [{ value: 'web', label: 'web · 1.2k' }]
|
|
39
|
-
|
|
40
|
-
/** Never rendered — the file's product is the type errors below, not a DOM assertion. */
|
|
41
|
-
function Rejected(): ReactNode {
|
|
42
|
-
return (
|
|
43
|
-
<>
|
|
44
|
-
{/* @ts-expect-error C2 — a filter has no `value`; the field owns it. */}
|
|
45
|
-
<SelectFilter field={local.field.currency} label="Currency" value="EUR" />
|
|
46
|
-
{/* @ts-expect-error C2 — nor an `onChange`; the write goes through the field. */}
|
|
47
|
-
<SelectFilter field={local.field.currency} label="Currency" onChange={() => {}} />
|
|
48
|
-
{/* @ts-expect-error C5 — the home sets the tier; a control carries no `size`. */}
|
|
49
|
-
<SelectFilter field={local.field.currency} label="Currency" size="xs" />
|
|
50
|
-
{/* @ts-expect-error C5 — nor a responsive override; the swap is the control's own. */}
|
|
51
|
-
<ViewTabs field={local.field.currency} visibleFrom="sm" />
|
|
52
|
-
{/* @ts-expect-error C2 — a tab is store state too. */}
|
|
53
|
-
<ViewTabs field={local.field.currency} value="USD" />
|
|
54
|
-
{/* @ts-expect-error a boolean field is not an enum field. */}
|
|
55
|
-
<ToggleFilter field={local.field.currency} label="Errors only" />
|
|
56
|
-
{/* @ts-expect-error a multi field is not an enum field. */}
|
|
57
|
-
<SelectFilter field={local.field.channels} label="Channels" />
|
|
58
|
-
{/* @ts-expect-error an enum field is not a range field. */}
|
|
59
|
-
<RangeFilter field={local.field.currency} />
|
|
60
|
-
{/* @ts-expect-error a string field is not a boolean field. */}
|
|
61
|
-
<ToggleFilter field={local.field.q} label="Errors only" />
|
|
62
|
-
{/* @ts-expect-error CompareFilter's enum is the three basalt names, not any enum. */}
|
|
63
|
-
<CompareFilter field={local.field.currency} />
|
|
64
|
-
{/* @ts-expect-error `label` is required on SelectFilter — the pill needs a name at rest. */}
|
|
65
|
-
<SelectFilter field={local.field.currency} />
|
|
66
|
-
{/* A string field declares no values, so `options` is the only possible row source — without
|
|
67
|
-
it the popover would render empty. Two overloads rather than one union prop type precisely
|
|
68
|
-
so the message names `options`; see `SelectFilter`'s own doc. */}
|
|
69
|
-
{/* @ts-expect-error a string field needs `options` — nothing else can supply the rows. */}
|
|
70
|
-
<SelectFilter field={local.field.q} label="Project" />
|
|
71
|
-
{/* @ts-expect-error `options` does not widen a MULTI field into a single-select either. */}
|
|
72
|
-
<SelectFilter field={local.field.channels} label="Channels" options={PROJECTS} />
|
|
73
|
-
</>
|
|
74
|
-
)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** The same call sites, spelled correctly — so a type error above cannot be a false positive. */
|
|
78
|
-
function Accepted(): ReactNode {
|
|
79
|
-
return (
|
|
80
|
-
<>
|
|
81
|
-
<SelectFilter field={local.field.currency} label="Currency" clearable />
|
|
82
|
-
{/* A runtime catalogue over a closed enum — `options` is optional there. */}
|
|
83
|
-
<SelectFilter
|
|
84
|
-
field={local.field.currency}
|
|
85
|
-
label="Currency"
|
|
86
|
-
options={[{ value: 'USD', label: 'USD · 1.00' }]}
|
|
87
|
-
/>
|
|
88
|
-
{/* A string field WITH options — the id set an enum cannot close over. */}
|
|
89
|
-
<SelectFilter field={local.field.q} label="Project" options={PROJECTS} />
|
|
90
|
-
<MultiSelectFilter field={local.field.channels} label="All channels" options={CHANNELS} />
|
|
91
|
-
<CompareFilter field={local.field.compare} />
|
|
92
|
-
<MultiSelectFilter field={local.field.channels} label="All channels" noun="channels" />
|
|
93
|
-
<RangeFilter field={local.field.range} />
|
|
94
|
-
<ToggleFilter field={local.field.errorsOnly} label="Errors only" />
|
|
95
|
-
<SearchFilter field={local.field.q} placeholder="Search" />
|
|
96
|
-
<ViewTabs field={local.field.currency} />
|
|
97
|
-
</>
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
describe('props contract', () => {
|
|
102
|
-
test('both fixtures exist — tsc, not bun, is the assertion (see this file header)', () => {
|
|
103
|
-
expect(typeof Rejected).toBe('function')
|
|
104
|
-
expect(typeof Accepted).toBe('function')
|
|
105
|
-
})
|
|
106
|
-
})
|