@linzjs/step-ag-grid 29.2.4 → 29.3.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/src/components/GridCell.d.ts +0 -1
- package/dist/src/components/GridWrapper.d.ts +4 -2
- package/dist/step-ag-grid.cjs +50 -21
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +51 -22
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Grid.tsx +72 -43
- package/src/components/GridCell.tsx +0 -1
- package/src/components/GridWrapper.tsx +13 -6
package/package.json
CHANGED
package/src/components/Grid.tsx
CHANGED
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
GetRowIdParams,
|
|
15
15
|
GridOptions,
|
|
16
16
|
GridReadyEvent,
|
|
17
|
-
GridSizeChangedEvent,
|
|
18
17
|
IColumnLimit,
|
|
19
18
|
ModelUpdatedEvent,
|
|
20
19
|
ModuleRegistry,
|
|
@@ -27,15 +26,14 @@ import {
|
|
|
27
26
|
} from 'ag-grid-community';
|
|
28
27
|
import { AgGridReact } from 'ag-grid-react';
|
|
29
28
|
import clsx from 'clsx';
|
|
30
|
-
import { defer, difference, isEmpty, last, omit,
|
|
29
|
+
import { defer, difference, isEmpty, last, omit, xorBy } from 'lodash-es';
|
|
31
30
|
import { ReactElement, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
32
31
|
import { useInterval } from 'usehooks-ts';
|
|
33
32
|
|
|
34
|
-
import { useGridContext } from '../contexts/GridContext';
|
|
33
|
+
import { AutoSizeColumnsResult, useGridContext } from '../contexts/GridContext';
|
|
35
34
|
import { GridUpdatingContext } from '../contexts/GridUpdatingContext';
|
|
36
35
|
import { fnOrVar, isNotEmpty } from '../utils/util';
|
|
37
36
|
import { clickInputWhenContainingCellClicked } from './clickInputWhenContainingCellClicked';
|
|
38
|
-
import { ColDefT } from './GridCell';
|
|
39
37
|
import { GridHeaderSelect } from './gridHeader';
|
|
40
38
|
import { GridContextMenuComponent, useGridContextMenu } from './gridHook';
|
|
41
39
|
import { GridNoRowsOverlay } from './GridNoRowsOverlay';
|
|
@@ -196,6 +194,8 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
196
194
|
|
|
197
195
|
const lastFullResize = useRef<number>();
|
|
198
196
|
|
|
197
|
+
const autoSizeResultRef = useRef<AutoSizeColumnsResult | null>(null);
|
|
198
|
+
const prevRowsVisibleRef = useRef(false);
|
|
199
199
|
const setInitialContentSize = useCallback(() => {
|
|
200
200
|
if (!gridDivRef.current?.clientWidth || rowData == null) {
|
|
201
201
|
// Don't resize grids if they are offscreen as it doesn't work.
|
|
@@ -210,36 +210,50 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
if (sizeColumns === 'auto' ||
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
213
|
+
// 1. First we autosize to get the size of the columns on an infinite grid.
|
|
214
|
+
if (sizeColumns === 'auto' || sizeColumns === 'auto-skip-headers') {
|
|
215
|
+
// You can't skip headers until the grid has content
|
|
216
|
+
const rowsVisible = gridRendered === 'rows-visible';
|
|
217
|
+
const skipHeader = sizeColumns === 'auto-skip-headers' && rowsVisible;
|
|
218
|
+
// If grid was empty and now has content we need to autosize
|
|
219
|
+
if (rowsVisible !== prevRowsVisibleRef.current && rowsVisible) {
|
|
220
|
+
prevRowsVisibleRef.current = rowsVisible;
|
|
221
|
+
autoSizeResultRef.current = null;
|
|
222
|
+
}
|
|
223
|
+
const autoSizeResult =
|
|
224
|
+
autoSizeResultRef.current ??
|
|
225
|
+
autoSizeColumns({
|
|
226
|
+
skipHeader,
|
|
227
|
+
userSizedColIds: new Set(userSizedColIds.current.keys()),
|
|
228
|
+
});
|
|
229
|
+
// Auto-size failed retry later
|
|
230
|
+
if (!autoSizeResult) {
|
|
221
231
|
needsAutoSize.current = true;
|
|
222
232
|
return;
|
|
223
233
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
result.width = Math.min(result.width, maxWidth);
|
|
234
|
+
|
|
235
|
+
autoSizeResultRef.current = autoSizeResult;
|
|
236
|
+
// Calculate the auto-sized width, limit it to maxInitialWidth
|
|
237
|
+
autoSizeResult.width = maxInitialWidth ? Math.min(autoSizeResult.width, maxInitialWidth) : autoSizeResult.width;
|
|
229
238
|
if (gridRendered === 'empty') {
|
|
239
|
+
// If the grid is empty we still do an onContentSize callback, we will do another callback when grid has data
|
|
240
|
+
// We don't do this callback if we have previously had row data, or have already called back for empty
|
|
230
241
|
if (!hasSetContentSizeEmpty.current && !hasSetContentSize.current) {
|
|
231
242
|
hasSetContentSizeEmpty.current = true;
|
|
232
|
-
params.onContentSize?.(
|
|
243
|
+
params.onContentSize?.(autoSizeResult);
|
|
233
244
|
}
|
|
234
245
|
} else if (gridRendered === 'rows-visible') {
|
|
246
|
+
// we have rows now so callback grid size
|
|
235
247
|
if (!hasSetContentSize.current) {
|
|
236
|
-
if
|
|
248
|
+
// Only callback if grid size has settled
|
|
249
|
+
if (lastFullResize.current === autoSizeResult.width) {
|
|
237
250
|
hasSetContentSize.current = true;
|
|
238
|
-
params.onContentSize?.(
|
|
251
|
+
params.onContentSize?.(autoSizeResult);
|
|
239
252
|
} else {
|
|
240
|
-
|
|
253
|
+
// Need to retry callback when size has settelled
|
|
254
|
+
lastFullResize.current = autoSizeResult.width;
|
|
255
|
+
return;
|
|
241
256
|
}
|
|
242
|
-
lastFullResize.current = result.width;
|
|
243
257
|
}
|
|
244
258
|
} else {
|
|
245
259
|
// It should be impossible to get here
|
|
@@ -247,6 +261,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
247
261
|
}
|
|
248
262
|
}
|
|
249
263
|
|
|
264
|
+
// 2. Now we size columns to fit the grid width
|
|
250
265
|
if (sizeColumns !== 'none') {
|
|
251
266
|
sizeColumnsToFit();
|
|
252
267
|
}
|
|
@@ -430,6 +445,8 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
430
445
|
const onRowDataChanged = useCallback(() => {
|
|
431
446
|
const length = rowData?.length ?? 0;
|
|
432
447
|
if (previousRowDataLength.current !== length) {
|
|
448
|
+
// We need to autosize all cells again
|
|
449
|
+
autoSizeResultRef.current = null;
|
|
433
450
|
setInitialContentSize();
|
|
434
451
|
previousRowDataLength.current = length;
|
|
435
452
|
}
|
|
@@ -594,14 +611,17 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
594
611
|
/**
|
|
595
612
|
* Resize columns to fit if required on window/container resize
|
|
596
613
|
*/
|
|
597
|
-
const
|
|
598
|
-
(event:
|
|
614
|
+
const onGridResize = useCallback(
|
|
615
|
+
(event: AgGridEvent<TData>) => {
|
|
599
616
|
if (sizeColumns !== 'none') {
|
|
617
|
+
// Flex columns can expand to fit after resize, but they cannot shrink less than use resized value
|
|
618
|
+
// Double click column resize handle to reset this behaviour
|
|
600
619
|
const columnLimits = [
|
|
601
620
|
...userSizedColIds.current.entries().map(
|
|
602
621
|
([c, w]): IColumnLimit => ({
|
|
603
622
|
key: c,
|
|
604
623
|
minWidth: w,
|
|
624
|
+
maxWidth: w,
|
|
605
625
|
}),
|
|
606
626
|
),
|
|
607
627
|
];
|
|
@@ -619,24 +639,32 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
619
639
|
/**
|
|
620
640
|
* Lock/unlock column width on user edit/reset.
|
|
621
641
|
*/
|
|
622
|
-
const onColumnResized = useCallback(
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
642
|
+
const onColumnResized = useCallback(
|
|
643
|
+
(e: ColumnResizedEvent) => {
|
|
644
|
+
const colId = e.column?.getColId();
|
|
645
|
+
if (colId == null) {
|
|
646
|
+
return;
|
|
647
|
+
}
|
|
648
|
+
const width = e.column?.getActualWidth();
|
|
649
|
+
if (width == null) {
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
switch (e.source) {
|
|
653
|
+
case 'uiColumnResized':
|
|
654
|
+
userSizedColIds.current.set(colId, width);
|
|
655
|
+
const colDef = e.column?.getColDef();
|
|
656
|
+
if (!colDef?.flex) {
|
|
657
|
+
onGridResize(e);
|
|
658
|
+
}
|
|
659
|
+
break;
|
|
660
|
+
case 'autosizeColumns':
|
|
661
|
+
userSizedColIds.current.delete(colId);
|
|
662
|
+
onGridResize(e);
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
[onGridResize],
|
|
667
|
+
);
|
|
640
668
|
|
|
641
669
|
const gridContextMenu = useGridContextMenu({ contextMenu: params.contextMenu, contextMenuSelectRow });
|
|
642
670
|
|
|
@@ -773,6 +801,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
773
801
|
);
|
|
774
802
|
|
|
775
803
|
const selectionColumnDef = useMemo((): SelectionColumnDef => {
|
|
804
|
+
// Note this has to be 1 for hidden otherwise ag-grid does crazy things whilst resizing
|
|
776
805
|
const selectWidth = params.hideSelectColumn ? 0 : selectable && params.onRowDragEnd ? 76 : 48;
|
|
777
806
|
return {
|
|
778
807
|
suppressNavigable: params.hideSelectColumn,
|
|
@@ -840,7 +869,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
840
869
|
animateRows={params.animateRows ?? false}
|
|
841
870
|
rowClassRules={params.rowClassRules}
|
|
842
871
|
getRowId={getRowId}
|
|
843
|
-
onGridSizeChanged={
|
|
872
|
+
onGridSizeChanged={onGridResize}
|
|
844
873
|
suppressColumnVirtualisation={suppressColumnVirtualization}
|
|
845
874
|
suppressClickEdit={true}
|
|
846
875
|
onColumnVisible={setInitialContentSize}
|
|
@@ -71,7 +71,6 @@ export interface ColDefT<TData extends GridBaseRow, ValueType = any> extends Col
|
|
|
71
71
|
editable?: boolean | EditableCallback<TData, ValueType>;
|
|
72
72
|
valueGetter?: string | ValueGetterFunc<TData, ValueType>;
|
|
73
73
|
valueFormatter?: string | ValueFormatterFunc<TData, ValueType>;
|
|
74
|
-
maxInitialWidth?: number;
|
|
75
74
|
cellRenderer?:
|
|
76
75
|
| ((props: ICellRendererParams<TData, ValueType>) => ReactElement | string | false | null | undefined)
|
|
77
76
|
| string;
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import { forwardRef, PropsWithChildren } from 'react';
|
|
2
3
|
|
|
3
4
|
export interface GridWrapperProps {
|
|
5
|
+
className?: string | undefined;
|
|
4
6
|
maxHeight?: number | string;
|
|
5
7
|
}
|
|
6
8
|
|
|
7
|
-
export const GridWrapper =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
export const GridWrapper = forwardRef<HTMLDivElement, PropsWithChildren<GridWrapperProps>>(function GridWrapperFr(
|
|
10
|
+
{ children, maxHeight, className },
|
|
11
|
+
ref,
|
|
12
|
+
) {
|
|
13
|
+
return (
|
|
14
|
+
<div className={clsx('Grid-wrapper', className)} style={{ maxHeight }} ref={ref}>
|
|
15
|
+
{children}
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
});
|