basalt-ui 1.28.0 → 1.29.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 +11 -18
- package/CHANGELOG.md +13 -0
- package/MIGRATING.md +151 -7
- package/README.md +23 -66
- package/agent/rules/basalt-batteries.md +59 -182
- package/agent/rules/basalt-charts.md +56 -75
- package/agent/rules/basalt-controls.md +38 -69
- package/agent/rules/basalt-mantine.md +58 -103
- package/agent/rules/basalt-state.md +42 -60
- package/agent/rules/basalt-tokens.md +46 -67
- package/agent/skills/basalt-app/SKILL.md +2 -0
- package/agent/templates/CLAUDE-block.md.tpl +14 -14
- package/configs/oxlint-plugin.js +70 -167
- package/configs/oxlint-plugin.test.ts +20 -186
- package/configs/oxlint.json +0 -1
- package/dist/agent/ai-sdk-transport.d.ts.map +1 -1
- package/dist/agent/ai-sdk-transport.js +7 -4
- package/dist/agent/coalesce.js +1 -1
- package/dist/agent/merge.js +1 -1
- package/dist/agent/transport.d.ts +13 -2
- package/dist/agent/transport.d.ts.map +1 -1
- package/dist/agent/use-agent-thread-runs.d.ts +12 -1
- package/dist/agent/use-agent-thread-runs.d.ts.map +1 -1
- package/dist/agent/use-agent-thread-runs.js +20 -6
- package/dist/agent-chat/index.d.ts +1 -1
- package/dist/agent-chat/index.d.ts.map +1 -1
- package/dist/agent-chat/relative-time.js +1 -1
- package/dist/agent-chat/thread-detail-panel.js +1 -1
- package/dist/agent-chat/thread-feed-row.d.ts +32 -7
- package/dist/agent-chat/thread-feed-row.d.ts.map +1 -1
- package/dist/agent-chat/thread-feed-row.js +121 -86
- package/dist/agent-chat/thread-feed.d.ts +11 -1
- package/dist/agent-chat/thread-feed.d.ts.map +1 -1
- package/dist/agent-chat/thread-feed.js +10 -6
- package/dist/agent-chat/thread-message.js +1 -1
- package/dist/agent-chat/virtualize.d.ts +39 -0
- package/dist/agent-chat/virtualize.d.ts.map +1 -1
- package/dist/agent-chat/virtualize.js +15 -0
- package/dist/charts/index.d.ts +3 -3
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/index.js +8 -4
- package/dist/charts/kinds/BandStrip.js +1 -1
- package/dist/charts/kinds/Bars.d.ts +1 -3
- package/dist/charts/kinds/Bars.d.ts.map +1 -1
- package/dist/charts/kinds/Bars.js +1 -1
- package/dist/charts/kinds/DualPanel.d.ts +3 -1
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +1 -1
- package/dist/charts/kinds/StackedArea.js +1 -1
- package/dist/charts/kinds/ZonedLine.d.ts +1 -3
- package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
- package/dist/charts/primitives/Axes.d.ts +21 -2
- package/dist/charts/primitives/Axes.d.ts.map +1 -1
- package/dist/charts/primitives/Axes.js +34 -2
- package/dist/charts/primitives/ChartCard.d.ts +20 -4
- package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
- package/dist/charts/primitives/ChartCard.js +62 -33
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +8 -1
- package/dist/charts/primitives/ChartPending.d.ts +12 -6
- package/dist/charts/primitives/ChartPending.d.ts.map +1 -1
- package/dist/charts/primitives/ChartPending.js +1 -1
- package/dist/charts/utils/format.d.ts +5 -92
- package/dist/charts/utils/format.d.ts.map +1 -1
- package/dist/charts/utils/format.js +10 -80
- package/dist/cli/audit-allows.d.ts +24 -0
- package/dist/cli/audit-allows.d.ts.map +1 -0
- package/dist/cli/audit-allows.js +240 -0
- package/dist/cli/check-theme.d.ts +10 -0
- package/dist/cli/check-theme.d.ts.map +1 -0
- package/dist/cli/check-theme.js +139 -0
- package/dist/cli/doctor.d.ts +47 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +197 -0
- package/dist/cli/guard-hook.d.ts +9 -0
- package/dist/cli/guard-hook.d.ts.map +1 -0
- package/dist/cli/guard-hook.js +93 -0
- package/dist/cli/help.d.ts +9 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +53 -0
- package/dist/cli/index.d.ts +360 -270
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +85 -1901
- package/dist/cli/init.d.ts +4 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +165 -0
- package/dist/cli/sync.d.ts +43 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +206 -0
- package/dist/cli/tokens-css.d.ts +51 -0
- package/dist/cli/tokens-css.d.ts.map +1 -0
- package/dist/cli/tokens-css.js +165 -0
- package/dist/commands/define-commands.js +1 -1
- package/dist/commands/define-overlays.js +1 -1
- package/dist/commands/index.d.ts +2 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +6 -0
- package/dist/commands/overlays-mount.d.ts +7 -9
- package/dist/commands/overlays-mount.d.ts.map +1 -1
- package/dist/commands/shell-bridge.d.ts +57 -0
- package/dist/commands/shell-bridge.d.ts.map +1 -0
- package/dist/commands/shell-bridge.js +32 -0
- package/dist/common/errors.d.ts +35 -0
- package/dist/common/errors.d.ts.map +1 -1
- package/dist/common/errors.js +29 -1
- package/dist/common/index.d.ts +2 -0
- package/dist/common/index.d.ts.map +1 -1
- package/dist/common/index.js +6 -0
- package/dist/common/is-dev.d.ts.map +1 -0
- package/dist/{motion/index.d.ts → common/motion.d.ts} +1 -1
- package/dist/common/motion.d.ts.map +1 -0
- package/dist/common/props.d.ts +1 -1
- package/dist/common/props.d.ts.map +1 -1
- package/dist/common/validate.js +1 -1
- package/dist/content/markdown.d.ts +3 -4
- package/dist/content/markdown.d.ts.map +1 -1
- package/dist/content/markdown.js +1 -4
- package/dist/controls/actions.d.ts +1 -1
- package/dist/controls/actions.d.ts.map +1 -1
- package/dist/controls/panel-row.js +1 -1
- package/dist/controls/range-filter.js +1 -1
- package/dist/dashboard/delta-badge.d.ts +18 -10
- package/dist/dashboard/delta-badge.d.ts.map +1 -1
- package/dist/dashboard/delta-badge.js +33 -1
- package/dist/dashboard/empty-state.d.ts +1 -4
- package/dist/dashboard/empty-state.d.ts.map +1 -1
- package/dist/dashboard/empty-state.js +1 -2
- package/dist/dashboard/index.d.ts +4 -2
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +7 -1
- package/dist/dashboard/query-state.d.ts +4 -13
- package/dist/dashboard/query-state.d.ts.map +1 -1
- package/dist/dashboard/query-state.js +4 -7
- package/dist/{section → dashboard}/section.d.ts +2 -2
- package/dist/{section → dashboard}/section.d.ts.map +1 -1
- package/dist/{section → dashboard}/section.js +2 -2
- package/dist/dashboard/settings-section.d.ts +1 -1
- package/dist/dashboard/settings-section.d.ts.map +1 -1
- package/dist/dashboard/settings-section.js +1 -1
- package/dist/dashboard/stat-card.d.ts +1 -1
- package/dist/dashboard/stat-card.d.ts.map +1 -1
- package/dist/dashboard/stat-card.js +1 -1
- package/dist/dashboard/widget-header.d.ts.map +1 -0
- package/dist/data/data-table.js +2 -2
- package/dist/data/table.d.ts +1 -1
- package/dist/data/table.d.ts.map +1 -1
- package/dist/data/table.js +2 -16
- package/dist/data/virtual.d.ts +3 -3
- package/dist/dev-dock.d.ts +28 -0
- package/dist/dev-dock.d.ts.map +1 -0
- package/dist/dev-dock.js +85 -0
- package/dist/format/date.d.ts +62 -0
- package/dist/format/date.d.ts.map +1 -0
- package/dist/format/date.js +106 -0
- package/dist/format/index.d.ts +39 -0
- package/dist/format/index.d.ts.map +1 -0
- package/dist/format/index.js +54 -0
- package/dist/format/measure.d.ts +15 -0
- package/dist/format/measure.d.ts.map +1 -0
- package/dist/format/measure.js +16 -0
- package/dist/format/number.d.ts +69 -0
- package/dist/format/number.d.ts.map +1 -0
- package/dist/format/number.js +62 -0
- package/dist/format/shared.d.ts +27 -0
- package/dist/format/shared.d.ts.map +1 -0
- package/dist/format/shared.js +29 -0
- package/dist/forms/field.d.ts +4 -20
- package/dist/forms/field.d.ts.map +1 -1
- package/dist/forms/field.js +0 -4
- package/dist/forms/form-layout.d.ts +1 -1
- package/dist/forms/form-layout.d.ts.map +1 -1
- package/dist/forms/form-layout.js +1 -1
- package/dist/forms/index.d.ts +1 -1
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +1 -2
- package/dist/forms/use-form-submit.js +1 -1
- package/dist/guard/index.d.ts +2 -9
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +16 -26
- package/dist/guard/types.d.ts +8 -10
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/index.d.ts +16 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -29
- package/dist/notifications/index.d.ts +5 -5
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +0 -2
- package/dist/notifications/mount-guard.d.ts.map +1 -1
- package/dist/notifications/mount-guard.js +2 -2
- package/dist/provider/connectivity-indicator.d.ts.map +1 -0
- package/dist/{connectivity → provider}/connectivity-provider.d.ts +1 -1
- package/dist/provider/connectivity-provider.d.ts.map +1 -0
- package/dist/{connectivity/types.d.ts → provider/connectivity-types.d.ts} +1 -1
- package/dist/provider/connectivity-types.d.ts.map +1 -0
- package/dist/provider/error-fallback.module.css +21 -0
- package/dist/provider/error-fallback.module.css.d.ts +9 -0
- package/dist/provider/index.d.ts +20 -36
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +42 -32
- package/dist/provider/lab-theme.js +1 -1
- package/dist/provider/use-connectivity.d.ts +3 -0
- package/dist/provider/use-connectivity.d.ts.map +1 -0
- package/dist/query-client.d.ts +63 -0
- package/dist/query-client.d.ts.map +1 -0
- package/dist/query-client.js +33 -0
- package/dist/{query/devtools.d.ts → query-devtools.d.ts} +2 -2
- package/dist/query-devtools.d.ts.map +1 -0
- package/dist/register.d.ts +17 -3
- package/dist/register.d.ts.map +1 -1
- package/dist/router-tanstack/index.d.ts +4 -7
- package/dist/router-tanstack/index.d.ts.map +1 -1
- package/dist/router-tanstack/index.js +1 -9
- package/dist/router-tanstack/nav.d.ts +1 -1
- package/dist/router-tanstack/nav.d.ts.map +1 -1
- package/dist/router-tanstack/search-store.d.ts +3 -6
- package/dist/router-tanstack/search-store.d.ts.map +1 -1
- package/dist/router-tanstack/use-nav.d.ts +1 -1
- package/dist/router-tanstack/use-nav.d.ts.map +1 -1
- package/dist/shell/app-breadcrumbs.d.ts +1 -1
- package/dist/shell/app-breadcrumbs.d.ts.map +1 -1
- package/dist/shell/app-main.module.css +11 -0
- package/dist/shell/app-mobile-nav.d.ts +1 -1
- package/dist/shell/app-mobile-nav.d.ts.map +1 -1
- package/dist/shell/app-mobile-nav.js +24 -2
- package/dist/shell/app-sidebar.d.ts +1 -1
- package/dist/shell/app-sidebar.d.ts.map +1 -1
- package/dist/shell/app-sidebar.js +31 -2
- package/dist/shell/app-sidebar.module.css +10 -0
- package/dist/shell/index.d.ts +10 -4
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +13 -17
- package/dist/shell/mobile-nav-model.d.ts +1 -1
- package/dist/shell/mobile-nav-model.d.ts.map +1 -1
- package/dist/{nav/types.d.ts → shell/nav-types.d.ts} +1 -1
- package/dist/shell/nav-types.d.ts.map +1 -0
- package/dist/shell/page-aside.d.ts.map +1 -1
- package/dist/shell/page-aside.js +2 -29
- package/dist/shell/page-title.d.ts +14 -0
- package/dist/shell/page-title.d.ts.map +1 -0
- package/dist/shell/page-title.js +25 -0
- package/dist/shell/page-title.module.css +33 -0
- package/dist/shell/page-title.module.css.d.ts +11 -0
- package/dist/shell/sidebar-block-model.d.ts +1 -1
- package/dist/shell/sidebar-block-model.d.ts.map +1 -1
- package/dist/shell/sidebar-blocks.d.ts +1 -1
- package/dist/shell/sidebar-blocks.d.ts.map +1 -1
- package/dist/shell/use-breakpoint.d.ts +11 -0
- package/dist/shell/use-breakpoint.d.ts.map +1 -0
- package/dist/shell/use-breakpoint.js +33 -0
- package/dist/state/fields.d.ts +3 -19
- package/dist/state/fields.d.ts.map +1 -1
- package/dist/state/fields.js +6 -16
- package/dist/styles.css +36 -0
- package/dist/surfaces.d.ts +18 -41
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +46 -59
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/{theme-toggle/index.d.ts → theme/theme-toggle.d.ts} +1 -1
- package/dist/theme/theme-toggle.d.ts.map +1 -0
- package/dist/{theme-toggle/index.js → theme/theme-toggle.js} +1 -1
- package/dist/tokens/index.d.ts +1 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +10 -0
- package/dist/tokens/palette.d.ts +12 -0
- package/dist/tokens/palette.d.ts.map +1 -1
- package/dist/tokens/palette.js +13 -1
- package/dist/tokens.css +1 -0
- package/llms.txt +9 -24
- package/package.json +12 -16
- package/src/agent/ai-sdk-transport.ts +11 -4
- package/src/agent/coalesce.ts +1 -1
- package/src/agent/merge.ts +1 -1
- package/src/agent/transport.ts +15 -2
- package/src/agent/use-agent-thread-runs.ts +65 -15
- package/src/agent-chat/index.ts +6 -4
- package/src/agent-chat/relative-time.ts +1 -1
- package/src/agent-chat/thread-detail-panel.tsx +1 -1
- package/src/agent-chat/thread-feed-row.tsx +105 -30
- package/src/agent-chat/thread-feed.tsx +51 -25
- package/src/agent-chat/thread-message.tsx +1 -1
- package/src/agent-chat/virtualize.ts +48 -0
- package/src/charts/index.ts +7 -10
- package/src/charts/kinds/BandStrip.tsx +1 -1
- package/src/charts/kinds/Bars.tsx +2 -5
- package/src/charts/kinds/DualPanel.tsx +4 -3
- package/src/charts/kinds/StackedArea.tsx +1 -1
- package/src/charts/kinds/ZonedLine.tsx +1 -4
- package/src/charts/primitives/Axes.tsx +49 -0
- package/src/charts/primitives/ChartCard.tsx +49 -6
- package/src/charts/primitives/ChartFrame.tsx +5 -1
- package/src/charts/primitives/ChartPending.tsx +14 -8
- package/src/charts/utils/format.ts +17 -186
- package/src/cli/audit-allows.ts +371 -0
- package/src/cli/check-theme.ts +197 -0
- package/src/cli/doctor.ts +331 -0
- package/src/cli/guard-hook.ts +115 -0
- package/src/cli/help.ts +101 -0
- package/src/cli/index.ts +269 -3439
- package/src/cli/init.ts +247 -0
- package/src/cli/sync.ts +324 -0
- package/src/cli/tokens-css.ts +252 -0
- package/src/commands/define-commands.ts +1 -1
- package/src/commands/define-overlays.ts +1 -1
- package/src/commands/index.ts +10 -1
- package/src/commands/overlays-mount.tsx +8 -10
- package/src/commands/shell-bridge.ts +86 -0
- package/src/common/errors.ts +70 -0
- package/src/common/index.ts +2 -0
- package/src/common/props.ts +1 -1
- package/src/common/validate.ts +1 -1
- package/src/content/markdown.tsx +4 -8
- package/src/controls/actions.tsx +1 -1
- package/src/controls/panel-row.tsx +1 -1
- package/src/controls/range-filter.tsx +1 -1
- package/src/dashboard/delta-badge.tsx +74 -7
- package/src/dashboard/empty-state.tsx +2 -6
- package/src/dashboard/index.ts +11 -2
- package/src/dashboard/query-state.tsx +5 -18
- package/src/{section → dashboard}/section.tsx +4 -4
- package/src/dashboard/settings-section.tsx +2 -2
- package/src/dashboard/stat-card.tsx +2 -2
- package/src/data/data-table.tsx +3 -3
- package/src/data/table.ts +6 -25
- package/src/data/virtual-list.tsx +1 -1
- package/src/data/virtual.ts +3 -3
- package/src/dev-dock.tsx +159 -0
- package/src/format/date.ts +184 -0
- package/src/format/index.ts +69 -0
- package/src/format/measure.ts +31 -0
- package/src/format/number.ts +129 -0
- package/src/format/shared.ts +63 -0
- package/src/forms/field.ts +4 -24
- package/src/forms/form-layout.tsx +2 -2
- package/src/forms/index.ts +1 -2
- package/src/forms/use-form-submit.ts +1 -1
- package/src/guard/index.ts +30 -56
- package/src/guard/types.ts +7 -10
- package/src/index.ts +38 -29
- package/src/notifications/index.ts +5 -7
- package/src/notifications/mount-guard.ts +7 -9
- package/src/{connectivity → provider}/connectivity-indicator.tsx +1 -1
- package/src/{connectivity → provider}/connectivity-provider.tsx +1 -1
- package/src/provider/error-fallback.module.css +21 -0
- package/src/provider/error-fallback.module.css.d.ts +9 -0
- package/src/provider/index.tsx +71 -71
- package/src/provider/lab-theme.ts +1 -1
- package/src/{connectivity → provider}/use-connectivity.ts +3 -3
- package/src/query-client.ts +100 -0
- package/src/{query/devtools.tsx → query-devtools.tsx} +5 -4
- package/src/register.ts +20 -4
- package/src/router-tanstack/index.ts +4 -15
- package/src/router-tanstack/nav.ts +1 -1
- package/src/router-tanstack/search-store.ts +3 -4
- package/src/router-tanstack/use-nav.ts +1 -1
- package/src/shell/app-breadcrumbs.tsx +1 -1
- package/src/shell/app-main.module.css +11 -0
- package/src/shell/app-mobile-nav.tsx +28 -1
- package/src/shell/app-sidebar.module.css +10 -0
- package/src/shell/app-sidebar.tsx +31 -2
- package/src/shell/index.tsx +23 -28
- package/src/shell/mobile-nav-model.ts +1 -1
- package/src/shell/page-aside.tsx +2 -52
- package/src/shell/page-title.module.css +33 -0
- package/src/shell/page-title.module.css.d.ts +11 -0
- package/src/shell/page-title.tsx +57 -0
- package/src/shell/sidebar-block-model.ts +1 -1
- package/src/shell/sidebar-blocks.tsx +1 -1
- package/src/shell/use-breakpoint.ts +73 -0
- package/src/state/fields.ts +7 -43
- package/src/styles.css +36 -0
- package/src/surfaces.ts +45 -60
- package/src/theme/index.ts +7 -0
- package/src/{theme-toggle/index.tsx → theme/theme-toggle.tsx} +1 -1
- package/src/tokens/index.ts +10 -0
- package/src/tokens/palette.ts +12 -0
- package/dist/connectivity/connectivity-indicator.d.ts.map +0 -1
- package/dist/connectivity/connectivity-provider.d.ts.map +0 -1
- package/dist/connectivity/index.d.ts +0 -14
- package/dist/connectivity/index.d.ts.map +0 -1
- package/dist/connectivity/index.js +0 -8
- package/dist/connectivity/types.d.ts.map +0 -1
- package/dist/connectivity/use-connectivity.d.ts +0 -3
- package/dist/connectivity/use-connectivity.d.ts.map +0 -1
- package/dist/data/index.d.ts +0 -38
- package/dist/data/index.d.ts.map +0 -1
- package/dist/data/index.js +0 -24
- package/dist/motion/index.d.ts.map +0 -1
- package/dist/nav/types.d.ts.map +0 -1
- package/dist/notifications/overlay.d.ts +0 -20
- package/dist/notifications/overlay.d.ts.map +0 -1
- package/dist/notifications/overlay.js +0 -14
- package/dist/query/devtools.d.ts.map +0 -1
- package/dist/query/error-message.d.ts +0 -41
- package/dist/query/error-message.d.ts.map +0 -1
- package/dist/query/error-message.js +0 -30
- package/dist/query/index.d.ts +0 -47
- package/dist/query/index.d.ts.map +0 -1
- package/dist/query/index.js +0 -56
- package/dist/router-tanstack/field.d.ts +0 -14
- package/dist/router-tanstack/field.d.ts.map +0 -1
- package/dist/router-tanstack/field.js +0 -4
- package/dist/router-tanstack/multi-search-param-store.d.ts +0 -43
- package/dist/router-tanstack/multi-search-param-store.d.ts.map +0 -1
- package/dist/router-tanstack/multi-search-param-store.js +0 -30
- package/dist/router-tanstack/search-param-store.d.ts +0 -42
- package/dist/router-tanstack/search-param-store.d.ts.map +0 -1
- package/dist/router-tanstack/search-param-store.js +0 -25
- package/dist/section/index.d.ts +0 -2
- package/dist/section/index.d.ts.map +0 -1
- package/dist/section/index.js +0 -4
- package/dist/theme-toggle/index.d.ts.map +0 -1
- package/dist/utils/is-dev.d.ts.map +0 -1
- package/dist/widget-header/delta-badge.d.ts +0 -19
- package/dist/widget-header/delta-badge.d.ts.map +0 -1
- package/dist/widget-header/delta-badge.js +0 -36
- package/dist/widget-header/index.d.ts +0 -3
- package/dist/widget-header/index.d.ts.map +0 -1
- package/dist/widget-header/index.js +0 -8
- package/dist/widget-header/widget-header.d.ts.map +0 -1
- package/src/connectivity/index.ts +0 -19
- package/src/data/index.ts +0 -69
- package/src/notifications/overlay.tsx +0 -66
- package/src/query/error-message.ts +0 -70
- package/src/query/index.ts +0 -97
- package/src/router-tanstack/field.ts +0 -36
- package/src/router-tanstack/multi-search-param-store.ts +0 -106
- package/src/router-tanstack/search-param-store.ts +0 -100
- package/src/section/index.ts +0 -1
- package/src/widget-header/delta-badge.tsx +0 -77
- package/src/widget-header/index.ts +0 -10
- /package/dist/{utils → common}/is-dev.d.ts +0 -0
- /package/dist/{utils → common}/is-dev.js +0 -0
- /package/dist/{motion/index.js → common/motion.js} +0 -0
- /package/dist/{section → dashboard}/section.module.css +0 -0
- /package/dist/{section → dashboard}/section.module.css.d.ts +0 -0
- /package/dist/{widget-header → dashboard}/widget-header.d.ts +0 -0
- /package/dist/{widget-header → dashboard}/widget-header.js +0 -0
- /package/dist/{widget-header → dashboard}/widget-header.module.css +0 -0
- /package/dist/{widget-header → dashboard}/widget-header.module.css.d.ts +0 -0
- /package/dist/{connectivity → provider}/connectivity-indicator.d.ts +0 -0
- /package/dist/{connectivity → provider}/connectivity-indicator.js +0 -0
- /package/dist/{connectivity → provider}/connectivity-provider.js +0 -0
- /package/dist/{connectivity/types.js → provider/connectivity-types.js} +0 -0
- /package/dist/{connectivity → provider}/use-connectivity.js +0 -0
- /package/dist/{query/devtools.js → query-devtools.js} +0 -0
- /package/dist/{nav/types.js → shell/nav-types.js} +0 -0
- /package/src/{utils → common}/is-dev.ts +0 -0
- /package/src/{motion/index.ts → common/motion.ts} +0 -0
- /package/src/{section → dashboard}/section.module.css +0 -0
- /package/src/{section → dashboard}/section.module.css.d.ts +0 -0
- /package/src/{widget-header → dashboard}/widget-header.module.css +0 -0
- /package/src/{widget-header → dashboard}/widget-header.module.css.d.ts +0 -0
- /package/src/{widget-header → dashboard}/widget-header.tsx +0 -0
- /package/src/{connectivity/types.ts → provider/connectivity-types.ts} +0 -0
- /package/src/{nav/types.ts → shell/nav-types.ts} +0 -0
package/src/provider/index.tsx
CHANGED
|
@@ -15,20 +15,28 @@
|
|
|
15
15
|
*
|
|
16
16
|
* Mantine usage is allowed in this `./` root layer (unlike `src/charts/**` and `src/tokens/**`).
|
|
17
17
|
*/
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
MantineProvider,
|
|
20
|
+
useComputedColorScheme,
|
|
21
|
+
useMantineColorScheme,
|
|
22
|
+
useMantineTheme,
|
|
23
|
+
} from '@mantine/core'
|
|
19
24
|
import type { MantineProviderProps } from '@mantine/core'
|
|
20
25
|
import { Component, useEffect, useMemo } from 'react'
|
|
21
26
|
import type { ErrorInfo, ReactNode } from 'react'
|
|
22
27
|
import { VxThemeProvider } from '../charts/theme'
|
|
23
|
-
import
|
|
24
|
-
import
|
|
28
|
+
import fallbackClasses from './error-fallback.module.css'
|
|
29
|
+
import { ConnectivityProvider } from './connectivity-provider'
|
|
30
|
+
import type { ConnectivityProviderProps } from './connectivity-types'
|
|
25
31
|
import { cssVariablesResolver } from '../theme'
|
|
26
32
|
import { useLabTheme } from './lab-theme'
|
|
27
33
|
import { buildDensityCss, buildFontsCss, buildPaletteCss, buildRadiusCss } from '../tokens'
|
|
28
34
|
import type { BuildPaletteOpts } from '../tokens'
|
|
29
35
|
import { isDefaultDeriveConfig } from '../tokens/derive'
|
|
30
36
|
import { buildPaletteData } from '../tokens/palette'
|
|
31
|
-
import { isDev } from '../
|
|
37
|
+
import { isDev } from '../common/is-dev'
|
|
38
|
+
import { registerColorSchemeSetter } from '../commands/shell-bridge'
|
|
39
|
+
import { PageTitle } from '../shell/page-title'
|
|
32
40
|
|
|
33
41
|
/**
|
|
34
42
|
* Where an error surfaced — drives consumer routing (a render error vs a global rejection differ).
|
|
@@ -97,25 +105,9 @@ export type BasaltProviderProps = {
|
|
|
97
105
|
* Options threaded through to the auto-mounted `ConnectivityProvider` (everything except
|
|
98
106
|
* `children`) — `sseUrl`, `healthUrl`, `healthIntervalMs`, and `override` (previously
|
|
99
107
|
* unreachable through `BasaltProvider`: the only way to reach it was a second, shadowing
|
|
100
|
-
* `ConnectivityProvider`).
|
|
101
|
-
* are set.
|
|
108
|
+
* `ConnectivityProvider`).
|
|
102
109
|
*/
|
|
103
110
|
connectivity?: Omit<ConnectivityProviderProps, 'children'>
|
|
104
|
-
/**
|
|
105
|
-
* @deprecated Use `connectivity={{ sseUrl }}` instead. Still honoured when `connectivity` is
|
|
106
|
-
* unset or omits `sseUrl`; removed in 1.29.0.
|
|
107
|
-
*/
|
|
108
|
-
sseUrl?: string
|
|
109
|
-
/**
|
|
110
|
-
* @deprecated Use `connectivity={{ healthUrl }}` instead. Still honoured when `connectivity` is
|
|
111
|
-
* unset or omits `healthUrl`; removed in 1.29.0.
|
|
112
|
-
*/
|
|
113
|
-
healthUrl?: string
|
|
114
|
-
/**
|
|
115
|
-
* @deprecated Use `connectivity={{ healthIntervalMs }}` instead. Still honoured when
|
|
116
|
-
* `connectivity` is unset or omits `healthIntervalMs`; removed in 1.29.0.
|
|
117
|
-
*/
|
|
118
|
-
healthIntervalMs?: number
|
|
119
111
|
} & Omit<MantineProviderProps, 'children' | 'theme' | 'defaultColorScheme' | 'cssVariablesResolver'>
|
|
120
112
|
|
|
121
113
|
// ── Default error handler ─────────────────────────────────────────────────────────────────────────
|
|
@@ -130,15 +122,54 @@ function defaultOnError(error: unknown, ctx: BasaltErrorContext): void {
|
|
|
130
122
|
|
|
131
123
|
// ── Error boundary ────────────────────────────────────────────────────────────────────────────────
|
|
132
124
|
|
|
133
|
-
|
|
125
|
+
/**
|
|
126
|
+
* `BasaltErrorBoundary`'s props — exported (C5 consolidation) so a consumer mounting a nested
|
|
127
|
+
* boundary can name the type, e.g. for a wrapper component's own prop forwarding.
|
|
128
|
+
*/
|
|
129
|
+
export type BasaltErrorBoundaryProps = {
|
|
134
130
|
children: ReactNode
|
|
135
|
-
|
|
136
|
-
|
|
131
|
+
/**
|
|
132
|
+
* Report the caught render error. Unset → `defaultOnError` (console.error in dev, no-op in
|
|
133
|
+
* prod — the same fallback `BasaltProvider`'s own top-level `onError` uses), so a NESTED
|
|
134
|
+
* boundary mounted with no `onError` still surfaces something in dev instead of silently
|
|
135
|
+
* swallowing it.
|
|
136
|
+
*/
|
|
137
|
+
onError?: (error: unknown, ctx: BasaltErrorContext) => void
|
|
138
|
+
/**
|
|
139
|
+
* UI to render when a render error is caught. If a function, called with the error. Unset →
|
|
140
|
+
* {@link DefaultErrorFallback} — a minimal `PageTitle` + reload button, never a silent `null`;
|
|
141
|
+
* pass `fallback={null}` explicitly for the old swallow-it behaviour.
|
|
142
|
+
*/
|
|
137
143
|
fallback?: ReactNode | ((error: unknown) => ReactNode)
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
type BoundaryState = { hasError: boolean; error: unknown }
|
|
141
147
|
|
|
148
|
+
/**
|
|
149
|
+
* The boundary's own default fallback — a `PageTitle` (C5's shell-less page-title primitive, so
|
|
150
|
+
* this needs no `in-body-page-title` waiver) plus a plain reload affordance. Deliberately minimal:
|
|
151
|
+
* a consumer wanting session ids, a stack trace or a "try to recover" reset (argo's own
|
|
152
|
+
* `lib/error-boundary.tsx`) still passes its own `fallback` render function — this default exists
|
|
153
|
+
* so an app that mounts `BasaltErrorBoundary` and does nothing else shows a page, not a blank one.
|
|
154
|
+
*/
|
|
155
|
+
function DefaultErrorFallback(): ReactNode {
|
|
156
|
+
return (
|
|
157
|
+
<div className={fallbackClasses.root}>
|
|
158
|
+
<PageTitle
|
|
159
|
+
title="Something went wrong"
|
|
160
|
+
subtitle="The page hit an unexpected error and was unloaded to keep the app stable."
|
|
161
|
+
/>
|
|
162
|
+
<button
|
|
163
|
+
type="button"
|
|
164
|
+
className={fallbackClasses.reload}
|
|
165
|
+
onClick={() => window.location.reload()}
|
|
166
|
+
>
|
|
167
|
+
Reload page
|
|
168
|
+
</button>
|
|
169
|
+
</div>
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
142
173
|
/**
|
|
143
174
|
* Error boundary that catches render-phase errors inside `BasaltProvider`. Wraps `BasaltBridge` +
|
|
144
175
|
* children INSIDE `MantineProvider` so a thrown render error still has theme context for a fallback.
|
|
@@ -149,8 +180,8 @@ type BoundaryState = { hasError: boolean; error: unknown }
|
|
|
149
180
|
* <MyFeature />
|
|
150
181
|
* </BasaltErrorBoundary>
|
|
151
182
|
*/
|
|
152
|
-
export class BasaltErrorBoundary extends Component<
|
|
153
|
-
constructor(props:
|
|
183
|
+
export class BasaltErrorBoundary extends Component<BasaltErrorBoundaryProps, BoundaryState> {
|
|
184
|
+
constructor(props: BasaltErrorBoundaryProps) {
|
|
154
185
|
super(props)
|
|
155
186
|
this.state = { hasError: false, error: undefined }
|
|
156
187
|
}
|
|
@@ -160,13 +191,15 @@ export class BasaltErrorBoundary extends Component<BoundaryProps, BoundaryState>
|
|
|
160
191
|
}
|
|
161
192
|
|
|
162
193
|
override componentDidCatch(error: unknown, info: ErrorInfo): void {
|
|
163
|
-
this.props.onError
|
|
194
|
+
const onError = this.props.onError ?? defaultOnError
|
|
195
|
+
onError(error, { kind: 'render', info })
|
|
164
196
|
}
|
|
165
197
|
|
|
166
198
|
override render(): ReactNode {
|
|
167
199
|
if (this.state.hasError) {
|
|
168
200
|
const { fallback } = this.props
|
|
169
|
-
if (fallback === undefined) return
|
|
201
|
+
if (fallback === undefined) return <DefaultErrorFallback />
|
|
202
|
+
if (fallback === null) return null
|
|
170
203
|
return typeof fallback === 'function' ? fallback(this.state.error) : fallback
|
|
171
204
|
}
|
|
172
205
|
return this.props.children
|
|
@@ -219,6 +252,15 @@ function BasaltBridge({
|
|
|
219
252
|
// (fallback 'dark' before hydration, matching the provider's defaultColorScheme).
|
|
220
253
|
const resolved = useComputedColorScheme('dark')
|
|
221
254
|
|
|
255
|
+
// `commands/shell-bridge.ts`'s `setColorScheme` handle — registered here (already inside
|
|
256
|
+
// `MantineProvider`) so a consumer's `commands.tsx` calls it with ZERO `__root.tsx` wiring,
|
|
257
|
+
// unlike argo's hand-rolled `color-scheme-bridge.ts` this seeds from (see that file's own doc).
|
|
258
|
+
const { setColorScheme: setMantineColorScheme } = useMantineColorScheme()
|
|
259
|
+
useEffect(() => {
|
|
260
|
+
registerColorSchemeSetter(setMantineColorScheme)
|
|
261
|
+
return () => registerColorSchemeSetter(null)
|
|
262
|
+
}, [setMantineColorScheme])
|
|
263
|
+
|
|
222
264
|
// `createBasaltTheme`'s non-default `{ derive }` / `{ fonts }` / `{ radius }` / `{ density }`
|
|
223
265
|
// paths stash the resolved values on `theme.other.basaltDerive` / `theme.other.basaltFonts` /
|
|
224
266
|
// `theme.other.basaltRadius` / `theme.other.basaltDensity` — read them here (INSIDE
|
|
@@ -302,40 +344,6 @@ function useDuplicateProviderGuard(): void {
|
|
|
302
344
|
}, [])
|
|
303
345
|
}
|
|
304
346
|
|
|
305
|
-
/**
|
|
306
|
-
* Resolves the `connectivity` object against the three deprecated flattened props: `connectivity`
|
|
307
|
-
* wins WHOLESALE when provided, not per-key — a partial `connectivity={{ sseUrl }}` no longer picks
|
|
308
|
-
* up a stray `healthUrl` left on the old prop, which was surprising for a mid-migration consumer who
|
|
309
|
-
* expected the new prop to fully replace the old ones once set. Warns once, dev builds only, when
|
|
310
|
-
* both are actually supplied. Exported as a pure function (same rationale as `composeInjectedCss`
|
|
311
|
-
* above) so `provider/index.test.ts` can assert the precedence without rendering a tree.
|
|
312
|
-
*/
|
|
313
|
-
export function resolveConnectivityProps(props: {
|
|
314
|
-
connectivity: Omit<ConnectivityProviderProps, 'children'> | undefined
|
|
315
|
-
sseUrl: string | undefined
|
|
316
|
-
healthUrl: string | undefined
|
|
317
|
-
healthIntervalMs: number | undefined
|
|
318
|
-
}): Omit<ConnectivityProviderProps, 'children'> {
|
|
319
|
-
if (props.connectivity !== undefined) {
|
|
320
|
-
const hasDeprecated =
|
|
321
|
-
props.sseUrl !== undefined ||
|
|
322
|
-
props.healthUrl !== undefined ||
|
|
323
|
-
props.healthIntervalMs !== undefined
|
|
324
|
-
if (hasDeprecated && isDev()) {
|
|
325
|
-
console.warn(
|
|
326
|
-
'[basalt] BasaltProvider: `connectivity` and one of `sseUrl`/`healthUrl`/`healthIntervalMs` ' +
|
|
327
|
-
'were both supplied — `connectivity` wins wholesale and the deprecated props are ignored.',
|
|
328
|
-
)
|
|
329
|
-
}
|
|
330
|
-
return props.connectivity
|
|
331
|
-
}
|
|
332
|
-
return {
|
|
333
|
-
...(props.sseUrl !== undefined ? { sseUrl: props.sseUrl } : {}),
|
|
334
|
-
...(props.healthUrl !== undefined ? { healthUrl: props.healthUrl } : {}),
|
|
335
|
-
...(props.healthIntervalMs !== undefined ? { healthIntervalMs: props.healthIntervalMs } : {}),
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
347
|
// ── Public provider ───────────────────────────────────────────────────────────────────────────────
|
|
340
348
|
|
|
341
349
|
export function BasaltProvider({
|
|
@@ -347,9 +355,6 @@ export function BasaltProvider({
|
|
|
347
355
|
onError,
|
|
348
356
|
nonce,
|
|
349
357
|
connectivity,
|
|
350
|
-
sseUrl,
|
|
351
|
-
healthUrl,
|
|
352
|
-
healthIntervalMs,
|
|
353
358
|
...rest
|
|
354
359
|
}: BasaltProviderProps) {
|
|
355
360
|
useDuplicateProviderGuard()
|
|
@@ -361,12 +366,7 @@ export function BasaltProvider({
|
|
|
361
366
|
// Basalt base and nothing else. See `./lab-theme.ts`.
|
|
362
367
|
const resolvedTheme = useLabTheme(theme)
|
|
363
368
|
|
|
364
|
-
const resolvedConnectivity =
|
|
365
|
-
connectivity,
|
|
366
|
-
sseUrl,
|
|
367
|
-
healthUrl,
|
|
368
|
-
healthIntervalMs,
|
|
369
|
-
})
|
|
369
|
+
const resolvedConnectivity = connectivity ?? {}
|
|
370
370
|
|
|
371
371
|
return (
|
|
372
372
|
// `...rest` spreads FIRST so a consumer's `MantineProviderProps` can never shadow the three
|
|
@@ -44,7 +44,7 @@ import { useMemo } from 'react'
|
|
|
44
44
|
import { useDeriveControlsState, toDeriveOverride } from '../theme-lab/derive-state'
|
|
45
45
|
import type { DeriveOverride } from '../theme-lab/derive-state'
|
|
46
46
|
import { baseTheme, createBasaltTheme } from '../theme'
|
|
47
|
-
import { isDev } from '../
|
|
47
|
+
import { isDev } from '../common/is-dev'
|
|
48
48
|
|
|
49
49
|
type Plain = Record<string, unknown>
|
|
50
50
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* useConnectivity — reads the aggregated connectivity status from ConnectivityContext.
|
|
3
3
|
*
|
|
4
4
|
* Throws if used outside a ConnectivityProvider. `BasaltProvider` auto-mounts
|
|
5
|
-
* `ConnectivityProvider`, so this hook works with zero setup in the common case
|
|
6
|
-
*
|
|
5
|
+
* `ConnectivityProvider`, so this hook works with zero setup in the common case. It replaced the
|
|
6
|
+
* former online-status hook that lived on `basalt-ui/state` (see MIGRATING.md).
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* const { status, details } = useConnectivity()
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { useContext } from 'react'
|
|
13
13
|
import { ConnectivityContext } from './connectivity-provider'
|
|
14
|
-
import type { ConnectivitySnapshot } from './types'
|
|
14
|
+
import type { ConnectivitySnapshot } from './connectivity-types'
|
|
15
15
|
|
|
16
16
|
export function useConnectivity(): ConnectivitySnapshot {
|
|
17
17
|
const snapshot = useContext(ConnectivityContext)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `createBasaltQueryClient` + `unwrap` — the two TanStack Query primitives basalt ships. Folded
|
|
3
|
+
* onto the root barrel (C1 consolidation, dropping the `./query` subpath): the root already
|
|
4
|
+
* requires `@tanstack/react-query` as a peer, so a dedicated Mantine-free subpath bought nothing —
|
|
5
|
+
* and it re-exported 10 raw TanStack symbols no consumer imported through it.
|
|
6
|
+
* Optional peer: @tanstack/react-query.
|
|
7
|
+
*/
|
|
8
|
+
import { QueryClient } from '@tanstack/react-query'
|
|
9
|
+
import type { QueryClientConfig } from '@tanstack/react-query'
|
|
10
|
+
|
|
11
|
+
// ── createBasaltQueryClient ───────────────────────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
const BASALT_QUERY_DEFAULTS = {
|
|
14
|
+
staleTime: 30_000,
|
|
15
|
+
gcTime: 5 * 60 * 1000,
|
|
16
|
+
retry: 2,
|
|
17
|
+
refetchOnWindowFocus: false,
|
|
18
|
+
} as const
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Wraps QueryClient with basalt dashboard defaults. All options are mergeable — consumer
|
|
22
|
+
* overrides win per-query, framework defaults are the fallback.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* import { createBasaltQueryClient } from 'basalt-ui'
|
|
26
|
+
* import { QueryClientProvider } from '@tanstack/react-query'
|
|
27
|
+
* import { useState } from 'react'
|
|
28
|
+
*
|
|
29
|
+
* function Root({ children }: { children: React.ReactNode }) {
|
|
30
|
+
* const [client] = useState(() => createBasaltQueryClient())
|
|
31
|
+
* return <QueryClientProvider client={client}>{children}</QueryClientProvider>
|
|
32
|
+
* }
|
|
33
|
+
*/
|
|
34
|
+
export function createBasaltQueryClient(config?: QueryClientConfig): QueryClient {
|
|
35
|
+
return new QueryClient({
|
|
36
|
+
...config,
|
|
37
|
+
defaultOptions: {
|
|
38
|
+
...config?.defaultOptions,
|
|
39
|
+
queries: { ...BASALT_QUERY_DEFAULTS, ...config?.defaultOptions?.queries },
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ── unwrap ────────────────────────────────────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Transport-agnostic unwrap for any `{ data, error }` envelope (Eden Treaty, raw fetch wrappers,
|
|
48
|
+
* etc.). TData is inferred from the data field. Throws on the error branch so failures surface
|
|
49
|
+
* to the nearest error boundary or TanStack Query's error state.
|
|
50
|
+
*
|
|
51
|
+
* Absence guard: if `error` is falsy but `data` is `null` OR `undefined`, unwrap throws with a
|
|
52
|
+
* descriptive message. This catches 204 No Content responses and silent transport failures that
|
|
53
|
+
* return `{ data: null, error: null }` — both signal an unexpected absence of data and should not
|
|
54
|
+
* silently resolve. `undefined` joined `null` here (C5 consolidation) so a hand-rolled fetch
|
|
55
|
+
* wrapper that leaves `data` unset on a miss — rather than explicitly `null` — is caught the same
|
|
56
|
+
* way; the two envelope shapes argo's own pre-basalt `unwrap` and basalt's ONLY differed on.
|
|
57
|
+
*
|
|
58
|
+
* **Two overloads, one name** — a Promise of the envelope (basalt's original shape,
|
|
59
|
+
* `queryFn: () => unwrap(api.x.get())`), or the ALREADY-RESOLVED envelope itself
|
|
60
|
+
* (`unwrap(await api.x.get())`, or passed directly as a `.then(unwrap)` callback — both argo's
|
|
61
|
+
* 97 call sites' shapes). Never a generic argument to disambiguate: TS infers the right overload
|
|
62
|
+
* from whether the argument IS a `Promise`.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* import { unwrap } from 'basalt-ui'
|
|
66
|
+
*
|
|
67
|
+
* // Promise-of-envelope — queryFn:
|
|
68
|
+
* queryFn: () => unwrap(api.users.get({ query: params }))
|
|
69
|
+
* // mutation:
|
|
70
|
+
* mutationFn: (body) => unwrap(api.resource.post({ body }))
|
|
71
|
+
*
|
|
72
|
+
* // resolved-envelope — either shape:
|
|
73
|
+
* const rows = unwrap(await api.users.get())
|
|
74
|
+
* const rows2 = await api.users.get().then(unwrap)
|
|
75
|
+
*/
|
|
76
|
+
export function unwrap<TData>(
|
|
77
|
+
response: Promise<{ data: TData | null | undefined; error: unknown }>,
|
|
78
|
+
): Promise<TData>
|
|
79
|
+
export function unwrap<TData>(response: { data: TData | null | undefined; error: unknown }): TData
|
|
80
|
+
export function unwrap<TData>(
|
|
81
|
+
response:
|
|
82
|
+
| Promise<{ data: TData | null | undefined; error: unknown }>
|
|
83
|
+
| { data: TData | null | undefined; error: unknown },
|
|
84
|
+
): TData | Promise<TData> {
|
|
85
|
+
if (response instanceof Promise) return response.then((envelope) => unwrapEnvelope(envelope))
|
|
86
|
+
return unwrapEnvelope(response)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function unwrapEnvelope<TData>(envelope: {
|
|
90
|
+
data: TData | null | undefined
|
|
91
|
+
error: unknown
|
|
92
|
+
}): TData {
|
|
93
|
+
const { data, error } = envelope
|
|
94
|
+
if (error) throw error
|
|
95
|
+
if (data === null || data === undefined)
|
|
96
|
+
throw new Error(
|
|
97
|
+
'unwrap: null/undefined data with no error — check for a 204 response or a transport failure',
|
|
98
|
+
)
|
|
99
|
+
return data
|
|
100
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* The
|
|
2
|
+
* `BasaltQueryDevtools` — prod-safe lazy wrapper for @tanstack/react-query-devtools. Folded onto
|
|
3
|
+
* the root barrel alongside `query-client.ts` (C1 consolidation, dropping the `./query` subpath).
|
|
4
|
+
* The devtools package is an OPTIONAL peer — never imported at module evaluation time. The dynamic
|
|
5
|
+
* import() resolves only when rendered in non-production.
|
|
5
6
|
*/
|
|
6
7
|
import { lazy, Suspense } from 'react'
|
|
7
8
|
import type { ComponentProps } from 'react'
|
|
@@ -18,7 +19,7 @@ Object.assign(LazyDevtools, { displayName: 'LazyDevtools' })
|
|
|
18
19
|
* import fires. In production this returns null immediately.
|
|
19
20
|
*
|
|
20
21
|
* @example
|
|
21
|
-
* import { BasaltQueryDevtools } from 'basalt-ui
|
|
22
|
+
* import { BasaltQueryDevtools } from 'basalt-ui'
|
|
22
23
|
*
|
|
23
24
|
* function Root() {
|
|
24
25
|
* return (
|
package/src/register.ts
CHANGED
|
@@ -37,11 +37,27 @@ export interface BasaltRegister {}
|
|
|
37
37
|
* slot instantiates against. At 1.0 the `series`, `commands`, `overlays`, and `notifications`
|
|
38
38
|
* slots ship and have concrete instantiations (define-commands.ts, define-overlays.ts,
|
|
39
39
|
* define-notifications.ts); `router`, `query`, and `state` remain advisory.
|
|
40
|
+
*
|
|
41
|
+
* **Indexed-access form, not a mapped-type structural match (C5 consolidation)** — this used to
|
|
42
|
+
* read `BasaltRegister extends { [P in K]: infer S extends Constraint } ? S : {}`, which forces
|
|
43
|
+
* TS to structurally match the WHOLE `BasaltRegister` interface (every augmented slot's VALUE
|
|
44
|
+
* type, not just `K`'s) before it can answer "does slot `K` exist". That is the commands↔overlays
|
|
45
|
+
* cycle argo's `lib/overlays.tsx` documents: `defineCommands`'s inferred type has to type-check a
|
|
46
|
+
* command `run` body calling `overlays.open(…)`, which resolves `Slot<'overlays', …>` — and the
|
|
47
|
+
* OLD form's whole-interface match ALSO had to resolve `BasaltRegister['commands']`
|
|
48
|
+
* (`typeof COMMANDS`, the very type still being computed) to complete the match, because a
|
|
49
|
+
* mapped-type pattern binds every property simultaneously. `K extends keyof BasaltRegister` only
|
|
50
|
+
* needs the augmented KEY NAMES (available from declaration merging with no value-type checking
|
|
51
|
+
* at all), and `BasaltRegister[K]` then touches ONLY that one slot's value — so resolving
|
|
52
|
+
* `overlays` never has to resolve `commands` first, and a consumer can define both registries,
|
|
53
|
+
* with one calling the other's imperative controller, in a SINGLE file. Behaviourally identical to
|
|
54
|
+
* the old form for every existing augmentation (fixture J.1/J.2 pin both the `{}` fallback and the
|
|
55
|
+
* `Extract<keyof, string>` guard below); ONLY the internal resolution path changed.
|
|
40
56
|
*/
|
|
41
|
-
export type Slot<K extends string, Constraint> =
|
|
42
|
-
[
|
|
43
|
-
|
|
44
|
-
|
|
57
|
+
export type Slot<K extends string, Constraint> = K extends keyof BasaltRegister
|
|
58
|
+
? BasaltRegister[K] extends Constraint
|
|
59
|
+
? BasaltRegister[K]
|
|
60
|
+
: {}
|
|
45
61
|
: {}
|
|
46
62
|
|
|
47
63
|
/** The consumer's registered series map, or `{}` when un-augmented. */
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
* Carries the typed navigation definition (`defineNav`/`navGroup`/`navTarget`/`flattenNav`) and
|
|
5
5
|
* `useNav`, which resolves it into `BasaltShell`'s `sections` + `mobileNav` props; plus the
|
|
6
6
|
* StaticDataRouteOption augmentation (title/icon/navSection) for router-derived breadcrumbs, plus
|
|
7
|
-
* `createSearchStore` + the `field.*` vocabulary
|
|
8
|
-
* replaced) — no Mantine, no JSX.
|
|
7
|
+
* `createSearchStore` + the `field.*` vocabulary — no Mantine, no JSX.
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
10
|
export { createSearchStore, type CreateSearchStoreOptions, type SearchStore } from './search-store'
|
|
12
|
-
export { field } from '
|
|
11
|
+
export { field } from '../state'
|
|
13
12
|
export type {
|
|
14
13
|
AnyField,
|
|
15
14
|
BooleanField,
|
|
@@ -32,17 +31,7 @@ export type {
|
|
|
32
31
|
SearchValues,
|
|
33
32
|
StoredValues,
|
|
34
33
|
StringField,
|
|
35
|
-
} from '
|
|
36
|
-
export {
|
|
37
|
-
createSearchParamStore,
|
|
38
|
-
type SearchParamStore,
|
|
39
|
-
type SearchParamStoreOptions,
|
|
40
|
-
} from './search-param-store'
|
|
41
|
-
export {
|
|
42
|
-
createMultiSearchParamStore,
|
|
43
|
-
type MultiSearchParamStore,
|
|
44
|
-
type MultiSearchParamStoreOptions,
|
|
45
|
-
} from './multi-search-param-store'
|
|
34
|
+
} from '../state'
|
|
46
35
|
export { defineNav, navGroup, navTarget, flattenNav } from './nav'
|
|
47
36
|
export type {
|
|
48
37
|
NavItemMeta,
|
|
@@ -59,7 +48,7 @@ export type {
|
|
|
59
48
|
} from './nav'
|
|
60
49
|
export { useNav } from './use-nav'
|
|
61
50
|
export type { UseNavOptions, NavBinding } from './use-nav'
|
|
62
|
-
export type { NavAnchor, NavAnchorProps, NavMobilePlacement } from '../nav
|
|
51
|
+
export type { NavAnchor, NavAnchorProps, NavMobilePlacement } from '../shell/nav-types'
|
|
63
52
|
import type { ReactNode } from 'react'
|
|
64
53
|
import { useLocation, useMatches } from '@tanstack/react-router'
|
|
65
54
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* No JSX and no Mantine in this module — `./router-tanstack` is a headless barrel by contract.
|
|
13
13
|
*/
|
|
14
14
|
import type { ReactNode } from 'react'
|
|
15
|
-
import type { NavMobilePlacement, NavSectionMobile } from '../nav
|
|
15
|
+
import type { NavMobilePlacement, NavSectionMobile } from '../shell/nav-types'
|
|
16
16
|
|
|
17
17
|
// ── authoring shapes ─────────────────────────────────────────────────────────────────────────────
|
|
18
18
|
|
|
@@ -212,12 +212,11 @@ function isMemoryLane(entry: StoreEntry): boolean {
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
/**
|
|
215
|
-
* The store
|
|
216
|
-
*
|
|
217
|
-
* Not exported from the barrel — `createSearchStore` is the public door.
|
|
215
|
+
* The store's implementation. Not exported from the barrel — `createSearchStore` is the public
|
|
216
|
+
* door.
|
|
218
217
|
*/
|
|
219
218
|
export function buildSearchStore<const S extends Record<string, AnyField>>(
|
|
220
|
-
o: CreateSearchStoreOptions<S
|
|
219
|
+
o: CreateSearchStoreOptions<S>,
|
|
221
220
|
): InternalSearchStore<S> {
|
|
222
221
|
assertNoLazyUrlFallback(o.key, o.fields)
|
|
223
222
|
const core = createStoreCore(o)
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { createElement, useMemo } from 'react'
|
|
13
13
|
import type { ElementType, ReactNode } from 'react'
|
|
14
14
|
import { Link, useMatchRoute, useRouterState } from '@tanstack/react-router'
|
|
15
|
-
import type { MobileNavConfig, NavAnchor, SidebarItem, SidebarSection } from '../nav
|
|
15
|
+
import type { MobileNavConfig, NavAnchor, SidebarItem, SidebarSection } from '../shell/nav-types'
|
|
16
16
|
import { flattenNav } from './nav'
|
|
17
17
|
import type { AnyNavGroup, AnyNavItem, NavConfig, NavItemId, NavTabId } from './nav'
|
|
18
18
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { Anchor, Group, Text } from '@mantine/core'
|
|
14
14
|
import type { CSSProperties } from 'react'
|
|
15
|
-
import type { NavAnchor } from '
|
|
15
|
+
import type { NavAnchor } from './nav-types'
|
|
16
16
|
import { VX } from '../tokens'
|
|
17
17
|
import type { BasaltProps } from '../common/props'
|
|
18
18
|
import classes from './app-header.module.css'
|
|
@@ -105,3 +105,14 @@
|
|
|
105
105
|
* tracks those instead. The HEIGHT is flex's job and needs no transition of its own. */
|
|
106
106
|
transition-property: margin;
|
|
107
107
|
}
|
|
108
|
+
|
|
109
|
+
/* Installed PWA (C5 consolidation, seeded from argo's `styles/native.css`): clear the landscape
|
|
110
|
+
* notch on the side Main touches. `max()` is a FLOOR over `.main`'s own `padding` shorthand above
|
|
111
|
+
* — same mechanism as `app-sidebar.module.css`'s left counterpart. The bottom inset already rides
|
|
112
|
+
* `margin-bottom` above (`env(safe-area-inset-bottom)`); the PWA's top inset needs no rule here
|
|
113
|
+
* (the status bar uses the opaque `default` style, per argo's own seed comment). */
|
|
114
|
+
@media (display-mode: standalone) {
|
|
115
|
+
.main {
|
|
116
|
+
padding-right: max(var(--app-shell-padding), env(safe-area-inset-right));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -34,7 +34,7 @@ import type {
|
|
|
34
34
|
SidebarItem,
|
|
35
35
|
SidebarListBlock,
|
|
36
36
|
SidebarProgressBlock,
|
|
37
|
-
} from '
|
|
37
|
+
} from './nav-types'
|
|
38
38
|
import type { BasaltAccountProps } from './account-types'
|
|
39
39
|
import type { SettingsMenuItem } from './index'
|
|
40
40
|
import { NavCountBadge } from './nav-count-badge'
|
|
@@ -95,6 +95,26 @@ function IconMore() {
|
|
|
95
95
|
)
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
/** The `ActionRow.active` glyph — same shape as `app-sidebar.tsx`'s own copy (no icon dependency
|
|
99
|
+
* to import between the two render trees). */
|
|
100
|
+
function IconCheck() {
|
|
101
|
+
return (
|
|
102
|
+
<svg
|
|
103
|
+
width={14}
|
|
104
|
+
height={14}
|
|
105
|
+
viewBox="0 0 24 24"
|
|
106
|
+
fill="none"
|
|
107
|
+
stroke="currentColor"
|
|
108
|
+
strokeWidth={2.5}
|
|
109
|
+
strokeLinecap="round"
|
|
110
|
+
strokeLinejoin="round"
|
|
111
|
+
aria-hidden
|
|
112
|
+
>
|
|
113
|
+
<path d="M5 12l5 5l10 -10" />
|
|
114
|
+
</svg>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
98
118
|
/** A row the More surface derives from `account`/`settingsMenuItems` — never a destination. */
|
|
99
119
|
type ActionRow = {
|
|
100
120
|
key: string
|
|
@@ -102,6 +122,8 @@ type ActionRow = {
|
|
|
102
122
|
icon?: ReactNode
|
|
103
123
|
danger?: boolean
|
|
104
124
|
onClick?: ((e: MouseEvent<HTMLElement>) => void) | undefined
|
|
125
|
+
/** Mirrors `SettingsMenuItem.active` — a trailing check + `aria-current` in every row form. */
|
|
126
|
+
active?: boolean
|
|
105
127
|
}
|
|
106
128
|
|
|
107
129
|
/**
|
|
@@ -172,6 +194,7 @@ function settingsRows(items: SettingsMenuItem[] | undefined): ActionRow[] {
|
|
|
172
194
|
label: item.label,
|
|
173
195
|
icon: item.icon,
|
|
174
196
|
onClick: item.onClick,
|
|
197
|
+
...(item.active !== undefined && { active: item.active }),
|
|
175
198
|
}))
|
|
176
199
|
}
|
|
177
200
|
|
|
@@ -234,8 +257,10 @@ const menuActionRow = (row: ActionRow) => (
|
|
|
234
257
|
key={row.key}
|
|
235
258
|
className={classes.menuItem}
|
|
236
259
|
leftSection={row.icon}
|
|
260
|
+
rightSection={row.active ? <IconCheck /> : undefined}
|
|
237
261
|
{...(row.danger ? { color: 'red' } : {})}
|
|
238
262
|
onClick={(event: MouseEvent<HTMLElement>) => row.onClick?.(event)}
|
|
263
|
+
aria-current={row.active ? 'true' : undefined}
|
|
239
264
|
>
|
|
240
265
|
{row.label}
|
|
241
266
|
</Menu.Item>
|
|
@@ -480,11 +505,13 @@ export function MobileNav({
|
|
|
480
505
|
classNames={{ root: classes.row }}
|
|
481
506
|
label={row.label}
|
|
482
507
|
leftSection={row.icon}
|
|
508
|
+
rightSection={row.active ? <IconCheck /> : undefined}
|
|
483
509
|
{...(row.danger ? { color: 'red' } : {})}
|
|
484
510
|
onClick={(event: MouseEvent<HTMLElement>) => {
|
|
485
511
|
row.onClick?.(event)
|
|
486
512
|
close()
|
|
487
513
|
}}
|
|
514
|
+
aria-current={row.active ? 'true' : undefined}
|
|
488
515
|
/>
|
|
489
516
|
)
|
|
490
517
|
|
|
@@ -26,6 +26,16 @@
|
|
|
26
26
|
padding: 0 var(--vx-space-row-inset-x);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
/* Installed PWA (C5 consolidation, seeded from argo's `styles/native.css`): clear the landscape
|
|
30
|
+
* notch on the side the sidebar touches. `max()` is a FLOOR — the inset only grows the padding
|
|
31
|
+
* past its normal value, never shrinks it. Right inset is `app-main.module.css`'s to draw; the
|
|
32
|
+
* PWA's top inset needs no rule here (the status bar uses the opaque `default` style). */
|
|
33
|
+
@media (display-mode: standalone) {
|
|
34
|
+
.root {
|
|
35
|
+
padding-left: max(var(--vx-space-row-inset-x), env(safe-area-inset-left));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
29
39
|
.link {
|
|
30
40
|
font-size: var(--vx-text-md);
|
|
31
41
|
border-radius: var(--vx-radius-ctrl) !important;
|