@linzjs/step-ag-grid 29.2.3 → 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/README.md +0 -1
- package/dist/src/components/Grid.d.ts +5 -1
- package/dist/src/components/GridWrapper.d.ts +4 -2
- package/dist/src/contexts/GridContext.d.ts +2 -2
- package/dist/step-ag-grid.cjs +54 -21
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +54 -21
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +2 -2
- package/src/components/Grid.tsx +77 -37
- package/src/components/GridWrapper.tsx +13 -6
- package/src/contexts/GridContext.tsx +2 -2
- package/src/contexts/GridContextProvider.tsx +9 -5
- package/src/stories/grid/gridAutosize/ShowPanelResizingAgGrid/ShowPanelResizingStepAgGrid.tsx +14 -3
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@linzjs/step-ag-grid",
|
|
3
3
|
"repository": "github:linz/step-ag-grid.git",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "29.
|
|
5
|
+
"version": "29.3.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"aggrid",
|
|
8
8
|
"ag-grid",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"@chromatic-com/storybook": "^4.1.1",
|
|
84
84
|
"@linzjs/lui": "^23.11.1",
|
|
85
85
|
"@linzjs/style": "^5.4.0",
|
|
86
|
-
"@linzjs/windows": "^5.
|
|
86
|
+
"@linzjs/windows": "^5.6.0",
|
|
87
87
|
"@rollup/plugin-commonjs": "^28.0.6",
|
|
88
88
|
"@rollup/plugin-json": "^6.1.0",
|
|
89
89
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
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,
|
|
@@ -31,7 +30,7 @@ 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';
|
|
@@ -99,6 +98,10 @@ export interface GridProps<TData extends GridBaseRow = GridBaseRow> {
|
|
|
99
98
|
* If you want to stretch to container width if width is greater than the container add a flex column.
|
|
100
99
|
*/
|
|
101
100
|
sizeColumns?: 'fit' | 'auto' | 'auto-skip-headers' | 'none';
|
|
101
|
+
/**
|
|
102
|
+
* On first don't return a content size larger than this.
|
|
103
|
+
*/
|
|
104
|
+
maxInitialWidth?: number;
|
|
102
105
|
/**
|
|
103
106
|
* When pressing tab whilst editing the grid will select and edit the next cell if available.
|
|
104
107
|
* Once the last cell to edit closes this callback is called.
|
|
@@ -145,6 +148,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
145
148
|
rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40,
|
|
146
149
|
selectable,
|
|
147
150
|
onCellFocused: paramsOnCellFocused,
|
|
151
|
+
maxInitialWidth,
|
|
148
152
|
...params
|
|
149
153
|
}: GridProps<TData>): ReactElement => {
|
|
150
154
|
const {
|
|
@@ -190,6 +194,8 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
190
194
|
|
|
191
195
|
const lastFullResize = useRef<number>();
|
|
192
196
|
|
|
197
|
+
const autoSizeResultRef = useRef<AutoSizeColumnsResult | null>(null);
|
|
198
|
+
const prevRowsVisibleRef = useRef(false);
|
|
193
199
|
const setInitialContentSize = useCallback(() => {
|
|
194
200
|
if (!gridDivRef.current?.clientWidth || rowData == null) {
|
|
195
201
|
// Don't resize grids if they are offscreen as it doesn't work.
|
|
@@ -204,31 +210,50 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
204
210
|
return;
|
|
205
211
|
}
|
|
206
212
|
|
|
207
|
-
|
|
208
|
-
if (sizeColumns === 'auto' ||
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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) {
|
|
215
231
|
needsAutoSize.current = true;
|
|
216
232
|
return;
|
|
217
233
|
}
|
|
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;
|
|
218
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
|
|
219
241
|
if (!hasSetContentSizeEmpty.current && !hasSetContentSize.current) {
|
|
220
242
|
hasSetContentSizeEmpty.current = true;
|
|
221
|
-
params.onContentSize?.(
|
|
243
|
+
params.onContentSize?.(autoSizeResult);
|
|
222
244
|
}
|
|
223
245
|
} else if (gridRendered === 'rows-visible') {
|
|
246
|
+
// we have rows now so callback grid size
|
|
224
247
|
if (!hasSetContentSize.current) {
|
|
225
|
-
if
|
|
248
|
+
// Only callback if grid size has settled
|
|
249
|
+
if (lastFullResize.current === autoSizeResult.width) {
|
|
226
250
|
hasSetContentSize.current = true;
|
|
227
|
-
params.onContentSize?.(
|
|
251
|
+
params.onContentSize?.(autoSizeResult);
|
|
228
252
|
} else {
|
|
229
|
-
|
|
253
|
+
// Need to retry callback when size has settelled
|
|
254
|
+
lastFullResize.current = autoSizeResult.width;
|
|
255
|
+
return;
|
|
230
256
|
}
|
|
231
|
-
lastFullResize.current = result.width;
|
|
232
257
|
}
|
|
233
258
|
} else {
|
|
234
259
|
// It should be impossible to get here
|
|
@@ -236,12 +261,13 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
236
261
|
}
|
|
237
262
|
}
|
|
238
263
|
|
|
264
|
+
// 2. Now we size columns to fit the grid width
|
|
239
265
|
if (sizeColumns !== 'none') {
|
|
240
266
|
sizeColumnsToFit();
|
|
241
267
|
}
|
|
242
268
|
setAutoSized(true);
|
|
243
269
|
needsAutoSize.current = false;
|
|
244
|
-
}, [autoSizeColumns, gridRenderState, params, rowData, sizeColumns, sizeColumnsToFit]);
|
|
270
|
+
}, [autoSizeColumns, gridRenderState, maxInitialWidth, params, rowData, sizeColumns, sizeColumnsToFit]);
|
|
245
271
|
|
|
246
272
|
const lastOwnerDocumentRef = useRef<Document>();
|
|
247
273
|
const wasVisibleRef = useRef(false);
|
|
@@ -419,6 +445,8 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
419
445
|
const onRowDataChanged = useCallback(() => {
|
|
420
446
|
const length = rowData?.length ?? 0;
|
|
421
447
|
if (previousRowDataLength.current !== length) {
|
|
448
|
+
// We need to autosize all cells again
|
|
449
|
+
autoSizeResultRef.current = null;
|
|
422
450
|
setInitialContentSize();
|
|
423
451
|
previousRowDataLength.current = length;
|
|
424
452
|
}
|
|
@@ -583,14 +611,17 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
583
611
|
/**
|
|
584
612
|
* Resize columns to fit if required on window/container resize
|
|
585
613
|
*/
|
|
586
|
-
const
|
|
587
|
-
(event:
|
|
614
|
+
const onGridResize = useCallback(
|
|
615
|
+
(event: AgGridEvent<TData>) => {
|
|
588
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
|
|
589
619
|
const columnLimits = [
|
|
590
620
|
...userSizedColIds.current.entries().map(
|
|
591
621
|
([c, w]): IColumnLimit => ({
|
|
592
622
|
key: c,
|
|
593
623
|
minWidth: w,
|
|
624
|
+
maxWidth: w,
|
|
594
625
|
}),
|
|
595
626
|
),
|
|
596
627
|
];
|
|
@@ -608,24 +639,32 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
608
639
|
/**
|
|
609
640
|
* Lock/unlock column width on user edit/reset.
|
|
610
641
|
*/
|
|
611
|
-
const onColumnResized = useCallback(
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
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
|
+
);
|
|
629
668
|
|
|
630
669
|
const gridContextMenu = useGridContextMenu({ contextMenu: params.contextMenu, contextMenuSelectRow });
|
|
631
670
|
|
|
@@ -762,6 +801,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
762
801
|
);
|
|
763
802
|
|
|
764
803
|
const selectionColumnDef = useMemo((): SelectionColumnDef => {
|
|
804
|
+
// Note this has to be 1 for hidden otherwise ag-grid does crazy things whilst resizing
|
|
765
805
|
const selectWidth = params.hideSelectColumn ? 0 : selectable && params.onRowDragEnd ? 76 : 48;
|
|
766
806
|
return {
|
|
767
807
|
suppressNavigable: params.hideSelectColumn,
|
|
@@ -829,7 +869,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
829
869
|
animateRows={params.animateRows ?? false}
|
|
830
870
|
rowClassRules={params.rowClassRules}
|
|
831
871
|
getRowId={getRowId}
|
|
832
|
-
onGridSizeChanged={
|
|
872
|
+
onGridSizeChanged={onGridResize}
|
|
833
873
|
suppressColumnVirtualisation={suppressColumnVirtualization}
|
|
834
874
|
suppressClickEdit={true}
|
|
835
875
|
onColumnVisible={setInitialContentSize}
|
|
@@ -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
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColDef, GridApi, IRowNode } from 'ag-grid-community';
|
|
1
|
+
import { ColDef, GridApi, IRowNode, ISizeColumnsToFitParams } from 'ag-grid-community';
|
|
2
2
|
import { CsvExportParams } from 'ag-grid-community';
|
|
3
3
|
import { createContext, useContext } from 'react';
|
|
4
4
|
|
|
@@ -47,7 +47,7 @@ export interface GridContextType<TData extends GridBaseRow> {
|
|
|
47
47
|
ensureSelectedRowIsVisible: () => void;
|
|
48
48
|
getFirstRowId: () => number;
|
|
49
49
|
autoSizeColumns: (props?: AutoSizeColumnsProps) => AutoSizeColumnsResult;
|
|
50
|
-
sizeColumnsToFit: () => void;
|
|
50
|
+
sizeColumnsToFit: (paramsOrGridWidth?: ISizeColumnsToFitParams) => void;
|
|
51
51
|
startCellEditing: ({ rowId, colId }: StartCellEditingProps) => Promise<void>;
|
|
52
52
|
// Restores the previous focus after cell editing
|
|
53
53
|
resetFocusedCellAfterCellEditing: () => void;
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
CsvExportParams,
|
|
5
5
|
GridApi,
|
|
6
6
|
IRowNode,
|
|
7
|
+
ISizeColumnsToFitParams,
|
|
7
8
|
ProcessCellForExportParams,
|
|
8
9
|
RowNode,
|
|
9
10
|
} from 'ag-grid-community';
|
|
@@ -455,11 +456,14 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
455
456
|
/**
|
|
456
457
|
* Resize columns to fit container
|
|
457
458
|
*/
|
|
458
|
-
const sizeColumnsToFit = useCallback(
|
|
459
|
-
|
|
460
|
-
gridApi
|
|
461
|
-
|
|
462
|
-
|
|
459
|
+
const sizeColumnsToFit = useCallback(
|
|
460
|
+
(paramsOrGridWidth?: ISizeColumnsToFitParams): void => {
|
|
461
|
+
if (gridApi && !gridApi?.isDestroyed()) {
|
|
462
|
+
gridApi.sizeColumnsToFit(paramsOrGridWidth);
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
[gridApi],
|
|
466
|
+
);
|
|
463
467
|
|
|
464
468
|
/**
|
|
465
469
|
*
|
package/src/stories/grid/gridAutosize/ShowPanelResizingAgGrid/ShowPanelResizingStepAgGrid.tsx
CHANGED
|
@@ -71,7 +71,7 @@ interface ITestRow {
|
|
|
71
71
|
// Note: Resize can only be used from within the panel content.
|
|
72
72
|
export const PanelContentsWithResize = () => {
|
|
73
73
|
// This is the first important bit
|
|
74
|
-
const {
|
|
74
|
+
const { initialResizePanel } = useContext(PanelContext);
|
|
75
75
|
|
|
76
76
|
const columnDefs: ColDefT<ITestRow>[] = useMemo(
|
|
77
77
|
() => [
|
|
@@ -151,7 +151,13 @@ export const PanelContentsWithResize = () => {
|
|
|
151
151
|
const [rowData] = useState([
|
|
152
152
|
/* Your grid row data */
|
|
153
153
|
/* exclude */
|
|
154
|
-
{
|
|
154
|
+
{
|
|
155
|
+
id: 1000,
|
|
156
|
+
position: 'Tester',
|
|
157
|
+
age: 30,
|
|
158
|
+
desc: 'Tests application',
|
|
159
|
+
dd: '1',
|
|
160
|
+
},
|
|
155
161
|
{ id: 1001, position: 'Developer', age: 12, desc: 'Develops application', dd: '2' },
|
|
156
162
|
{ id: 1002, position: 'Manager', age: 65, desc: 'Manages', dd: '3' },
|
|
157
163
|
/* exclude */
|
|
@@ -161,7 +167,12 @@ export const PanelContentsWithResize = () => {
|
|
|
161
167
|
<GridUpdatingContextProvider>
|
|
162
168
|
<GridContextProvider>
|
|
163
169
|
<GridWrapper>
|
|
164
|
-
<Grid
|
|
170
|
+
<Grid
|
|
171
|
+
columnDefs={columnDefs}
|
|
172
|
+
rowData={rowData}
|
|
173
|
+
onContentSize={initialResizePanel}
|
|
174
|
+
sizeColumns={'auto-skip-headers'}
|
|
175
|
+
/>
|
|
165
176
|
</GridWrapper>
|
|
166
177
|
</GridContextProvider>
|
|
167
178
|
</GridUpdatingContextProvider>
|