@alaarab/ogrid-react 2.1.7 → 2.1.8
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/esm/index.js
CHANGED
|
@@ -74,6 +74,9 @@ function getCellValue(item, col) {
|
|
|
74
74
|
if (col.valueGetter) return col.valueGetter(item);
|
|
75
75
|
return item[col.columnId];
|
|
76
76
|
}
|
|
77
|
+
function isColumnEditable(col, item) {
|
|
78
|
+
return col.editable === true || typeof col.editable === "function" && col.editable(item);
|
|
79
|
+
}
|
|
77
80
|
function isColumnGroupDef(c) {
|
|
78
81
|
return "children" in c && Array.isArray(c.children);
|
|
79
82
|
}
|
|
@@ -735,9 +738,9 @@ function getHeaderFilterConfig(col, input) {
|
|
|
735
738
|
function getCellRenderDescriptor(item, col, rowIndex, colIdx, input) {
|
|
736
739
|
const rowId = input.getRowId(item);
|
|
737
740
|
const globalColIndex = colIdx + input.colOffset;
|
|
738
|
-
const colEditable = col
|
|
739
|
-
const canEditInline = input.editable !== false &&
|
|
740
|
-
const canEditPopup = input.editable !== false &&
|
|
741
|
+
const colEditable = isColumnEditable(col, item);
|
|
742
|
+
const canEditInline = input.editable !== false && colEditable && !!input.onCellValueChanged && typeof col.cellEditor !== "function";
|
|
743
|
+
const canEditPopup = input.editable !== false && colEditable && !!input.onCellValueChanged && typeof col.cellEditor === "function" && col.cellEditorPopup !== false;
|
|
741
744
|
const canEditAny = canEditInline || canEditPopup;
|
|
742
745
|
const isEditing = input.editingCell?.rowId === rowId && input.editingCell?.columnId === col.columnId;
|
|
743
746
|
const isActive = !input.isDragging && input.activeCell?.rowIndex === rowIndex && input.activeCell?.columnIndex === globalColIndex;
|
|
@@ -850,6 +853,18 @@ function measureRange(container, range, colOffset) {
|
|
|
850
853
|
height: brRect.bottom - tlRect.top
|
|
851
854
|
};
|
|
852
855
|
}
|
|
856
|
+
function buildCellIndex(container) {
|
|
857
|
+
const index = /* @__PURE__ */ new Map();
|
|
858
|
+
if (!container) return index;
|
|
859
|
+
const cells = container.querySelectorAll("[data-row-index][data-col-index]");
|
|
860
|
+
for (let i = 0; i < cells.length; i++) {
|
|
861
|
+
const el = cells[i];
|
|
862
|
+
const r = el.getAttribute("data-row-index") ?? "";
|
|
863
|
+
const c = el.getAttribute("data-col-index") ?? "";
|
|
864
|
+
index.set(`${r},${c}`, el);
|
|
865
|
+
}
|
|
866
|
+
return index;
|
|
867
|
+
}
|
|
853
868
|
function injectGlobalStyles(id, css) {
|
|
854
869
|
if (typeof document === "undefined") return;
|
|
855
870
|
if (document.getElementById(id)) return;
|
|
@@ -1003,8 +1018,7 @@ function applyCellDeletion(range, items, visibleCols) {
|
|
|
1003
1018
|
if (r >= items.length || c >= visibleCols.length) continue;
|
|
1004
1019
|
const item = items[r];
|
|
1005
1020
|
const col = visibleCols[c];
|
|
1006
|
-
|
|
1007
|
-
if (!colEditable) continue;
|
|
1021
|
+
if (!isColumnEditable(col, item)) continue;
|
|
1008
1022
|
const oldValue = getCellValue(item, col);
|
|
1009
1023
|
const result = parseValue("", oldValue, item, col);
|
|
1010
1024
|
if (!result.valid) continue;
|
|
@@ -1100,8 +1114,7 @@ function applyPastedValues(parsedRows, anchorRow, anchorCol, items, visibleCols)
|
|
|
1100
1114
|
if (targetRow >= items.length || targetCol >= visibleCols.length) continue;
|
|
1101
1115
|
const item = items[targetRow];
|
|
1102
1116
|
const col = visibleCols[targetCol];
|
|
1103
|
-
|
|
1104
|
-
if (!colEditable) continue;
|
|
1117
|
+
if (!isColumnEditable(col, item)) continue;
|
|
1105
1118
|
const rawValue = cells[c] ?? "";
|
|
1106
1119
|
const oldValue = getCellValue(item, col);
|
|
1107
1120
|
const result = parseValue(rawValue, oldValue, item, col);
|
|
@@ -1124,8 +1137,7 @@ function applyCutClear(cutRange, items, visibleCols) {
|
|
|
1124
1137
|
if (r >= items.length || c >= visibleCols.length) continue;
|
|
1125
1138
|
const item = items[r];
|
|
1126
1139
|
const col = visibleCols[c];
|
|
1127
|
-
|
|
1128
|
-
if (!colEditable) continue;
|
|
1140
|
+
if (!isColumnEditable(col, item)) continue;
|
|
1129
1141
|
const oldValue = getCellValue(item, col);
|
|
1130
1142
|
const result = parseValue("", oldValue, item, col);
|
|
1131
1143
|
if (!result.valid) continue;
|
|
@@ -1152,8 +1164,7 @@ function applyFillValues(range, sourceRow, sourceCol, items, visibleCols) {
|
|
|
1152
1164
|
if (row >= items.length || col >= visibleCols.length) continue;
|
|
1153
1165
|
const item = items[row];
|
|
1154
1166
|
const colDef = visibleCols[col];
|
|
1155
|
-
|
|
1156
|
-
if (!colEditable) continue;
|
|
1167
|
+
if (!isColumnEditable(colDef, item)) continue;
|
|
1157
1168
|
const oldValue = getCellValue(item, colDef);
|
|
1158
1169
|
const result = parseValue(startValue, oldValue, item, colDef);
|
|
1159
1170
|
if (!result.valid) continue;
|
|
@@ -2267,18 +2278,6 @@ function useCellSelection(params) {
|
|
|
2267
2278
|
useEffect(() => {
|
|
2268
2279
|
const markedCells = /* @__PURE__ */ new Set();
|
|
2269
2280
|
let cellIndex = null;
|
|
2270
|
-
const buildCellIndex = () => {
|
|
2271
|
-
const wrapper = wrapperRef.current;
|
|
2272
|
-
if (!wrapper) return;
|
|
2273
|
-
cellIndex = /* @__PURE__ */ new Map();
|
|
2274
|
-
const cells = wrapper.querySelectorAll("[data-row-index][data-col-index]");
|
|
2275
|
-
for (let i = 0; i < cells.length; i++) {
|
|
2276
|
-
const el = cells[i];
|
|
2277
|
-
const r = el.getAttribute("data-row-index") ?? "";
|
|
2278
|
-
const c = el.getAttribute("data-col-index") ?? "";
|
|
2279
|
-
cellIndex.set(`${r},${c}`, el);
|
|
2280
|
-
}
|
|
2281
|
-
};
|
|
2282
2281
|
const styleCellInRange = (el, r, c, minR, maxR, minC, maxC, anchor) => {
|
|
2283
2282
|
if (!el.hasAttribute(DRAG_ATTR)) el.setAttribute(DRAG_ATTR, "");
|
|
2284
2283
|
const isAnchor = anchor && r === anchor.row && c === anchor.col;
|
|
@@ -2318,13 +2317,13 @@ function useCellSelection(params) {
|
|
|
2318
2317
|
markedCells.delete(el);
|
|
2319
2318
|
}
|
|
2320
2319
|
}
|
|
2321
|
-
if (!cellIndex) buildCellIndex();
|
|
2320
|
+
if (!cellIndex) cellIndex = buildCellIndex(wrapperRef.current);
|
|
2322
2321
|
for (let r = minR; r <= maxR; r++) {
|
|
2323
2322
|
for (let c = minC; c <= maxC; c++) {
|
|
2324
2323
|
const key = `${r},${c + colOff}`;
|
|
2325
2324
|
let el = cellIndex?.get(key);
|
|
2326
2325
|
if (el && !el.isConnected) {
|
|
2327
|
-
buildCellIndex();
|
|
2326
|
+
cellIndex = buildCellIndex(wrapperRef.current);
|
|
2328
2327
|
el = cellIndex?.get(key);
|
|
2329
2328
|
}
|
|
2330
2329
|
if (el) {
|
|
@@ -2423,7 +2422,7 @@ function useCellSelection(params) {
|
|
|
2423
2422
|
if (!dragMovedRef.current) {
|
|
2424
2423
|
dragMovedRef.current = true;
|
|
2425
2424
|
setIsDragging(true);
|
|
2426
|
-
buildCellIndex();
|
|
2425
|
+
cellIndex = buildCellIndex(wrapperRef.current);
|
|
2427
2426
|
}
|
|
2428
2427
|
lastMousePosRef.current = { cx: e.clientX, cy: e.clientY };
|
|
2429
2428
|
updateAutoScroll();
|
|
@@ -3000,20 +2999,7 @@ function useFillHandle(params) {
|
|
|
3000
2999
|
fillDragEndRef.current = { endRow: fillDrag.startRow, endCol: fillDrag.startCol };
|
|
3001
3000
|
liveFillRangeRef.current = null;
|
|
3002
3001
|
const markedCells = /* @__PURE__ */ new Set();
|
|
3003
|
-
let cellIndex =
|
|
3004
|
-
const buildCellIndex = () => {
|
|
3005
|
-
const wrapper = wrapperRef.current;
|
|
3006
|
-
if (!wrapper) return;
|
|
3007
|
-
cellIndex = /* @__PURE__ */ new Map();
|
|
3008
|
-
const cells = wrapper.querySelectorAll("[data-row-index][data-col-index]");
|
|
3009
|
-
for (let i = 0; i < cells.length; i++) {
|
|
3010
|
-
const el = cells[i];
|
|
3011
|
-
const r = el.getAttribute("data-row-index") ?? "";
|
|
3012
|
-
const c = el.getAttribute("data-col-index") ?? "";
|
|
3013
|
-
cellIndex.set(`${r},${c}`, el);
|
|
3014
|
-
}
|
|
3015
|
-
};
|
|
3016
|
-
buildCellIndex();
|
|
3002
|
+
let cellIndex = buildCellIndex(wrapperRef.current);
|
|
3017
3003
|
const applyDragAttrs = (range) => {
|
|
3018
3004
|
const wrapper = wrapperRef.current;
|
|
3019
3005
|
if (!wrapper) return;
|
|
@@ -3035,8 +3021,8 @@ function useFillHandle(params) {
|
|
|
3035
3021
|
const key = `${r},${c + colOff}`;
|
|
3036
3022
|
let el = cellIndex?.get(key);
|
|
3037
3023
|
if (el && !el.isConnected) {
|
|
3038
|
-
buildCellIndex();
|
|
3039
|
-
el = cellIndex
|
|
3024
|
+
cellIndex = buildCellIndex(wrapperRef.current);
|
|
3025
|
+
el = cellIndex.get(key);
|
|
3040
3026
|
}
|
|
3041
3027
|
if (el) {
|
|
3042
3028
|
if (!el.hasAttribute(DRAG_ATTR2)) el.setAttribute(DRAG_ATTR2, "");
|
|
@@ -3050,7 +3036,6 @@ function useFillHandle(params) {
|
|
|
3050
3036
|
el.removeAttribute(DRAG_ATTR2);
|
|
3051
3037
|
}
|
|
3052
3038
|
markedCells.clear();
|
|
3053
|
-
cellIndex = null;
|
|
3054
3039
|
};
|
|
3055
3040
|
let lastFillMousePos = null;
|
|
3056
3041
|
const resolveRange = (cx, cy) => {
|
|
@@ -3605,7 +3590,9 @@ function useDataGridEditing(params) {
|
|
|
3605
3590
|
pendingEditorValue,
|
|
3606
3591
|
setPendingEditorValue,
|
|
3607
3592
|
onCellValueChanged,
|
|
3608
|
-
setActiveCell
|
|
3593
|
+
setActiveCell,
|
|
3594
|
+
setSelectionRange,
|
|
3595
|
+
colOffset
|
|
3609
3596
|
} = params;
|
|
3610
3597
|
const [popoverAnchorEl, setPopoverAnchorEl] = useState(null);
|
|
3611
3598
|
const visibleColsRef = useLatestRef(params.visibleCols);
|
|
@@ -3635,11 +3622,14 @@ function useDataGridEditing(params) {
|
|
|
3635
3622
|
setPopoverAnchorEl(null);
|
|
3636
3623
|
setPendingEditorValue(void 0);
|
|
3637
3624
|
if (rowIndex < itemsLengthRef.current - 1) {
|
|
3638
|
-
|
|
3625
|
+
const newRow = rowIndex + 1;
|
|
3626
|
+
const localCol = globalColIndex - colOffset;
|
|
3627
|
+
setActiveCell({ rowIndex: newRow, columnIndex: globalColIndex });
|
|
3628
|
+
setSelectionRange({ startRow: newRow, startCol: localCol, endRow: newRow, endCol: localCol });
|
|
3639
3629
|
}
|
|
3640
3630
|
},
|
|
3641
3631
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3642
|
-
[setEditingCell, setPendingEditorValue, setActiveCell, visibleColsRef, itemsLengthRef]
|
|
3632
|
+
[setEditingCell, setPendingEditorValue, setActiveCell, setSelectionRange, colOffset, visibleColsRef, itemsLengthRef]
|
|
3643
3633
|
);
|
|
3644
3634
|
const cancelPopoverEdit = useCallback(() => {
|
|
3645
3635
|
setEditingCell(null);
|
|
@@ -3915,6 +3905,7 @@ function useDataGridState(params) {
|
|
|
3915
3905
|
});
|
|
3916
3906
|
const {
|
|
3917
3907
|
selectionRange,
|
|
3908
|
+
setSelectionRange,
|
|
3918
3909
|
cutRange,
|
|
3919
3910
|
copyRange,
|
|
3920
3911
|
isDragging,
|
|
@@ -3928,7 +3919,9 @@ function useDataGridState(params) {
|
|
|
3928
3919
|
visibleCols,
|
|
3929
3920
|
itemsLength: items.length,
|
|
3930
3921
|
onCellValueChanged,
|
|
3931
|
-
setActiveCell
|
|
3922
|
+
setActiveCell,
|
|
3923
|
+
setSelectionRange,
|
|
3924
|
+
colOffset
|
|
3932
3925
|
});
|
|
3933
3926
|
const {
|
|
3934
3927
|
sortBy,
|
|
@@ -3939,6 +3932,7 @@ function useDataGridState(params) {
|
|
|
3939
3932
|
loadingFilterOptions,
|
|
3940
3933
|
peopleSearch
|
|
3941
3934
|
} = props;
|
|
3935
|
+
const hasPeopleSearch = !!peopleSearch;
|
|
3942
3936
|
const onFilterChangeRef = useLatestRef(onFilterChange);
|
|
3943
3937
|
const peopleSearchRef = useLatestRef(peopleSearch);
|
|
3944
3938
|
const stableOnFilterChange = useCallback(
|
|
@@ -3958,7 +3952,7 @@ function useDataGridState(params) {
|
|
|
3958
3952
|
onFilterChange: stableOnFilterChange,
|
|
3959
3953
|
filterOptions,
|
|
3960
3954
|
loadingFilterOptions,
|
|
3961
|
-
peopleSearch:
|
|
3955
|
+
peopleSearch: hasPeopleSearch ? stablePeopleSearch : void 0
|
|
3962
3956
|
}),
|
|
3963
3957
|
[
|
|
3964
3958
|
sortBy,
|
|
@@ -3968,7 +3962,7 @@ function useDataGridState(params) {
|
|
|
3968
3962
|
stableOnFilterChange,
|
|
3969
3963
|
filterOptions,
|
|
3970
3964
|
loadingFilterOptions,
|
|
3971
|
-
|
|
3965
|
+
hasPeopleSearch,
|
|
3972
3966
|
stablePeopleSearch
|
|
3973
3967
|
]
|
|
3974
3968
|
);
|
|
@@ -24,6 +24,13 @@ export interface UseDataGridEditingParams<T> {
|
|
|
24
24
|
rowIndex: number;
|
|
25
25
|
columnIndex: number;
|
|
26
26
|
} | null) => void;
|
|
27
|
+
setSelectionRange: (range: {
|
|
28
|
+
startRow: number;
|
|
29
|
+
startCol: number;
|
|
30
|
+
endRow: number;
|
|
31
|
+
endCol: number;
|
|
32
|
+
} | null) => void;
|
|
33
|
+
colOffset: number;
|
|
27
34
|
}
|
|
28
35
|
export interface UseDataGridEditingResult<T> {
|
|
29
36
|
editing: DataGridEditingState<T>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { escapeCsvValue, buildCsvHeader, buildCsvRows, exportToCsv, triggerCsvDownload, getCellValue, flattenColumns, buildHeaderRows, getFilterField, mergeFilter, deriveFilterOptionsFromData, getMultiSelectFilterFields, getStatusBarParts, getDataGridStatusBarConfig, getPaginationViewModel, PAGE_SIZE_OPTIONS, MAX_PAGE_BUTTONS, GRID_CONTEXT_MENU_ITEMS, COLUMN_HEADER_MENU_ITEMS, getContextMenuHandlers, getColumnHeaderMenuItems, formatShortcut, parseValue, numberParser, currencyParser, dateParser, emailParser, booleanParser, computeAggregations, processClientSideData, computeNextSortState, measureColumnContentWidth, AUTOSIZE_EXTRA_PX, AUTOSIZE_MAX_PX, findCtrlArrowTarget, computeTabNavigation, rangesEqual, clampSelectionToBounds, computeAutoScrollSpeed, formatCellValueForTsv, formatSelectionAsTsv, parseTsvClipboard, applyPastedValues, applyCutClear, applyFillValues, computeArrowNavigation, applyCellDeletion, applyRangeRowSelection, computeRowSelectionState, UndoRedoStack, } from '@alaarab/ogrid-core';
|
|
1
|
+
export { escapeCsvValue, buildCsvHeader, buildCsvRows, exportToCsv, triggerCsvDownload, getCellValue, flattenColumns, buildHeaderRows, getFilterField, mergeFilter, deriveFilterOptionsFromData, getMultiSelectFilterFields, getStatusBarParts, getDataGridStatusBarConfig, getPaginationViewModel, PAGE_SIZE_OPTIONS, MAX_PAGE_BUTTONS, GRID_CONTEXT_MENU_ITEMS, COLUMN_HEADER_MENU_ITEMS, getContextMenuHandlers, getColumnHeaderMenuItems, formatShortcut, parseValue, numberParser, currencyParser, dateParser, emailParser, booleanParser, computeAggregations, processClientSideData, computeNextSortState, measureColumnContentWidth, AUTOSIZE_EXTRA_PX, AUTOSIZE_MAX_PX, findCtrlArrowTarget, computeTabNavigation, rangesEqual, clampSelectionToBounds, computeAutoScrollSpeed, formatCellValueForTsv, formatSelectionAsTsv, parseTsvClipboard, applyPastedValues, applyCutClear, applyFillValues, computeArrowNavigation, applyCellDeletion, applyRangeRowSelection, computeRowSelectionState, UndoRedoStack, buildCellIndex, } from '@alaarab/ogrid-core';
|
|
2
2
|
export type { CsvColumn, StatusBarPart, StatusBarPartsInput, GridContextMenuItem, GridContextMenuHandlerProps, PaginationViewModel, ParseValueResult, AggregationResult, IColumnHeaderMenuItem, ColumnHeaderMenuInput, ColumnHeaderMenuHandlers, ArrowNavigationContext, ArrowNavigationResult, } from '@alaarab/ogrid-core';
|
|
3
3
|
export { getHeaderFilterConfig, getCellRenderDescriptor, resolveCellDisplayContent, resolveCellStyle, buildInlineEditorProps, buildPopoverEditorProps, getCellInteractionProps, } from './dataGridViewModel';
|
|
4
4
|
export type { HeaderFilterConfigInput, HeaderFilterConfig, CellRenderDescriptorInput, CellRenderDescriptor, CellRenderMode, CellInteractionHandlers, } from './dataGridViewModel';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alaarab/ogrid-react",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.8",
|
|
4
4
|
"description": "OGrid React – React hooks, headless components, and utilities for OGrid data grids.",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"node": ">=18"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@alaarab/ogrid-core": "2.1.
|
|
42
|
+
"@alaarab/ogrid-core": "2.1.8",
|
|
43
43
|
"@tanstack/react-virtual": "^3.0.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|