@bmsuisse/datagrid 0.39.0 → 0.40.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/dist/index.d.ts +15 -1
- package/dist/index.js +250 -150
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2235,6 +2235,20 @@ interface TreeDataGridProps<TRow> extends TreeAccessors<TRow> {
|
|
|
2235
2235
|
* bottom) but neither requires the other. Defaults to false.
|
|
2236
2236
|
*/
|
|
2237
2237
|
showTotals?: boolean;
|
|
2238
|
+
/**
|
|
2239
|
+
* Opt-in: defaults to false. Gives every header a drag handle (and
|
|
2240
|
+
* ArrowLeft/ArrowRight keyboard resize) on its trailing edge, and switches
|
|
2241
|
+
* the table to `table-layout: fixed` so a dragged width is exactly the
|
|
2242
|
+
* rendered width. A column without an explicit `width` stays flexible and
|
|
2243
|
+
* absorbs the leftover space until it is resized itself.
|
|
2244
|
+
*/
|
|
2245
|
+
enableColumnResizing?: boolean;
|
|
2246
|
+
/**
|
|
2247
|
+
* Controlled column widths in px, keyed by column id. Both must be supplied
|
|
2248
|
+
* together to control it — omit both for `<TreeDataGrid>` to own the state.
|
|
2249
|
+
*/
|
|
2250
|
+
columnSizing?: ColumnSizingState;
|
|
2251
|
+
onColumnSizingChange?: (sizing: ColumnSizingState) => void;
|
|
2238
2252
|
/**
|
|
2239
2253
|
* Enables the same built-in inline-editing workflow `<DataGrid>` has:
|
|
2240
2254
|
* any column with `editable` set renders as an interactive editor
|
|
@@ -2263,7 +2277,7 @@ interface TreeDataGridProps<TRow> extends TreeAccessors<TRow> {
|
|
|
2263
2277
|
* column's cell matches `treeColumnId` (defaults to `columns[0]`); every
|
|
2264
2278
|
* other column renders exactly like it would in `<DataGrid>`.
|
|
2265
2279
|
*/
|
|
2266
|
-
declare function TreeDataGrid<TRow>({ columns, data, loading, error, onRetry, statusLabels, treeColumnId, columnVisibility, getRowId, getChildren, hasChildren, onLoadChildren, initialExpandedLevel, expanded: controlledExpanded, onExpandedChange, childrenMap: controlledChildrenMap, onChildrenMapChange, indentSize, getRowProps, getRowTestId, rowActions, virtualizeThreshold, estimatedRowHeight, maxBodyHeight, testId, selectedIds: controlledSelectedIds, onSelectedIdsChange, getRowSelectionState, isRowSelectionDisabled, groupBy, renderGroupHeader, defaultGroupsExpanded, expandedGroups: controlledExpandedGroups, onExpandedGroupsChange, zebra, showTotals, editing, }: TreeDataGridProps<TRow>): ReactElement;
|
|
2280
|
+
declare function TreeDataGrid<TRow>({ columns, data, loading, error, onRetry, statusLabels, treeColumnId, columnVisibility, getRowId, getChildren, hasChildren, onLoadChildren, initialExpandedLevel, expanded: controlledExpanded, onExpandedChange, childrenMap: controlledChildrenMap, onChildrenMapChange, indentSize, getRowProps, getRowTestId, rowActions, virtualizeThreshold, estimatedRowHeight, maxBodyHeight, testId, selectedIds: controlledSelectedIds, onSelectedIdsChange, getRowSelectionState, isRowSelectionDisabled, groupBy, renderGroupHeader, defaultGroupsExpanded, expandedGroups: controlledExpandedGroups, onExpandedGroupsChange, zebra, showTotals, editing, enableColumnResizing, columnSizing: controlledColumnSizing, onColumnSizingChange, }: TreeDataGridProps<TRow>): ReactElement;
|
|
2267
2281
|
|
|
2268
2282
|
interface FlatTreeRow<TRow> {
|
|
2269
2283
|
row: TRow;
|
package/dist/index.js
CHANGED
|
@@ -4718,7 +4718,73 @@ import {
|
|
|
4718
4718
|
ChevronDownIcon as ChevronDownIcon3,
|
|
4719
4719
|
ChevronRightIcon as ChevronRightIcon3
|
|
4720
4720
|
} from "@heroicons/react/24/outline";
|
|
4721
|
-
import { Fragment as Fragment5, useEffect as useEffect13, useMemo as useMemo11, useRef as
|
|
4721
|
+
import { Fragment as Fragment5, useEffect as useEffect13, useMemo as useMemo11, useRef as useRef15 } from "react";
|
|
4722
|
+
|
|
4723
|
+
// src/hooks/useColumnSizing.ts
|
|
4724
|
+
import { useCallback as useCallback5, useState as useState17 } from "react";
|
|
4725
|
+
var MIN_COLUMN_SIZE2 = 40;
|
|
4726
|
+
var KEYBOARD_RESIZE_STEP = 10;
|
|
4727
|
+
function useColumnSizing(controlled, onChange) {
|
|
4728
|
+
const [internal, setInternal] = useState17({});
|
|
4729
|
+
const columnSizing = controlled ?? internal;
|
|
4730
|
+
const setColumnSize = useCallback5(
|
|
4731
|
+
(columnId, width) => {
|
|
4732
|
+
const next = { ...columnSizing, [columnId]: Math.max(MIN_COLUMN_SIZE2, Math.round(width)) };
|
|
4733
|
+
setInternal(next);
|
|
4734
|
+
onChange?.(next);
|
|
4735
|
+
},
|
|
4736
|
+
[columnSizing, onChange]
|
|
4737
|
+
);
|
|
4738
|
+
return { columnSizing, setColumnSize };
|
|
4739
|
+
}
|
|
4740
|
+
|
|
4741
|
+
// src/tree/ColumnResizeHandle.tsx
|
|
4742
|
+
import { useRef as useRef14 } from "react";
|
|
4743
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
4744
|
+
function ColumnResizeHandle({ columnId, label, width, onResize }) {
|
|
4745
|
+
const drag = useRef14(null);
|
|
4746
|
+
const cellWidth = (handle) => handle.parentElement?.getBoundingClientRect().width ?? 0;
|
|
4747
|
+
const onPointerDown = (event) => {
|
|
4748
|
+
event.preventDefault();
|
|
4749
|
+
event.stopPropagation();
|
|
4750
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
4751
|
+
drag.current = { startX: event.clientX, startWidth: cellWidth(event.currentTarget) };
|
|
4752
|
+
};
|
|
4753
|
+
const onPointerMove = (event) => {
|
|
4754
|
+
if (!drag.current) return;
|
|
4755
|
+
onResize(columnId, drag.current.startWidth + event.clientX - drag.current.startX);
|
|
4756
|
+
};
|
|
4757
|
+
const endDrag = (event) => {
|
|
4758
|
+
if (!drag.current) return;
|
|
4759
|
+
drag.current = null;
|
|
4760
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
4761
|
+
};
|
|
4762
|
+
const onKeyDown = (event) => {
|
|
4763
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
|
|
4764
|
+
event.preventDefault();
|
|
4765
|
+
const delta = event.key === "ArrowRight" ? KEYBOARD_RESIZE_STEP : -KEYBOARD_RESIZE_STEP;
|
|
4766
|
+
onResize(columnId, cellWidth(event.currentTarget) + delta);
|
|
4767
|
+
};
|
|
4768
|
+
return /* @__PURE__ */ jsx36(
|
|
4769
|
+
"div",
|
|
4770
|
+
{
|
|
4771
|
+
"data-testid": `resize-handle-${columnId}`,
|
|
4772
|
+
role: "separator",
|
|
4773
|
+
"aria-orientation": "vertical",
|
|
4774
|
+
"aria-label": `Resize ${label} column`,
|
|
4775
|
+
"aria-valuenow": width,
|
|
4776
|
+
"aria-valuemin": MIN_COLUMN_SIZE2,
|
|
4777
|
+
"aria-valuetext": width === void 0 ? void 0 : `${width} pixels`,
|
|
4778
|
+
tabIndex: 0,
|
|
4779
|
+
onPointerDown,
|
|
4780
|
+
onPointerMove,
|
|
4781
|
+
onPointerUp: endDrag,
|
|
4782
|
+
onPointerCancel: endDrag,
|
|
4783
|
+
onKeyDown,
|
|
4784
|
+
className: "absolute right-0 top-0 h-full w-1 cursor-col-resize touch-none select-none hover:bg-accent focus-visible:bg-accent focus-visible:outline-none"
|
|
4785
|
+
}
|
|
4786
|
+
);
|
|
4787
|
+
}
|
|
4722
4788
|
|
|
4723
4789
|
// src/tree/flattenTree.ts
|
|
4724
4790
|
function flattenTree(roots, accessors, expanded, childrenOverride) {
|
|
@@ -4763,7 +4829,7 @@ function computeSelectionStates(roots, accessors, childrenOverride, selectedIds)
|
|
|
4763
4829
|
}
|
|
4764
4830
|
|
|
4765
4831
|
// src/tree/useTreeState.ts
|
|
4766
|
-
import { useCallback as
|
|
4832
|
+
import { useCallback as useCallback6, useMemo as useMemo10, useState as useState18 } from "react";
|
|
4767
4833
|
function useTreeState({
|
|
4768
4834
|
data,
|
|
4769
4835
|
getRowId,
|
|
@@ -4775,9 +4841,9 @@ function useTreeState({
|
|
|
4775
4841
|
childrenMap: controlledChildrenMap,
|
|
4776
4842
|
onChildrenMapChange
|
|
4777
4843
|
}) {
|
|
4778
|
-
const [internalExpanded, setInternalExpanded] =
|
|
4844
|
+
const [internalExpanded, setInternalExpanded] = useState18({});
|
|
4779
4845
|
const expanded = controlledExpanded ?? internalExpanded;
|
|
4780
|
-
const setExpanded =
|
|
4846
|
+
const setExpanded = useCallback6(
|
|
4781
4847
|
(updater) => {
|
|
4782
4848
|
if (controlledExpanded) {
|
|
4783
4849
|
onExpandedChange?.(updater(controlledExpanded));
|
|
@@ -4787,9 +4853,9 @@ function useTreeState({
|
|
|
4787
4853
|
},
|
|
4788
4854
|
[controlledExpanded, onExpandedChange]
|
|
4789
4855
|
);
|
|
4790
|
-
const [internalChildrenMap, setInternalChildrenMap] =
|
|
4856
|
+
const [internalChildrenMap, setInternalChildrenMap] = useState18(/* @__PURE__ */ new Map());
|
|
4791
4857
|
const childrenMap = controlledChildrenMap ?? internalChildrenMap;
|
|
4792
|
-
const setChildrenMap =
|
|
4858
|
+
const setChildrenMap = useCallback6(
|
|
4793
4859
|
(updater) => {
|
|
4794
4860
|
if (controlledChildrenMap) {
|
|
4795
4861
|
onChildrenMapChange?.(updater(controlledChildrenMap));
|
|
@@ -4799,13 +4865,13 @@ function useTreeState({
|
|
|
4799
4865
|
},
|
|
4800
4866
|
[controlledChildrenMap, onChildrenMapChange]
|
|
4801
4867
|
);
|
|
4802
|
-
const [loadingIds, setLoadingIds] =
|
|
4803
|
-
const [errorIds, setErrorIds] =
|
|
4868
|
+
const [loadingIds, setLoadingIds] = useState18(/* @__PURE__ */ new Set());
|
|
4869
|
+
const [errorIds, setErrorIds] = useState18(/* @__PURE__ */ new Map());
|
|
4804
4870
|
const resolveHasChildren = useMemo10(
|
|
4805
4871
|
() => hasChildren ?? ((row) => (getChildren(row)?.length ?? 0) > 0),
|
|
4806
4872
|
[hasChildren, getChildren]
|
|
4807
4873
|
);
|
|
4808
|
-
const loadChildrenFor =
|
|
4874
|
+
const loadChildrenFor = useCallback6(
|
|
4809
4875
|
async (row) => {
|
|
4810
4876
|
const id = getRowId(row);
|
|
4811
4877
|
const cached = childrenMap.get(id);
|
|
@@ -4838,7 +4904,7 @@ function useTreeState({
|
|
|
4838
4904
|
},
|
|
4839
4905
|
[childrenMap, getChildren, getRowId, onLoadChildren, setChildrenMap]
|
|
4840
4906
|
);
|
|
4841
|
-
const toggleExpand =
|
|
4907
|
+
const toggleExpand = useCallback6(
|
|
4842
4908
|
(row) => {
|
|
4843
4909
|
const id = getRowId(row);
|
|
4844
4910
|
const willExpand = !expanded[id];
|
|
@@ -4850,14 +4916,14 @@ function useTreeState({
|
|
|
4850
4916
|
},
|
|
4851
4917
|
[expanded, getRowId, loadChildrenFor, resolveHasChildren, setExpanded]
|
|
4852
4918
|
);
|
|
4853
|
-
const retry =
|
|
4919
|
+
const retry = useCallback6(
|
|
4854
4920
|
(row) => {
|
|
4855
4921
|
loadChildrenFor(row).catch(() => {
|
|
4856
4922
|
});
|
|
4857
4923
|
},
|
|
4858
4924
|
[loadChildrenFor]
|
|
4859
4925
|
);
|
|
4860
|
-
const expandToLevel =
|
|
4926
|
+
const expandToLevel = useCallback6(
|
|
4861
4927
|
async (level) => {
|
|
4862
4928
|
const nextExpanded = { ...expanded };
|
|
4863
4929
|
async function visit(row, depth) {
|
|
@@ -4880,7 +4946,7 @@ function useTreeState({
|
|
|
4880
4946
|
}
|
|
4881
4947
|
|
|
4882
4948
|
// src/tree/TreeDataGrid.tsx
|
|
4883
|
-
import { Fragment as Fragment6, jsx as
|
|
4949
|
+
import { Fragment as Fragment6, jsx as jsx37, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4884
4950
|
var EMPTY_SELECTED_IDS = /* @__PURE__ */ new Set();
|
|
4885
4951
|
var UNCHECKED_STATE = { checked: false, indeterminate: false };
|
|
4886
4952
|
function renderCell(column, row, editingCtx) {
|
|
@@ -4898,7 +4964,7 @@ function TreeCell({
|
|
|
4898
4964
|
editingCtx
|
|
4899
4965
|
}) {
|
|
4900
4966
|
return /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-1", style: { paddingLeft: flatRow.depth * indentSize }, children: [
|
|
4901
|
-
flatRow.hasChildren ? /* @__PURE__ */
|
|
4967
|
+
flatRow.hasChildren ? /* @__PURE__ */ jsx37(
|
|
4902
4968
|
"button",
|
|
4903
4969
|
{
|
|
4904
4970
|
type: "button",
|
|
@@ -4910,11 +4976,11 @@ function TreeCell({
|
|
|
4910
4976
|
"aria-label": flatRow.isExpanded ? "Collapse" : "Expand",
|
|
4911
4977
|
"aria-expanded": flatRow.isExpanded,
|
|
4912
4978
|
className: "flex h-4 w-4 shrink-0 items-center justify-center text-muted-foreground hover:text-foreground disabled:opacity-50",
|
|
4913
|
-
children: isLoading ? /* @__PURE__ */
|
|
4979
|
+
children: isLoading ? /* @__PURE__ */ jsx37(ArrowPathIcon2, { className: "h-3.5 w-3.5 animate-spin", "aria-hidden": "true" }) : flatRow.isExpanded ? /* @__PURE__ */ jsx37(ChevronDownIcon3, { className: "h-3.5 w-3.5", "aria-hidden": "true" }) : /* @__PURE__ */ jsx37(ChevronRightIcon3, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
|
|
4914
4980
|
}
|
|
4915
|
-
) : /* @__PURE__ */
|
|
4916
|
-
/* @__PURE__ */
|
|
4917
|
-
flatRow.isExpanded && error ? /* @__PURE__ */
|
|
4981
|
+
) : /* @__PURE__ */ jsx37("span", { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
|
|
4982
|
+
/* @__PURE__ */ jsx37("span", { className: "min-w-0 flex-1 truncate", children: renderCell(column, flatRow.row, editingCtx) }),
|
|
4983
|
+
flatRow.isExpanded && error ? /* @__PURE__ */ jsx37(
|
|
4918
4984
|
GridInlineError,
|
|
4919
4985
|
{
|
|
4920
4986
|
error: { message: labels.nodeLoadFailed, details: error },
|
|
@@ -4962,7 +5028,10 @@ function TreeDataGrid({
|
|
|
4962
5028
|
onExpandedGroupsChange,
|
|
4963
5029
|
zebra = true,
|
|
4964
5030
|
showTotals = false,
|
|
4965
|
-
editing
|
|
5031
|
+
editing,
|
|
5032
|
+
enableColumnResizing = false,
|
|
5033
|
+
columnSizing: controlledColumnSizing,
|
|
5034
|
+
onColumnSizingChange
|
|
4966
5035
|
}) {
|
|
4967
5036
|
const labels = resolveStatusLabels(statusLabels);
|
|
4968
5037
|
const hasError = toErrorInfo(error) !== void 0;
|
|
@@ -4982,7 +5051,7 @@ function TreeDataGrid({
|
|
|
4982
5051
|
childrenMap: controlledChildrenMap,
|
|
4983
5052
|
onChildrenMapChange
|
|
4984
5053
|
});
|
|
4985
|
-
const didAutoExpand =
|
|
5054
|
+
const didAutoExpand = useRef15(false);
|
|
4986
5055
|
useEffect13(() => {
|
|
4987
5056
|
if (didAutoExpand.current) return;
|
|
4988
5057
|
didAutoExpand.current = true;
|
|
@@ -5022,6 +5091,12 @@ function TreeDataGrid({
|
|
|
5022
5091
|
const showRowActionsColumn = Boolean(rowActions?.length);
|
|
5023
5092
|
const showSelectionColumn = controlledSelectedIds !== void 0;
|
|
5024
5093
|
const totalColumnCount = visibleColumns.length + (showRowActionsColumn ? 1 : 0) + (showSelectionColumn ? 1 : 0);
|
|
5094
|
+
const { columnSizing, setColumnSize } = useColumnSizing(controlledColumnSizing, onColumnSizingChange);
|
|
5095
|
+
const columnWidthStyle = (column) => {
|
|
5096
|
+
const width = enableColumnResizing ? columnSizing[column.id] ?? column.width : column.width;
|
|
5097
|
+
return width ? { width } : void 0;
|
|
5098
|
+
};
|
|
5099
|
+
const fixedTableWidth = enableColumnResizing && !showRowActionsColumn && visibleColumns.every((c) => columnWidthStyle(c)) ? visibleColumns.reduce((sum, c) => sum + Number(columnWidthStyle(c)?.width), showSelectionColumn ? SELECTION_COLUMN_WIDTH : 0) : void 0;
|
|
5025
5100
|
const { theadRef, groupHeaderTop } = useStickyGroupHeaderTop(Boolean(groupBy));
|
|
5026
5101
|
const selectionStates = useMemo11(
|
|
5027
5102
|
() => showSelectionColumn ? computeSelectionStates(data, accessors, childrenMap, controlledSelectedIds ?? EMPTY_SELECTED_IDS) : void 0,
|
|
@@ -5055,14 +5130,15 @@ function TreeDataGrid({
|
|
|
5055
5130
|
}
|
|
5056
5131
|
const bodyTdClassByColumn = useMemo11(() => {
|
|
5057
5132
|
const map = /* @__PURE__ */ new Map();
|
|
5058
|
-
|
|
5133
|
+
const clip = enableColumnResizing ? "overflow-hidden " : "";
|
|
5134
|
+
for (const column of visibleColumns) map.set(column.id, `${clip}p-2 ${alignClassName(column)}`);
|
|
5059
5135
|
return map;
|
|
5060
|
-
}, [visibleColumns]);
|
|
5136
|
+
}, [visibleColumns, enableColumnResizing]);
|
|
5061
5137
|
const hasColumnSummary = visibleColumns.some((column) => column.summary);
|
|
5062
5138
|
function renderGroupSummaryCells(rows) {
|
|
5063
|
-
return visibleColumns.map((column) => /* @__PURE__ */
|
|
5139
|
+
return visibleColumns.map((column) => /* @__PURE__ */ jsx37("td", { className: cn(bodyTdClassByColumn.get(column.id), "font-medium"), children: column.summary?.(rows) }, column.id));
|
|
5064
5140
|
}
|
|
5065
|
-
const scrollRef =
|
|
5141
|
+
const scrollRef = useRef15(null);
|
|
5066
5142
|
const shouldVirtualize = !groupBy && flatRows.length > virtualizeThreshold;
|
|
5067
5143
|
const virtualizer = useVirtualizer2({
|
|
5068
5144
|
count: flatRows.length,
|
|
@@ -5088,9 +5164,9 @@ function TreeDataGrid({
|
|
|
5088
5164
|
isOddRow && "bg-foreground/5"
|
|
5089
5165
|
) : `border-b border-border divide-x divide-border${isOddRow ? " bg-foreground/5" : ""}`,
|
|
5090
5166
|
children: [
|
|
5091
|
-
showSelectionColumn && /* @__PURE__ */
|
|
5167
|
+
showSelectionColumn && /* @__PURE__ */ jsx37("td", { className: "p-1", style: { width: SELECTION_COLUMN_WIDTH }, children: (() => {
|
|
5092
5168
|
const state = resolveSelectionState(flatRow.row, flatRow.id);
|
|
5093
|
-
return /* @__PURE__ */
|
|
5169
|
+
return /* @__PURE__ */ jsx37(
|
|
5094
5170
|
Checkbox,
|
|
5095
5171
|
{
|
|
5096
5172
|
"aria-label": `Select row ${flatRow.id}`,
|
|
@@ -5101,7 +5177,7 @@ function TreeDataGrid({
|
|
|
5101
5177
|
}
|
|
5102
5178
|
);
|
|
5103
5179
|
})() }),
|
|
5104
|
-
visibleColumns.map((column) => /* @__PURE__ */
|
|
5180
|
+
visibleColumns.map((column) => /* @__PURE__ */ jsx37("td", { className: bodyTdClassByColumn.get(column.id), children: column.id === treeColId ? /* @__PURE__ */ jsx37(
|
|
5105
5181
|
TreeCell,
|
|
5106
5182
|
{
|
|
5107
5183
|
flatRow,
|
|
@@ -5115,7 +5191,7 @@ function TreeDataGrid({
|
|
|
5115
5191
|
editingCtx: editingState.ctx
|
|
5116
5192
|
}
|
|
5117
5193
|
) : renderCell(column, flatRow.row, editingState.ctx) }, column.id)),
|
|
5118
|
-
showRowActionsColumn && rowActions && /* @__PURE__ */
|
|
5194
|
+
showRowActionsColumn && rowActions && /* @__PURE__ */ jsx37("td", { className: "p-2", children: /* @__PURE__ */ jsx37(
|
|
5119
5195
|
ActionsMenu,
|
|
5120
5196
|
{
|
|
5121
5197
|
items: rowActions,
|
|
@@ -5132,8 +5208,8 @@ function TreeDataGrid({
|
|
|
5132
5208
|
const paddingTop = virtualItems.length > 0 ? virtualItems[0].start : 0;
|
|
5133
5209
|
const paddingBottom = virtualItems.length > 0 ? virtualizer.getTotalSize() - virtualItems[virtualItems.length - 1].end : 0;
|
|
5134
5210
|
return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-2", "data-testid": "tree-datagrid", children: [
|
|
5135
|
-
hasError && data.length > 0 && /* @__PURE__ */
|
|
5136
|
-
editing && editingState.pendingEdits.size > 0 && /* @__PURE__ */
|
|
5211
|
+
hasError && data.length > 0 && /* @__PURE__ */ jsx37("div", { className: "flex shrink-0 items-center rounded-md border border-destructive/40 bg-destructive/10 px-2 py-1", children: /* @__PURE__ */ jsx37(GridInlineError, { error, onRetry, labels }) }),
|
|
5212
|
+
editing && editingState.pendingEdits.size > 0 && /* @__PURE__ */ jsx37(
|
|
5137
5213
|
EditingBar,
|
|
5138
5214
|
{
|
|
5139
5215
|
editing,
|
|
@@ -5144,143 +5220,167 @@ function TreeDataGrid({
|
|
|
5144
5220
|
testIdPrefix: "tree-datagrid"
|
|
5145
5221
|
}
|
|
5146
5222
|
),
|
|
5147
|
-
/* @__PURE__ */
|
|
5223
|
+
/* @__PURE__ */ jsx37(
|
|
5148
5224
|
"div",
|
|
5149
5225
|
{
|
|
5150
5226
|
ref: scrollRef,
|
|
5151
5227
|
"data-testid": testId,
|
|
5152
5228
|
className: "overflow-y-auto",
|
|
5153
5229
|
style: { maxHeight: maxBodyHeight },
|
|
5154
|
-
children: /* @__PURE__ */ jsxs22(
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5230
|
+
children: /* @__PURE__ */ jsxs22(
|
|
5231
|
+
"table",
|
|
5232
|
+
{
|
|
5233
|
+
className: cn(
|
|
5234
|
+
"border-collapse text-sm",
|
|
5235
|
+
fixedTableWidth === void 0 && "w-full",
|
|
5236
|
+
enableColumnResizing && "table-fixed"
|
|
5237
|
+
),
|
|
5238
|
+
style: fixedTableWidth === void 0 ? void 0 : { width: fixedTableWidth },
|
|
5239
|
+
children: [
|
|
5240
|
+
/* @__PURE__ */ jsx37("thead", { ref: theadRef, children: /* @__PURE__ */ jsxs22("tr", { className: "divide-x divide-border", children: [
|
|
5241
|
+
showSelectionColumn && /* @__PURE__ */ jsx37(
|
|
5242
|
+
"th",
|
|
5163
5243
|
{
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5244
|
+
className: "sticky top-0 z-20 border-b border-border bg-muted p-1",
|
|
5245
|
+
style: { width: SELECTION_COLUMN_WIDTH },
|
|
5246
|
+
children: /* @__PURE__ */ jsx37(
|
|
5247
|
+
Checkbox,
|
|
5248
|
+
{
|
|
5249
|
+
"aria-label": "Select all visible rows",
|
|
5250
|
+
checked: allVisibleSelected,
|
|
5251
|
+
onCheckedChange: toggleAllVisibleSelected
|
|
5252
|
+
}
|
|
5253
|
+
)
|
|
5167
5254
|
}
|
|
5168
|
-
)
|
|
5169
|
-
}
|
|
5170
|
-
),
|
|
5171
|
-
visibleColumns.map((column) => /* @__PURE__ */ jsx36(
|
|
5172
|
-
"th",
|
|
5173
|
-
{
|
|
5174
|
-
style: column.width ? { width: column.width } : void 0,
|
|
5175
|
-
className: cn(
|
|
5176
|
-
"sticky top-0 z-20 border-b border-border bg-muted p-2 font-medium",
|
|
5177
|
-
alignClassName(column)
|
|
5178
5255
|
),
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5256
|
+
visibleColumns.map((column) => /* @__PURE__ */ jsxs22(
|
|
5257
|
+
"th",
|
|
5258
|
+
{
|
|
5259
|
+
style: columnWidthStyle(column),
|
|
5260
|
+
className: cn(
|
|
5261
|
+
"sticky top-0 z-20 border-b border-border bg-muted p-2 font-medium",
|
|
5262
|
+
enableColumnResizing && "overflow-hidden",
|
|
5263
|
+
alignClassName(column)
|
|
5264
|
+
),
|
|
5265
|
+
children: [
|
|
5266
|
+
column.header,
|
|
5267
|
+
enableColumnResizing && /* @__PURE__ */ jsx37(
|
|
5268
|
+
ColumnResizeHandle,
|
|
5269
|
+
{
|
|
5270
|
+
columnId: column.id,
|
|
5271
|
+
label: String(column.header),
|
|
5272
|
+
width: columnSizing[column.id] ?? column.width,
|
|
5273
|
+
onResize: setColumnSize
|
|
5274
|
+
}
|
|
5275
|
+
)
|
|
5276
|
+
]
|
|
5277
|
+
},
|
|
5278
|
+
column.id
|
|
5279
|
+
)),
|
|
5280
|
+
showRowActionsColumn && /* @__PURE__ */ jsx37("th", { className: "sticky top-0 z-20 border-b border-border bg-muted p-2", "aria-label": "Row actions" })
|
|
5281
|
+
] }) }),
|
|
5282
|
+
/* @__PURE__ */ jsx37("tbody", { children: data.length === 0 ? /* @__PURE__ */ jsx37("tr", { children: /* @__PURE__ */ jsx37("td", { colSpan: totalColumnCount, className: "p-4 text-center text-muted-foreground", children: loading ? /* @__PURE__ */ jsx37(LoadingRows, { label: labels.loading }) : hasError ? /* @__PURE__ */ jsx37(GridErrorState, { error, onRetry, labels }) : labels.noResults }) }) : groupedBuckets ? groupedBuckets.map((bucket) => {
|
|
5283
|
+
const groupExpanded = isGroupExpanded(bucket.key);
|
|
5284
|
+
return /* @__PURE__ */ jsxs22(Fragment5, { children: [
|
|
5285
|
+
/* @__PURE__ */ jsx37("tr", { "data-testid": `group-header-${bucket.key}`, children: /* @__PURE__ */ jsx37(
|
|
5286
|
+
"td",
|
|
5287
|
+
{
|
|
5288
|
+
colSpan: totalColumnCount,
|
|
5289
|
+
className: cn(
|
|
5290
|
+
"sticky z-20 border-b p-2 font-medium",
|
|
5291
|
+
zebra ? "bg-muted" : "bg-background"
|
|
5292
|
+
),
|
|
5293
|
+
style: { top: groupHeaderTop },
|
|
5294
|
+
children: /* @__PURE__ */ jsxs22(
|
|
5295
|
+
"button",
|
|
5296
|
+
{
|
|
5297
|
+
type: "button",
|
|
5298
|
+
className: "flex w-full items-center gap-1 text-left",
|
|
5299
|
+
onClick: () => toggleGroupExpanded(bucket.key),
|
|
5300
|
+
"aria-expanded": groupExpanded,
|
|
5301
|
+
children: [
|
|
5302
|
+
/* @__PURE__ */ jsx37(
|
|
5303
|
+
ChevronRightIcon3,
|
|
5304
|
+
{
|
|
5305
|
+
className: `h-4 w-4 shrink-0 transition-transform${groupExpanded ? " rotate-90" : ""}`,
|
|
5306
|
+
"aria-hidden": true
|
|
5307
|
+
}
|
|
5308
|
+
),
|
|
5309
|
+
renderGroupHeader ? renderGroupHeader(bucket.key, bucket.roots, groupExpanded) : `${bucket.key} (${bucket.roots.length})`
|
|
5310
|
+
]
|
|
5311
|
+
}
|
|
5312
|
+
)
|
|
5313
|
+
}
|
|
5314
|
+
) }),
|
|
5315
|
+
hasColumnSummary && /* @__PURE__ */ jsxs22(
|
|
5316
|
+
"tr",
|
|
5199
5317
|
{
|
|
5200
|
-
|
|
5201
|
-
className: "
|
|
5202
|
-
onClick: () => toggleGroupExpanded(bucket.key),
|
|
5203
|
-
"aria-expanded": groupExpanded,
|
|
5318
|
+
"data-testid": `group-summary-${bucket.key}`,
|
|
5319
|
+
className: "border-b border-border divide-x divide-border",
|
|
5204
5320
|
children: [
|
|
5205
|
-
/* @__PURE__ */
|
|
5206
|
-
|
|
5321
|
+
showSelectionColumn && /* @__PURE__ */ jsx37(
|
|
5322
|
+
"td",
|
|
5207
5323
|
{
|
|
5208
|
-
className:
|
|
5209
|
-
|
|
5324
|
+
className: cn("p-2", zebra ? "bg-muted" : "bg-background"),
|
|
5325
|
+
style: { width: SELECTION_COLUMN_WIDTH }
|
|
5210
5326
|
}
|
|
5211
5327
|
),
|
|
5212
|
-
|
|
5328
|
+
renderGroupSummaryCells(bucket.roots),
|
|
5329
|
+
showRowActionsColumn && /* @__PURE__ */ jsx37("td", { className: cn("p-2", zebra ? "bg-muted" : "bg-background"), "aria-hidden": true })
|
|
5213
5330
|
]
|
|
5214
5331
|
}
|
|
5215
|
-
)
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
{
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
"td",
|
|
5226
|
-
{
|
|
5227
|
-
className: cn("p-2", zebra ? "bg-muted" : "bg-background"),
|
|
5228
|
-
style: { width: SELECTION_COLUMN_WIDTH }
|
|
5229
|
-
}
|
|
5230
|
-
),
|
|
5231
|
-
renderGroupSummaryCells(bucket.roots),
|
|
5232
|
-
showRowActionsColumn && /* @__PURE__ */ jsx36("td", { className: cn("p-2", zebra ? "bg-muted" : "bg-background"), "aria-hidden": true })
|
|
5233
|
-
]
|
|
5234
|
-
}
|
|
5235
|
-
),
|
|
5236
|
-
groupExpanded && (() => {
|
|
5237
|
-
const startIndex = groupedRender?.startIndexByBucket.get(bucket.key) ?? 0;
|
|
5238
|
-
return bucket.flatRows.map((flatRow, i) => renderRow(flatRow, startIndex + i));
|
|
5239
|
-
})()
|
|
5240
|
-
] }, `group-${bucket.key}`);
|
|
5241
|
-
}) : shouldVirtualize ? /* @__PURE__ */ jsxs22(Fragment6, { children: [
|
|
5242
|
-
paddingTop > 0 && /* @__PURE__ */ jsx36("tr", { "aria-hidden": "true", children: /* @__PURE__ */ jsx36("td", { colSpan: totalColumnCount, style: { padding: 0, border: "none", height: paddingTop } }) }),
|
|
5243
|
-
virtualItems.map(
|
|
5244
|
-
(virtualItem) => renderRow(flatRows[virtualItem.index], virtualItem.index, (el) => virtualizer.measureElement(el))
|
|
5245
|
-
),
|
|
5246
|
-
paddingBottom > 0 && /* @__PURE__ */ jsx36("tr", { "aria-hidden": "true", children: /* @__PURE__ */ jsx36(
|
|
5247
|
-
"td",
|
|
5248
|
-
{
|
|
5249
|
-
colSpan: totalColumnCount,
|
|
5250
|
-
style: { padding: 0, border: "none", height: paddingBottom }
|
|
5251
|
-
}
|
|
5252
|
-
) })
|
|
5253
|
-
] }) : flatRows.map((flatRow, index) => renderRow(flatRow, index)) }),
|
|
5254
|
-
showTotals && hasColumnSummary && // Sticky to the BOTTOM of the scroll container, mirroring the
|
|
5255
|
-
// `<thead>`'s own `top-0` stickiness — see `<DataGrid>`'s own
|
|
5256
|
-
// `renderTotalsFooter` for the full reasoning. Summarizes `data`
|
|
5257
|
-
// (the root-level rows), not `flatRows`/`allFlatRows` — same
|
|
5258
|
-
// "roots only" scope `groupBy` itself uses, and for the same
|
|
5259
|
-
// reason (a child's value is usually already folded into its
|
|
5260
|
-
// parent's).
|
|
5261
|
-
/* @__PURE__ */ jsx36("tfoot", { children: /* @__PURE__ */ jsxs22("tr", { "data-testid": "totals-row", className: "divide-x divide-border", children: [
|
|
5262
|
-
showSelectionColumn && /* @__PURE__ */ jsx36(
|
|
5263
|
-
"td",
|
|
5264
|
-
{
|
|
5265
|
-
className: "sticky bottom-0 z-20 border-t border-border bg-muted p-2",
|
|
5266
|
-
style: { width: SELECTION_COLUMN_WIDTH }
|
|
5267
|
-
}
|
|
5268
|
-
),
|
|
5269
|
-
visibleColumns.map((column) => /* @__PURE__ */ jsx36(
|
|
5270
|
-
"td",
|
|
5271
|
-
{
|
|
5272
|
-
style: column.width ? { width: column.width } : void 0,
|
|
5273
|
-
className: cn(
|
|
5274
|
-
"sticky bottom-0 z-20 border-t border-border bg-muted p-2 font-medium",
|
|
5275
|
-
alignClassName(column)
|
|
5332
|
+
),
|
|
5333
|
+
groupExpanded && (() => {
|
|
5334
|
+
const startIndex = groupedRender?.startIndexByBucket.get(bucket.key) ?? 0;
|
|
5335
|
+
return bucket.flatRows.map((flatRow, i) => renderRow(flatRow, startIndex + i));
|
|
5336
|
+
})()
|
|
5337
|
+
] }, `group-${bucket.key}`);
|
|
5338
|
+
}) : shouldVirtualize ? /* @__PURE__ */ jsxs22(Fragment6, { children: [
|
|
5339
|
+
paddingTop > 0 && /* @__PURE__ */ jsx37("tr", { "aria-hidden": "true", children: /* @__PURE__ */ jsx37("td", { colSpan: totalColumnCount, style: { padding: 0, border: "none", height: paddingTop } }) }),
|
|
5340
|
+
virtualItems.map(
|
|
5341
|
+
(virtualItem) => renderRow(flatRows[virtualItem.index], virtualItem.index, (el) => virtualizer.measureElement(el))
|
|
5276
5342
|
),
|
|
5277
|
-
children:
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5343
|
+
paddingBottom > 0 && /* @__PURE__ */ jsx37("tr", { "aria-hidden": "true", children: /* @__PURE__ */ jsx37(
|
|
5344
|
+
"td",
|
|
5345
|
+
{
|
|
5346
|
+
colSpan: totalColumnCount,
|
|
5347
|
+
style: { padding: 0, border: "none", height: paddingBottom }
|
|
5348
|
+
}
|
|
5349
|
+
) })
|
|
5350
|
+
] }) : flatRows.map((flatRow, index) => renderRow(flatRow, index)) }),
|
|
5351
|
+
showTotals && hasColumnSummary && // Sticky to the BOTTOM of the scroll container, mirroring the
|
|
5352
|
+
// `<thead>`'s own `top-0` stickiness — see `<DataGrid>`'s own
|
|
5353
|
+
// `renderTotalsFooter` for the full reasoning. Summarizes `data`
|
|
5354
|
+
// (the root-level rows), not `flatRows`/`allFlatRows` — same
|
|
5355
|
+
// "roots only" scope `groupBy` itself uses, and for the same
|
|
5356
|
+
// reason (a child's value is usually already folded into its
|
|
5357
|
+
// parent's).
|
|
5358
|
+
/* @__PURE__ */ jsx37("tfoot", { children: /* @__PURE__ */ jsxs22("tr", { "data-testid": "totals-row", className: "divide-x divide-border", children: [
|
|
5359
|
+
showSelectionColumn && /* @__PURE__ */ jsx37(
|
|
5360
|
+
"td",
|
|
5361
|
+
{
|
|
5362
|
+
className: "sticky bottom-0 z-20 border-t border-border bg-muted p-2",
|
|
5363
|
+
style: { width: SELECTION_COLUMN_WIDTH }
|
|
5364
|
+
}
|
|
5365
|
+
),
|
|
5366
|
+
visibleColumns.map((column) => /* @__PURE__ */ jsx37(
|
|
5367
|
+
"td",
|
|
5368
|
+
{
|
|
5369
|
+
style: columnWidthStyle(column),
|
|
5370
|
+
className: cn(
|
|
5371
|
+
"sticky bottom-0 z-20 border-t border-border bg-muted p-2 font-medium",
|
|
5372
|
+
enableColumnResizing && "overflow-hidden",
|
|
5373
|
+
alignClassName(column)
|
|
5374
|
+
),
|
|
5375
|
+
children: column.summary?.(data)
|
|
5376
|
+
},
|
|
5377
|
+
column.id
|
|
5378
|
+
)),
|
|
5379
|
+
showRowActionsColumn && /* @__PURE__ */ jsx37("td", { className: "sticky bottom-0 z-20 border-t border-border bg-muted p-2", "aria-hidden": true })
|
|
5380
|
+
] }) })
|
|
5381
|
+
]
|
|
5382
|
+
}
|
|
5383
|
+
)
|
|
5284
5384
|
}
|
|
5285
5385
|
)
|
|
5286
5386
|
] });
|