basalt-ui 1.30.2 → 1.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +31 -0
- package/MIGRATING.md +172 -12
- package/agent/rules/basalt-controls.md +19 -19
- package/agent/rules/basalt-mantine.md +1 -1
- package/configs/oxlint-plugin.js +254 -4
- package/configs/oxlint-plugin.test.ts +145 -2
- package/configs/oxlint.json +2 -1
- package/dist/agent-chat/composer.d.ts.map +1 -1
- package/dist/agent-chat/composer.js +41 -43
- package/dist/agent-chat/thread-workspace.d.ts +2 -2
- package/dist/agent-chat/thread-workspace.d.ts.map +1 -1
- package/dist/agent-chat/thread-workspace.js +3 -4
- package/dist/agent-chat/use-keyboard-inset.d.ts +2 -0
- package/dist/agent-chat/use-keyboard-inset.d.ts.map +1 -0
- package/dist/agent-chat/use-keyboard-inset.js +34 -0
- package/dist/charts/cursor/touch-pin.d.ts +45 -0
- package/dist/charts/cursor/touch-pin.d.ts.map +1 -0
- package/dist/charts/cursor/touch-pin.js +79 -0
- package/dist/charts/hooks/use-discrete-cursor.d.ts +66 -0
- package/dist/charts/hooks/use-discrete-cursor.d.ts.map +1 -0
- package/dist/charts/hooks/use-discrete-cursor.js +198 -0
- package/dist/charts/hooks/use-hysteresis.d.ts +18 -0
- package/dist/charts/hooks/use-hysteresis.d.ts.map +1 -0
- package/dist/charts/hooks/use-hysteresis.js +12 -0
- package/dist/charts/hooks/useBandPlot.d.ts +7 -0
- package/dist/charts/hooks/useBandPlot.d.ts.map +1 -1
- package/dist/charts/hooks/useBandPlot.js +62 -18
- package/dist/charts/hooks/useChartCursor.d.ts +40 -11
- package/dist/charts/hooks/useChartCursor.d.ts.map +1 -1
- package/dist/charts/hooks/useChartCursor.js +102 -11
- package/dist/charts/index.d.ts +0 -1
- package/dist/charts/index.d.ts.map +1 -1
- package/dist/charts/index.js +0 -10
- package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
- package/dist/charts/kinds/BandStrip.js +54 -41
- package/dist/charts/kinds/Donut.d.ts +9 -3
- package/dist/charts/kinds/Donut.d.ts.map +1 -1
- package/dist/charts/kinds/Donut.js +110 -48
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +145 -131
- package/dist/charts/kinds/Heatmap.d.ts +7 -0
- package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
- package/dist/charts/kinds/Heatmap.js +37 -16
- package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
- package/dist/charts/kinds/MirroredBars.js +83 -68
- package/dist/charts/kinds/donut-layout.d.ts +47 -0
- package/dist/charts/kinds/donut-layout.d.ts.map +1 -0
- package/dist/charts/kinds/donut-layout.js +52 -0
- package/dist/charts/layout/auto-margin.d.ts +7 -2
- package/dist/charts/layout/auto-margin.d.ts.map +1 -1
- package/dist/charts/layout/auto-margin.js +12 -3
- package/dist/charts/layout/end-labels.d.ts +64 -0
- package/dist/charts/layout/end-labels.d.ts.map +1 -0
- package/dist/charts/layout/end-labels.js +76 -0
- package/dist/charts/primitives/Axes.d.ts +32 -4
- package/dist/charts/primitives/Axes.d.ts.map +1 -1
- package/dist/charts/primitives/Axes.js +62 -16
- package/dist/charts/primitives/CartesianChart.d.ts +7 -6
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
- package/dist/charts/primitives/CartesianChart.js +271 -125
- package/dist/charts/primitives/ChartCard.d.ts +0 -14
- package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
- package/dist/charts/primitives/ChartCard.js +74 -21
- package/dist/charts/primitives/ChartFrame.d.ts +28 -22
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +133 -34
- package/dist/charts/primitives/ChartLegend.d.ts +19 -15
- package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
- package/dist/charts/primitives/ChartLegend.js +212 -71
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +4 -3
- package/dist/charts/primitives/Crosshair.js +2 -2
- package/dist/charts/primitives/HoverOverlay.d.ts +6 -1
- package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
- package/dist/charts/primitives/HoverOverlay.js +37 -26
- package/dist/charts/primitives/HoverOverlay.module.css +13 -0
- package/dist/charts/primitives/HoverOverlay.module.css.d.ts +8 -0
- package/dist/charts/primitives/chart-card-context.d.ts +29 -0
- package/dist/charts/primitives/chart-card-context.d.ts.map +1 -0
- package/dist/charts/primitives/chart-card-context.js +13 -0
- package/dist/charts/primitives/chart-frame-layout.d.ts +93 -113
- package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -1
- package/dist/charts/primitives/chart-frame-layout.js +76 -29
- package/dist/charts/primitives/chart-layout.d.ts +112 -0
- package/dist/charts/primitives/chart-layout.d.ts.map +1 -0
- package/dist/charts/primitives/chart-layout.js +175 -0
- package/dist/charts/primitives/chart-tier.d.ts +13 -11
- package/dist/charts/primitives/chart-tier.d.ts.map +1 -1
- package/dist/charts/primitives/chart-tier.js +42 -13
- package/dist/charts/series.d.ts +4 -1
- package/dist/charts/series.d.ts.map +1 -1
- package/dist/charts/utils/ticks.d.ts +27 -8
- package/dist/charts/utils/ticks.d.ts.map +1 -1
- package/dist/charts/utils/ticks.js +35 -11
- package/dist/common/errors.d.ts +11 -1
- package/dist/common/errors.d.ts.map +1 -1
- package/dist/common/errors.js +16 -2
- package/dist/common/hit-floor.d.ts +10 -0
- package/dist/common/hit-floor.d.ts.map +1 -0
- package/dist/common/hit-floor.js +6 -0
- package/dist/{shell → common}/isomorphic-layout-effect.d.ts +4 -3
- package/dist/common/isomorphic-layout-effect.d.ts.map +1 -0
- package/dist/common/use-measured-widths.d.ts +37 -0
- package/dist/common/use-measured-widths.d.ts.map +1 -0
- package/dist/common/use-measured-widths.js +51 -0
- package/dist/common/use-media-query.d.ts +6 -0
- package/dist/common/use-media-query.d.ts.map +1 -0
- package/dist/common/use-media-query.js +40 -0
- package/dist/common/validate.d.ts +9 -0
- package/dist/common/validate.d.ts.map +1 -1
- package/dist/common/validate.js +9 -4
- package/dist/content/article-layout.d.ts +4 -2
- package/dist/content/article-layout.d.ts.map +1 -1
- package/dist/content/article-layout.js +43 -3
- package/dist/content/article-layout.module.css +45 -4
- package/dist/content/article-layout.module.css.d.ts +3 -0
- package/dist/content/code-block.d.ts.map +1 -1
- package/dist/content/code-block.js +40 -2
- package/dist/content/code-block.module.css +32 -2
- package/dist/content/prose.module.css +13 -8
- package/dist/controls/actions.d.ts +29 -6
- package/dist/controls/actions.d.ts.map +1 -1
- package/dist/controls/actions.js +158 -27
- package/dist/controls/actions.module.css +14 -1
- package/dist/controls/actions.module.css.d.ts +1 -0
- package/dist/controls/controls.module.css +8 -31
- package/dist/controls/enum-filter.js +2 -2
- package/dist/controls/filter-context.d.ts +10 -0
- package/dist/controls/filter-context.d.ts.map +1 -1
- package/dist/controls/filter-context.js +2 -0
- package/dist/controls/filter-pill.d.ts.map +1 -1
- package/dist/controls/filter-pill.js +1 -0
- package/dist/controls/index.d.ts +1 -1
- package/dist/controls/index.d.ts.map +1 -1
- package/dist/controls/index.js +0 -2
- package/dist/controls/multi-select-filter.js +2 -2
- package/dist/controls/sync-button.module.css +1 -1
- package/dist/dashboard/section.d.ts.map +1 -1
- package/dist/dashboard/section.js +1 -0
- package/dist/dashboard/section.module.css +1 -26
- package/dist/dashboard/stat-card.d.ts +1 -1
- package/dist/dashboard/stat-card.d.ts.map +1 -1
- package/dist/dashboard/stat-card.js +4 -1
- package/dist/dashboard/stat-card.module.css +6 -9
- package/dist/dashboard/stat-group.module.css +16 -4
- package/dist/dashboard/widget-grid.d.ts.map +1 -1
- package/dist/dashboard/widget-header.d.ts +14 -4
- package/dist/dashboard/widget-header.d.ts.map +1 -1
- package/dist/dashboard/widget-header.js +23 -6
- package/dist/dashboard/widget-header.module.css +145 -133
- package/dist/dashboard/widget-header.module.css.d.ts +2 -0
- package/dist/data/data-table.d.ts +23 -0
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +339 -141
- package/dist/data/data-table.module.css +94 -0
- package/dist/data/data-table.module.css.d.ts +11 -0
- package/dist/data/virtual-list.d.ts.map +1 -1
- package/dist/data/virtual-list.js +10 -0
- package/dist/forms/form-layout.d.ts.map +1 -1
- package/dist/forms/form-layout.js +3 -3
- package/dist/forms/form-layout.module.css +30 -5
- package/dist/forms/form-layout.module.css.d.ts +1 -0
- package/dist/guard/index.d.ts +8 -2
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +67 -2
- package/dist/guard/types.d.ts +3 -3
- package/dist/guard/types.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/provider/index.d.ts +20 -1
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +22 -2
- package/dist/shell/app-brand.d.ts.map +1 -1
- package/dist/shell/app-brand.js +1 -0
- package/dist/shell/app-brand.module.css +2 -2
- package/dist/shell/app-header.module.css +18 -8
- package/dist/shell/app-main.module.css +54 -3
- package/dist/shell/app-main.module.css.d.ts +1 -0
- package/dist/shell/app-mobile-nav.module.css +16 -4
- package/dist/shell/app-sidebar.module.css +4 -6
- package/dist/shell/index.d.ts +12 -0
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +57 -16
- package/dist/shell/mobile-nav-model.d.ts +1 -1
- package/dist/shell/page-aside.d.ts +22 -3
- package/dist/shell/page-aside.d.ts.map +1 -1
- package/dist/shell/page-aside.js +27 -13
- package/dist/shell/page-bar.d.ts.map +1 -1
- package/dist/shell/page-bar.js +10 -5
- package/dist/shell/page-bar.module.css +10 -34
- package/dist/shell/use-breakpoint.d.ts +3 -4
- package/dist/shell/use-breakpoint.d.ts.map +1 -1
- package/dist/shell/use-breakpoint.js +3 -25
- package/dist/shell/use-size-class.d.ts +6 -0
- package/dist/shell/use-size-class.d.ts.map +1 -0
- package/dist/shell/use-size-class.js +19 -0
- package/dist/state/persisted-or-local.d.ts +4 -1
- package/dist/state/persisted-or-local.d.ts.map +1 -1
- package/dist/state/persisted-or-local.js +4 -3
- package/dist/state/persisted.d.ts +10 -0
- package/dist/state/persisted.d.ts.map +1 -1
- package/dist/state/persisted.js +44 -14
- package/dist/styles.css +41 -0
- package/dist/surfaces.d.ts +4 -4
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +11 -3
- package/dist/theme/controls.module.css +7 -0
- package/dist/theme/ctl-theme.d.ts +1 -0
- package/dist/theme/ctl-theme.d.ts.map +1 -1
- package/dist/theme/ctl-theme.js +12 -4
- package/dist/theme/floating.module.css +36 -0
- package/dist/theme/floating.module.css.d.ts +3 -0
- package/dist/theme/index.d.ts +2 -2
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +34 -5
- package/dist/theme/nav-link.module.css +7 -0
- package/dist/tokens/index.d.ts +7 -16
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +23 -28
- package/dist/tokens/palette.d.ts +5 -27
- package/dist/tokens/palette.d.ts.map +1 -1
- package/dist/tokens/palette.js +8 -30
- package/dist/tokens/size-classes.d.ts +40 -0
- package/dist/tokens/size-classes.d.ts.map +1 -0
- package/dist/tokens/size-classes.js +29 -0
- package/dist/tokens.css +8 -4
- package/llms.txt +3 -3
- package/package.json +17 -17
- package/src/agent-chat/composer.tsx +74 -47
- package/src/agent-chat/thread-workspace.tsx +8 -11
- package/src/agent-chat/use-keyboard-inset.ts +68 -0
- package/src/charts/cursor/touch-pin.ts +138 -0
- package/src/charts/hooks/use-discrete-cursor.ts +335 -0
- package/src/charts/hooks/use-hysteresis.ts +26 -0
- package/src/charts/hooks/useBandPlot.ts +90 -27
- package/src/charts/hooks/useChartCursor.ts +211 -26
- package/src/charts/index.ts +0 -8
- package/src/charts/kinds/BandStrip.tsx +11 -1
- package/src/charts/kinds/Donut.tsx +153 -62
- package/src/charts/kinds/DualPanel.tsx +19 -4
- package/src/charts/kinds/Heatmap.tsx +61 -22
- package/src/charts/kinds/MirroredBars.tsx +15 -3
- package/src/charts/kinds/donut-layout.ts +82 -0
- package/src/charts/layout/auto-margin.ts +24 -5
- package/src/charts/layout/end-labels.ts +135 -0
- package/src/charts/primitives/Axes.tsx +112 -21
- package/src/charts/primitives/CartesianChart.tsx +282 -68
- package/src/charts/primitives/ChartCard.tsx +141 -48
- package/src/charts/primitives/ChartFrame.tsx +243 -60
- package/src/charts/primitives/ChartLegend.tsx +257 -73
- package/src/charts/primitives/ChartTooltip.tsx +8 -3
- package/src/charts/primitives/Crosshair.tsx +2 -2
- package/src/charts/primitives/HoverOverlay.module.css +13 -0
- package/src/charts/primitives/HoverOverlay.module.css.d.ts +8 -0
- package/src/charts/primitives/HoverOverlay.tsx +15 -4
- package/src/charts/primitives/chart-card-context.ts +37 -0
- package/src/charts/primitives/chart-frame-layout.ts +214 -177
- package/src/charts/primitives/chart-layout.ts +318 -0
- package/src/charts/primitives/chart-tier.tsx +66 -21
- package/src/charts/series.ts +4 -1
- package/src/charts/utils/ticks.ts +95 -19
- package/src/common/errors.ts +25 -1
- package/src/common/hit-floor.ts +9 -0
- package/src/{shell → common}/isomorphic-layout-effect.ts +4 -3
- package/src/common/use-measured-widths.ts +88 -0
- package/src/common/use-media-query.ts +56 -0
- package/src/common/validate.ts +17 -4
- package/src/content/article-layout.module.css +45 -4
- package/src/content/article-layout.module.css.d.ts +3 -0
- package/src/content/article-layout.tsx +60 -5
- package/src/content/code-block.module.css +32 -2
- package/src/content/code-block.tsx +47 -3
- package/src/content/prose.module.css +13 -8
- package/src/controls/actions.module.css +14 -1
- package/src/controls/actions.module.css.d.ts +1 -0
- package/src/controls/actions.tsx +223 -75
- package/src/controls/controls.module.css +8 -31
- package/src/controls/enum-filter.tsx +2 -2
- package/src/controls/filter-context.tsx +11 -0
- package/src/controls/filter-pill.tsx +1 -0
- package/src/controls/index.ts +0 -1
- package/src/controls/multi-select-filter.tsx +2 -2
- package/src/controls/sync-button.module.css +1 -1
- package/src/dashboard/section.module.css +1 -26
- package/src/dashboard/section.tsx +1 -0
- package/src/dashboard/stat-card.module.css +6 -9
- package/src/dashboard/stat-card.tsx +6 -3
- package/src/dashboard/stat-group.module.css +16 -4
- package/src/dashboard/widget-grid.tsx +7 -6
- package/src/dashboard/widget-header.module.css +145 -133
- package/src/dashboard/widget-header.module.css.d.ts +2 -0
- package/src/dashboard/widget-header.tsx +45 -11
- package/src/data/data-table.module.css +94 -0
- package/src/data/data-table.module.css.d.ts +11 -0
- package/src/data/data-table.tsx +503 -164
- package/src/data/virtual-list.tsx +31 -0
- package/src/forms/form-layout.module.css +30 -5
- package/src/forms/form-layout.module.css.d.ts +1 -0
- package/src/forms/form-layout.tsx +12 -10
- package/src/guard/index.ts +183 -3
- package/src/guard/types.ts +3 -2
- package/src/index.ts +2 -0
- package/src/provider/index.tsx +53 -1
- package/src/shell/app-brand.module.css +2 -2
- package/src/shell/app-brand.tsx +1 -0
- package/src/shell/app-header.module.css +18 -8
- package/src/shell/app-main.module.css +54 -3
- package/src/shell/app-main.module.css.d.ts +1 -0
- package/src/shell/app-mobile-nav.module.css +16 -4
- package/src/shell/app-sidebar.module.css +4 -6
- package/src/shell/index.tsx +200 -129
- package/src/shell/mobile-nav-model.ts +1 -1
- package/src/shell/page-aside.tsx +70 -21
- package/src/shell/page-bar.module.css +10 -34
- package/src/shell/page-bar.tsx +10 -5
- package/src/shell/use-breakpoint.ts +9 -45
- package/src/shell/use-size-class.ts +31 -0
- package/src/state/persisted-or-local.ts +10 -4
- package/src/state/persisted.ts +76 -17
- package/src/styles.css +41 -0
- package/src/surfaces.ts +9 -1
- package/src/theme/controls.module.css +7 -0
- package/src/theme/ctl-theme.tsx +15 -3
- package/src/theme/floating.module.css +36 -0
- package/src/theme/floating.module.css.d.ts +3 -0
- package/src/theme/index.ts +46 -8
- package/src/theme/nav-link.module.css +7 -0
- package/src/tokens/index.ts +20 -30
- package/src/tokens/palette.ts +6 -28
- package/src/tokens/size-classes.ts +46 -0
- package/dist/shell/isomorphic-layout-effect.d.ts.map +0 -1
- /package/dist/{shell → common}/isomorphic-layout-effect.js +0 -0
package/dist/shell/page-bar.js
CHANGED
|
@@ -3,11 +3,16 @@ import { createContext, useCallback, useContext, useEffect, useRef, useState } f
|
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
4
|
import { cx } from "../common/props.js";
|
|
5
5
|
import { CtlSlot } from "../theme/index.js";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
BarActionRow,
|
|
8
|
+
BarExtrasProvider,
|
|
9
|
+
PAGE_BAR_END_ATTR,
|
|
10
|
+
globalActionAsBarAction
|
|
11
|
+
} from "../controls/actions.js";
|
|
7
12
|
import { FilterPill } from "../controls/filter-pill.js";
|
|
8
13
|
import { FilterSheet } from "../controls/filter-sheet.js";
|
|
9
14
|
import { SyncButton } from "../controls/sync-button.js";
|
|
10
|
-
import { useIsomorphicLayoutEffect } from "
|
|
15
|
+
import { useIsomorphicLayoutEffect } from "../common/isomorphic-layout-effect.js";
|
|
11
16
|
import classes from "./page-bar.module.css";
|
|
12
17
|
import asideClasses from "./page-aside.module.css";
|
|
13
18
|
const PAGE_BAR_HEIGHT_VAR = "--basalt-page-bar-h";
|
|
@@ -162,12 +167,12 @@ function PageBar({
|
|
|
162
167
|
if (!inShell || !hasRow2) return;
|
|
163
168
|
return claimPanelHost();
|
|
164
169
|
}, [inShell, hasRow2, claimPanelHost]);
|
|
165
|
-
const row1 = hasRow1 ? /* @__PURE__ */ jsxs("div", { className: cx(classes.row1, classNames?.row1), children: [
|
|
170
|
+
const row1 = hasRow1 ? /* @__PURE__ */ jsxs("div", { className: cx(classes.row1, classNames?.row1), "data-basalt-hit-scope": true, children: [
|
|
166
171
|
hasLead && /* @__PURE__ */ jsxs("div", { className: classes.lead, children: [
|
|
167
172
|
icon !== void 0 && /* @__PURE__ */ jsx("span", { className: classes.icon, "aria-hidden": true, children: icon }),
|
|
168
173
|
title !== void 0 && /* @__PURE__ */ jsx("h1", { className: classes.title, children: title })
|
|
169
174
|
] }),
|
|
170
|
-
/* @__PURE__ */ jsx("div", { className: classes.row1End, children: (actions !== void 0 || filtersEndActions.length > 0 || sync !== void 0) && /* @__PURE__ */ jsx(CtlSlot, { children: /* @__PURE__ */ jsx(
|
|
175
|
+
/* @__PURE__ */ jsx("div", { className: classes.row1End, ...{ [PAGE_BAR_END_ATTR]: "" }, children: (actions !== void 0 || filtersEndActions.length > 0 || sync !== void 0) && /* @__PURE__ */ jsx(CtlSlot, { children: /* @__PURE__ */ jsx(
|
|
171
176
|
BarActionRow,
|
|
172
177
|
{
|
|
173
178
|
...actions,
|
|
@@ -178,7 +183,7 @@ function PageBar({
|
|
|
178
183
|
) }) })
|
|
179
184
|
] }) : null;
|
|
180
185
|
const hasPills = filters !== void 0 || panel !== null || filtersEndActions.length > 0;
|
|
181
|
-
const row2 = hasRow2 ? /* @__PURE__ */ jsxs("div", { className: cx(classes.row2, classNames?.row2), children: [
|
|
186
|
+
const row2 = hasRow2 ? /* @__PURE__ */ jsxs("div", { className: cx(classes.row2, classNames?.row2), "data-basalt-hit-scope": true, children: [
|
|
182
187
|
tabs !== void 0 && /* @__PURE__ */ jsx("div", { className: classes.tabs, "data-basalt-page-bar-line": "tabs", children: /* @__PURE__ */ jsx(CtlSlot, { children: tabs }) }),
|
|
183
188
|
hasPills && /* @__PURE__ */ jsxs("div", { className: classes.pills, "data-basalt-page-bar-line": "pills", children: [
|
|
184
189
|
filters !== void 0 && /* @__PURE__ */ jsx("div", { className: classes.filters, children: /* @__PURE__ */ jsx(CtlSlot, { children: filters }) }),
|
|
@@ -46,6 +46,8 @@
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
.row1 {
|
|
49
|
+
/* Fills the header's elastic outlet, so `.row1End` below is the ROOM the action fold measures. */
|
|
50
|
+
width: 100%;
|
|
49
51
|
display: flex;
|
|
50
52
|
flex-wrap: nowrap;
|
|
51
53
|
align-items: center;
|
|
@@ -188,42 +190,16 @@
|
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
/*
|
|
191
|
-
* Law C15 —
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* so a hit area drawn there would fight it. `pointer-events` stays default so the overlay is the
|
|
195
|
-
* one receiving the tap.
|
|
196
|
-
*
|
|
197
|
-
* `overflow: visible` is LOAD-BEARING, not tidying. Mantine's Button and ActionIcon roots both set
|
|
198
|
-
* `overflow: hidden` (`Button.css`, `ActionIcon.css`), which clips an overlay that by definition
|
|
199
|
-
* extends past the 30px box — so without this the 36px target simply does not exist and a tap 3px
|
|
200
|
-
* above the control misses. What `overflow: hidden` buys those roots is clipping the loading
|
|
201
|
-
* overlay's blur, and that overlay is only painted under `[data-loading]`, which is excluded below.
|
|
193
|
+
* Law C15 — controls in a home adopt the shared `[data-basalt-hit]` overlay (`styles.css`) through
|
|
194
|
+
* `data-basalt-hit-scope` on `.row1`/`.row2`; `--vx-hit-gap` caps the expansion at the real gap so
|
|
195
|
+
* neighbours' hit boxes never overlap. The VISIBLE box stays the 30px `ctl` tier.
|
|
202
196
|
*/
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
.row1 :is(button, a):not([data-loading]),
|
|
210
|
-
.row2 :is(button, a):not([data-loading]) {
|
|
211
|
-
overflow: visible;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
.row1 :is(button, a)::after,
|
|
215
|
-
.row2 :is(button, a)::after {
|
|
216
|
-
content: '';
|
|
217
|
-
position: absolute;
|
|
218
|
-
top: 50%;
|
|
219
|
-
left: 50%;
|
|
220
|
-
translate: -50% -50%;
|
|
221
|
-
width: 100%;
|
|
222
|
-
height: 100%;
|
|
223
|
-
min-width: var(--vx-space-touch-control-height);
|
|
224
|
-
min-height: var(--vx-space-touch-control-height);
|
|
225
|
-
}
|
|
197
|
+
.row1,
|
|
198
|
+
.row2 {
|
|
199
|
+
--vx-hit-gap: var(--vx-space-control-gap);
|
|
200
|
+
}
|
|
226
201
|
|
|
202
|
+
@media (max-width: 52.49375em) {
|
|
227
203
|
/*
|
|
228
204
|
* Row 2's phone form: two declared lines, tabs then pills — not a wrap (law C7). `.pills` folds
|
|
229
205
|
* every overflow into `Filters (n)` at any width, EXCEPT when it holds nothing visible: below `sm`
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
export type BreakpointName = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* @deprecated Use `useSizeClass` — removed next minor (see `MIGRATING.md`). `theme.breakpoints` is
|
|
4
|
+
* now derived: `sm` moved 48em → 52.5em and `md`/`lg`/`xl` all sit at 75em (`xs`/`sm` collapse,
|
|
5
|
+
* `md`/`lg`/`xl` collapse).
|
|
6
6
|
*/
|
|
7
|
-
export declare function useMediaQueryMatches(query: string, fallback: boolean): boolean;
|
|
8
7
|
export declare function useBreakpoint(name: BreakpointName, edge?: 'min' | 'max', options?: {
|
|
9
8
|
fallback?: boolean;
|
|
10
9
|
}): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-breakpoint.d.ts","sourceRoot":"","sources":["../../src/shell/use-breakpoint.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"use-breakpoint.d.ts","sourceRoot":"","sources":["../../src/shell/use-breakpoint.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAE7D;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,cAAc,EACpB,IAAI,GAAE,KAAK,GAAG,KAAa,EAC3B,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/B,OAAO,CAKT"}
|
|
@@ -1,33 +1,11 @@
|
|
|
1
|
-
import { useCallback, useMemo, useSyncExternalStore } from "react";
|
|
2
1
|
import { useMantineTheme } from "@mantine/core";
|
|
3
|
-
|
|
4
|
-
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return null;
|
|
5
|
-
return window.matchMedia(query);
|
|
6
|
-
}
|
|
7
|
-
function useMediaQueryMatches(query, fallback) {
|
|
8
|
-
const list = useMemo(() => mediaQueryList(query), [query]);
|
|
9
|
-
const subscribe = useCallback(
|
|
10
|
-
(onStoreChange) => {
|
|
11
|
-
if (list === null) return () => {
|
|
12
|
-
};
|
|
13
|
-
list.addEventListener("change", onStoreChange);
|
|
14
|
-
return () => {
|
|
15
|
-
list.removeEventListener("change", onStoreChange);
|
|
16
|
-
};
|
|
17
|
-
},
|
|
18
|
-
[list]
|
|
19
|
-
);
|
|
20
|
-
const getSnapshot = useCallback(() => list?.matches ?? fallback, [list, fallback]);
|
|
21
|
-
const getServerSnapshot = useCallback(() => fallback, [fallback]);
|
|
22
|
-
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
23
|
-
}
|
|
2
|
+
import { useMediaQuery } from "../common/use-media-query.js";
|
|
24
3
|
function useBreakpoint(name, edge = "min", options) {
|
|
25
4
|
const theme = useMantineTheme();
|
|
26
5
|
const bp = theme.breakpoints[name];
|
|
27
6
|
const fallback = options?.fallback ?? edge === "max";
|
|
28
|
-
return
|
|
7
|
+
return useMediaQuery(`(${edge}-width: ${bp})`, fallback);
|
|
29
8
|
}
|
|
30
9
|
export {
|
|
31
|
-
useBreakpoint
|
|
32
|
-
useMediaQueryMatches
|
|
10
|
+
useBreakpoint
|
|
33
11
|
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SIZE_CLASSES } from '../tokens/size-classes.js';
|
|
2
|
+
export type SizeClass = keyof typeof SIZE_CLASSES;
|
|
3
|
+
/** Provided by `BasaltProvider`'s `sizeClassHint`; the server snapshot. `undefined` = no provider. */
|
|
4
|
+
export declare const SizeClassHintContext: import("react").Context<"compact" | "medium" | "expanded" | undefined>;
|
|
5
|
+
export declare function useSizeClass(): SizeClass;
|
|
6
|
+
//# sourceMappingURL=use-size-class.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-size-class.d.ts","sourceRoot":"","sources":["../../src/shell/use-size-class.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,YAAY,EAAQ,MAAM,wBAAwB,CAAA;AAE3D,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,YAAY,CAAA;AAEjD,sGAAsG;AACtG,eAAO,MAAM,oBAAoB,wEAAkD,CAAA;AAEnF,wBAAgB,YAAY,IAAI,SAAS,CAUxC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
import { useMediaQuery } from "../common/use-media-query.js";
|
|
3
|
+
import { SIZE_CLASSES, toEm } from "../tokens/size-classes.js";
|
|
4
|
+
const SizeClassHintContext = createContext(void 0);
|
|
5
|
+
function useSizeClass() {
|
|
6
|
+
const hint = useContext(SizeClassHintContext) ?? "compact";
|
|
7
|
+
const isMedium = useMediaQuery(`(min-width: ${toEm(SIZE_CLASSES.medium)})`, hint !== "compact");
|
|
8
|
+
const isExpanded = useMediaQuery(
|
|
9
|
+
`(min-width: ${toEm(SIZE_CLASSES.expanded)})`,
|
|
10
|
+
hint === "expanded"
|
|
11
|
+
);
|
|
12
|
+
if (isExpanded) return "expanded";
|
|
13
|
+
if (isMedium) return "medium";
|
|
14
|
+
return "compact";
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
SizeClassHintContext,
|
|
18
|
+
useSizeClass
|
|
19
|
+
};
|
|
@@ -3,7 +3,10 @@ export declare function usePersistedOrLocal<T>({ scope, persistKey, initial, }:
|
|
|
3
3
|
scope: string;
|
|
4
4
|
/** Persist under `basalt:<scope>:<persistKey>`. Omitted → local state, nothing written. */
|
|
5
5
|
persistKey: string | undefined;
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* The value while the user has not chosen one — unset, NOT "written as this". It may change
|
|
8
|
+
* between renders (a size-class default) and the flag follows until a set call pins it.
|
|
9
|
+
*/
|
|
7
10
|
initial: T;
|
|
8
11
|
}): readonly [T, (next: T) => void];
|
|
9
12
|
//# sourceMappingURL=persisted-or-local.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persisted-or-local.d.ts","sourceRoot":"","sources":["../../src/state/persisted-or-local.ts"],"names":[],"mappings":"AAqBA,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,EACrC,KAAK,EACL,UAAU,EACV,OAAO,GACR,EAAE;IACD,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAA;IACb,2FAA2F;IAC3F,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B
|
|
1
|
+
{"version":3,"file":"persisted-or-local.d.ts","sourceRoot":"","sources":["../../src/state/persisted-or-local.ts"],"names":[],"mappings":"AAqBA,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,EACrC,KAAK,EACL,UAAU,EACV,OAAO,GACR,EAAE;IACD,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAA;IACb,2FAA2F;IAC3F,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B;;;OAGG;IACH,OAAO,EAAE,CAAC,CAAA;CACX,GAAG,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,CAoBlC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useMemo, useState } from "react";
|
|
1
|
+
import { useCallback, useMemo, useState } from "react";
|
|
2
2
|
import { createPersistedState } from "./persisted.js";
|
|
3
3
|
const UNPERSISTED_KEY = "__local__";
|
|
4
4
|
function usePersistedOrLocal({
|
|
@@ -6,7 +6,7 @@ function usePersistedOrLocal({
|
|
|
6
6
|
persistKey,
|
|
7
7
|
initial
|
|
8
8
|
}) {
|
|
9
|
-
const [local, setLocal] = useState(
|
|
9
|
+
const [local, setLocal] = useState(null);
|
|
10
10
|
const usePersisted = useMemo(
|
|
11
11
|
() => createPersistedState({
|
|
12
12
|
key: `${scope}:${persistKey ?? UNPERSISTED_KEY}`,
|
|
@@ -16,8 +16,9 @@ function usePersistedOrLocal({
|
|
|
16
16
|
[scope, persistKey, initial]
|
|
17
17
|
);
|
|
18
18
|
const [persisted, setPersisted] = usePersisted();
|
|
19
|
+
const setLocalValue = useCallback((next) => setLocal({ value: next }), []);
|
|
19
20
|
if (persistKey !== void 0) return [persisted, setPersisted];
|
|
20
|
-
return [local,
|
|
21
|
+
return [local === null ? initial : local.value, setLocalValue];
|
|
21
22
|
}
|
|
22
23
|
export {
|
|
23
24
|
usePersistedOrLocal
|
|
@@ -27,6 +27,16 @@ export type PersistedStateOptions<T> = {
|
|
|
27
27
|
* const [draft, setDraft] = useFilterDraft()
|
|
28
28
|
*/
|
|
29
29
|
export declare function createPersistedState<T>(opts: PersistedStateOptions<T>): () => readonly [T, (next: T) => void];
|
|
30
|
+
/**
|
|
31
|
+
* `createPersistedState` plus a third tuple element: `isSet`, false until a value is written or a
|
|
32
|
+
* stored one is accepted (a stale-version or schema-invalid envelope is NOT set).
|
|
33
|
+
* `value` alone cannot say — an unset key and an explicit write of `initial` both read as `initial`,
|
|
34
|
+
* and a default that depends on context (the shell's size-class collapse default) may apply to the
|
|
35
|
+
* first only.
|
|
36
|
+
*
|
|
37
|
+
* @internal Not exported from the `basalt-ui/state` barrel.
|
|
38
|
+
*/
|
|
39
|
+
export declare function createPersistedStore<T>(opts: PersistedStateOptions<T>): () => readonly [T, (next: T) => void, boolean];
|
|
30
40
|
/**
|
|
31
41
|
* Read a value previously written by `createPersistedState` under the namespaced key
|
|
32
42
|
* `basalt:<key>`. Parses the versioned envelope shape `{ v, value }`. Returns `null` on
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persisted.d.ts","sourceRoot":"","sources":["../../src/state/persisted.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"persisted.d.ts","sourceRoot":"","sources":["../../src/state/persisted.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAUnD,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI;IACrC,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAA;IACnB,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC,CAAA;IACjE;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;CAC/C,CAAA;AA+GD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAC7B,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,CAMvC;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAC7B,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,OAAO,CAAC,CA0FhD;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAYhF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAItF"}
|
package/dist/state/persisted.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useSyncExternalStore } from "react";
|
|
2
2
|
const noopSubscribe = (_cb) => () => {
|
|
3
3
|
};
|
|
4
|
+
const serverIsSet = () => false;
|
|
4
5
|
const channels = /* @__PURE__ */ new Map();
|
|
5
6
|
function notify(storageKey) {
|
|
6
7
|
const channel = channels.get(storageKey);
|
|
@@ -18,43 +19,57 @@ function isEnvelope(raw) {
|
|
|
18
19
|
return typeof raw === "object" && raw !== null && "v" in raw && typeof raw["v"] === "number" && "value" in raw;
|
|
19
20
|
}
|
|
20
21
|
function parseStorage(raw, opts) {
|
|
21
|
-
|
|
22
|
+
const miss = { value: opts.initial, accepted: false };
|
|
23
|
+
if (raw === null) return miss;
|
|
22
24
|
try {
|
|
23
25
|
const parsed = JSON.parse(raw);
|
|
24
|
-
if (!isEnvelope(parsed)) return
|
|
26
|
+
if (!isEnvelope(parsed)) return miss;
|
|
25
27
|
let value = parsed.value;
|
|
26
28
|
if (parsed.v !== opts.version) {
|
|
27
|
-
|
|
29
|
+
if (!opts.migrate) return miss;
|
|
30
|
+
value = opts.migrate(parsed.value, parsed.v);
|
|
28
31
|
}
|
|
29
32
|
if (opts.schema) {
|
|
30
33
|
const result = opts.schema["~standard"].validate(value);
|
|
31
|
-
if (result instanceof Promise) return
|
|
32
|
-
if (result.issues !== void 0) return
|
|
33
|
-
return result.value;
|
|
34
|
+
if (result instanceof Promise) return miss;
|
|
35
|
+
if (result.issues !== void 0) return miss;
|
|
36
|
+
return { value: result.value, accepted: true };
|
|
34
37
|
}
|
|
35
|
-
return value;
|
|
38
|
+
return { value, accepted: true };
|
|
36
39
|
} catch {
|
|
37
|
-
return
|
|
40
|
+
return miss;
|
|
38
41
|
}
|
|
39
42
|
}
|
|
43
|
+
const unpersisted = /* @__PURE__ */ new Map();
|
|
40
44
|
function writeEnvelope(storageKey, version, value) {
|
|
41
45
|
try {
|
|
42
46
|
const envelope = { v: version, value };
|
|
43
47
|
window.localStorage.setItem(storageKey, JSON.stringify(envelope));
|
|
48
|
+
unpersisted.delete(storageKey);
|
|
44
49
|
} catch {
|
|
50
|
+
unpersisted.set(storageKey, { value });
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
53
|
function writeStorage(opts, next) {
|
|
48
54
|
writeEnvelope(`basalt:${opts.key}`, opts.version, next);
|
|
49
55
|
}
|
|
50
56
|
function createPersistedState(opts) {
|
|
57
|
+
const useStore = createPersistedStore(opts);
|
|
58
|
+
return function usePersistedState() {
|
|
59
|
+
const [value, setValue] = useStore();
|
|
60
|
+
return [value, setValue];
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function createPersistedStore(opts) {
|
|
51
64
|
const storageKey = `basalt:${opts.key}`;
|
|
52
65
|
const subscribe = (cb) => {
|
|
53
66
|
const channel = channelFor(storageKey);
|
|
54
67
|
channel.listeners.add(cb);
|
|
55
68
|
if (channel.handler === null) {
|
|
56
69
|
channel.handler = (e) => {
|
|
57
|
-
if (e.key
|
|
70
|
+
if (e.key !== storageKey) return;
|
|
71
|
+
unpersisted.delete(storageKey);
|
|
72
|
+
notify(storageKey);
|
|
58
73
|
};
|
|
59
74
|
window.addEventListener("storage", channel.handler);
|
|
60
75
|
}
|
|
@@ -68,8 +83,11 @@ function createPersistedState(opts) {
|
|
|
68
83
|
};
|
|
69
84
|
let cachedRaw = null;
|
|
70
85
|
let cachedValue = opts.initial;
|
|
86
|
+
let cachedIsSet = false;
|
|
71
87
|
let primed = false;
|
|
72
88
|
const getSnapshot = () => {
|
|
89
|
+
const override = unpersisted.get(storageKey);
|
|
90
|
+
if (override !== void 0) return override.value;
|
|
73
91
|
let raw;
|
|
74
92
|
try {
|
|
75
93
|
raw = window.localStorage.getItem(storageKey);
|
|
@@ -77,25 +95,36 @@ function createPersistedState(opts) {
|
|
|
77
95
|
raw = null;
|
|
78
96
|
}
|
|
79
97
|
if (primed && raw === cachedRaw) return cachedValue;
|
|
98
|
+
const parsed = parseStorage(raw, opts);
|
|
80
99
|
cachedRaw = raw;
|
|
81
|
-
cachedValue =
|
|
100
|
+
cachedValue = parsed.value;
|
|
101
|
+
cachedIsSet = parsed.accepted;
|
|
82
102
|
primed = true;
|
|
83
103
|
return cachedValue;
|
|
84
104
|
};
|
|
105
|
+
const getIsSet = () => {
|
|
106
|
+
getSnapshot();
|
|
107
|
+
return unpersisted.has(storageKey) || cachedIsSet;
|
|
108
|
+
};
|
|
85
109
|
const getServerSnapshot = () => opts.initial;
|
|
86
110
|
const setState = (next) => {
|
|
87
111
|
writeStorage(opts, next);
|
|
88
112
|
notify(storageKey);
|
|
89
113
|
};
|
|
90
114
|
const isServer = typeof window === "undefined";
|
|
91
|
-
return function
|
|
115
|
+
return function usePersistedStore() {
|
|
116
|
+
const listen = isServer ? noopSubscribe : subscribe;
|
|
92
117
|
const value = useSyncExternalStore(
|
|
93
|
-
|
|
94
|
-
isServer ? noopSubscribe : subscribe,
|
|
118
|
+
listen,
|
|
95
119
|
isServer ? getServerSnapshot : getSnapshot,
|
|
96
120
|
getServerSnapshot
|
|
97
121
|
);
|
|
98
|
-
|
|
122
|
+
const isSet = useSyncExternalStore(
|
|
123
|
+
listen,
|
|
124
|
+
isServer ? serverIsSet : getIsSet,
|
|
125
|
+
serverIsSet
|
|
126
|
+
);
|
|
127
|
+
return [value, setState, isSet];
|
|
99
128
|
};
|
|
100
129
|
}
|
|
101
130
|
function readPersistedValue(key, version) {
|
|
@@ -118,6 +147,7 @@ function writePersistedValue(key, version, value) {
|
|
|
118
147
|
}
|
|
119
148
|
export {
|
|
120
149
|
createPersistedState,
|
|
150
|
+
createPersistedStore,
|
|
121
151
|
readPersistedValue,
|
|
122
152
|
writePersistedValue
|
|
123
153
|
};
|
package/dist/styles.css
CHANGED
|
@@ -210,6 +210,47 @@
|
|
|
210
210
|
background-color: var(--basalt-scrollbar-thumb-hover);
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
/* Bottom-anchored toasts clear the shell's bottom bar + safe area (docs/CONTROLS-SPEC.md §2). */
|
|
214
|
+
.mantine-Notifications-root[data-position^='bottom'] {
|
|
215
|
+
bottom: calc(
|
|
216
|
+
var(--app-shell-footer-offset, 0px) + env(safe-area-inset-bottom, 0px) +
|
|
217
|
+
var(--mantine-spacing-md)
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* Pointer tier: an invisible hit-area expansion to at least `--vx-hit` (44px coarse, 24px fine),
|
|
222
|
+
no layout change. `::after`, not `::before` — Mantine's Button owns `::before` for its loading
|
|
223
|
+
overlay. `overflow: visible` is load-bearing: Button/ActionIcon roots clip to their box, which
|
|
224
|
+
would clip the overlay; the clip only serves their `[data-loading]` overlay, so it stays then.
|
|
225
|
+
Adopters: `data-basalt-hit` on the control, or `data-basalt-hit-scope` on a home whose
|
|
226
|
+
`button`/`a` descendants (consumer-supplied) adopt it.
|
|
227
|
+
DECISION: the axis is `pointer: coarse` (the PRIMARY input, via `--vx-hit`), never
|
|
228
|
+
`any-pointer` — a touch laptop's mouse-first session must not inflate every hit area.
|
|
229
|
+
OVERLAP CAP: a host with neighbours sets `--vx-hit-gap` (its real gap between controls); the
|
|
230
|
+
expansion is then limited to that gap in total (half per side), so adjacent hit boxes never
|
|
231
|
+
overlap and a later sibling never steals a tap. Unset = uncapped (an isolated control). The
|
|
232
|
+
`+ 2px` is the control's own 1px border (Mantine buttons carry one, transparent or not): `100%`
|
|
233
|
+
is the PADDING box, the gap is measured between border boxes.
|
|
234
|
+
`position: relative` is the ::after's containing block; an adopter that must be
|
|
235
|
+
absolute/sticky sets its own `position` in an unlayered rule, which outranks this layer. */
|
|
236
|
+
:is([data-basalt-hit], [data-basalt-hit-scope] :is(button, a)) {
|
|
237
|
+
position: relative;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
:is([data-basalt-hit], [data-basalt-hit-scope] :is(button, a)):not([data-loading]) {
|
|
241
|
+
overflow: visible;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
:is([data-basalt-hit], [data-basalt-hit-scope] :is(button, a))::after {
|
|
245
|
+
content: '';
|
|
246
|
+
position: absolute;
|
|
247
|
+
top: 50%;
|
|
248
|
+
left: 50%;
|
|
249
|
+
translate: -50% -50%;
|
|
250
|
+
width: min(max(100%, var(--vx-hit)), calc(100% + 2px + var(--vx-hit-gap, 100vmax)));
|
|
251
|
+
height: min(max(100%, var(--vx-hit)), calc(100% + 2px + var(--vx-hit-gap, 100vmax)));
|
|
252
|
+
}
|
|
253
|
+
|
|
213
254
|
/* Print: hide the BasaltShell chrome so only page content prints.
|
|
214
255
|
Scoped to AppShell's own class hooks, NOT to bare nav/header/footer. The element form matched
|
|
215
256
|
any landmark on the page — a consumer with a real <nav> and no BasaltShell silently printed a
|
package/dist/surfaces.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export type RuleName = 'tokens' | 'charts' | 'mantine' | 'state' | 'controls' |
|
|
|
32
32
|
* const id: PluginRuleId = 'hand-rolled-filter' // ok
|
|
33
33
|
* // const bad: PluginRuleId = 'hand-rolled-filters' // tsc error
|
|
34
34
|
*/
|
|
35
|
-
export declare const PLUGIN_RULE_ID_LIST: readonly ["no-raw-font-size", "raw-size-literal", "card-inset", "chart-in-raw-surface", "hand-rolled-plot", "chart-legend-literal", "shadow-basalt-export", "hand-rolled-shell", "raw-scroll-container", "hand-rolled-filter", "control-outside-home", "bound-control-outside-home", "control-size-literal", "page-bar-budget", "in-body-page-title", "responsive-twin", "search-literal-link", "use-search-from-literal", "provider-above-router", "query-fn-unwrap", "deprecated-export", "forms-field-key", "visx-boundary", "visx-tooltip", "token-layer-boundary", "agent-resume-guard", "agent-no-raw-usechat", "ai-sdk-major", "no-import-meta-env"];
|
|
35
|
+
export declare const PLUGIN_RULE_ID_LIST: readonly ["no-raw-font-size", "raw-size-literal", "card-inset", "chart-in-raw-surface", "hand-rolled-plot", "chart-legend-literal", "shadow-basalt-export", "hand-rolled-shell", "raw-scroll-container", "hand-rolled-filter", "control-outside-home", "bound-control-outside-home", "control-size-literal", "page-bar-budget", "in-body-page-title", "responsive-twin", "search-literal-link", "use-search-from-literal", "provider-above-router", "query-fn-unwrap", "deprecated-export", "forms-field-key", "visx-boundary", "visx-tooltip", "token-layer-boundary", "agent-resume-guard", "agent-no-raw-usechat", "ai-sdk-major", "no-import-meta-env", "raw-breakpoint"];
|
|
36
36
|
/** One registered oxlint plugin rule id — the literal union of {@link PLUGIN_RULE_ID_LIST}. */
|
|
37
37
|
export type PluginRuleId = (typeof PLUGIN_RULE_ID_LIST)[number];
|
|
38
38
|
/** The 3 shipped skill names (agent/skills/basalt-{name}/SKILL.md, placed into a consumer's
|
|
@@ -172,10 +172,10 @@ export declare const SURFACES: {
|
|
|
172
172
|
readonly layer: "mantine-coupled";
|
|
173
173
|
readonly rule: "mantine";
|
|
174
174
|
readonly skill: readonly ["basalt-app", "basalt-design"];
|
|
175
|
-
readonly guardKinds: readonly ["raw-motion-value", "card-with-border", "raw-form-control", "sub-16-input-font", "mantine-shade-index", "in-body-page-title", "raw-spacing", "inline-spacing", "inline-display", "raw-html-layout", "hidden-inline-style"];
|
|
176
|
-
readonly pluginRules: readonly ["hand-rolled-shell", "card-inset", "in-body-page-title", "raw-scroll-container", "page-bar-budget", "shadow-basalt-export", "provider-above-router", "deprecated-export", "no-import-meta-env"];
|
|
175
|
+
readonly guardKinds: readonly ["raw-motion-value", "card-with-border", "raw-form-control", "sub-16-input-font", "mantine-shade-index", "in-body-page-title", "raw-spacing", "inline-spacing", "inline-display", "raw-html-layout", "hidden-inline-style", "raw-media-query"];
|
|
176
|
+
readonly pluginRules: readonly ["hand-rolled-shell", "raw-breakpoint", "card-inset", "in-body-page-title", "raw-scroll-container", "page-bar-budget", "shadow-basalt-export", "provider-above-router", "deprecated-export", "no-import-meta-env"];
|
|
177
177
|
readonly advisoryLaws: readonly ["no second cssVariablesResolver — don't hand-build createTheme or re-add the resolver basalt already installs"];
|
|
178
|
-
readonly description: "BasaltProvider, createBasaltTheme, BasaltShell + sidebar/mobile-nav/breadcrumbs, PageBar, PageAside, useBreakpoint, NavCountBadge, ThemeToggle, ThreadWorkspace + thread-chat components, WidgetHeader, dashboard composites (DeltaBadge, StatCard with threshold tone, EmptyState, QueryState/LoadingState/ErrorState, SettingsSection/SettingsRow/DangerZone), ConnectivityProvider/useConnectivity/ConnectivityIndicator (auto-mounted, C1: absorbed from the dropped ./connectivity), createBasaltQueryClient/unwrap/BasaltQueryDevtools (C1: absorbed from the dropped ./query), BasaltDevDock (C5: lazy Router/Query devtools + theme lab in one dock)";
|
|
178
|
+
readonly description: "BasaltProvider, createBasaltTheme, BasaltShell + sidebar/mobile-nav/breadcrumbs, PageBar, PageAside, useSizeClass (useBreakpoint on notice), NavCountBadge, ThemeToggle, ThreadWorkspace + thread-chat components, WidgetHeader, dashboard composites (DeltaBadge, StatCard with threshold tone, EmptyState, QueryState/LoadingState/ErrorState, SettingsSection/SettingsRow/DangerZone), ConnectivityProvider/useConnectivity/ConnectivityIndicator (auto-mounted, C1: absorbed from the dropped ./connectivity), createBasaltQueryClient/unwrap/BasaltQueryDevtools (C1: absorbed from the dropped ./query), BasaltDevDock (C5: lazy Router/Query devtools + theme lab in one dock)";
|
|
179
179
|
readonly optionalPeers: readonly ["react-markdown", "remark-gfm", "rehype-sanitize", "remend", "shiki", "beautiful-mermaid", "@tanstack/react-router-devtools"];
|
|
180
180
|
readonly forbiddenImports: readonly [];
|
|
181
181
|
};
|
package/dist/surfaces.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../src/surfaces.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAI9C;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAA;AAE3F;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../src/surfaces.ts"],"names":[],"mappings":"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"}
|
package/dist/surfaces.js
CHANGED
|
@@ -27,7 +27,8 @@ const PLUGIN_RULE_ID_LIST = [
|
|
|
27
27
|
"agent-resume-guard",
|
|
28
28
|
"agent-no-raw-usechat",
|
|
29
29
|
"ai-sdk-major",
|
|
30
|
-
"no-import-meta-env"
|
|
30
|
+
"no-import-meta-env",
|
|
31
|
+
"raw-breakpoint"
|
|
31
32
|
];
|
|
32
33
|
const v = (spec, message, extra) => ({
|
|
33
34
|
spec,
|
|
@@ -67,13 +68,20 @@ const SURFACES = {
|
|
|
67
68
|
"inline-spacing",
|
|
68
69
|
"inline-display",
|
|
69
70
|
"raw-html-layout",
|
|
70
|
-
"hidden-inline-style"
|
|
71
|
+
"hidden-inline-style",
|
|
72
|
+
// The CSS-text twin of `raw-breakpoint` (below) — a width @media, an undeclared @container
|
|
73
|
+
// name/literal, or a non-coarse pointer query, the shape a JSX-only AST rule cannot see.
|
|
74
|
+
"raw-media-query"
|
|
71
75
|
],
|
|
72
76
|
// The chrome half of the plugin: the shell, the card idiom, the page title and the scroll
|
|
73
77
|
// doctrine. `hand-rolled-shell` sits here rather than on a shell-shaped surface because
|
|
74
78
|
// `BasaltShell` IS the root barrel's promise (docs/CONTROLS-SPEC.md §6 wave 6).
|
|
75
79
|
pluginRules: [
|
|
76
80
|
"hand-rolled-shell",
|
|
81
|
+
// The size-class axis's one JSX escape hatch (docs/CONTROLS-SPEC.md §6) is reserved
|
|
82
|
+
// for BasaltShell/AppSidebar/MobileNav/AppBrand (`SHELL_HOME_NAMES`, configs/oxlint-plugin.js)
|
|
83
|
+
// — the same shell promise `hand-rolled-shell` polices, one axis over.
|
|
84
|
+
"raw-breakpoint",
|
|
77
85
|
"card-inset",
|
|
78
86
|
"in-body-page-title",
|
|
79
87
|
"raw-scroll-container",
|
|
@@ -96,7 +104,7 @@ const SURFACES = {
|
|
|
96
104
|
advisoryLaws: [
|
|
97
105
|
"no second cssVariablesResolver \u2014 don't hand-build createTheme or re-add the resolver basalt already installs"
|
|
98
106
|
],
|
|
99
|
-
description: "BasaltProvider, createBasaltTheme, BasaltShell + sidebar/mobile-nav/breadcrumbs, PageBar, PageAside, useBreakpoint, NavCountBadge, ThemeToggle, ThreadWorkspace + thread-chat components, WidgetHeader, dashboard composites (DeltaBadge, StatCard with threshold tone, EmptyState, QueryState/LoadingState/ErrorState, SettingsSection/SettingsRow/DangerZone), ConnectivityProvider/useConnectivity/ConnectivityIndicator (auto-mounted, C1: absorbed from the dropped ./connectivity), createBasaltQueryClient/unwrap/BasaltQueryDevtools (C1: absorbed from the dropped ./query), BasaltDevDock (C5: lazy Router/Query devtools + theme lab in one dock)",
|
|
107
|
+
description: "BasaltProvider, createBasaltTheme, BasaltShell + sidebar/mobile-nav/breadcrumbs, PageBar, PageAside, useSizeClass (useBreakpoint on notice), NavCountBadge, ThemeToggle, ThreadWorkspace + thread-chat components, WidgetHeader, dashboard composites (DeltaBadge, StatCard with threshold tone, EmptyState, QueryState/LoadingState/ErrorState, SettingsSection/SettingsRow/DangerZone), ConnectivityProvider/useConnectivity/ConnectivityIndicator (auto-mounted, C1: absorbed from the dropped ./connectivity), createBasaltQueryClient/unwrap/BasaltQueryDevtools (C1: absorbed from the dropped ./query), BasaltDevDock (C5: lazy Router/Query devtools + theme lab in one dock)",
|
|
100
108
|
optionalPeers: [
|
|
101
109
|
"react-markdown",
|
|
102
110
|
"remark-gfm",
|
|
@@ -61,6 +61,13 @@ html[data-mantine-color-scheme] .inputWrapper[data-variant='default']:not([data-
|
|
|
61
61
|
box-shadow: var(--field-depth);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
/* An input cannot host the `[data-basalt-hit]` ::after overlay, so its touch floor is real height. */
|
|
65
|
+
@media (pointer: coarse) {
|
|
66
|
+
.input {
|
|
67
|
+
min-height: var(--vx-hit);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
64
71
|
.input[data-variant='default'] {
|
|
65
72
|
--field-depth: var(--vx-shadow-raised);
|
|
66
73
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { MantineThemeOverride } from '@mantine/core';
|
|
2
2
|
import type { ReactNode } from 'react';
|
|
3
|
+
export declare const HIT_ATTR: Record<string, true>;
|
|
3
4
|
/** The `MantineThemeOverride` a `<CtlSlot>` provides — see this module's doc for the merge/
|
|
4
5
|
* precedence contract. Exported so a consumer composing its own slot (a bespoke home not covered
|
|
5
6
|
* by `PageBar`/`Section`/the sidebar blocks) can reach the SAME tier without re-declaring it. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ctl-theme.d.ts","sourceRoot":"","sources":["../../src/theme/ctl-theme.tsx"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAe,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"ctl-theme.d.ts","sourceRoot":"","sources":["../../src/theme/ctl-theme.tsx"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAe,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAA+B,CAAA;AAEzE;;iGAEiG;AACjG,eAAO,MAAM,SAAS,EAAE,oBA+BvB,CAAA;AAoCD,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,SAAS,CAAA;IACnB;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;CACxB,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAY,EAAE,EAAE,YAAY,GAAG,SAAS,CAQ3E"}
|
package/dist/theme/ctl-theme.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
Switch,
|
|
15
15
|
TextInput
|
|
16
16
|
} from "@mantine/core";
|
|
17
|
+
const HIT_ATTR = { "data-basalt-hit": true };
|
|
17
18
|
const CTL_THEME = {
|
|
18
19
|
components: {
|
|
19
20
|
Button: Button.extend({ defaultProps: { size: "ctl" } }),
|
|
@@ -26,7 +27,9 @@ const CTL_THEME = {
|
|
|
26
27
|
NativeSelect: NativeSelect.extend({ defaultProps: { size: "ctl" } }),
|
|
27
28
|
// The theme keys are the component names Mantine's own `useProps` looks up — `RadioGroup`, not
|
|
28
29
|
// `Radio.Group` (`RadioGroup.mjs`: `useProps("RadioGroup", …)`).
|
|
29
|
-
Radio: Radio.extend({
|
|
30
|
+
Radio: Radio.extend({
|
|
31
|
+
defaultProps: { size: "ctl", attributes: { label: HIT_ATTR } }
|
|
32
|
+
}),
|
|
30
33
|
// Mantine types `RadioGroup.size` as a CLOSED `MantineSize`, while `Radio`, `Checkbox`,
|
|
31
34
|
// `Checkbox.Group`, `Switch` and `Switch.Group` all type theirs OPEN
|
|
32
35
|
// (`MantineSize | (string & {})`) — verified in the installed 9.3.0 `.d.ts` files, so this is an
|
|
@@ -34,9 +37,13 @@ const CTL_THEME = {
|
|
|
34
37
|
// runtime `getSize` interpolates the string identically for all six. The cast restores what
|
|
35
38
|
// every sibling type already allows; it widens nothing.
|
|
36
39
|
RadioGroup: Radio.Group.extend({ defaultProps: { size: "ctl" } }),
|
|
37
|
-
Checkbox: Checkbox.extend({
|
|
40
|
+
Checkbox: Checkbox.extend({
|
|
41
|
+
defaultProps: { size: "ctl", attributes: { label: HIT_ATTR } }
|
|
42
|
+
}),
|
|
38
43
|
CheckboxGroup: Checkbox.Group.extend({ defaultProps: { size: "ctl" } }),
|
|
39
|
-
Switch: Switch.extend({
|
|
44
|
+
Switch: Switch.extend({
|
|
45
|
+
defaultProps: { size: "ctl", attributes: { track: HIT_ATTR } }
|
|
46
|
+
}),
|
|
40
47
|
SwitchGroup: Switch.Group.extend({ defaultProps: { size: "ctl" } })
|
|
41
48
|
}
|
|
42
49
|
};
|
|
@@ -50,5 +57,6 @@ function CtlSlot({ children, tier = "ctl" }) {
|
|
|
50
57
|
}
|
|
51
58
|
export {
|
|
52
59
|
CTL_THEME,
|
|
53
|
-
CtlSlot
|
|
60
|
+
CtlSlot,
|
|
61
|
+
HIT_ATTR
|
|
54
62
|
};
|