@bmsuisse/datagrid 0.31.1 → 0.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/dist/index.js +121 -66
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2272,7 +2272,7 @@ function renderCellModeCell(column, row, rawValue, ctx) {
|
|
|
2272
2272
|
}
|
|
2273
2273
|
|
|
2274
2274
|
// src/cell-editing/SelectionOverlay.tsx
|
|
2275
|
-
import { useLayoutEffect as useLayoutEffect2, useState as useState9 } from "react";
|
|
2275
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef9, useState as useState9 } from "react";
|
|
2276
2276
|
import { Fragment as Fragment2, jsx as jsx27, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2277
2277
|
function cellSelector(rowId, columnId) {
|
|
2278
2278
|
const escape = (value) => typeof CSS !== "undefined" && CSS.escape ? CSS.escape(value) : value.replace(/["\\]/g, "\\$&");
|
|
@@ -2305,13 +2305,27 @@ function SelectionOverlay({
|
|
|
2305
2305
|
}) {
|
|
2306
2306
|
const [rect, setRect] = useState9(void 0);
|
|
2307
2307
|
const [previewRect, setPreviewRect] = useState9(void 0);
|
|
2308
|
-
|
|
2308
|
+
const recomputeRef = useRef9(() => {
|
|
2309
|
+
});
|
|
2310
|
+
recomputeRef.current = () => {
|
|
2309
2311
|
const container = containerRef.current;
|
|
2310
2312
|
const nextRect = range && container ? computeRangeRect(container, range) : void 0;
|
|
2311
2313
|
setRect((prev) => rectsEqual(prev, nextRect) ? prev : nextRect);
|
|
2312
2314
|
const nextPreviewRect = fillPreviewRange && container ? computeRangeRect(container, fillPreviewRange) : void 0;
|
|
2313
2315
|
setPreviewRect((prev) => rectsEqual(prev, nextPreviewRect) ? prev : nextPreviewRect);
|
|
2316
|
+
};
|
|
2317
|
+
useLayoutEffect2(() => {
|
|
2318
|
+
recomputeRef.current();
|
|
2314
2319
|
});
|
|
2320
|
+
useLayoutEffect2(() => {
|
|
2321
|
+
const container = containerRef.current;
|
|
2322
|
+
if (!container) return;
|
|
2323
|
+
function handleScroll() {
|
|
2324
|
+
recomputeRef.current();
|
|
2325
|
+
}
|
|
2326
|
+
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
2327
|
+
return () => container.removeEventListener("scroll", handleScroll);
|
|
2328
|
+
}, [containerRef.current]);
|
|
2315
2329
|
if (!rect) return null;
|
|
2316
2330
|
return /* @__PURE__ */ jsxs16(Fragment2, { children: [
|
|
2317
2331
|
/* @__PURE__ */ jsx27(
|
|
@@ -2803,7 +2817,7 @@ import { BarsArrowDownIcon, BarsArrowUpIcon, FunnelIcon as FunnelIcon7 } from "@
|
|
|
2803
2817
|
import { columnResizingFeature, columnSizingFeature, flexRender, tableFeatures, useTable } from "@tanstack/react-table";
|
|
2804
2818
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
2805
2819
|
import { ChevronRight, Loader2 } from "lucide-react";
|
|
2806
|
-
import { Fragment as Fragment3, useEffect as useEffect10, useMemo as useMemo8, useRef as
|
|
2820
|
+
import { Fragment as Fragment3, useEffect as useEffect10, useMemo as useMemo8, useRef as useRef12, useState as useState14 } from "react";
|
|
2807
2821
|
|
|
2808
2822
|
// src/cell-editing/renderAlwaysEditCell.tsx
|
|
2809
2823
|
import {
|
|
@@ -2942,9 +2956,9 @@ function useGroupExpansion(defaultGroupsExpanded, controlledExpandedGroups, onEx
|
|
|
2942
2956
|
}
|
|
2943
2957
|
|
|
2944
2958
|
// src/hooks/useStickyGroupHeaderTop.ts
|
|
2945
|
-
import { useLayoutEffect as useLayoutEffect3, useRef as
|
|
2959
|
+
import { useLayoutEffect as useLayoutEffect3, useRef as useRef10, useState as useState12 } from "react";
|
|
2946
2960
|
function useStickyGroupHeaderTop(enabled) {
|
|
2947
|
-
const theadRef =
|
|
2961
|
+
const theadRef = useRef10(null);
|
|
2948
2962
|
const [groupHeaderTop, setGroupHeaderTop] = useState12(0);
|
|
2949
2963
|
useLayoutEffect3(() => {
|
|
2950
2964
|
if (!enabled) return;
|
|
@@ -3012,11 +3026,11 @@ function processClientData(data, state) {
|
|
|
3012
3026
|
import { useCallback as useCallback4, useEffect as useEffect9, useMemo as useMemo7, useState as useState13 } from "react";
|
|
3013
3027
|
|
|
3014
3028
|
// src/hooks/useDebouncedCallback.ts
|
|
3015
|
-
import { useEffect as useEffect8, useMemo as useMemo6, useRef as
|
|
3029
|
+
import { useEffect as useEffect8, useMemo as useMemo6, useRef as useRef11 } from "react";
|
|
3016
3030
|
function useDebouncedCallback(callback, delayMs) {
|
|
3017
|
-
const callbackRef =
|
|
3031
|
+
const callbackRef = useRef11(callback);
|
|
3018
3032
|
callbackRef.current = callback;
|
|
3019
|
-
const timeoutRef =
|
|
3033
|
+
const timeoutRef = useRef11(void 0);
|
|
3020
3034
|
useEffect8(() => {
|
|
3021
3035
|
return () => {
|
|
3022
3036
|
clearTimeout(timeoutRef.current);
|
|
@@ -3141,6 +3155,12 @@ function useGridState(dataSource, initialState, externalState, showPagination =
|
|
|
3141
3155
|
import { Fragment as Fragment4, jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3142
3156
|
var gridTableFeatures = tableFeatures({ columnSizingFeature, columnResizingFeature });
|
|
3143
3157
|
var DEFAULT_COLUMN_SIZE = 150;
|
|
3158
|
+
var MIN_COLUMN_SIZE = 40;
|
|
3159
|
+
function sortDirToAriaSort(dir) {
|
|
3160
|
+
if (dir === "asc") return "ascending";
|
|
3161
|
+
if (dir === "desc") return "descending";
|
|
3162
|
+
return "none";
|
|
3163
|
+
}
|
|
3144
3164
|
var DETAIL_COLUMN_WIDTH = 44;
|
|
3145
3165
|
var ROW_ACTIONS_COLUMN_WIDTH = 44;
|
|
3146
3166
|
var EMPTY_ID_ARRAY = [];
|
|
@@ -3269,7 +3289,7 @@ function DataGrid({
|
|
|
3269
3289
|
hasCellEditing ? cellEditing : void 0,
|
|
3270
3290
|
getRowId
|
|
3271
3291
|
);
|
|
3272
|
-
const atomicGestureRef =
|
|
3292
|
+
const atomicGestureRef = useRef12(void 0);
|
|
3273
3293
|
const visibleColumns = useVisibleColumns(columns, columnVisibility);
|
|
3274
3294
|
const serverRowCount = dataSource.mode === "server" ? dataSource.rowCount : void 0;
|
|
3275
3295
|
const { rows, rowCount } = useMemo8(() => {
|
|
@@ -3423,7 +3443,7 @@ function DataGrid({
|
|
|
3423
3443
|
return map;
|
|
3424
3444
|
}, [visibleColumns, enableColumnResizing, leftPinnedOffsets, rightPinnedOffsets, columnSizing]);
|
|
3425
3445
|
const tableRows = table.getRowModel().rows;
|
|
3426
|
-
const truncationWarnedRef =
|
|
3446
|
+
const truncationWarnedRef = useRef12(false);
|
|
3427
3447
|
useEffect10(() => {
|
|
3428
3448
|
if (process.env.NODE_ENV === "production") return;
|
|
3429
3449
|
if (showPagination) return;
|
|
@@ -3454,7 +3474,7 @@ function DataGrid({
|
|
|
3454
3474
|
}
|
|
3455
3475
|
return items;
|
|
3456
3476
|
}, [shouldVirtualize, groupedBuckets, tableRows, isGroupExpanded]);
|
|
3457
|
-
const scrollRef =
|
|
3477
|
+
const scrollRef = useRef12(null);
|
|
3458
3478
|
const virtualizer = useVirtualizer({
|
|
3459
3479
|
count: flatItems.length,
|
|
3460
3480
|
getScrollElement: () => scrollRef.current,
|
|
@@ -3466,7 +3486,10 @@ function DataGrid({
|
|
|
3466
3486
|
const paddingTop = virtualItems.length > 0 ? virtualItems[0].start : 0;
|
|
3467
3487
|
const paddingBottom = virtualItems.length > 0 ? virtualizer.getTotalSize() - virtualItems[virtualItems.length - 1].end : 0;
|
|
3468
3488
|
const lastVisibleIndex = virtualItems.length > 0 ? virtualItems[virtualItems.length - 1].index : -1;
|
|
3469
|
-
const notifiedForLengthRef =
|
|
3489
|
+
const notifiedForLengthRef = useRef12(-1);
|
|
3490
|
+
useEffect10(() => {
|
|
3491
|
+
notifiedForLengthRef.current = -1;
|
|
3492
|
+
}, [state.filter, state.sort]);
|
|
3470
3493
|
useEffect10(() => {
|
|
3471
3494
|
if (!virtualize?.onEndReached) return;
|
|
3472
3495
|
if (lastVisibleIndex < 0 || lastVisibleIndex < flatItems.length - 1) return;
|
|
@@ -3493,8 +3516,8 @@ function DataGrid({
|
|
|
3493
3516
|
if (index !== void 0) virtualizer.scrollToIndex(index);
|
|
3494
3517
|
}
|
|
3495
3518
|
});
|
|
3496
|
-
const clickCellRef =
|
|
3497
|
-
const dragMovedRef =
|
|
3519
|
+
const clickCellRef = useRef12(null);
|
|
3520
|
+
const dragMovedRef = useRef12(false);
|
|
3498
3521
|
const [pendingOpenEnumCell, setPendingOpenEnumCell] = useState14(void 0);
|
|
3499
3522
|
atomicGestureRef.current = {
|
|
3500
3523
|
shouldOpenEnum: (rowId, columnId) => pendingOpenEnumCell?.rowId === rowId && pendingOpenEnumCell?.columnId === columnId,
|
|
@@ -3518,8 +3541,8 @@ function DataGrid({
|
|
|
3518
3541
|
if (!column || row === void 0 || !isEditable(column, row)) return;
|
|
3519
3542
|
cellEditingCtx.onBeginEdit(cell);
|
|
3520
3543
|
}
|
|
3521
|
-
const pendingDragCellRef =
|
|
3522
|
-
const dragRafRef =
|
|
3544
|
+
const pendingDragCellRef = useRef12(null);
|
|
3545
|
+
const dragRafRef = useRef12(null);
|
|
3523
3546
|
useEffect10(() => {
|
|
3524
3547
|
if (!cellSelection.isDragging) return;
|
|
3525
3548
|
function handleMouseMove(event) {
|
|
@@ -3559,8 +3582,8 @@ function DataGrid({
|
|
|
3559
3582
|
dragRafRef.current = null;
|
|
3560
3583
|
};
|
|
3561
3584
|
}, [cellSelection.isDragging, cellSelection.updateDrag, cellSelection.endDrag]);
|
|
3562
|
-
const pendingFillCellRef =
|
|
3563
|
-
const fillRafRef =
|
|
3585
|
+
const pendingFillCellRef = useRef12(null);
|
|
3586
|
+
const fillRafRef = useRef12(null);
|
|
3564
3587
|
useEffect10(() => {
|
|
3565
3588
|
if (!cellSelection.isFillDragging) return;
|
|
3566
3589
|
function handleMouseMove(event) {
|
|
@@ -3597,7 +3620,7 @@ function DataGrid({
|
|
|
3597
3620
|
fillRafRef.current = null;
|
|
3598
3621
|
};
|
|
3599
3622
|
}, [cellSelection.isFillDragging, cellSelection.updateFillDrag, cellSelection.endFillDrag]);
|
|
3600
|
-
const wasEditingCellRef =
|
|
3623
|
+
const wasEditingCellRef = useRef12(void 0);
|
|
3601
3624
|
useEffect10(() => {
|
|
3602
3625
|
const wasEditing = wasEditingCellRef.current !== void 0;
|
|
3603
3626
|
wasEditingCellRef.current = cellEditingCtx?.editingCell;
|
|
@@ -3911,52 +3934,84 @@ function DataGrid({
|
|
|
3911
3934
|
const filterable = isFilterable(column) && column.filterDisplay !== "row";
|
|
3912
3935
|
const cellProps = leafHeaderCellPropsByColumn.get(column.id);
|
|
3913
3936
|
const headerContent = column.renderHeader ? column.renderHeader(column) : column.header;
|
|
3914
|
-
return /* @__PURE__ */ jsxs20(
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3937
|
+
return /* @__PURE__ */ jsxs20(
|
|
3938
|
+
"th",
|
|
3939
|
+
{
|
|
3940
|
+
rowSpan,
|
|
3941
|
+
style: cellProps?.style,
|
|
3942
|
+
className: cellProps?.className,
|
|
3943
|
+
"aria-sort": sortable ? sortDirToAriaSort(sortEntry?.dir) : void 0,
|
|
3944
|
+
"aria-label": column.header,
|
|
3945
|
+
children: [
|
|
3946
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-1", children: [
|
|
3947
|
+
sortable ? /* @__PURE__ */ jsxs20(
|
|
3948
|
+
"button",
|
|
3949
|
+
{
|
|
3950
|
+
type: "button",
|
|
3951
|
+
"data-testid": `sort-button-${column.id}`,
|
|
3952
|
+
className: "flex items-center gap-1 rounded-sm px-1 hover:bg-accent hover:text-accent-foreground",
|
|
3953
|
+
onClick: (event) => toggleSort(column.id, enableMultiSort && event.shiftKey, column.sortDescFirst === true),
|
|
3954
|
+
children: [
|
|
3955
|
+
headerContent,
|
|
3956
|
+
sortEntry?.dir === "asc" && /* @__PURE__ */ jsx33(BarsArrowUpIcon, { className: "h-3 w-3", "aria-hidden": true }),
|
|
3957
|
+
sortEntry?.dir === "desc" && /* @__PURE__ */ jsx33(BarsArrowDownIcon, { className: "h-3 w-3", "aria-hidden": true })
|
|
3958
|
+
]
|
|
3959
|
+
}
|
|
3960
|
+
) : (
|
|
3961
|
+
// Not wrapped in a `<button>` (unlike the sortable branch above): a
|
|
3962
|
+
// disabled `<button>` swallows pointer events for its entire subtree,
|
|
3963
|
+
// silently breaking any interactive content a column's own `renderHeader`
|
|
3964
|
+
// embeds directly (bare filter inputs, "select/reject all" buttons) —
|
|
3965
|
+
// clicks never reach them at all, even though nothing looks wrong visually.
|
|
3966
|
+
/* @__PURE__ */ jsx33("div", { className: "flex items-center gap-1 px-1", children: headerContent })
|
|
3967
|
+
),
|
|
3968
|
+
filterable && /* @__PURE__ */ jsxs20(Popover, { children: [
|
|
3969
|
+
/* @__PURE__ */ jsx33(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx33(
|
|
3970
|
+
Button,
|
|
3971
|
+
{
|
|
3972
|
+
variant: "ghost",
|
|
3973
|
+
size: "icon",
|
|
3974
|
+
"data-testid": `filter-trigger-${column.id}`,
|
|
3975
|
+
"aria-label": `Filter ${column.header}`,
|
|
3976
|
+
children: /* @__PURE__ */ jsx33(
|
|
3977
|
+
FunnelIcon7,
|
|
3978
|
+
{
|
|
3979
|
+
className: cn(
|
|
3980
|
+
"h-3 w-3",
|
|
3981
|
+
filtersByColumn.get(column.id) !== void 0 ? "opacity-100 text-primary" : "opacity-40"
|
|
3982
|
+
),
|
|
3983
|
+
"aria-hidden": true
|
|
3984
|
+
}
|
|
3985
|
+
)
|
|
3986
|
+
}
|
|
3987
|
+
) }),
|
|
3988
|
+
/* @__PURE__ */ jsx33(PopoverContent, { children: renderFilterWidget(column) })
|
|
3989
|
+
] })
|
|
3990
|
+
] }),
|
|
3991
|
+
enableColumnResizing && /* @__PURE__ */ jsx33(
|
|
3992
|
+
"div",
|
|
3939
3993
|
{
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3994
|
+
"data-testid": `resize-handle-${column.id}`,
|
|
3995
|
+
role: "separator",
|
|
3996
|
+
"aria-orientation": "vertical",
|
|
3997
|
+
"aria-label": `Resize ${column.header} column`,
|
|
3998
|
+
tabIndex: 0,
|
|
3999
|
+
onMouseDown: header.getResizeHandler(),
|
|
4000
|
+
onTouchStart: header.getResizeHandler(),
|
|
4001
|
+
onKeyDown: (event) => {
|
|
4002
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
|
|
4003
|
+
event.preventDefault();
|
|
4004
|
+
const delta = event.key === "ArrowRight" ? 10 : -10;
|
|
4005
|
+
const nextSize = Math.max(MIN_COLUMN_SIZE, columnSize(column.id) + delta);
|
|
4006
|
+
updateColumnSizing({ ...columnSizing, [column.id]: nextSize });
|
|
4007
|
+
},
|
|
4008
|
+
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"
|
|
3945
4009
|
}
|
|
3946
|
-
)
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
"div",
|
|
3952
|
-
{
|
|
3953
|
-
"data-testid": `resize-handle-${column.id}`,
|
|
3954
|
-
onMouseDown: header.getResizeHandler(),
|
|
3955
|
-
onTouchStart: header.getResizeHandler(),
|
|
3956
|
-
className: "absolute right-0 top-0 h-full w-1 cursor-col-resize touch-none select-none hover:bg-accent"
|
|
3957
|
-
}
|
|
3958
|
-
)
|
|
3959
|
-
] }, header.id);
|
|
4010
|
+
)
|
|
4011
|
+
]
|
|
4012
|
+
},
|
|
4013
|
+
header.id
|
|
4014
|
+
);
|
|
3960
4015
|
}
|
|
3961
4016
|
return /* @__PURE__ */ jsxs20(Fragment3, { children: [
|
|
3962
4017
|
hasHeaderGroups && /* @__PURE__ */ jsxs20("tr", { "data-testid": "header-group-row", className: "divide-x divide-border", children: [
|
|
@@ -4137,7 +4192,7 @@ function DataGrid({
|
|
|
4137
4192
|
// src/tree/TreeDataGrid.tsx
|
|
4138
4193
|
import { useVirtualizer as useVirtualizer2 } from "@tanstack/react-virtual";
|
|
4139
4194
|
import { AlertCircle, ChevronDown as ChevronDown2, ChevronRight as ChevronRight2, Loader2 as Loader22 } from "lucide-react";
|
|
4140
|
-
import { Fragment as Fragment5, useEffect as useEffect11, useMemo as useMemo10, useRef as
|
|
4195
|
+
import { Fragment as Fragment5, useEffect as useEffect11, useMemo as useMemo10, useRef as useRef13 } from "react";
|
|
4141
4196
|
|
|
4142
4197
|
// src/tree/flattenTree.ts
|
|
4143
4198
|
function flattenTree(roots, accessors, expanded, childrenOverride) {
|
|
@@ -4388,7 +4443,7 @@ function TreeDataGrid({
|
|
|
4388
4443
|
childrenMap: controlledChildrenMap,
|
|
4389
4444
|
onChildrenMapChange
|
|
4390
4445
|
});
|
|
4391
|
-
const didAutoExpand =
|
|
4446
|
+
const didAutoExpand = useRef13(false);
|
|
4392
4447
|
useEffect11(() => {
|
|
4393
4448
|
if (didAutoExpand.current) return;
|
|
4394
4449
|
didAutoExpand.current = true;
|
|
@@ -4464,7 +4519,7 @@ function TreeDataGrid({
|
|
|
4464
4519
|
for (const column of visibleColumns) map.set(column.id, `p-2 ${alignClassName(column)}`);
|
|
4465
4520
|
return map;
|
|
4466
4521
|
}, [visibleColumns]);
|
|
4467
|
-
const scrollRef =
|
|
4522
|
+
const scrollRef = useRef13(null);
|
|
4468
4523
|
const shouldVirtualize = !groupBy && flatRows.length > virtualizeThreshold;
|
|
4469
4524
|
const virtualizer = useVirtualizer2({
|
|
4470
4525
|
count: flatRows.length,
|