@ornery/ui-grid-react 0.1.9 → 0.1.10
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/demo/main.tsx +4 -2
- package/dist/UiGrid.d.ts.map +1 -1
- package/dist/index.js +149 -27
- package/dist/index.mjs +150 -27
- package/dist/ui-grid.css +46 -0
- package/dist/useGridState.d.ts +5 -0
- package/dist/useGridState.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/UiGrid.tsx +22 -6
- package/src/ui-grid.css +46 -0
- package/src/useGridState.ts +168 -20
package/demo/main.tsx
CHANGED
|
@@ -45,6 +45,7 @@ function App() {
|
|
|
45
45
|
enableFiltering: true,
|
|
46
46
|
enableGrouping: true,
|
|
47
47
|
enableColumnMoving: true,
|
|
48
|
+
enableColumnResizing: true,
|
|
48
49
|
enableVirtualization: true,
|
|
49
50
|
enableCellEditOnFocus: true,
|
|
50
51
|
virtualizationThreshold: 25,
|
|
@@ -121,7 +122,8 @@ function App() {
|
|
|
121
122
|
<h2>{options.title ?? 'UI Grid'}</h2>
|
|
122
123
|
<p>
|
|
123
124
|
Familiar <code>gridOptions</code> and <code>onRegisterApi</code>, rebuilt with React
|
|
124
|
-
hooks, virtualization, grouping, sorting, filtering,
|
|
125
|
+
hooks, virtualization, grouping, sorting, filtering, column ordering, and Excel-style
|
|
126
|
+
column resizing with drag handles plus double-click auto fit.
|
|
125
127
|
</p>
|
|
126
128
|
</div>
|
|
127
129
|
|
|
@@ -169,7 +171,7 @@ function App() {
|
|
|
169
171
|
</div>
|
|
170
172
|
<p>
|
|
171
173
|
<code>gridOptions</code> compatibility layer: sorting, filtering, grouping, column moving,
|
|
172
|
-
templating, and virtualized rendering.
|
|
174
|
+
column resizing, templating, and virtualized rendering.
|
|
173
175
|
</p>
|
|
174
176
|
</div>
|
|
175
177
|
|
package/dist/UiGrid.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UiGrid.d.ts","sourceRoot":"","sources":["../src/UiGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EACV,WAAW,EACX,uBAAuB,EACvB,6BAA6B,EAC7B,yBAAyB,EACzB,SAAS,EAGV,MAAM,sBAAsB,CAAC;AAK9B,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,KAAK,CAAC,SAAS,CAAC;IACrE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,KAAK,CAAC,SAAS,CAAC;IACzE,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,KAAK,CAAC,SAAS,CAAC;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAO,EACP,aAAa,EACb,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,SAAS,GACV,EAAE,WAAW,2CA+
|
|
1
|
+
{"version":3,"file":"UiGrid.d.ts","sourceRoot":"","sources":["../src/UiGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EACV,WAAW,EACX,uBAAuB,EACvB,6BAA6B,EAC7B,yBAAyB,EACzB,SAAS,EAGV,MAAM,sBAAsB,CAAC;AAK9B,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,KAAK,CAAC,SAAS,CAAC;IACrE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,KAAK,CAAC,SAAS,CAAC;IACzE,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,6BAA6B,KAAK,KAAK,CAAC,SAAS,CAAC;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAO,EACP,aAAa,EACb,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,SAAS,GACV,EAAE,WAAW,2CA+sBb"}
|
package/dist/index.js
CHANGED
|
@@ -136,6 +136,7 @@ function useGridState(options, onRegisterApi) {
|
|
|
136
136
|
});
|
|
137
137
|
const [autoViewportHeight, setAutoViewportHeight] = (0, import_react.useState)(null);
|
|
138
138
|
const [pinnedColumns, setPinnedColumns] = (0, import_react.useState)({});
|
|
139
|
+
const [columnWidthOverrides, setColumnWidthOverrides] = (0, import_react.useState)({});
|
|
139
140
|
const gridContainerRef = (0, import_react.useRef)(null);
|
|
140
141
|
const initializedGridIdRef = (0, import_react.useRef)(null);
|
|
141
142
|
const lastCanvasHeightRef = (0, import_react.useRef)(0);
|
|
@@ -173,6 +174,14 @@ function useGridState(options, onRegisterApi) {
|
|
|
173
174
|
currentPageRef.current = currentPage;
|
|
174
175
|
const pageSizeRef = (0, import_react.useRef)(pageSize);
|
|
175
176
|
pageSizeRef.current = pageSize;
|
|
177
|
+
const setEditingCellState = (0, import_react.useCallback)((nextEditingCell) => {
|
|
178
|
+
editingCellRef.current = nextEditingCell;
|
|
179
|
+
setEditingCell(nextEditingCell);
|
|
180
|
+
}, []);
|
|
181
|
+
const setEditingValueState = (0, import_react.useCallback)((nextEditingValue) => {
|
|
182
|
+
editingValueRef.current = nextEditingValue;
|
|
183
|
+
setEditingValue(nextEditingValue);
|
|
184
|
+
}, []);
|
|
176
185
|
const infiniteScrollStateRef = (0, import_react.useRef)(infiniteScrollState);
|
|
177
186
|
infiniteScrollStateRef.current = infiniteScrollState;
|
|
178
187
|
const optionsRef = (0, import_react.useRef)(options);
|
|
@@ -180,9 +189,13 @@ function useGridState(options, onRegisterApi) {
|
|
|
180
189
|
const rowSize = options.rowHeight ?? 44;
|
|
181
190
|
const visibleColumns = (0, import_react.useMemo)(() => {
|
|
182
191
|
const orderedColumns = orderVisibleColumns(options.columnDefs, columnOrder);
|
|
192
|
+
const applyWidthOverrides = (columns) => columns.map((col) => {
|
|
193
|
+
const override = columnWidthOverrides[col.name];
|
|
194
|
+
return override == null ? col : { ...col, width: override };
|
|
195
|
+
});
|
|
183
196
|
const pinnedEntries = Object.entries(pinnedColumns);
|
|
184
197
|
if (pinnedEntries.length === 0) {
|
|
185
|
-
return orderedColumns;
|
|
198
|
+
return applyWidthOverrides(orderedColumns);
|
|
186
199
|
}
|
|
187
200
|
const columnByName = new Map(orderedColumns.map((column) => [column.name, column]));
|
|
188
201
|
const pinnedLeft = pinnedEntries.filter(([, direction]) => direction === "left").map(([columnName]) => columnByName.get(columnName)).filter((column) => column !== void 0);
|
|
@@ -190,8 +203,8 @@ function useGridState(options, onRegisterApi) {
|
|
|
190
203
|
const centerColumns = orderedColumns.filter(
|
|
191
204
|
(column) => pinnedColumns[column.name] === void 0
|
|
192
205
|
);
|
|
193
|
-
return [...pinnedLeft, ...centerColumns, ...pinnedRight];
|
|
194
|
-
}, [options.columnDefs, columnOrder, pinnedColumns]);
|
|
206
|
+
return applyWidthOverrides([...pinnedLeft, ...centerColumns, ...pinnedRight]);
|
|
207
|
+
}, [options.columnDefs, columnOrder, pinnedColumns, columnWidthOverrides]);
|
|
195
208
|
const visibleColumnsRef = (0, import_react.useRef)(visibleColumns);
|
|
196
209
|
visibleColumnsRef.current = visibleColumns;
|
|
197
210
|
const pipeline = (0, import_react.useMemo)(() => {
|
|
@@ -328,11 +341,12 @@ function useGridState(options, onRegisterApi) {
|
|
|
328
341
|
if (retry) requestAnimationFrame(() => doFocus(false));
|
|
329
342
|
return;
|
|
330
343
|
}
|
|
331
|
-
target.focus();
|
|
344
|
+
target.focus({ preventScroll: true });
|
|
332
345
|
if (retry && container.ownerDocument.activeElement !== target) {
|
|
333
346
|
requestAnimationFrame(() => doFocus(false));
|
|
334
347
|
}
|
|
335
348
|
};
|
|
349
|
+
doFocus(true);
|
|
336
350
|
queueMicrotask(() => doFocus(true));
|
|
337
351
|
}, []);
|
|
338
352
|
const focusEditorInput = (0, import_react.useCallback)((focusToken) => {
|
|
@@ -660,8 +674,8 @@ function useGridState(options, onRegisterApi) {
|
|
|
660
674
|
gridApiRef.current,
|
|
661
675
|
{
|
|
662
676
|
setFocusedCell: (fc) => setFocusedCell(fc),
|
|
663
|
-
setEditingCell:
|
|
664
|
-
setEditingValue:
|
|
677
|
+
setEditingCell: setEditingCellState,
|
|
678
|
+
setEditingValue: setEditingValueState
|
|
665
679
|
},
|
|
666
680
|
row,
|
|
667
681
|
column,
|
|
@@ -673,15 +687,15 @@ function useGridState(options, onRegisterApi) {
|
|
|
673
687
|
queueMicrotask(() => focusEditorInput(focusToken));
|
|
674
688
|
}
|
|
675
689
|
},
|
|
676
|
-
[focusEditorInput]
|
|
690
|
+
[focusEditorInput, setEditingCellState, setEditingValueState]
|
|
677
691
|
);
|
|
678
692
|
const commitCellEditFn = (0, import_react.useCallback)(
|
|
679
693
|
(direction, restoreFocus = true) => {
|
|
680
694
|
const result = (0, import_ui_grid_core2.commitGridCellEditCommand)(gridApiRef.current, {
|
|
681
695
|
getEditingCell: () => editingCellRef.current,
|
|
682
696
|
getEditingValue: () => editingValueRef.current,
|
|
683
|
-
setEditingCell:
|
|
684
|
-
setEditingValue:
|
|
697
|
+
setEditingCell: setEditingCellState,
|
|
698
|
+
setEditingValue: setEditingValueState,
|
|
685
699
|
findRowById: (rowId) => (0, import_ui_grid_core2.findGridRowById)(buildRowsFromData(optionsRef.current.data), rowId),
|
|
686
700
|
findColumnByName: (columnName) => visibleColumnsRef.current.find((c) => c.name === columnName),
|
|
687
701
|
parseEditedValue: (column, value, oldValue) => (0, import_ui_grid_core2.parseGridEditedValue)(column, value, oldValue),
|
|
@@ -699,25 +713,25 @@ function useGridState(options, onRegisterApi) {
|
|
|
699
713
|
focusRenderedCell(result.focusTarget);
|
|
700
714
|
}
|
|
701
715
|
},
|
|
702
|
-
[buildRowsFromData, focusRenderedCell]
|
|
716
|
+
[buildRowsFromData, focusRenderedCell, setEditingCellState, setEditingValueState]
|
|
703
717
|
);
|
|
704
718
|
const cancelCellEditFn = (0, import_react.useCallback)(() => {
|
|
705
719
|
const hadEditingCell = editingCellRef.current !== null;
|
|
706
720
|
const result = (0, import_ui_grid_core2.cancelGridCellEditCommand)(gridApiRef.current, {
|
|
707
721
|
getEditingCell: () => editingCellRef.current,
|
|
708
|
-
setEditingCell:
|
|
709
|
-
setEditingValue:
|
|
722
|
+
setEditingCell: setEditingCellState,
|
|
723
|
+
setEditingValue: setEditingValueState,
|
|
710
724
|
findRowById: (rowId) => (0, import_ui_grid_core2.findGridRowById)(buildRowsFromData(optionsRef.current.data), rowId),
|
|
711
725
|
findColumnByName: (columnName) => visibleColumnsRef.current.find((c) => c.name === columnName)
|
|
712
726
|
});
|
|
713
727
|
if (!hadEditingCell) return;
|
|
714
728
|
editorFocusTokenRef.current += 1;
|
|
715
729
|
if (result.focusTarget) focusRenderedCell(result.focusTarget);
|
|
716
|
-
}, [buildRowsFromData, focusRenderedCell]);
|
|
730
|
+
}, [buildRowsFromData, focusRenderedCell, setEditingCellState, setEditingValueState]);
|
|
717
731
|
const moveFocusFn = (0, import_react.useCallback)(
|
|
718
732
|
(row, column, direction, triggerEvent) => {
|
|
719
733
|
const nextCell = (0, import_ui_grid_core2.findNextGridCell)({
|
|
720
|
-
rows: pipelineRef.current.
|
|
734
|
+
rows: pipelineRef.current.displayItems.filter((item) => item.kind === "row").map((item) => item.row),
|
|
721
735
|
columns: visibleColumnsRef.current,
|
|
722
736
|
rowId: row.id,
|
|
723
737
|
columnName: column.name,
|
|
@@ -794,8 +808,8 @@ function useGridState(options, onRegisterApi) {
|
|
|
794
808
|
setHiddenRowReasons({});
|
|
795
809
|
setCollapsedGroups({});
|
|
796
810
|
setFocusedCell(null);
|
|
797
|
-
|
|
798
|
-
|
|
811
|
+
setEditingCellState(null);
|
|
812
|
+
setEditingValueState("");
|
|
799
813
|
setExpandedRows({});
|
|
800
814
|
setExpandedTreeRows({});
|
|
801
815
|
setColumnOrder(options.columnDefs.map((column) => column.name));
|
|
@@ -829,7 +843,7 @@ function useGridState(options, onRegisterApi) {
|
|
|
829
843
|
}
|
|
830
844
|
}, [pipeline, gridApi, rowSize]);
|
|
831
845
|
(0, import_react.useEffect)(() => {
|
|
832
|
-
if (!import_ui_grid_core2.FEATURE_AUTO_RESIZE
|
|
846
|
+
if (!import_ui_grid_core2.FEATURE_AUTO_RESIZE) return;
|
|
833
847
|
const container = gridContainerRef.current;
|
|
834
848
|
if (!container) return;
|
|
835
849
|
const observer = (0, import_ui_grid_core2.observeGridHostSize)(container, ({ height: nextHeight, width: nextWidth }) => {
|
|
@@ -931,6 +945,9 @@ function useGridState(options, onRegisterApi) {
|
|
|
931
945
|
const isFocusedCellFn = (0, import_react.useCallback)((row, column) => {
|
|
932
946
|
return (0, import_ui_grid_core2.isGridCellPosition)(focusedCellRef.current, row.id, column.name);
|
|
933
947
|
}, []);
|
|
948
|
+
const isFocusedRowFn = (0, import_react.useCallback)((row) => {
|
|
949
|
+
return focusedCellRef.current?.rowId === row.id || editingCellRef.current?.rowId === row.id;
|
|
950
|
+
}, []);
|
|
934
951
|
const isEditingCellFn = (0, import_react.useCallback)((row, column) => {
|
|
935
952
|
return (0, import_ui_grid_core2.isGridCellPosition)(editingCellRef.current, row.id, column.name);
|
|
936
953
|
}, []);
|
|
@@ -1054,34 +1071,45 @@ function useGridState(options, onRegisterApi) {
|
|
|
1054
1071
|
);
|
|
1055
1072
|
const handleCellKeyDownFn = (0, import_react.useCallback)(
|
|
1056
1073
|
(row, column, event) => {
|
|
1057
|
-
|
|
1074
|
+
if ((0, import_ui_grid_core2.isGridNavigationKey)(event.key)) {
|
|
1075
|
+
setFocusedCell({ rowId: row.id, columnName: column.name });
|
|
1076
|
+
} else {
|
|
1077
|
+
focusCellFn(row, column, event.nativeEvent);
|
|
1078
|
+
}
|
|
1058
1079
|
switch (event.key) {
|
|
1059
1080
|
case "ArrowLeft":
|
|
1060
1081
|
event.preventDefault();
|
|
1082
|
+
event.stopPropagation();
|
|
1061
1083
|
moveFocusFn(row, column, "left", event.nativeEvent);
|
|
1062
1084
|
return;
|
|
1063
1085
|
case "ArrowRight":
|
|
1064
1086
|
event.preventDefault();
|
|
1087
|
+
event.stopPropagation();
|
|
1065
1088
|
moveFocusFn(row, column, "right", event.nativeEvent);
|
|
1066
1089
|
return;
|
|
1067
1090
|
case "ArrowUp":
|
|
1068
1091
|
event.preventDefault();
|
|
1092
|
+
event.stopPropagation();
|
|
1069
1093
|
moveFocusFn(row, column, "up", event.nativeEvent);
|
|
1070
1094
|
return;
|
|
1071
1095
|
case "ArrowDown":
|
|
1072
1096
|
event.preventDefault();
|
|
1097
|
+
event.stopPropagation();
|
|
1073
1098
|
moveFocusFn(row, column, "down", event.nativeEvent);
|
|
1074
1099
|
return;
|
|
1075
1100
|
case "Tab":
|
|
1076
1101
|
event.preventDefault();
|
|
1102
|
+
event.stopPropagation();
|
|
1077
1103
|
moveFocusFn(row, column, event.shiftKey ? "left" : "right", event.nativeEvent);
|
|
1078
1104
|
return;
|
|
1079
1105
|
case "Enter":
|
|
1080
1106
|
event.preventDefault();
|
|
1107
|
+
event.stopPropagation();
|
|
1081
1108
|
moveFocusFn(row, column, event.shiftKey ? "up" : "down", event.nativeEvent);
|
|
1082
1109
|
return;
|
|
1083
1110
|
case "F2":
|
|
1084
1111
|
event.preventDefault();
|
|
1112
|
+
event.stopPropagation();
|
|
1085
1113
|
if (isCellEditable(row, column, event.nativeEvent)) {
|
|
1086
1114
|
startCellEditFn(row, column, event.nativeEvent);
|
|
1087
1115
|
}
|
|
@@ -1090,6 +1118,7 @@ function useGridState(options, onRegisterApi) {
|
|
|
1090
1118
|
case "Delete":
|
|
1091
1119
|
if (isCellEditable(row, column, event.nativeEvent)) {
|
|
1092
1120
|
event.preventDefault();
|
|
1121
|
+
event.stopPropagation();
|
|
1093
1122
|
startCellEditFn(row, column, event.nativeEvent, "");
|
|
1094
1123
|
}
|
|
1095
1124
|
return;
|
|
@@ -1098,6 +1127,7 @@ function useGridState(options, onRegisterApi) {
|
|
|
1098
1127
|
}
|
|
1099
1128
|
if ((0, import_ui_grid_core2.isPrintableGridKey)(event.key, event.ctrlKey, event.metaKey, event.altKey) && isCellEditable(row, column, event.nativeEvent)) {
|
|
1100
1129
|
event.preventDefault();
|
|
1130
|
+
event.stopPropagation();
|
|
1101
1131
|
startCellEditFn(row, column, event.nativeEvent, event.key);
|
|
1102
1132
|
}
|
|
1103
1133
|
},
|
|
@@ -1113,23 +1143,32 @@ function useGridState(options, onRegisterApi) {
|
|
|
1113
1143
|
[focusCellFn, isCellEditable, startCellEditFn]
|
|
1114
1144
|
);
|
|
1115
1145
|
const updateEditingValueFn = (0, import_react.useCallback)((value) => {
|
|
1116
|
-
|
|
1117
|
-
}, []);
|
|
1146
|
+
setEditingValueState(value);
|
|
1147
|
+
}, [setEditingValueState]);
|
|
1118
1148
|
const handleEditorKeyDownFn = (0, import_react.useCallback)(
|
|
1119
1149
|
(event) => {
|
|
1120
1150
|
if (event.key === "Escape") {
|
|
1121
1151
|
event.preventDefault();
|
|
1152
|
+
event.stopPropagation();
|
|
1122
1153
|
cancelCellEditFn();
|
|
1123
1154
|
return;
|
|
1124
1155
|
}
|
|
1125
1156
|
if (event.key === "Enter") {
|
|
1126
1157
|
event.preventDefault();
|
|
1158
|
+
event.stopPropagation();
|
|
1127
1159
|
commitCellEditFn(event.shiftKey ? "up" : "down");
|
|
1128
1160
|
return;
|
|
1129
1161
|
}
|
|
1130
1162
|
if (event.key === "Tab") {
|
|
1131
1163
|
event.preventDefault();
|
|
1164
|
+
event.stopPropagation();
|
|
1132
1165
|
commitCellEditFn(event.shiftKey ? "left" : "right");
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
1169
|
+
event.preventDefault();
|
|
1170
|
+
event.stopPropagation();
|
|
1171
|
+
commitCellEditFn(event.key === "ArrowUp" ? "up" : "down");
|
|
1133
1172
|
}
|
|
1134
1173
|
},
|
|
1135
1174
|
[cancelCellEditFn, commitCellEditFn]
|
|
@@ -1191,6 +1230,72 @@ function useGridState(options, onRegisterApi) {
|
|
|
1191
1230
|
},
|
|
1192
1231
|
[setPaginationPageSizeFn]
|
|
1193
1232
|
);
|
|
1233
|
+
const canResizeColumnsFn = (0, import_react.useCallback)(() => {
|
|
1234
|
+
return optionsRef.current.enableColumnResizing !== false;
|
|
1235
|
+
}, []);
|
|
1236
|
+
const setColumnWidthOverrideFn = (0, import_react.useCallback)((columnName, widthPx) => {
|
|
1237
|
+
const nextWidth = `${Math.max(88, Math.round(widthPx))}px`;
|
|
1238
|
+
setColumnWidthOverrides((current) => ({ ...current, [columnName]: nextWidth }));
|
|
1239
|
+
}, []);
|
|
1240
|
+
const measureAutoColumnWidthFn = (0, import_react.useCallback)((columnName) => {
|
|
1241
|
+
const container = gridContainerRef.current;
|
|
1242
|
+
if (container == null) return 176;
|
|
1243
|
+
const escaped = CSS.escape ? CSS.escape(columnName) : columnName.replace(/([\\".#:[\](){}+~> ])/g, "\\$1");
|
|
1244
|
+
const selectors = [
|
|
1245
|
+
`.header-cell[data-col-name="${escaped}"]`,
|
|
1246
|
+
`.filter-cell[data-col-name="${escaped}"]`,
|
|
1247
|
+
`.body-cell[data-col-name="${escaped}"] .cell-shell`
|
|
1248
|
+
];
|
|
1249
|
+
let maxWidth = 0;
|
|
1250
|
+
for (const selector of selectors) {
|
|
1251
|
+
const elements = container.querySelectorAll(selector);
|
|
1252
|
+
for (const element of elements) {
|
|
1253
|
+
maxWidth = Math.max(maxWidth, element.scrollWidth);
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
return maxWidth + 12;
|
|
1257
|
+
}, []);
|
|
1258
|
+
const handleHeaderResizeMouseDownFn = (0, import_react.useCallback)(
|
|
1259
|
+
(column, event) => {
|
|
1260
|
+
if (!canResizeColumnsFn()) return;
|
|
1261
|
+
event.preventDefault();
|
|
1262
|
+
event.stopPropagation();
|
|
1263
|
+
const headerCell = event.currentTarget.closest(".header-cell");
|
|
1264
|
+
if (headerCell == null) return;
|
|
1265
|
+
const startX = event.clientX;
|
|
1266
|
+
const startWidth = headerCell.getBoundingClientRect().width;
|
|
1267
|
+
let lastWidth = startWidth;
|
|
1268
|
+
const handleMove = (moveEvent) => {
|
|
1269
|
+
lastWidth = Math.max(88, startWidth + (moveEvent.clientX - startX));
|
|
1270
|
+
const widthStr = `${Math.round(lastWidth)}px`;
|
|
1271
|
+
const newTemplate = buildGridTemplateColumns(
|
|
1272
|
+
visibleColumnsRef.current.map(
|
|
1273
|
+
(c) => c.name === column.name ? { ...c, width: widthStr } : c
|
|
1274
|
+
)
|
|
1275
|
+
);
|
|
1276
|
+
gridContainerRef.current?.querySelectorAll(".header-grid, .filter-grid, .body-grid").forEach((el) => {
|
|
1277
|
+
el.style.gridTemplateColumns = newTemplate;
|
|
1278
|
+
});
|
|
1279
|
+
};
|
|
1280
|
+
const handleUp = () => {
|
|
1281
|
+
window.removeEventListener("mousemove", handleMove);
|
|
1282
|
+
window.removeEventListener("mouseup", handleUp);
|
|
1283
|
+
setColumnWidthOverrideFn(column.name, lastWidth);
|
|
1284
|
+
};
|
|
1285
|
+
window.addEventListener("mousemove", handleMove);
|
|
1286
|
+
window.addEventListener("mouseup", handleUp);
|
|
1287
|
+
},
|
|
1288
|
+
[canResizeColumnsFn, setColumnWidthOverrideFn]
|
|
1289
|
+
);
|
|
1290
|
+
const autoSizeColumnFn = (0, import_react.useCallback)(
|
|
1291
|
+
(column, event) => {
|
|
1292
|
+
if (!canResizeColumnsFn()) return;
|
|
1293
|
+
event.preventDefault();
|
|
1294
|
+
event.stopPropagation();
|
|
1295
|
+
setColumnWidthOverrideFn(column.name, measureAutoColumnWidthFn(column.name));
|
|
1296
|
+
},
|
|
1297
|
+
[canResizeColumnsFn, setColumnWidthOverrideFn, measureAutoColumnWidthFn]
|
|
1298
|
+
);
|
|
1194
1299
|
const onViewportScrollFn = (0, import_react.useCallback)((startIndex) => {
|
|
1195
1300
|
if (!scrollingRef.current) {
|
|
1196
1301
|
scrollingRef.current = true;
|
|
@@ -1248,6 +1353,7 @@ function useGridState(options, onRegisterApi) {
|
|
|
1248
1353
|
paginationSelectedPageSize,
|
|
1249
1354
|
rowSize,
|
|
1250
1355
|
viewportHeightPx,
|
|
1356
|
+
autoViewportHeight,
|
|
1251
1357
|
headerLabel: headerLabelFn,
|
|
1252
1358
|
isGroupItem: isGroupItemFn,
|
|
1253
1359
|
isExpandableItem: isExpandableItemFn,
|
|
@@ -1263,6 +1369,7 @@ function useGridState(options, onRegisterApi) {
|
|
|
1263
1369
|
groupDisclosureLabel: groupDisclosureLabelFn,
|
|
1264
1370
|
displayValue: displayValueFn,
|
|
1265
1371
|
isFocusedCell: isFocusedCellFn,
|
|
1372
|
+
isFocusedRow: isFocusedRowFn,
|
|
1266
1373
|
isEditingCell: isEditingCellFn,
|
|
1267
1374
|
editorInputType: editorInputTypeFn,
|
|
1268
1375
|
cellContext: cellContextFn,
|
|
@@ -1309,6 +1416,9 @@ function useGridState(options, onRegisterApi) {
|
|
|
1309
1416
|
toggleTreeRow: toggleTreeRowFn,
|
|
1310
1417
|
moveColumn: moveColumnFn,
|
|
1311
1418
|
moveVisibleColumn: moveVisibleColumnFn,
|
|
1419
|
+
canResizeColumns: canResizeColumnsFn,
|
|
1420
|
+
handleHeaderResizeMouseDown: handleHeaderResizeMouseDownFn,
|
|
1421
|
+
autoSizeColumn: autoSizeColumnFn,
|
|
1312
1422
|
nextPage: nextPageFn,
|
|
1313
1423
|
previousPage: previousPageFn,
|
|
1314
1424
|
onPageSizeChange: onPageSizeChangeFn,
|
|
@@ -1396,6 +1506,7 @@ function UiGrid({
|
|
|
1396
1506
|
virtualizationEnabled,
|
|
1397
1507
|
rowSize,
|
|
1398
1508
|
editingValue,
|
|
1509
|
+
autoViewportHeight,
|
|
1399
1510
|
sortingFeature,
|
|
1400
1511
|
filteringFeature,
|
|
1401
1512
|
groupingFeature,
|
|
@@ -1413,10 +1524,8 @@ function UiGrid({
|
|
|
1413
1524
|
const [headerStickyHeight, setHeaderStickyHeight] = import_react3.default.useState(0);
|
|
1414
1525
|
const [filterStickyHeight, setFilterStickyHeight] = import_react3.default.useState(0);
|
|
1415
1526
|
const stickyChromeHeight = headerStickyHeight + filterStickyHeight;
|
|
1416
|
-
const
|
|
1417
|
-
|
|
1418
|
-
(options.viewportHeight ?? 560) - stickyChromeHeight
|
|
1419
|
-
);
|
|
1527
|
+
const resolvedViewportHeight = options.viewportHeight ?? (autoViewportHeight && autoViewportHeight > 0 ? autoViewportHeight : 560);
|
|
1528
|
+
const bodyViewportHeight = Math.max(rowSize, resolvedViewportHeight - stickyChromeHeight);
|
|
1420
1529
|
const virtualScroll = useVirtualScroll({
|
|
1421
1530
|
itemCount: displayItems.length,
|
|
1422
1531
|
itemSize: rowSize,
|
|
@@ -1426,7 +1535,7 @@ function UiGrid({
|
|
|
1426
1535
|
const [openPinMenuColumn, setOpenPinMenuColumn] = import_react3.default.useState(null);
|
|
1427
1536
|
const [draggedColumnName, setDraggedColumnName] = import_react3.default.useState(null);
|
|
1428
1537
|
const [dropTargetColumnName, setDropTargetColumnName] = import_react3.default.useState(null);
|
|
1429
|
-
const scrollContainerHeight = `${
|
|
1538
|
+
const scrollContainerHeight = `${resolvedViewportHeight}px`;
|
|
1430
1539
|
function renderHeaderContent(column) {
|
|
1431
1540
|
const value = state.headerLabel(column);
|
|
1432
1541
|
const context = {
|
|
@@ -1732,6 +1841,7 @@ function UiGrid({
|
|
|
1732
1841
|
if (column.align === "center") classes.push("align-center");
|
|
1733
1842
|
if (column.align === "end") classes.push("align-end");
|
|
1734
1843
|
if (state.isFocusedCell(item.row, column)) classes.push("cell-focused");
|
|
1844
|
+
if (state.isFocusedRow(item.row)) classes.push("row-focused");
|
|
1735
1845
|
if (cellEditFeature && state.isEditingCell(item.row, column)) classes.push("cell-editing");
|
|
1736
1846
|
return classes.join(" ");
|
|
1737
1847
|
}
|
|
@@ -1779,7 +1889,7 @@ function UiGrid({
|
|
|
1779
1889
|
{
|
|
1780
1890
|
className: `header-cell ui-grid-header-cell${sortingFeature && state.sortDirection(column) !== "none" ? " is-active" : ""}${pinned ? " is-pinned" : ""}${pinMenuOpen ? " is-pin-menu-open" : ""}${draggedColumnName === column.name ? " is-dragging" : ""}${dropTargetColumnName === column.name ? " is-drag-target" : ""}`,
|
|
1781
1891
|
"data-part": "header-cell",
|
|
1782
|
-
|
|
1892
|
+
"data-col-name": column.name,
|
|
1783
1893
|
"aria-sort": sortingFeature ? state.sortAriaSort(column) : void 0,
|
|
1784
1894
|
draggable: columnMovingFeature,
|
|
1785
1895
|
onDragStart: (event) => handleHeaderDragStart(column, event),
|
|
@@ -1902,7 +2012,19 @@ function UiGrid({
|
|
|
1902
2012
|
]
|
|
1903
2013
|
}
|
|
1904
2014
|
)
|
|
1905
|
-
] })
|
|
2015
|
+
] }),
|
|
2016
|
+
state.canResizeColumns() && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2017
|
+
"button",
|
|
2018
|
+
{
|
|
2019
|
+
type: "button",
|
|
2020
|
+
className: "column-resizer",
|
|
2021
|
+
"data-col-name": column.name,
|
|
2022
|
+
"aria-label": `Resize ${state.headerLabel(column)} column`,
|
|
2023
|
+
title: "Drag to resize, double-click to auto fit",
|
|
2024
|
+
onMouseDown: (event) => state.handleHeaderResizeMouseDown(column, event),
|
|
2025
|
+
onDoubleClick: (event) => state.autoSizeColumn(column, event)
|
|
2026
|
+
}
|
|
2027
|
+
)
|
|
1906
2028
|
]
|
|
1907
2029
|
},
|
|
1908
2030
|
column.name
|