basalt-ui 1.30.2 → 1.32.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 +54 -0
- package/MIGRATING.md +256 -12
- package/agent/rules/basalt-controls.md +19 -19
- package/agent/rules/basalt-mantine.md +5 -5
- package/configs/oxlint-plugin.js +371 -4
- package/configs/oxlint-plugin.test.ts +327 -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 +47 -82
- 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 +138 -145
- 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 +68 -111
- package/dist/charts/kinds/band-chrome.d.ts +31 -0
- package/dist/charts/kinds/band-chrome.d.ts.map +1 -0
- package/dist/charts/kinds/band-chrome.js +71 -0
- 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 +264 -145
- 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 +56 -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 +116 -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 +86 -73
- package/dist/charts/primitives/ChartTooltip.d.ts +5 -0
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +20 -4
- package/dist/charts/primitives/Crosshair.js +2 -2
- package/dist/charts/primitives/HoverOverlay.d.ts +29 -9
- package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
- package/dist/charts/primitives/HoverOverlay.js +54 -27
- 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 +33 -0
- package/dist/charts/primitives/chart-card-context.d.ts.map +1 -0
- package/dist/charts/primitives/chart-card-context.js +18 -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 +75 -34
- 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/primitives/legend-disclosure.d.ts +27 -0
- package/dist/charts/primitives/legend-disclosure.d.ts.map +1 -0
- package/dist/charts/primitives/legend-disclosure.js +153 -0
- 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 +13 -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 +2 -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 +33 -66
- package/dist/dashboard/widget-grid.d.ts.map +1 -1
- package/dist/dashboard/widget-grid.module.css +11 -38
- 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-state.d.ts +83 -0
- package/dist/data/data-table-state.d.ts.map +1 -0
- package/dist/data/data-table-state.js +139 -0
- package/dist/data/data-table.d.ts +56 -2
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +436 -336
- 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 +20 -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 +68 -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/notifications/center.d.ts.map +1 -1
- package/dist/provider/index.d.ts +20 -1
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +30 -8
- 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/aside-docking.d.ts +31 -0
- package/dist/shell/aside-docking.d.ts.map +1 -0
- package/dist/shell/aside-docking.js +19 -0
- package/dist/shell/index.d.ts +1 -0
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +56 -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 +37 -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/theme-lab/derive-controls.d.ts.map +1 -1
- 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 +18 -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 +25 -61
- package/src/charts/kinds/Donut.tsx +153 -62
- package/src/charts/kinds/DualPanel.tsx +21 -26
- package/src/charts/kinds/Heatmap.tsx +61 -22
- package/src/charts/kinds/MirroredBars.tsx +23 -65
- package/src/charts/kinds/band-chrome.tsx +91 -0
- 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 -111
- package/src/charts/primitives/ChartCard.tsx +119 -48
- package/src/charts/primitives/ChartFrame.tsx +204 -60
- package/src/charts/primitives/ChartLegend.tsx +115 -78
- package/src/charts/primitives/ChartTooltip.tsx +24 -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 +62 -20
- package/src/charts/primitives/chart-card-context.ts +46 -0
- package/src/charts/primitives/chart-frame-layout.ts +207 -182
- package/src/charts/primitives/chart-layout.ts +318 -0
- package/src/charts/primitives/chart-tier.tsx +66 -21
- package/src/charts/primitives/legend-disclosure.tsx +177 -0
- 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 +13 -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 +2 -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 +33 -66
- package/src/dashboard/widget-grid.module.css +11 -38
- 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-state.ts +218 -0
- 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 +547 -299
- package/src/data/virtual-list.tsx +31 -0
- package/src/forms/form-layout.module.css +20 -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 +188 -3
- package/src/guard/types.ts +3 -2
- package/src/index.ts +2 -0
- package/src/notifications/center.tsx +3 -0
- package/src/provider/index.tsx +60 -7
- 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/aside-docking.ts +54 -0
- package/src/shell/index.tsx +178 -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 +37 -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/theme-lab/derive-controls.tsx +2 -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/data/data-table.js
CHANGED
|
@@ -4,8 +4,10 @@ import {
|
|
|
4
4
|
Checkbox,
|
|
5
5
|
Group,
|
|
6
6
|
Pagination,
|
|
7
|
+
ScrollArea,
|
|
7
8
|
Select,
|
|
8
9
|
Skeleton,
|
|
10
|
+
Stack,
|
|
9
11
|
Table,
|
|
10
12
|
Text,
|
|
11
13
|
TextInput
|
|
@@ -18,9 +20,11 @@ import {
|
|
|
18
20
|
getSortedRowModel,
|
|
19
21
|
useReactTable
|
|
20
22
|
} from "@tanstack/react-table";
|
|
21
|
-
import {
|
|
23
|
+
import { Fragment, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
22
24
|
import { cx } from "../common/props.js";
|
|
23
25
|
import { BASALT_PREFIX } from "../common/errors.js";
|
|
26
|
+
import { HIT_COARSE } from "../common/hit-floor.js";
|
|
27
|
+
import { useMeasuredWidths } from "../common/use-measured-widths.js";
|
|
24
28
|
import { assertRequiredProps, useValidateProps } from "../common/validate.js";
|
|
25
29
|
import { FilterSet } from "../controls/index.js";
|
|
26
30
|
import { ActionGroup, BarActionSlot } from "../controls/actions.js";
|
|
@@ -30,6 +34,13 @@ import { CtlSlot } from "../theme/index.js";
|
|
|
30
34
|
import { alpha, VX } from "../tokens/index.js";
|
|
31
35
|
import { WidgetHeader } from "../dashboard/index.js";
|
|
32
36
|
import { ErrorState } from "../dashboard/query-state.js";
|
|
37
|
+
import {
|
|
38
|
+
activationProps,
|
|
39
|
+
EMPTY_FOLD_SET,
|
|
40
|
+
useCardProjection,
|
|
41
|
+
useDataTableState,
|
|
42
|
+
useRowDisclosure
|
|
43
|
+
} from "./data-table-state.js";
|
|
33
44
|
import { dataQueryBranch } from "./query-branch.js";
|
|
34
45
|
import { isDev } from "../common/is-dev.js";
|
|
35
46
|
import classes from "./data-table.module.css";
|
|
@@ -106,26 +117,31 @@ function selectionColumn() {
|
|
|
106
117
|
return {
|
|
107
118
|
id: SELECT_COLUMN_ID,
|
|
108
119
|
enableSorting: false,
|
|
109
|
-
header: ({ table }) =>
|
|
110
|
-
Checkbox
|
|
111
|
-
{
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
120
|
+
header: ({ table }) => (
|
|
121
|
+
// oxlint-disable-next-line jsx-a11y/label-has-associated-control -- wraps <Checkbox>, which oxlint cannot see is an input
|
|
122
|
+
/* @__PURE__ */ jsx("label", { className: classes.selectHit, children: /* @__PURE__ */ jsx(
|
|
123
|
+
Checkbox,
|
|
124
|
+
{
|
|
125
|
+
size: "xs",
|
|
126
|
+
"aria-label": "Select all rows",
|
|
127
|
+
checked: table.getIsAllPageRowsSelected(),
|
|
128
|
+
indeterminate: table.getIsSomePageRowsSelected() && !table.getIsAllPageRowsSelected(),
|
|
129
|
+
onChange: table.getToggleAllPageRowsSelectedHandler()
|
|
130
|
+
}
|
|
131
|
+
) })
|
|
118
132
|
),
|
|
119
|
-
cell: ({ row }) =>
|
|
120
|
-
Checkbox
|
|
121
|
-
{
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
133
|
+
cell: ({ row }) => (
|
|
134
|
+
// oxlint-disable-next-line jsx-a11y/label-has-associated-control -- wraps <Checkbox>, which oxlint cannot see is an input
|
|
135
|
+
/* @__PURE__ */ jsx("label", { className: classes.selectHit, children: /* @__PURE__ */ jsx(
|
|
136
|
+
Checkbox,
|
|
137
|
+
{
|
|
138
|
+
size: "xs",
|
|
139
|
+
"aria-label": `Select row ${row.index + 1}`,
|
|
140
|
+
checked: row.getIsSelected(),
|
|
141
|
+
disabled: !row.getCanSelect(),
|
|
142
|
+
onChange: row.getToggleSelectedHandler()
|
|
143
|
+
}
|
|
144
|
+
) })
|
|
129
145
|
)
|
|
130
146
|
};
|
|
131
147
|
}
|
|
@@ -142,6 +158,7 @@ function SortIndicator({ direction }) {
|
|
|
142
158
|
if (!direction) return null;
|
|
143
159
|
return /* @__PURE__ */ jsx(Box, { component: "span", ml: 4, "aria-hidden": true, children: direction === "asc" ? "\u2191" : "\u2193" });
|
|
144
160
|
}
|
|
161
|
+
const ARIA_SORT = { asc: "ascending", desc: "descending" };
|
|
145
162
|
const NUMERIC_CELL_STYLE = {
|
|
146
163
|
fontFamily: "var(--mantine-font-family-monospace)",
|
|
147
164
|
fontSize: VX.text.sm,
|
|
@@ -201,6 +218,117 @@ function getPinnedCellStyle(table, column) {
|
|
|
201
218
|
boxShadow: isEdge ? `-4px 0 6px -4px ${alpha(VX.ink, 0.18)}` : void 0
|
|
202
219
|
};
|
|
203
220
|
}
|
|
221
|
+
function columnDefId(column) {
|
|
222
|
+
if (column.id !== void 0) return column.id;
|
|
223
|
+
return "accessorKey" in column && typeof column.accessorKey === "string" ? column.accessorKey : void 0;
|
|
224
|
+
}
|
|
225
|
+
function foldOrder(columns) {
|
|
226
|
+
return columns.map((column, index) => ({
|
|
227
|
+
id: columnDefId(column),
|
|
228
|
+
priority: column.meta?.priority ?? index,
|
|
229
|
+
index
|
|
230
|
+
})).filter(
|
|
231
|
+
(candidate) => Boolean(candidate.id)
|
|
232
|
+
).toSorted((a, b) => b.priority - a.priority || b.index - a.index).map((candidate) => candidate.id);
|
|
233
|
+
}
|
|
234
|
+
const FOLD_ID_ATTR = "data-basalt-fold-id";
|
|
235
|
+
function planColumnFold(input) {
|
|
236
|
+
const { room, toggleWidth, overhead, order, widths } = input;
|
|
237
|
+
const known = order.filter((id) => widths.has(id));
|
|
238
|
+
let unfolded = overhead + known.reduce((sum, id) => sum + (widths.get(id) ?? 0), 0);
|
|
239
|
+
const folded = /* @__PURE__ */ new Set();
|
|
240
|
+
for (const id of known) {
|
|
241
|
+
if (folded.size >= known.length - 1) break;
|
|
242
|
+
const withToggle = unfolded + (folded.size > 0 ? toggleWidth : 0);
|
|
243
|
+
if (withToggle <= room) break;
|
|
244
|
+
folded.add(id);
|
|
245
|
+
unfolded -= widths.get(id) ?? 0;
|
|
246
|
+
}
|
|
247
|
+
return folded;
|
|
248
|
+
}
|
|
249
|
+
function useColumnFold(input) {
|
|
250
|
+
const { active, order, fixedIds } = input;
|
|
251
|
+
const wrapperRef = useRef(null);
|
|
252
|
+
const [folded, setFolded] = useState(EMPTY_FOLD_SET);
|
|
253
|
+
const orderRef = useRef(order);
|
|
254
|
+
orderRef.current = order;
|
|
255
|
+
const fixedIdsRef = useRef(fixedIds);
|
|
256
|
+
fixedIdsRef.current = fixedIds;
|
|
257
|
+
useLayoutEffect(() => {
|
|
258
|
+
if (!active || order.length === 0) {
|
|
259
|
+
setFolded((current) => current.size === 0 ? current : EMPTY_FOLD_SET);
|
|
260
|
+
}
|
|
261
|
+
}, [active, order.length]);
|
|
262
|
+
useMeasuredWidths({
|
|
263
|
+
resolveRoot: () => wrapperRef.current,
|
|
264
|
+
signature: `${order.join("|")}::${fixedIds.join("|")}`,
|
|
265
|
+
enabled: active && order.length > 0,
|
|
266
|
+
// The table too, not only the wrapper: a re-measured column set moves its min-content width
|
|
267
|
+
// while the wrapper's own box never changes.
|
|
268
|
+
extra: (root) => [root.querySelector("table")],
|
|
269
|
+
onMeasure: (root, boxes) => {
|
|
270
|
+
for (const cell of root.querySelectorAll(`[${FOLD_ID_ATTR}]`)) {
|
|
271
|
+
const id = cell.getAttribute(FOLD_ID_ATTR);
|
|
272
|
+
if (id !== null && cell.offsetWidth > 0) {
|
|
273
|
+
boxes.current.set(id, { width: cell.offsetWidth, height: cell.offsetHeight });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const room = root.clientWidth;
|
|
277
|
+
if (room === 0) return;
|
|
278
|
+
const widths = new Map([...boxes.current].map(([id, box]) => [id, box.width]));
|
|
279
|
+
const overhead = fixedIdsRef.current.reduce((sum, id) => sum + (widths.get(id) ?? 0), 0);
|
|
280
|
+
const next = planColumnFold({
|
|
281
|
+
room,
|
|
282
|
+
// The disclosure toggle is a fixed icon-button cell matched to the coarse hit floor, so it
|
|
283
|
+
// reads as one more `--vx-hit` control rather than a narrower afterthought.
|
|
284
|
+
toggleWidth: HIT_COARSE,
|
|
285
|
+
overhead,
|
|
286
|
+
order: orderRef.current,
|
|
287
|
+
widths
|
|
288
|
+
});
|
|
289
|
+
setFolded(
|
|
290
|
+
(current) => current.size === next.size && [...current].every((id) => next.has(id)) ? current : next
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
return { wrapperRef, folded: active ? folded : EMPTY_FOLD_SET };
|
|
295
|
+
}
|
|
296
|
+
function columnLabel(column) {
|
|
297
|
+
const header = column.columnDef.header;
|
|
298
|
+
return typeof header === "string" ? header : column.id;
|
|
299
|
+
}
|
|
300
|
+
function RowDisclosure({
|
|
301
|
+
row,
|
|
302
|
+
folded
|
|
303
|
+
}) {
|
|
304
|
+
const cells = row.getAllCells().filter((cell) => folded.has(cell.column.id));
|
|
305
|
+
return /* @__PURE__ */ jsx("div", { className: classes.foldDisclosure, children: cells.map((cell) => /* @__PURE__ */ jsxs("div", { className: classes.foldDisclosureRow, children: [
|
|
306
|
+
/* @__PURE__ */ jsx(Text, { className: classes.foldDisclosureLabel, children: columnLabel(cell.column) }),
|
|
307
|
+
/* @__PURE__ */ jsx("div", { className: classes.foldDisclosureValue, children: flexRender(cell.column.columnDef.cell, cell.getContext()) })
|
|
308
|
+
] }, cell.id)) });
|
|
309
|
+
}
|
|
310
|
+
function FoldToggle({
|
|
311
|
+
expanded,
|
|
312
|
+
controlsId,
|
|
313
|
+
onToggle
|
|
314
|
+
}) {
|
|
315
|
+
return /* @__PURE__ */ jsx(
|
|
316
|
+
"button",
|
|
317
|
+
{
|
|
318
|
+
type: "button",
|
|
319
|
+
className: classes.foldToggle,
|
|
320
|
+
"data-basalt-hit": true,
|
|
321
|
+
"aria-expanded": expanded,
|
|
322
|
+
"aria-controls": controlsId,
|
|
323
|
+
"aria-label": expanded ? "Hide row details" : "Show row details",
|
|
324
|
+
onClick: (event) => {
|
|
325
|
+
event.stopPropagation();
|
|
326
|
+
onToggle();
|
|
327
|
+
},
|
|
328
|
+
children: /* @__PURE__ */ jsx(Box, { component: "span", "aria-hidden": true, children: expanded ? "\u25BE" : "\u25B8" })
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
}
|
|
204
332
|
const BREACH_REMEDY = {
|
|
205
333
|
inert: "`enablePagination` is not set, so `manualPagination` never reaches the table and the server page renders as if it were the whole set, with no bar to say otherwise. Pass `enablePagination`, or drop `manualPagination`.",
|
|
206
334
|
total: 'neither `rowCount` nor `pageCount` was given, so "of N" counts only the rows on this page and the pager collapses to one page nobody can leave. Pass `rowCount={total}`.',
|
|
@@ -233,35 +361,21 @@ function enforceManualPaginationContract(breaches) {
|
|
|
233
361
|
function useMeasuredContainment(active) {
|
|
234
362
|
const wrapperRef = useRef(null);
|
|
235
363
|
const [contained, setContained] = useState(false);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const
|
|
248
|
-
if (result === "unknown") return;
|
|
249
|
-
const next = result === "contained";
|
|
364
|
+
useMeasuredWidths({
|
|
365
|
+
resolveRoot: () => wrapperRef.current,
|
|
366
|
+
signature: String(active),
|
|
367
|
+
enabled: active,
|
|
368
|
+
// The TABLE too, not only the wrapper: a column set that re-measures (a facet filter changing
|
|
369
|
+
// the widest cell, a font settling) moves the table's min-content width while the wrapper's
|
|
370
|
+
// box never changes at all.
|
|
371
|
+
extra: (root) => [root.querySelector("table")],
|
|
372
|
+
onMeasure: (root) => {
|
|
373
|
+
const table = root.querySelector("table");
|
|
374
|
+
if (table === null || root.clientWidth === 0 || table.offsetWidth === 0) return;
|
|
375
|
+
const next = table.offsetWidth > root.clientWidth;
|
|
250
376
|
setContained((current) => current === next ? current : next);
|
|
251
|
-
};
|
|
252
|
-
if (typeof ResizeObserver === "undefined") {
|
|
253
|
-
apply();
|
|
254
|
-
return;
|
|
255
377
|
}
|
|
256
|
-
|
|
257
|
-
observer.observe(wrapper);
|
|
258
|
-
const table = wrapper.querySelector("table");
|
|
259
|
-
if (table !== null) observer.observe(table);
|
|
260
|
-
apply();
|
|
261
|
-
return () => {
|
|
262
|
-
observer.disconnect();
|
|
263
|
-
};
|
|
264
|
-
}, [active]);
|
|
378
|
+
});
|
|
265
379
|
return { wrapperRef, contained: active && contained };
|
|
266
380
|
}
|
|
267
381
|
function BasaltDataTable(props) {
|
|
@@ -280,32 +394,23 @@ function BasaltDataTable(props) {
|
|
|
280
394
|
isLoading = false,
|
|
281
395
|
query,
|
|
282
396
|
skeletonRows = 5,
|
|
283
|
-
initialSorting,
|
|
284
|
-
onSortingChange,
|
|
285
397
|
enableGlobalFilter = false,
|
|
286
398
|
globalFilterPlaceholder = "Search\u2026",
|
|
287
399
|
searchIcon,
|
|
288
|
-
initialGlobalFilter,
|
|
289
|
-
onGlobalFilterChange,
|
|
290
400
|
facets,
|
|
291
|
-
onColumnFiltersChange,
|
|
292
401
|
manualFiltering = false,
|
|
293
402
|
actions,
|
|
294
403
|
onRowActivate,
|
|
404
|
+
renderCard,
|
|
295
405
|
enableRowSelection = false,
|
|
296
|
-
rowSelection,
|
|
297
|
-
onRowSelectionChange,
|
|
298
406
|
getRowId,
|
|
299
407
|
bulkActions,
|
|
300
408
|
enablePagination = false,
|
|
301
409
|
pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
|
|
302
|
-
initialPagination,
|
|
303
|
-
onPaginationChange,
|
|
304
410
|
manualPagination = false,
|
|
305
411
|
rowCount,
|
|
306
412
|
pageCount,
|
|
307
413
|
enablePinning = false,
|
|
308
|
-
initialColumnPinning,
|
|
309
414
|
maxHeight,
|
|
310
415
|
minWidth,
|
|
311
416
|
stickyHeader,
|
|
@@ -318,15 +423,8 @@ function BasaltDataTable(props) {
|
|
|
318
423
|
style,
|
|
319
424
|
classNames
|
|
320
425
|
} = props;
|
|
321
|
-
const
|
|
322
|
-
const
|
|
323
|
-
const [columnFilters, setColumnFilters] = useState([]);
|
|
324
|
-
const [pagination, setPagination] = useState(
|
|
325
|
-
initialPagination ?? { pageIndex: 0, pageSize: pageSizeOptions[0] ?? 10 }
|
|
326
|
-
);
|
|
327
|
-
const [columnPinning, setColumnPinning] = useState(initialColumnPinning ?? {});
|
|
328
|
-
const [internalRowSelection, setInternalRowSelection] = useState({});
|
|
329
|
-
const rowSelectionState = rowSelection ?? internalRowSelection;
|
|
426
|
+
const tableState = useDataTableState(props, pageSizeOptions[0] ?? 10);
|
|
427
|
+
const { globalFilter, columnPinning, onGlobalFilterChange: handleGlobalFilterChange } = tableState;
|
|
330
428
|
useValidateProps(
|
|
331
429
|
"BasaltDataTable",
|
|
332
430
|
() => [
|
|
@@ -343,65 +441,11 @@ function BasaltDataTable(props) {
|
|
|
343
441
|
props.isLoading === void 0
|
|
344
442
|
]
|
|
345
443
|
);
|
|
346
|
-
const handleSortingChange = useCallback(
|
|
347
|
-
(updater) => {
|
|
348
|
-
setSorting((prev) => {
|
|
349
|
-
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
350
|
-
onSortingChange?.(next);
|
|
351
|
-
return next;
|
|
352
|
-
});
|
|
353
|
-
},
|
|
354
|
-
[onSortingChange]
|
|
355
|
-
);
|
|
356
|
-
const handleGlobalFilterChange = useCallback(
|
|
357
|
-
(updater) => {
|
|
358
|
-
setGlobalFilter((prev) => {
|
|
359
|
-
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
360
|
-
onGlobalFilterChange?.(next);
|
|
361
|
-
return next;
|
|
362
|
-
});
|
|
363
|
-
},
|
|
364
|
-
[onGlobalFilterChange]
|
|
365
|
-
);
|
|
366
|
-
const handleColumnFiltersChange = useCallback(
|
|
367
|
-
(updater) => {
|
|
368
|
-
setColumnFilters((prev) => {
|
|
369
|
-
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
370
|
-
onColumnFiltersChange?.(next);
|
|
371
|
-
return next;
|
|
372
|
-
});
|
|
373
|
-
},
|
|
374
|
-
[onColumnFiltersChange]
|
|
375
|
-
);
|
|
376
|
-
const handlePaginationChange = useCallback(
|
|
377
|
-
(updater) => {
|
|
378
|
-
setPagination((prev) => {
|
|
379
|
-
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
380
|
-
onPaginationChange?.(next);
|
|
381
|
-
return next;
|
|
382
|
-
});
|
|
383
|
-
},
|
|
384
|
-
[onPaginationChange]
|
|
385
|
-
);
|
|
386
|
-
const handleRowSelectionChange = useCallback(
|
|
387
|
-
(updater) => {
|
|
388
|
-
if (rowSelection !== void 0) {
|
|
389
|
-
onRowSelectionChange?.(typeof updater === "function" ? updater(rowSelection) : updater);
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
setInternalRowSelection((prev) => {
|
|
393
|
-
const next = typeof updater === "function" ? updater(prev) : updater;
|
|
394
|
-
onRowSelectionChange?.(next);
|
|
395
|
-
return next;
|
|
396
|
-
});
|
|
397
|
-
},
|
|
398
|
-
[rowSelection, onRowSelectionChange]
|
|
399
|
-
);
|
|
400
444
|
const facetColumns = useMemo(() => {
|
|
401
445
|
if (!facets || facets.length === 0) return columns;
|
|
402
446
|
const facetById = new Map(facets.map((facet) => [facet.columnId, facet]));
|
|
403
447
|
return columns.map((column) => {
|
|
404
|
-
const id = column
|
|
448
|
+
const id = columnDefId(column);
|
|
405
449
|
const facet = id === void 0 ? void 0 : facetById.get(id);
|
|
406
450
|
if (!facet) return column;
|
|
407
451
|
const filterFn = facet.multiple ? (row, columnId, filterValue) => !Array.isArray(filterValue) || filterValue.length === 0 ? true : filterValue.includes(String(row.getValue(columnId))) : (row, columnId, filterValue) => filterValue === null || filterValue === void 0 || filterValue === "" ? true : String(row.getValue(columnId)) === filterValue;
|
|
@@ -430,25 +474,54 @@ function BasaltDataTable(props) {
|
|
|
430
474
|
const sortingEnabled = enableSorting && !breaches.includes("sorting");
|
|
431
475
|
const filteringEnabled = !breaches.includes("filtering");
|
|
432
476
|
const totalIsAuthoritative = !breaches.includes("total");
|
|
477
|
+
const scrolls = maxHeight !== void 0 || minWidth !== void 0;
|
|
478
|
+
const foldEligible = minWidth === void 0;
|
|
479
|
+
const { columnFoldOrder, columnFoldFixedIds } = useMemo(() => {
|
|
480
|
+
const pinnedIds = /* @__PURE__ */ new Set([...columnPinning.left ?? [], ...columnPinning.right ?? []]);
|
|
481
|
+
const excluded = new Set(
|
|
482
|
+
columns.flatMap((column) => {
|
|
483
|
+
const id = columnDefId(column);
|
|
484
|
+
if (id === void 0) return [];
|
|
485
|
+
return column.enableHiding === false || pinnedIds.has(id) ? [id] : [];
|
|
486
|
+
})
|
|
487
|
+
);
|
|
488
|
+
return {
|
|
489
|
+
columnFoldOrder: foldOrder(columns).filter((id) => !excluded.has(id)),
|
|
490
|
+
columnFoldFixedIds: [...excluded]
|
|
491
|
+
};
|
|
492
|
+
}, [columns, columnPinning]);
|
|
493
|
+
const projection = useCardProjection(renderCard !== void 0);
|
|
494
|
+
const columnFold = useColumnFold({
|
|
495
|
+
active: foldEligible && !projection.cards,
|
|
496
|
+
order: columnFoldOrder,
|
|
497
|
+
fixedIds: columnFoldFixedIds
|
|
498
|
+
});
|
|
499
|
+
const columnVisibility = useMemo(
|
|
500
|
+
() => Object.fromEntries([...columnFold.folded].map((id) => [id, false])),
|
|
501
|
+
[columnFold.folded]
|
|
502
|
+
);
|
|
503
|
+
const hasFolded = columnFold.folded.size > 0;
|
|
504
|
+
const foldRows = useRowDisclosure({ data, getRowId });
|
|
433
505
|
const table = useReactTable({
|
|
434
506
|
data,
|
|
435
507
|
columns: tableColumns,
|
|
436
508
|
state: {
|
|
437
|
-
sorting,
|
|
509
|
+
sorting: tableState.sorting,
|
|
438
510
|
globalFilter,
|
|
439
|
-
columnFilters,
|
|
511
|
+
columnFilters: tableState.columnFilters,
|
|
440
512
|
columnPinning,
|
|
441
|
-
|
|
442
|
-
...
|
|
513
|
+
columnVisibility,
|
|
514
|
+
...enablePagination && { pagination: tableState.pagination },
|
|
515
|
+
...enableRowSelection && { rowSelection: tableState.rowSelection }
|
|
443
516
|
},
|
|
444
|
-
onSortingChange:
|
|
517
|
+
onSortingChange: tableState.onSortingChange,
|
|
445
518
|
onGlobalFilterChange: handleGlobalFilterChange,
|
|
446
|
-
onColumnFiltersChange:
|
|
447
|
-
onColumnPinningChange:
|
|
448
|
-
...enablePagination && { onPaginationChange:
|
|
519
|
+
onColumnFiltersChange: tableState.onColumnFiltersChange,
|
|
520
|
+
onColumnPinningChange: tableState.onColumnPinningChange,
|
|
521
|
+
...enablePagination && { onPaginationChange: tableState.onPaginationChange },
|
|
449
522
|
...enableRowSelection && {
|
|
450
523
|
enableRowSelection: true,
|
|
451
|
-
onRowSelectionChange:
|
|
524
|
+
onRowSelectionChange: tableState.onRowSelectionChange
|
|
452
525
|
},
|
|
453
526
|
...getRowId !== void 0 && { getRowId },
|
|
454
527
|
getCoreRowModel: getCoreRowModel(),
|
|
@@ -476,7 +549,7 @@ function BasaltDataTable(props) {
|
|
|
476
549
|
const branch = query === void 0 ? void 0 : dataQueryBranch("BasaltDataTable", query);
|
|
477
550
|
const showSkeleton = branch === void 0 ? isLoading : branch === "pending";
|
|
478
551
|
const queryError = branch === "error" && query !== void 0 ? query : void 0;
|
|
479
|
-
const columnCount = columns.length + (enableRowSelection ? 1 : 0);
|
|
552
|
+
const columnCount = columns.length + (enableRowSelection ? 1 : 0) + (hasFolded ? 1 : 0) - columnFold.folded.size;
|
|
480
553
|
const selectedModelRows = enableRowSelection ? table.getSelectedRowModel().rows : void 0;
|
|
481
554
|
const selectedRows = useMemo(
|
|
482
555
|
() => selectedModelRows?.map((row) => row.original) ?? [],
|
|
@@ -488,10 +561,20 @@ function BasaltDataTable(props) {
|
|
|
488
561
|
);
|
|
489
562
|
const headerGroups = enablePinning ? getOrderedHeaderGroups(table) : table.getHeaderGroups();
|
|
490
563
|
const rows = table.getRowModel().rows;
|
|
491
|
-
const scrolls = maxHeight !== void 0 || minWidth !== void 0;
|
|
492
564
|
const pageStickyHeader = !scrolls && stickyHeader === true;
|
|
493
|
-
const containment = useMeasuredContainment(pageStickyHeader);
|
|
565
|
+
const containment = useMeasuredContainment(pageStickyHeader && !projection.cards);
|
|
494
566
|
const resolvedStickyHeaderOffset = scrolls ? void 0 : stickyHeaderOffset;
|
|
567
|
+
const errorNode = queryError !== void 0 && /* @__PURE__ */ jsx(
|
|
568
|
+
ErrorState,
|
|
569
|
+
{
|
|
570
|
+
error: queryError.error,
|
|
571
|
+
title: "Could not load",
|
|
572
|
+
tier: "section",
|
|
573
|
+
retrying: queryError.fetchStatus === "fetching",
|
|
574
|
+
onRetry: () => void queryError.refetch()
|
|
575
|
+
}
|
|
576
|
+
);
|
|
577
|
+
const emptyNode = emptyState ?? /* @__PURE__ */ jsx(Text, { c: "dimmed", ta: "center", size: "sm", py: "sm", children: "No data to display." });
|
|
495
578
|
const tableNode = /* @__PURE__ */ jsxs(
|
|
496
579
|
Table,
|
|
497
580
|
{
|
|
@@ -507,228 +590,245 @@ function BasaltDataTable(props) {
|
|
|
507
590
|
...withRowBorders !== void 0 && { withRowBorders },
|
|
508
591
|
withTableBorder,
|
|
509
592
|
children: [
|
|
510
|
-
/* @__PURE__ */ jsx(Table.Thead, { children: headerGroups.map((headerGroup) => /* @__PURE__ */
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
593
|
+
/* @__PURE__ */ jsx(Table.Thead, { children: headerGroups.map((headerGroup) => /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
594
|
+
hasFolded && /* @__PURE__ */ jsx(Table.Th, { className: classes.foldToggleCell, "aria-hidden": true }),
|
|
595
|
+
headerGroup.headers.map((header) => {
|
|
596
|
+
const canSort = sortingEnabled && header.column.getCanSort();
|
|
597
|
+
const sorted = header.column.getIsSorted();
|
|
598
|
+
const toggleSorting = header.column.getToggleSortingHandler();
|
|
599
|
+
const pinnedStyle = enablePinning ? getPinnedCellStyle(table, header.column) : void 0;
|
|
600
|
+
const align = resolveAlign(header.column);
|
|
601
|
+
const isSelectColumn = header.column.id === SELECT_COLUMN_ID;
|
|
602
|
+
return /* @__PURE__ */ jsxs(
|
|
603
|
+
Table.Th,
|
|
604
|
+
{
|
|
605
|
+
...isSelectColumn && { className: classes.selectCell },
|
|
606
|
+
...!isSelectColumn && { [FOLD_ID_ATTR]: header.column.id },
|
|
607
|
+
onClick: canSort ? toggleSorting : void 0,
|
|
608
|
+
onKeyDown: canSort ? (event) => {
|
|
609
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
610
|
+
event.preventDefault();
|
|
611
|
+
toggleSorting?.(event);
|
|
612
|
+
} : void 0,
|
|
613
|
+
tabIndex: canSort ? 0 : void 0,
|
|
614
|
+
"aria-sort": canSort ? sorted ? ARIA_SORT[sorted] : "none" : void 0,
|
|
615
|
+
style: {
|
|
616
|
+
...canSort ? { cursor: "pointer", userSelect: "none" } : void 0,
|
|
617
|
+
...align !== void 0 && { textAlign: align },
|
|
618
|
+
...pinnedStyle
|
|
619
|
+
},
|
|
620
|
+
children: [
|
|
621
|
+
header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()),
|
|
622
|
+
canSort && /* @__PURE__ */ jsx(SortIndicator, { direction: sorted })
|
|
623
|
+
]
|
|
531
624
|
},
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
header.id
|
|
538
|
-
);
|
|
539
|
-
}) }, headerGroup.id)) }),
|
|
540
|
-
/* @__PURE__ */ jsx(Table.Tbody, { children: queryError !== void 0 ? (
|
|
541
|
-
// The branch the table did not have (components audit #3). It spans every rendered
|
|
542
|
-
// column and carries the query's OWN `refetch` behind Retry, so the failure is reported
|
|
543
|
-
// where the rows would have been — not as an empty table saying nothing failed.
|
|
544
|
-
/* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, { colSpan: columnCount, children: /* @__PURE__ */ jsx(
|
|
545
|
-
ErrorState,
|
|
546
|
-
{
|
|
547
|
-
error: queryError.error,
|
|
548
|
-
title: "Could not load",
|
|
549
|
-
tier: "section",
|
|
550
|
-
retrying: queryError.fetchStatus === "fetching",
|
|
551
|
-
onRetry: () => void queryError.refetch()
|
|
552
|
-
}
|
|
553
|
-
) }) })
|
|
554
|
-
) : showSkeleton ? Array.from({ length: skeletonRows }, (_, rowIndex) => /* @__PURE__ */ jsx(Table.Tr, { children: Array.from({ length: columnCount }, (__, colIndex) => /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Skeleton, { height: 16, radius: "sm" }) }, `skeleton-${rowIndex}-${colIndex}`)) }, `skeleton-${rowIndex}`)) : rows.length === 0 ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, { colSpan: columnCount, children: emptyState ?? /* @__PURE__ */ jsx(Text, { c: "dimmed", ta: "center", size: "sm", py: "sm", children: "No data to display." }) }) }) : rows.map((row) => {
|
|
625
|
+
header.id
|
|
626
|
+
);
|
|
627
|
+
})
|
|
628
|
+
] }, headerGroup.id)) }),
|
|
629
|
+
/* @__PURE__ */ jsx(Table.Tbody, { children: queryError !== void 0 ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, { colSpan: columnCount, children: errorNode }) }) : showSkeleton ? Array.from({ length: skeletonRows }, (_, rowIndex) => /* @__PURE__ */ jsx(Table.Tr, { children: Array.from({ length: columnCount }, (__, colIndex) => /* @__PURE__ */ jsx(Table.Td, { children: /* @__PURE__ */ jsx(Skeleton, { height: 16, radius: "sm" }) }, `skeleton-${rowIndex}-${colIndex}`)) }, `skeleton-${rowIndex}`)) : rows.length === 0 ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, { colSpan: columnCount, children: emptyNode }) }) : rows.map((row) => {
|
|
555
630
|
const cells = enablePinning ? [
|
|
556
631
|
...row.getLeftVisibleCells(),
|
|
557
632
|
...row.getCenterVisibleCells(),
|
|
558
633
|
...row.getRightVisibleCells()
|
|
559
634
|
] : row.getVisibleCells();
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
635
|
+
const rowExpanded = hasFolded && foldRows.expanded.has(row.id);
|
|
636
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
637
|
+
/* @__PURE__ */ jsxs(
|
|
638
|
+
Table.Tr,
|
|
639
|
+
{
|
|
640
|
+
...enableRowSelection && row.getIsSelected() && { "data-selected": true },
|
|
641
|
+
...activationProps(onRowActivate, row.original),
|
|
642
|
+
children: [
|
|
643
|
+
hasFolded && /* @__PURE__ */ jsx(Table.Td, { className: classes.foldToggleCell, children: /* @__PURE__ */ jsx(
|
|
644
|
+
FoldToggle,
|
|
645
|
+
{
|
|
646
|
+
expanded: rowExpanded,
|
|
647
|
+
controlsId: `${row.id}-fold`,
|
|
648
|
+
onToggle: () => foldRows.toggle(row.id)
|
|
649
|
+
}
|
|
650
|
+
) }),
|
|
651
|
+
cells.map((cell) => {
|
|
652
|
+
const pinnedStyle = enablePinning ? getPinnedCellStyle(table, cell.column) : void 0;
|
|
653
|
+
const align = resolveAlign(cell.column);
|
|
654
|
+
return /* @__PURE__ */ jsx(
|
|
655
|
+
Table.Td,
|
|
656
|
+
{
|
|
657
|
+
...cell.column.id === SELECT_COLUMN_ID && {
|
|
658
|
+
className: classes.selectCell,
|
|
659
|
+
// The label's ::after fills the cell, so a tap on it bubbles to the row —
|
|
660
|
+
// stop it only where a tick is possible; a disabled row's tap is a row tap.
|
|
661
|
+
...cell.row.getCanSelect() && {
|
|
662
|
+
onClick: (event) => event.stopPropagation()
|
|
663
|
+
}
|
|
664
|
+
},
|
|
665
|
+
style: {
|
|
666
|
+
...typeof cell.getValue() === "number" && cell.column.columnDef.meta?.numeral !== false ? NUMERIC_CELL_STYLE : void 0,
|
|
667
|
+
...align !== void 0 && { textAlign: align },
|
|
668
|
+
...pinnedStyle
|
|
669
|
+
},
|
|
670
|
+
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
671
|
+
},
|
|
672
|
+
cell.id
|
|
673
|
+
);
|
|
674
|
+
})
|
|
675
|
+
]
|
|
676
|
+
}
|
|
677
|
+
),
|
|
678
|
+
rowExpanded && /* @__PURE__ */ jsx(Table.Tr, { id: `${row.id}-fold`, className: classes.foldDisclosureRowTr, children: /* @__PURE__ */ jsx(Table.Td, { colSpan: columnCount, className: classes.foldDisclosureCell, children: /* @__PURE__ */ jsx(RowDisclosure, { row, folded: columnFold.folded }) }) })
|
|
679
|
+
] }, row.id);
|
|
598
680
|
}) })
|
|
599
681
|
]
|
|
600
682
|
}
|
|
601
683
|
);
|
|
684
|
+
const renderCardList = () => /* @__PURE__ */ jsx(Stack, { gap: "xs", className: cx(classNames?.table), children: queryError !== void 0 ? errorNode : showSkeleton ? Array.from({ length: skeletonRows }, (_, index) => /* @__PURE__ */ jsx(Skeleton, { height: 48, radius: "md" }, `skeleton-${index}`)) : rows.length === 0 ? emptyNode : rows.map((row) => /* @__PURE__ */ jsx(Box, { ...activationProps(onRowActivate, row.original), children: renderCard?.(row.original) }, row.id)) });
|
|
602
685
|
const paginationState = table.getState().pagination;
|
|
603
686
|
const pageSizeRows = [.../* @__PURE__ */ new Set([...pageSizeOptions, paginationState.pageSize])].sort((a, b) => a - b).map((size) => ({ value: String(size), label: `${size} / page` }));
|
|
604
687
|
const total = table.getRowCount();
|
|
605
688
|
const rangeStart = total === 0 ? 0 : paginationState.pageIndex * paginationState.pageSize + 1;
|
|
606
689
|
const rangeEnd = Math.min((paginationState.pageIndex + 1) * paginationState.pageSize, total);
|
|
607
|
-
return /* @__PURE__ */ jsxs(
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
{
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
children: tableNode
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
),
|
|
686
|
-
enablePagination && /* @__PURE__ */ jsxs(
|
|
687
|
-
Group,
|
|
688
|
-
{
|
|
689
|
-
className: cx(classNames?.footer),
|
|
690
|
-
justify: "space-between",
|
|
691
|
-
mt: "xs",
|
|
692
|
-
wrap: "wrap",
|
|
693
|
-
gap: "xs",
|
|
694
|
-
align: "center",
|
|
695
|
-
children: [
|
|
696
|
-
/* @__PURE__ */ jsxs(Text, { style: RANGE_LABEL_STYLE, children: [
|
|
697
|
-
"Showing ",
|
|
698
|
-
rangeStart,
|
|
699
|
-
"\u2013",
|
|
700
|
-
rangeEnd,
|
|
701
|
-
totalIsAuthoritative ? ` of ${total}` : ""
|
|
702
|
-
] }),
|
|
703
|
-
/* @__PURE__ */ jsxs(Group, { gap: "xs", align: "center", children: [
|
|
704
|
-
/* @__PURE__ */ jsx(
|
|
705
|
-
Select,
|
|
706
|
-
{
|
|
707
|
-
size: "ctl",
|
|
708
|
-
radius: "md",
|
|
709
|
-
w: PAGE_SIZE_WIDTH,
|
|
710
|
-
data: pageSizeRows,
|
|
711
|
-
value: String(paginationState.pageSize),
|
|
712
|
-
onChange: (value) => value && table.setPageSize(Number(value)),
|
|
713
|
-
allowDeselect: false
|
|
714
|
-
}
|
|
715
|
-
),
|
|
690
|
+
return /* @__PURE__ */ jsxs(
|
|
691
|
+
"div",
|
|
692
|
+
{
|
|
693
|
+
ref: projection.rootRef,
|
|
694
|
+
className: cx(classNames?.root, className),
|
|
695
|
+
...style !== void 0 && { style },
|
|
696
|
+
children: [
|
|
697
|
+
(title !== void 0 || showToolbar) && /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", wrap: "wrap", gap: "xs", mb: "xs", children: [
|
|
698
|
+
title !== void 0 ? /* @__PURE__ */ jsx(Box, { style: TABLE_HEADER_LEAD_STYLE, children: /* @__PURE__ */ jsx(
|
|
699
|
+
WidgetHeader,
|
|
700
|
+
{
|
|
701
|
+
tier: "widget",
|
|
702
|
+
title,
|
|
703
|
+
...icon !== void 0 && { icon },
|
|
704
|
+
...subtitle !== void 0 && { subtitle },
|
|
705
|
+
count: table.getRowCount()
|
|
706
|
+
}
|
|
707
|
+
) }) : null,
|
|
708
|
+
showToolbar && /* @__PURE__ */ jsx(CtlSlot, { children: /* @__PURE__ */ jsxs(
|
|
709
|
+
Group,
|
|
710
|
+
{
|
|
711
|
+
className: cx(classNames?.toolbar),
|
|
712
|
+
gap: "xs",
|
|
713
|
+
wrap: "wrap",
|
|
714
|
+
align: "center",
|
|
715
|
+
style: TABLE_TOOLBAR_STYLE,
|
|
716
|
+
children: [
|
|
717
|
+
showSearch && /* @__PURE__ */ jsx(
|
|
718
|
+
TextInput,
|
|
719
|
+
{
|
|
720
|
+
radius: "md",
|
|
721
|
+
style: TABLE_SEARCH_STYLE,
|
|
722
|
+
placeholder: globalFilterPlaceholder,
|
|
723
|
+
leftSection: searchIcon,
|
|
724
|
+
value: globalFilter,
|
|
725
|
+
onChange: (event) => handleGlobalFilterChange(event.currentTarget.value)
|
|
726
|
+
}
|
|
727
|
+
),
|
|
728
|
+
showFacets && /* @__PURE__ */ jsx(FilterSet, { children: facets?.map((facet) => {
|
|
729
|
+
const column = resolveFacetColumn(table, facet);
|
|
730
|
+
if (!column) return null;
|
|
731
|
+
return facet.multiple ? /* @__PURE__ */ jsx(
|
|
732
|
+
MultiSelectFilter,
|
|
733
|
+
{
|
|
734
|
+
field: facetMultiHandle(column, facet),
|
|
735
|
+
label: facet.label
|
|
736
|
+
},
|
|
737
|
+
facet.columnId
|
|
738
|
+
) : /* @__PURE__ */ jsx(
|
|
739
|
+
EnumFilter,
|
|
740
|
+
{
|
|
741
|
+
field: facetEnumHandle(column, facet),
|
|
742
|
+
label: facet.label
|
|
743
|
+
},
|
|
744
|
+
facet.columnId
|
|
745
|
+
);
|
|
746
|
+
}) }),
|
|
747
|
+
actions !== void 0 && /* @__PURE__ */ jsx(BarActionSlot, { actions })
|
|
748
|
+
]
|
|
749
|
+
}
|
|
750
|
+
) })
|
|
751
|
+
] }),
|
|
752
|
+
bulkBarActions !== void 0 && /* @__PURE__ */ jsx(BulkActionBar, { count: selectedRows.length, actions: bulkBarActions }),
|
|
753
|
+
projection.cards ? maxHeight === void 0 ? renderCardList() : /* @__PURE__ */ jsx(ScrollArea.Autosize, { mah: maxHeight, type: "hover", scrollbars: "y", children: renderCardList() }) : !foldEligible ? (
|
|
754
|
+
// An explicit `minWidth` is the one genuinely DECLARED horizontal floor — the column fold
|
|
755
|
+
// never engages here (see `foldEligible`, above), so this shape keeps its exact
|
|
756
|
+
// pre-existing DOM: no extra measuring wrapper for a table nothing folds.
|
|
757
|
+
/* @__PURE__ */ jsx(Table.ScrollContainer, { type: "native", minWidth: minWidth ?? 0, maxHeight, children: tableNode })
|
|
758
|
+
) : (
|
|
759
|
+
// The column fold's own measuring box (`useColumnFold`) — wraps every remaining shape,
|
|
760
|
+
// `maxHeight`-only included: a vertical cap is orthogonal to column width, so a
|
|
761
|
+
// `stickyHeader` + `maxHeight` table (the pairing this package's own docs recommend) still
|
|
762
|
+
// folds instead of silently regressing to horizontal scroll. A plain block box, so it
|
|
763
|
+
// constrains nothing on its own; `columnFold.wrapperRef` only reads it.
|
|
764
|
+
/* @__PURE__ */ jsx("div", { ref: columnFold.wrapperRef, className: classes.foldWrapper, children: pageStickyHeader ? (
|
|
765
|
+
// Pinning takes this wrapper too — a pinned column's offsets are `position: sticky` on
|
|
766
|
+
// the cells and need no overflow box of their own, so the `overflow-x: auto` Box that
|
|
767
|
+
// used to sit here was the exact inert-sticky defect this shape exists to avoid.
|
|
716
768
|
/* @__PURE__ */ jsx(
|
|
717
|
-
|
|
769
|
+
"div",
|
|
718
770
|
{
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
onChange: (page) => table.setPageIndex(page - 1)
|
|
771
|
+
ref: containment.wrapperRef,
|
|
772
|
+
className: classes.containment,
|
|
773
|
+
"data-contained": containment.contained ? "true" : "false",
|
|
774
|
+
children: tableNode
|
|
724
775
|
}
|
|
725
776
|
)
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
777
|
+
) : (
|
|
778
|
+
// `pageStickyHeader` is false whenever `maxHeight` is set (`scrolls` above), so a vertical
|
|
779
|
+
// cap lands here — its own `ScrollArea` scrollport, just with no `minWidth` floor.
|
|
780
|
+
/* @__PURE__ */ jsx(Table.ScrollContainer, { type: "native", minWidth: 0, maxHeight, children: tableNode })
|
|
781
|
+
) })
|
|
782
|
+
),
|
|
783
|
+
enablePagination && /* @__PURE__ */ jsxs(
|
|
784
|
+
Group,
|
|
785
|
+
{
|
|
786
|
+
className: cx(classNames?.footer),
|
|
787
|
+
justify: "space-between",
|
|
788
|
+
mt: "xs",
|
|
789
|
+
wrap: "wrap",
|
|
790
|
+
gap: "xs",
|
|
791
|
+
align: "center",
|
|
792
|
+
children: [
|
|
793
|
+
/* @__PURE__ */ jsxs(Text, { style: RANGE_LABEL_STYLE, children: [
|
|
794
|
+
"Showing ",
|
|
795
|
+
rangeStart,
|
|
796
|
+
"\u2013",
|
|
797
|
+
rangeEnd,
|
|
798
|
+
totalIsAuthoritative ? ` of ${total}` : ""
|
|
799
|
+
] }),
|
|
800
|
+
/* @__PURE__ */ jsxs(Group, { gap: "xs", align: "center", children: [
|
|
801
|
+
/* @__PURE__ */ jsx(
|
|
802
|
+
Select,
|
|
803
|
+
{
|
|
804
|
+
size: "ctl",
|
|
805
|
+
radius: "md",
|
|
806
|
+
w: PAGE_SIZE_WIDTH,
|
|
807
|
+
data: pageSizeRows,
|
|
808
|
+
value: String(paginationState.pageSize),
|
|
809
|
+
onChange: (value) => value && table.setPageSize(Number(value)),
|
|
810
|
+
allowDeselect: false
|
|
811
|
+
}
|
|
812
|
+
),
|
|
813
|
+
/* @__PURE__ */ jsx(CtlSlot, { children: /* @__PURE__ */ jsx(
|
|
814
|
+
Pagination,
|
|
815
|
+
{
|
|
816
|
+
size: "sm",
|
|
817
|
+
radius: "md",
|
|
818
|
+
total: Math.max(table.getPageCount(), 1),
|
|
819
|
+
value: paginationState.pageIndex + 1,
|
|
820
|
+
onChange: (page) => table.setPageIndex(page - 1)
|
|
821
|
+
}
|
|
822
|
+
) })
|
|
823
|
+
] })
|
|
824
|
+
]
|
|
825
|
+
}
|
|
826
|
+
)
|
|
827
|
+
]
|
|
828
|
+
}
|
|
829
|
+
);
|
|
731
830
|
}
|
|
732
831
|
export {
|
|
733
|
-
BasaltDataTable
|
|
832
|
+
BasaltDataTable,
|
|
833
|
+
planColumnFold
|
|
734
834
|
};
|