basalt-ui 1.31.0 → 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.
Files changed (91) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/MIGRATING.md +101 -17
  3. package/agent/rules/basalt-mantine.md +4 -4
  4. package/configs/oxlint-plugin.js +159 -42
  5. package/configs/oxlint-plugin.test.ts +182 -0
  6. package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
  7. package/dist/charts/kinds/BandStrip.js +18 -66
  8. package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
  9. package/dist/charts/kinds/DualPanel.js +5 -26
  10. package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
  11. package/dist/charts/kinds/MirroredBars.js +10 -68
  12. package/dist/charts/kinds/band-chrome.d.ts +31 -0
  13. package/dist/charts/kinds/band-chrome.d.ts.map +1 -0
  14. package/dist/charts/kinds/band-chrome.js +71 -0
  15. package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
  16. package/dist/charts/primitives/CartesianChart.js +49 -76
  17. package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
  18. package/dist/charts/primitives/ChartCard.js +5 -23
  19. package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
  20. package/dist/charts/primitives/ChartFrame.js +23 -40
  21. package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
  22. package/dist/charts/primitives/ChartLegend.js +5 -133
  23. package/dist/charts/primitives/ChartTooltip.d.ts +5 -0
  24. package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
  25. package/dist/charts/primitives/ChartTooltip.js +16 -1
  26. package/dist/charts/primitives/HoverOverlay.d.ts +24 -9
  27. package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
  28. package/dist/charts/primitives/HoverOverlay.js +17 -1
  29. package/dist/charts/primitives/chart-card-context.d.ts +17 -13
  30. package/dist/charts/primitives/chart-card-context.d.ts.map +1 -1
  31. package/dist/charts/primitives/chart-card-context.js +10 -5
  32. package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -1
  33. package/dist/charts/primitives/chart-frame-layout.js +25 -31
  34. package/dist/charts/primitives/legend-disclosure.d.ts +27 -0
  35. package/dist/charts/primitives/legend-disclosure.d.ts.map +1 -0
  36. package/dist/charts/primitives/legend-disclosure.js +153 -0
  37. package/dist/controls/controls.module.css +5 -0
  38. package/dist/controls/sync-button.module.css +1 -0
  39. package/dist/dashboard/stat-group.module.css +19 -64
  40. package/dist/dashboard/widget-grid.module.css +11 -38
  41. package/dist/data/data-table-state.d.ts +83 -0
  42. package/dist/data/data-table-state.d.ts.map +1 -0
  43. package/dist/data/data-table-state.js +139 -0
  44. package/dist/data/data-table.d.ts +33 -2
  45. package/dist/data/data-table.d.ts.map +1 -1
  46. package/dist/data/data-table.js +179 -277
  47. package/dist/forms/form-layout.module.css +3 -13
  48. package/dist/guard/index.d.ts.map +1 -1
  49. package/dist/guard/index.js +6 -5
  50. package/dist/notifications/center.d.ts.map +1 -1
  51. package/dist/provider/index.d.ts.map +1 -1
  52. package/dist/provider/index.js +12 -10
  53. package/dist/shell/aside-docking.d.ts +31 -0
  54. package/dist/shell/aside-docking.d.ts.map +1 -0
  55. package/dist/shell/aside-docking.js +19 -0
  56. package/dist/shell/index.d.ts +0 -11
  57. package/dist/shell/index.d.ts.map +1 -1
  58. package/dist/shell/index.js +13 -14
  59. package/dist/shell/use-breakpoint.d.ts +1 -1
  60. package/dist/theme/floating.module.css +1 -0
  61. package/dist/theme-lab/derive-controls.d.ts.map +1 -1
  62. package/llms.txt +2 -2
  63. package/package.json +2 -1
  64. package/src/charts/kinds/BandStrip.tsx +18 -64
  65. package/src/charts/kinds/DualPanel.tsx +4 -24
  66. package/src/charts/kinds/MirroredBars.tsx +12 -66
  67. package/src/charts/kinds/band-chrome.tsx +91 -0
  68. package/src/charts/primitives/CartesianChart.tsx +79 -122
  69. package/src/charts/primitives/ChartCard.tsx +5 -27
  70. package/src/charts/primitives/ChartFrame.tsx +37 -76
  71. package/src/charts/primitives/ChartLegend.tsx +7 -154
  72. package/src/charts/primitives/ChartTooltip.tsx +16 -0
  73. package/src/charts/primitives/HoverOverlay.tsx +52 -21
  74. package/src/charts/primitives/chart-card-context.ts +25 -16
  75. package/src/charts/primitives/chart-frame-layout.ts +44 -56
  76. package/src/charts/primitives/legend-disclosure.tsx +177 -0
  77. package/src/controls/controls.module.css +5 -0
  78. package/src/controls/sync-button.module.css +1 -0
  79. package/src/dashboard/stat-group.module.css +19 -64
  80. package/src/dashboard/widget-grid.module.css +11 -38
  81. package/src/data/data-table-state.ts +218 -0
  82. package/src/data/data-table.tsx +127 -218
  83. package/src/forms/form-layout.module.css +3 -13
  84. package/src/guard/index.ts +21 -16
  85. package/src/notifications/center.tsx +3 -0
  86. package/src/provider/index.tsx +18 -17
  87. package/src/shell/aside-docking.ts +54 -0
  88. package/src/shell/index.tsx +15 -37
  89. package/src/shell/use-breakpoint.ts +2 -2
  90. package/src/theme/floating.module.css +1 -0
  91. package/src/theme-lab/derive-controls.tsx +2 -0
@@ -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,7 +20,7 @@ import {
18
20
  getSortedRowModel,
19
21
  useReactTable
20
22
  } from "@tanstack/react-table";
21
- import { Fragment, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
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";
24
26
  import { HIT_COARSE } from "../common/hit-floor.js";
@@ -32,6 +34,13 @@ import { CtlSlot } from "../theme/index.js";
32
34
  import { alpha, VX } from "../tokens/index.js";
33
35
  import { WidgetHeader } from "../dashboard/index.js";
34
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";
35
44
  import { dataQueryBranch } from "./query-branch.js";
36
45
  import { isDev } from "../common/is-dev.js";
37
46
  import classes from "./data-table.module.css";
@@ -149,6 +158,7 @@ function SortIndicator({ direction }) {
149
158
  if (!direction) return null;
150
159
  return /* @__PURE__ */ jsx(Box, { component: "span", ml: 4, "aria-hidden": true, children: direction === "asc" ? "\u2191" : "\u2193" });
151
160
  }
161
+ const ARIA_SORT = { asc: "ascending", desc: "descending" };
152
162
  const NUMERIC_CELL_STYLE = {
153
163
  fontFamily: "var(--mantine-font-family-monospace)",
154
164
  fontSize: VX.text.sm,
@@ -222,7 +232,6 @@ function foldOrder(columns) {
222
232
  ).toSorted((a, b) => b.priority - a.priority || b.index - a.index).map((candidate) => candidate.id);
223
233
  }
224
234
  const FOLD_ID_ATTR = "data-basalt-fold-id";
225
- const EMPTY_FOLD_SET = /* @__PURE__ */ new Set();
226
235
  function planColumnFold(input) {
227
236
  const { room, toggleWidth, overhead, order, widths } = input;
228
237
  const known = order.filter((id) => widths.has(id));
@@ -385,32 +394,23 @@ function BasaltDataTable(props) {
385
394
  isLoading = false,
386
395
  query,
387
396
  skeletonRows = 5,
388
- initialSorting,
389
- onSortingChange,
390
397
  enableGlobalFilter = false,
391
398
  globalFilterPlaceholder = "Search\u2026",
392
399
  searchIcon,
393
- initialGlobalFilter,
394
- onGlobalFilterChange,
395
400
  facets,
396
- onColumnFiltersChange,
397
401
  manualFiltering = false,
398
402
  actions,
399
403
  onRowActivate,
404
+ renderCard,
400
405
  enableRowSelection = false,
401
- rowSelection,
402
- onRowSelectionChange,
403
406
  getRowId,
404
407
  bulkActions,
405
408
  enablePagination = false,
406
409
  pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
407
- initialPagination,
408
- onPaginationChange,
409
410
  manualPagination = false,
410
411
  rowCount,
411
412
  pageCount,
412
413
  enablePinning = false,
413
- initialColumnPinning,
414
414
  maxHeight,
415
415
  minWidth,
416
416
  stickyHeader,
@@ -423,15 +423,8 @@ function BasaltDataTable(props) {
423
423
  style,
424
424
  classNames
425
425
  } = props;
426
- const [sorting, setSorting] = useState(initialSorting ?? []);
427
- const [globalFilter, setGlobalFilter] = useState(initialGlobalFilter ?? "");
428
- const [columnFilters, setColumnFilters] = useState([]);
429
- const [pagination, setPagination] = useState(
430
- initialPagination ?? { pageIndex: 0, pageSize: pageSizeOptions[0] ?? 10 }
431
- );
432
- const [columnPinning, setColumnPinning] = useState(initialColumnPinning ?? {});
433
- const [internalRowSelection, setInternalRowSelection] = useState({});
434
- const rowSelectionState = rowSelection ?? internalRowSelection;
426
+ const tableState = useDataTableState(props, pageSizeOptions[0] ?? 10);
427
+ const { globalFilter, columnPinning, onGlobalFilterChange: handleGlobalFilterChange } = tableState;
435
428
  useValidateProps(
436
429
  "BasaltDataTable",
437
430
  () => [
@@ -448,60 +441,6 @@ function BasaltDataTable(props) {
448
441
  props.isLoading === void 0
449
442
  ]
450
443
  );
451
- const handleSortingChange = useCallback(
452
- (updater) => {
453
- setSorting((prev) => {
454
- const next = typeof updater === "function" ? updater(prev) : updater;
455
- onSortingChange?.(next);
456
- return next;
457
- });
458
- },
459
- [onSortingChange]
460
- );
461
- const handleGlobalFilterChange = useCallback(
462
- (updater) => {
463
- setGlobalFilter((prev) => {
464
- const next = typeof updater === "function" ? updater(prev) : updater;
465
- onGlobalFilterChange?.(next);
466
- return next;
467
- });
468
- },
469
- [onGlobalFilterChange]
470
- );
471
- const handleColumnFiltersChange = useCallback(
472
- (updater) => {
473
- setColumnFilters((prev) => {
474
- const next = typeof updater === "function" ? updater(prev) : updater;
475
- onColumnFiltersChange?.(next);
476
- return next;
477
- });
478
- },
479
- [onColumnFiltersChange]
480
- );
481
- const handlePaginationChange = useCallback(
482
- (updater) => {
483
- setPagination((prev) => {
484
- const next = typeof updater === "function" ? updater(prev) : updater;
485
- onPaginationChange?.(next);
486
- return next;
487
- });
488
- },
489
- [onPaginationChange]
490
- );
491
- const handleRowSelectionChange = useCallback(
492
- (updater) => {
493
- if (rowSelection !== void 0) {
494
- onRowSelectionChange?.(typeof updater === "function" ? updater(rowSelection) : updater);
495
- return;
496
- }
497
- setInternalRowSelection((prev) => {
498
- const next = typeof updater === "function" ? updater(prev) : updater;
499
- onRowSelectionChange?.(next);
500
- return next;
501
- });
502
- },
503
- [rowSelection, onRowSelectionChange]
504
- );
505
444
  const facetColumns = useMemo(() => {
506
445
  if (!facets || facets.length === 0) return columns;
507
446
  const facetById = new Map(facets.map((facet) => [facet.columnId, facet]));
@@ -551,8 +490,9 @@ function BasaltDataTable(props) {
551
490
  columnFoldFixedIds: [...excluded]
552
491
  };
553
492
  }, [columns, columnPinning]);
493
+ const projection = useCardProjection(renderCard !== void 0);
554
494
  const columnFold = useColumnFold({
555
- active: foldEligible,
495
+ active: foldEligible && !projection.cards,
556
496
  order: columnFoldOrder,
557
497
  fixedIds: columnFoldFixedIds
558
498
  });
@@ -561,56 +501,27 @@ function BasaltDataTable(props) {
561
501
  [columnFold.folded]
562
502
  );
563
503
  const hasFolded = columnFold.folded.size > 0;
564
- const [expandedFoldRows, setExpandedFoldRows] = useState(EMPTY_FOLD_SET);
565
- const toggleFoldRow = useCallback((rowId) => {
566
- setExpandedFoldRows((current) => {
567
- const next = new Set(current);
568
- if (next.has(rowId)) next.delete(rowId);
569
- else next.add(rowId);
570
- return next;
571
- });
572
- }, []);
573
- const prevDataRef = useRef(data);
574
- useEffect(() => {
575
- const prevData = prevDataRef.current;
576
- prevDataRef.current = data;
577
- setExpandedFoldRows((current) => {
578
- if (current.size === 0) return current;
579
- let next;
580
- if (getRowId === void 0) {
581
- next = new Set(
582
- [...current].filter((id) => {
583
- const index = Number(id);
584
- return data[index] !== void 0 && data[index] === prevData[index];
585
- })
586
- );
587
- } else {
588
- const liveIds = new Set(data.map((row, index) => getRowId(row, index)));
589
- next = new Set([...current].filter((id) => liveIds.has(id)));
590
- }
591
- return next.size === current.size ? current : next;
592
- });
593
- }, [data, getRowId]);
504
+ const foldRows = useRowDisclosure({ data, getRowId });
594
505
  const table = useReactTable({
595
506
  data,
596
507
  columns: tableColumns,
597
508
  state: {
598
- sorting,
509
+ sorting: tableState.sorting,
599
510
  globalFilter,
600
- columnFilters,
511
+ columnFilters: tableState.columnFilters,
601
512
  columnPinning,
602
513
  columnVisibility,
603
- ...enablePagination && { pagination },
604
- ...enableRowSelection && { rowSelection: rowSelectionState }
514
+ ...enablePagination && { pagination: tableState.pagination },
515
+ ...enableRowSelection && { rowSelection: tableState.rowSelection }
605
516
  },
606
- onSortingChange: handleSortingChange,
517
+ onSortingChange: tableState.onSortingChange,
607
518
  onGlobalFilterChange: handleGlobalFilterChange,
608
- onColumnFiltersChange: handleColumnFiltersChange,
609
- onColumnPinningChange: setColumnPinning,
610
- ...enablePagination && { onPaginationChange: handlePaginationChange },
519
+ onColumnFiltersChange: tableState.onColumnFiltersChange,
520
+ onColumnPinningChange: tableState.onColumnPinningChange,
521
+ ...enablePagination && { onPaginationChange: tableState.onPaginationChange },
611
522
  ...enableRowSelection && {
612
523
  enableRowSelection: true,
613
- onRowSelectionChange: handleRowSelectionChange
524
+ onRowSelectionChange: tableState.onRowSelectionChange
614
525
  },
615
526
  ...getRowId !== void 0 && { getRowId },
616
527
  getCoreRowModel: getCoreRowModel(),
@@ -651,8 +562,19 @@ function BasaltDataTable(props) {
651
562
  const headerGroups = enablePinning ? getOrderedHeaderGroups(table) : table.getHeaderGroups();
652
563
  const rows = table.getRowModel().rows;
653
564
  const pageStickyHeader = !scrolls && stickyHeader === true;
654
- const containment = useMeasuredContainment(pageStickyHeader);
565
+ const containment = useMeasuredContainment(pageStickyHeader && !projection.cards);
655
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." });
656
578
  const tableNode = /* @__PURE__ */ jsxs(
657
579
  Table,
658
580
  {
@@ -689,7 +611,7 @@ function BasaltDataTable(props) {
689
611
  toggleSorting?.(event);
690
612
  } : void 0,
691
613
  tabIndex: canSort ? 0 : void 0,
692
- "aria-sort": canSort ? sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : "none" : void 0,
614
+ "aria-sort": canSort ? sorted ? ARIA_SORT[sorted] : "none" : void 0,
693
615
  style: {
694
616
  ...canSort ? { cursor: "pointer", userSelect: "none" } : void 0,
695
617
  ...align !== void 0 && { textAlign: align },
@@ -704,54 +626,26 @@ function BasaltDataTable(props) {
704
626
  );
705
627
  })
706
628
  ] }, headerGroup.id)) }),
707
- /* @__PURE__ */ jsx(Table.Tbody, { children: queryError !== void 0 ? (
708
- // The branch the table did not have (components audit #3). It spans every rendered
709
- // column and carries the query's OWN `refetch` behind Retry, so the failure is reported
710
- // where the rows would have been — not as an empty table saying nothing failed.
711
- /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, { colSpan: columnCount, children: /* @__PURE__ */ jsx(
712
- ErrorState,
713
- {
714
- error: queryError.error,
715
- title: "Could not load",
716
- tier: "section",
717
- retrying: queryError.fetchStatus === "fetching",
718
- onRetry: () => void queryError.refetch()
719
- }
720
- ) }) })
721
- ) : 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) => {
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) => {
722
630
  const cells = enablePinning ? [
723
631
  ...row.getLeftVisibleCells(),
724
632
  ...row.getCenterVisibleCells(),
725
633
  ...row.getRightVisibleCells()
726
634
  ] : row.getVisibleCells();
727
- const rowExpanded = hasFolded && expandedFoldRows.has(row.id);
635
+ const rowExpanded = hasFolded && foldRows.expanded.has(row.id);
728
636
  return /* @__PURE__ */ jsxs(Fragment, { children: [
729
637
  /* @__PURE__ */ jsxs(
730
638
  Table.Tr,
731
639
  {
732
640
  ...enableRowSelection && row.getIsSelected() && { "data-selected": true },
733
- ...onRowActivate !== void 0 && {
734
- className: classes.activatable,
735
- "data-activatable": true,
736
- tabIndex: 0,
737
- onClick: () => onRowActivate(row.original),
738
- // Enter only. Space is the browser's own page-scroll on a focused non-button, and
739
- // stealing it from a keyboard reader moving down a long table costs more than the
740
- // second activation key buys.
741
- onKeyDown: (event) => {
742
- if (event.key !== "Enter") return;
743
- if (event.target !== event.currentTarget) return;
744
- event.preventDefault();
745
- onRowActivate(row.original);
746
- }
747
- },
641
+ ...activationProps(onRowActivate, row.original),
748
642
  children: [
749
643
  hasFolded && /* @__PURE__ */ jsx(Table.Td, { className: classes.foldToggleCell, children: /* @__PURE__ */ jsx(
750
644
  FoldToggle,
751
645
  {
752
646
  expanded: rowExpanded,
753
647
  controlsId: `${row.id}-fold`,
754
- onToggle: () => toggleFoldRow(row.id)
648
+ onToggle: () => foldRows.toggle(row.id)
755
649
  }
756
650
  ) }),
757
651
  cells.map((cell) => {
@@ -787,144 +681,152 @@ function BasaltDataTable(props) {
787
681
  ]
788
682
  }
789
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)) });
790
685
  const paginationState = table.getState().pagination;
791
686
  const pageSizeRows = [.../* @__PURE__ */ new Set([...pageSizeOptions, paginationState.pageSize])].sort((a, b) => a - b).map((size) => ({ value: String(size), label: `${size} / page` }));
792
687
  const total = table.getRowCount();
793
688
  const rangeStart = total === 0 ? 0 : paginationState.pageIndex * paginationState.pageSize + 1;
794
689
  const rangeEnd = Math.min((paginationState.pageIndex + 1) * paginationState.pageSize, total);
795
- return /* @__PURE__ */ jsxs("div", { className: cx(classNames?.root, className), ...style !== void 0 && { style }, children: [
796
- (title !== void 0 || showToolbar) && /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "center", wrap: "wrap", gap: "xs", mb: "xs", children: [
797
- title !== void 0 ? /* @__PURE__ */ jsx(Box, { style: TABLE_HEADER_LEAD_STYLE, children: /* @__PURE__ */ jsx(
798
- WidgetHeader,
799
- {
800
- tier: "widget",
801
- title,
802
- ...icon !== void 0 && { icon },
803
- ...subtitle !== void 0 && { subtitle },
804
- count: table.getRowCount()
805
- }
806
- ) }) : null,
807
- showToolbar && /* @__PURE__ */ jsx(CtlSlot, { children: /* @__PURE__ */ jsxs(
808
- Group,
809
- {
810
- className: cx(classNames?.toolbar),
811
- gap: "xs",
812
- wrap: "wrap",
813
- align: "center",
814
- style: TABLE_TOOLBAR_STYLE,
815
- children: [
816
- showSearch && /* @__PURE__ */ jsx(
817
- TextInput,
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.
768
+ /* @__PURE__ */ jsx(
769
+ "div",
818
770
  {
819
- radius: "md",
820
- style: TABLE_SEARCH_STYLE,
821
- placeholder: globalFilterPlaceholder,
822
- leftSection: searchIcon,
823
- value: globalFilter,
824
- onChange: (event) => handleGlobalFilterChange(event.currentTarget.value)
771
+ ref: containment.wrapperRef,
772
+ className: classes.containment,
773
+ "data-contained": containment.contained ? "true" : "false",
774
+ children: tableNode
825
775
  }
826
- ),
827
- showFacets && /* @__PURE__ */ jsx(FilterSet, { children: facets?.map((facet) => {
828
- const column = resolveFacetColumn(table, facet);
829
- if (!column) return null;
830
- return facet.multiple ? /* @__PURE__ */ jsx(
831
- MultiSelectFilter,
832
- {
833
- field: facetMultiHandle(column, facet),
834
- label: facet.label
835
- },
836
- facet.columnId
837
- ) : /* @__PURE__ */ jsx(
838
- EnumFilter,
839
- {
840
- field: facetEnumHandle(column, facet),
841
- label: facet.label
842
- },
843
- facet.columnId
844
- );
845
- }) }),
846
- actions !== void 0 && /* @__PURE__ */ jsx(BarActionSlot, { actions })
847
- ]
848
- }
849
- ) })
850
- ] }),
851
- bulkBarActions !== void 0 && /* @__PURE__ */ jsx(BulkActionBar, { count: selectedRows.length, actions: bulkBarActions }),
852
- !foldEligible ? (
853
- // An explicit `minWidth` is the one genuinely DECLARED horizontal floor — the column fold
854
- // never engages here (see `foldEligible`, above), so this shape keeps its exact
855
- // pre-existing DOM: no extra measuring wrapper for a table nothing folds.
856
- /* @__PURE__ */ jsx(Table.ScrollContainer, { type: "native", minWidth: minWidth ?? 0, maxHeight, children: tableNode })
857
- ) : (
858
- // The column fold's own measuring box (`useColumnFold`) — wraps every remaining shape,
859
- // `maxHeight`-only included: a vertical cap is orthogonal to column width, so a
860
- // `stickyHeader` + `maxHeight` table (the pairing this package's own docs recommend) still
861
- // folds instead of silently regressing to horizontal scroll. A plain block box, so it
862
- // constrains nothing on its own; `columnFold.wrapperRef` only reads it.
863
- /* @__PURE__ */ jsx("div", { ref: columnFold.wrapperRef, className: classes.foldWrapper, children: pageStickyHeader ? (
864
- // Pinning takes this wrapper too — a pinned column's offsets are `position: sticky` on
865
- // the cells and need no overflow box of their own, so the `overflow-x: auto` Box that
866
- // used to sit here was the exact inert-sticky defect this shape exists to avoid.
867
- /* @__PURE__ */ jsx(
868
- "div",
776
+ )
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,
869
785
  {
870
- ref: containment.wrapperRef,
871
- className: classes.containment,
872
- "data-contained": containment.contained ? "true" : "false",
873
- children: tableNode
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
+ ]
874
825
  }
875
826
  )
876
- ) : maxHeight !== void 0 ? (
877
- // `pageStickyHeader` is already false whenever `maxHeight` is set (`scrolls` above), so
878
- // this is the ONE remaining case: a vertical cap with no sticky header to measure —
879
- // still wants its own `ScrollArea` scrollport, just with no `minWidth` floor.
880
- /* @__PURE__ */ jsx(Table.ScrollContainer, { type: "native", minWidth: 0, maxHeight, children: tableNode })
881
- ) : /* @__PURE__ */ jsx(Table.ScrollContainer, { type: "native", minWidth: 0, children: tableNode }) })
882
- ),
883
- enablePagination && /* @__PURE__ */ jsxs(
884
- Group,
885
- {
886
- className: cx(classNames?.footer),
887
- justify: "space-between",
888
- mt: "xs",
889
- wrap: "wrap",
890
- gap: "xs",
891
- align: "center",
892
- children: [
893
- /* @__PURE__ */ jsxs(Text, { style: RANGE_LABEL_STYLE, children: [
894
- "Showing ",
895
- rangeStart,
896
- "\u2013",
897
- rangeEnd,
898
- totalIsAuthoritative ? ` of ${total}` : ""
899
- ] }),
900
- /* @__PURE__ */ jsxs(Group, { gap: "xs", align: "center", children: [
901
- /* @__PURE__ */ jsx(
902
- Select,
903
- {
904
- size: "ctl",
905
- radius: "md",
906
- w: PAGE_SIZE_WIDTH,
907
- data: pageSizeRows,
908
- value: String(paginationState.pageSize),
909
- onChange: (value) => value && table.setPageSize(Number(value)),
910
- allowDeselect: false
911
- }
912
- ),
913
- /* @__PURE__ */ jsx(CtlSlot, { children: /* @__PURE__ */ jsx(
914
- Pagination,
915
- {
916
- size: "sm",
917
- radius: "md",
918
- total: Math.max(table.getPageCount(), 1),
919
- value: paginationState.pageIndex + 1,
920
- onChange: (page) => table.setPageIndex(page - 1)
921
- }
922
- ) })
923
- ] })
924
- ]
925
- }
926
- )
927
- ] });
827
+ ]
828
+ }
829
+ );
928
830
  }
929
831
  export {
930
832
  BasaltDataTable,
@@ -14,9 +14,10 @@
14
14
  * containment and `.grid` is the queried child, the same split `StatGroup`'s `.container`/`.root`
15
15
  * uses — a container cannot reliably query ITSELF for a layout-affecting property (measured here:
16
16
  * Chrome silently keeps the un-queried value even once the container's own width crosses the
17
- * condition), only a descendant. The `599.9px`/`47.99375em` literals: 600px is roughly the point
17
+ * condition), only a descendant. The `599.9px` literal: 600px is roughly the point
18
18
  * two ~250px+ cells stop feeling cramped; `@container`/`@media` conditions cannot read a custom
19
- * property, so both are written numbers, not `--vx-*` refs.
19
+ * property, so it is a written number, not a `--vx-*` ref. No viewport fallback — see
20
+ * `stat-group.module.css`: nothing that renders basalt lacks `@container`.
20
21
  */
21
22
 
22
23
  /* ── FormSection ─────────────────────────────────────────────────────────────────────────────── */
@@ -102,17 +103,6 @@
102
103
  }
103
104
  }
104
105
 
105
- /* Pre-container-query fallback (Safari < 16, Chrome < 106, Firefox < 110) — the old viewport law,
106
- * reachable only where `@container` itself cannot parse (same reasoning as `stat-group.module.css`). */
107
- @supports not (container-type: inline-size) {
108
- @media (max-width: 47.99375em) {
109
- .grid {
110
- grid-template-columns: minmax(0, 1fr);
111
- gap: var(--vx-space-stack-xs);
112
- }
113
- }
114
- }
115
-
116
106
  /* ── FormGroup ───────────────────────────────────────────────────────────────────────────────── */
117
107
 
118
108
  /* Same UA reset as `.control`, same reason. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guard/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/guard/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE7E,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,CAAA;AAkxB9D,8EAA8E;AAC9E,eAAO,MAAM,oBAAoB,EAAE,WAmBlC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAExE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,eAAO,MAAM,kBAAkB,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,CAkCrE,CAAA;AA0GD,sGAAsG;AACtG,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,UAAU,CAAA;CAC7C,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,WAAW,EAChB,eAAe,EAAE,SAAS,MAAM,EAAE,GACjC,sBAAsB,EAAE,CAc1B;AAID;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CA0D9C,CAAA;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAGzE,CAAA;AAieD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,gGACwD,CAAA;AA8F1F;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,EAAE,WAAW,CAAC,SAAS,CAyB5D,CAAA;AA2NF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;gCA0BL,WAAW;;;;;;;gCAcX,WAAW;;;;;gCAMX,WAAW;;;;;;;gCAaX,WAAW;;;;;;;gCAQX,WAAW;;;;;;gCAOX,WAAW;;;;;;;gCASX,WAAW;;;;;;gCAOX,WAAW;;;;;;;gCAaX,WAAW;;;;;;gCAMX,WAAW;;;;;;;gCAaX,WAAW;;;;;;;gCAUX,WAAW;;;;;;;gCAUX,WAAW;;;;;;;gCASX,WAAW;;;;;;;gCAUX,WAAW;;;;;;;;;;;;gCAgBX,WAAW;;;;;;gCAOX,WAAW;;;;;;;gCASX,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCmB,CAAA;AAEjD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAEvD;AAKD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAgBvD;AAUD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,EAAE,CAwetF;AAID;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;IAC/B,6FAA6F;IAC7F,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,CAAA;IACzC,oFAAoF;IACpF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAA;IACvC,oGAAoG;IACpG,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,wCAAwC;IACxC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,qGAAqG;IACrG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,WAAW,GACf,mBAAmB,EAAE,CAuBvB;AAED,kGAAkG;AAClG,eAAO,MAAM,uBAAuB,6BAA6B,CAAA;AAEjE;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,MAAM,CAM9F"}