@linzjs/step-ag-grid 29.11.2 → 29.11.4
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/contexts/GridContext.d.ts +1 -1
- package/dist/step-ag-grid.cjs +122 -79
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +123 -80
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Grid.tsx +104 -65
- package/src/contexts/GridContext.tsx +3 -3
- package/src/contexts/GridContextProvider.tsx +34 -20
- package/src/stories/grid/GridPopoutEditGeneric.stories.tsx +9 -3
- package/src/stories/grid/gridAutosize/GridAutoSize.stories.tsx +84 -0
- package/src/stories/grid/gridAutosize/GridFitSize.stories.tsx +84 -0
- package/src/stories/grid/gridAutosize/GridFitSizeFlex.stories.tsx +86 -0
- package/src/stories/grid/gridAutosize/ShowPanelResizingAgGrid/ShowPanelResizingStepAgGrid.tsx +49 -16
package/dist/step-ag-grid.esm.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import { LuiMiniSpinner, LuiStatusSpinner, LuiIcon, LuiButtonGroup, LuiButton, LuiCheckboxInput } from '@linzjs/lui';
|
|
3
3
|
import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community';
|
|
4
4
|
import { AgGridReact } from 'ag-grid-react';
|
|
5
|
-
import { negate, isEmpty, findIndex, defer, debounce as debounce$1, xorBy, last, difference, delay, omit, sortBy, partition, compact, pick, groupBy, fromPairs, toPairs, isEqual, pull, filter,
|
|
5
|
+
import { negate, isEmpty, findIndex, defer, debounce as debounce$1, xorBy, last, difference, delay, omit, sortBy, partition, compact, pick, groupBy, fromPairs, toPairs, isEqual, pull, filter, remove, sumBy, flatten, castArray } from 'lodash-es';
|
|
6
6
|
import React, { useRef, useLayoutEffect, useEffect, createContext, useContext, useState, useMemo, memo, forwardRef, useCallback, useReducer, cloneElement, useImperativeHandle, Fragment as Fragment$1, useId } from 'react';
|
|
7
7
|
import { unstable_batchedUpdates, flushSync, createPortal } from 'react-dom';
|
|
8
8
|
import { createRoot } from 'react-dom/client';
|
|
@@ -507,9 +507,9 @@ const GridContext = createContext({
|
|
|
507
507
|
console.error('no context provider for getFirstRowId');
|
|
508
508
|
return -1;
|
|
509
509
|
},
|
|
510
|
-
autoSizeColumns: () => {
|
|
510
|
+
autoSizeColumns: async () => {
|
|
511
511
|
console.error('no context provider for autoSizeColumns');
|
|
512
|
-
return null;
|
|
512
|
+
return Promise.resolve(null);
|
|
513
513
|
},
|
|
514
514
|
sizeColumnsToFit: () => {
|
|
515
515
|
console.error('no context provider for autoSizeAllColumns');
|
|
@@ -2785,67 +2785,77 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
2785
2785
|
const needsAutoSize = useRef(true);
|
|
2786
2786
|
const autoSizeResultRef = useRef(null);
|
|
2787
2787
|
const prevRowsVisibleRef = useRef(false);
|
|
2788
|
-
const
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
needsAutoSize.current = true;
|
|
2792
|
-
return;
|
|
2793
|
-
}
|
|
2794
|
-
const gridRendered = gridRenderState();
|
|
2795
|
-
if (gridRendered === null) {
|
|
2796
|
-
// Don't resize until grid has rendered, or it has 0 rows.
|
|
2797
|
-
needsAutoSize.current = true;
|
|
2788
|
+
const initialContentSizeInProgressRef = useRef(false);
|
|
2789
|
+
const setInitialContentSize = useCallback(async () => {
|
|
2790
|
+
if (initialContentSizeInProgressRef.current) {
|
|
2798
2791
|
return;
|
|
2799
2792
|
}
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
prevRowsVisibleRef.current = rowsVisible;
|
|
2808
|
-
autoSizeResultRef.current = null;
|
|
2793
|
+
initialContentSizeInProgressRef.current = true;
|
|
2794
|
+
try {
|
|
2795
|
+
needsAutoSize.current = false;
|
|
2796
|
+
if (!gridDivRef.current?.clientWidth || rowData == null) {
|
|
2797
|
+
// Don't resize grids if they are offscreen as it doesn't work.
|
|
2798
|
+
needsAutoSize.current = true;
|
|
2799
|
+
return;
|
|
2809
2800
|
}
|
|
2810
|
-
const
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
userSizedColIds: new Set(userSizedColIds.current.keys()),
|
|
2814
|
-
});
|
|
2815
|
-
// Auto-size failed retry later
|
|
2816
|
-
if (!autoSizeResult) {
|
|
2801
|
+
const gridRendered = gridRenderState();
|
|
2802
|
+
if (gridRendered === null) {
|
|
2803
|
+
// Don't resize until grid has rendered, or it has 0 rows.
|
|
2817
2804
|
needsAutoSize.current = true;
|
|
2818
2805
|
return;
|
|
2819
2806
|
}
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
//
|
|
2826
|
-
if (
|
|
2827
|
-
|
|
2828
|
-
|
|
2807
|
+
// 1. First we autosize to get the size of the columns on an infinite grid.
|
|
2808
|
+
if (sizeColumns === 'auto' || sizeColumns === 'auto-skip-headers') {
|
|
2809
|
+
// You can't skip headers until the grid has content
|
|
2810
|
+
const rowsVisible = gridRendered === 'rows-visible';
|
|
2811
|
+
const skipHeader = sizeColumns === 'auto-skip-headers' && rowsVisible;
|
|
2812
|
+
// If grid was empty and now has content we need to autosize
|
|
2813
|
+
if (rowsVisible !== prevRowsVisibleRef.current && rowsVisible) {
|
|
2814
|
+
prevRowsVisibleRef.current = rowsVisible;
|
|
2815
|
+
autoSizeResultRef.current = null;
|
|
2829
2816
|
}
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2817
|
+
const autoSizeResult = autoSizeResultRef.current ??
|
|
2818
|
+
(await autoSizeColumns({
|
|
2819
|
+
skipHeader,
|
|
2820
|
+
userSizedColIds: new Set(userSizedColIds.current.keys()),
|
|
2821
|
+
}));
|
|
2822
|
+
// Auto-size failed retry later
|
|
2823
|
+
if (!autoSizeResult) {
|
|
2824
|
+
needsAutoSize.current = true;
|
|
2825
|
+
return;
|
|
2826
|
+
}
|
|
2827
|
+
autoSizeResultRef.current = autoSizeResult;
|
|
2828
|
+
// Calculate the auto-sized width, limit it to maxInitialWidth
|
|
2829
|
+
autoSizeResult.width = maxInitialWidth ? Math.min(autoSizeResult.width, maxInitialWidth) : autoSizeResult.width;
|
|
2830
|
+
if (gridRendered === 'empty') {
|
|
2831
|
+
// If the grid is empty we still do an onContentSize callback, we will do another callback when grid has data
|
|
2832
|
+
// We don't do this callback if we have previously had row data, or have already called back for empty
|
|
2833
|
+
if (!hasSetContentSizeEmpty.current && !hasSetContentSize.current) {
|
|
2834
|
+
hasSetContentSizeEmpty.current = true;
|
|
2835
|
+
params.onContentSize?.(autoSizeResult);
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
else if (gridRendered === 'rows-visible') {
|
|
2839
|
+
// we have rows now so callback grid size
|
|
2840
|
+
if (!hasSetContentSize.current) {
|
|
2841
|
+
hasSetContentSize.current = true;
|
|
2842
|
+
params.onContentSize?.(autoSizeResult);
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
else {
|
|
2846
|
+
// It should be impossible to get here
|
|
2847
|
+
console.error('Unknown value returned from hasGridRendered');
|
|
2836
2848
|
}
|
|
2837
2849
|
}
|
|
2838
2850
|
else {
|
|
2839
|
-
|
|
2840
|
-
console.error('Unknown value returned from hasGridRendered');
|
|
2851
|
+
sizeColumnsToFit();
|
|
2841
2852
|
}
|
|
2853
|
+
setAutoSized(true);
|
|
2854
|
+
needsAutoSize.current = false;
|
|
2842
2855
|
}
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
sizeColumnsToFit();
|
|
2856
|
+
finally {
|
|
2857
|
+
initialContentSizeInProgressRef.current = false;
|
|
2846
2858
|
}
|
|
2847
|
-
setAutoSized(true);
|
|
2848
|
-
needsAutoSize.current = false;
|
|
2849
2859
|
}, [autoSizeColumns, gridRenderState, maxInitialWidth, params, rowData, sizeColumns, sizeColumnsToFit]);
|
|
2850
2860
|
const lastOwnerDocumentRef = useRef();
|
|
2851
2861
|
const wasVisibleRef = useRef(false);
|
|
@@ -2879,8 +2889,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
2879
2889
|
}
|
|
2880
2890
|
if (needsAutoSize.current ||
|
|
2881
2891
|
(!hasSetContentSize.current && (sizeColumns === 'auto' || sizeColumns === 'auto-skip-headers'))) {
|
|
2882
|
-
|
|
2883
|
-
setInitialContentSize();
|
|
2892
|
+
void setInitialContentSize();
|
|
2884
2893
|
}
|
|
2885
2894
|
}, 200);
|
|
2886
2895
|
/**
|
|
@@ -3009,11 +3018,13 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3009
3018
|
if (previousRowDataLength.current !== length) {
|
|
3010
3019
|
// We need to autosize all cells again
|
|
3011
3020
|
autoSizeResultRef.current = null;
|
|
3012
|
-
setInitialContentSize();
|
|
3013
3021
|
previousRowDataLength.current = length;
|
|
3022
|
+
void setInitialContentSize();
|
|
3023
|
+
return;
|
|
3014
3024
|
}
|
|
3015
|
-
if (lastUpdatedDep.current === updatedDep || isEmpty(colIdsEdited.current))
|
|
3025
|
+
if (lastUpdatedDep.current === updatedDep || isEmpty(colIdsEdited.current)) {
|
|
3016
3026
|
return;
|
|
3027
|
+
}
|
|
3017
3028
|
lastUpdatedDep.current = updatedDep;
|
|
3018
3029
|
// Don't update while there are spinners
|
|
3019
3030
|
if (anyUpdating()) {
|
|
@@ -3021,7 +3032,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3021
3032
|
}
|
|
3022
3033
|
const skipHeader = sizeColumns === 'auto-skip-headers';
|
|
3023
3034
|
if ((sizeColumns === 'auto' || sizeColumns === 'auto-skip-headers') && hasSetContentSize.current) {
|
|
3024
|
-
autoSizeColumns({
|
|
3035
|
+
void autoSizeColumns({
|
|
3025
3036
|
skipHeader,
|
|
3026
3037
|
userSizedColIds: new Set(userSizedColIds.current.keys()),
|
|
3027
3038
|
colIds: colIdsEdited.current,
|
|
@@ -3111,11 +3122,21 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3111
3122
|
...colDef,
|
|
3112
3123
|
children: colDef.children.map((colDef) => adjustColDefOrGroup(colDef)),
|
|
3113
3124
|
});
|
|
3114
|
-
const adjustColDef = (colDef) =>
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3125
|
+
const adjustColDef = (colDef) => {
|
|
3126
|
+
const flex = colDef.flex ?? (sizeColumns === 'fit' ? 1 : undefined);
|
|
3127
|
+
return {
|
|
3128
|
+
...colDef,
|
|
3129
|
+
// You cannot pass a width to a flex
|
|
3130
|
+
width: !!colDef.flex ? undefined : colDef.width,
|
|
3131
|
+
flexAutoSizeWidth: colDef.width,
|
|
3132
|
+
// If this is allowed flex columns don't size based on flex
|
|
3133
|
+
suppressSizeToFit: true,
|
|
3134
|
+
// Auto-sizing flex columns breaks everything
|
|
3135
|
+
flex,
|
|
3136
|
+
suppressAutoSize: !!flex,
|
|
3137
|
+
sortable: colDef.sortable && params.defaultColDef?.sortable !== false,
|
|
3138
|
+
};
|
|
3139
|
+
};
|
|
3119
3140
|
return columnDefs.map((colDef) => adjustColDefOrGroup(colDef));
|
|
3120
3141
|
}, [columnDefs, params.defaultColDef?.sortable, sizeColumns]);
|
|
3121
3142
|
/**
|
|
@@ -3140,7 +3161,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3140
3161
|
if (sizeColumns === 'auto' || skipHeader) {
|
|
3141
3162
|
defer(() => {
|
|
3142
3163
|
if (hasSetContentSize.current) {
|
|
3143
|
-
autoSizeColumns({
|
|
3164
|
+
void autoSizeColumns({
|
|
3144
3165
|
skipHeader,
|
|
3145
3166
|
userSizedColIds: new Set(userSizedColIds.current.keys()),
|
|
3146
3167
|
colIds: colIdsEdited.current,
|
|
@@ -3295,7 +3316,7 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3295
3316
|
}, [columnDefs, params.loading, params.noRowsMatchingOverlayText, params.noRowsOverlayText, rowData, rowHeight]);
|
|
3296
3317
|
const selectionColumnDef = useMemo(() => {
|
|
3297
3318
|
// Note this has to be 1 for hidden otherwise ag-grid does crazy things whilst resizing
|
|
3298
|
-
const selectWidth = params.
|
|
3319
|
+
const selectWidth = params.onRowDragEnd ? 76 : 48;
|
|
3299
3320
|
return {
|
|
3300
3321
|
suppressNavigable: params.hideSelectColumn,
|
|
3301
3322
|
rowDrag: !!params.onRowDragEnd,
|
|
@@ -3305,6 +3326,8 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3305
3326
|
headerComponentParams: {
|
|
3306
3327
|
exportable: false,
|
|
3307
3328
|
},
|
|
3329
|
+
suppressAutoSize: true,
|
|
3330
|
+
suppressSizeToFit: true,
|
|
3308
3331
|
headerClass: clsx('ag-header-hide-default-select', params.onRowDragEnd && 'ag-header-select-draggable'),
|
|
3309
3332
|
headerComponent: rowSelection == 'multiple' ? GridHeaderSelect : undefined,
|
|
3310
3333
|
suppressHeaderKeyboardEvent: (e) => {
|
|
@@ -3334,13 +3357,22 @@ const Grid = ({ 'data-testid': dataTestId, defaultPostSort = true, rowSelection
|
|
|
3334
3357
|
selectColumnPinned,
|
|
3335
3358
|
selectable,
|
|
3336
3359
|
]);
|
|
3360
|
+
const onGridSizeChanged = useCallback((event) => {
|
|
3361
|
+
if (sizeColumns === 'fit' || (['auto', 'auto-skip-headers'].includes(sizeColumns) && hasSetContentSize.current)) {
|
|
3362
|
+
event.api.sizeColumnsToFit();
|
|
3363
|
+
}
|
|
3364
|
+
}, [sizeColumns]);
|
|
3337
3365
|
return (jsxs("div", { "data-testid": dataTestId, className: clsx('Grid-container', theme, 'theme-specific', staleGrid && 'Grid-sortIsStale', gridReady && rowData && autoSized && 'Grid-ready'), children: [gridContextMenu.component, jsx("div", { style: { flex: 1 }, ref: gridDivRef, children: jsx(AgGridReact, { theme: 'legacy', rowSelection: selectable
|
|
3338
3366
|
? {
|
|
3339
3367
|
enableSelectionWithoutKeys: params.enableSelectionWithoutKeys ?? false,
|
|
3340
3368
|
enableClickSelection: params.enableClickSelection ?? false,
|
|
3341
3369
|
mode: rowSelection === 'single' ? 'singleRow' : 'multiRow',
|
|
3370
|
+
...(params.hideSelectColumn && {
|
|
3371
|
+
checkboxes: false,
|
|
3372
|
+
headerCheckbox: false,
|
|
3373
|
+
}),
|
|
3342
3374
|
}
|
|
3343
|
-
: undefined, rowHeight: rowHeight, animateRows: params.animateRows ?? false, rowClassRules: params.rowClassRules, getRowId: getRowId, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onColumnVisible: setInitialContentSize, onRowDataUpdated: onRowDataUpdated, onCellFocused: onCellFocused, onCellKeyDown: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStopped: onCellEditingStopped, domLayout: params.domLayout, onColumnResized: onColumnResized, defaultColDef: defaultColDef, columnDefs: columnDefsAdjusted,
|
|
3375
|
+
: undefined, selectionColumnDef: selectionColumnDef, rowHeight: rowHeight, animateRows: params.animateRows ?? false, rowClassRules: params.rowClassRules, getRowId: getRowId, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onGridSizeChanged: onGridSizeChanged, onColumnVisible: () => void setInitialContentSize(), onRowDataUpdated: onRowDataUpdated, onCellFocused: onCellFocused, onCellKeyDown: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStopped: onCellEditingStopped, domLayout: params.domLayout, onColumnResized: onColumnResized, defaultColDef: defaultColDef, columnDefs: columnDefsAdjusted, rowData: rowData, postSortRows: params.onRowDragEnd || !defaultPostSort ? undefined : postSortRows, onModelUpdated: onModelUpdated, onGridReady: onGridReady, onSortChanged: ensureSelectedRowIsVisible, quickFilterParser: quickFilterParser, onSelectionChanged: synchroniseExternalStateToGridSelection, onColumnMoved: params.onColumnMoved, noRowsOverlayComponent: noRowsOverlayComponent, alwaysShowVerticalScroll: params.alwaysShowVerticalScroll, isExternalFilterPresent: isExternalFilterPresent, doesExternalFilterPass: doesExternalFilterPass, maintainColumnOrder: true, preventDefaultOnContextMenu: true, onCellContextMenu: gridContextMenu.cellContextMenu, rowDragText: params.rowDragText, onRowDragCancel: clearHighlightRowClasses, onRowDragMove: onRowDragMove, onRowDragEnd: onRowDragEnd, suppressCellFocus: params.suppressCellFocus, pinnedTopRowData: params.pinnedTopRowData, pinnedBottomRowData: params.pinnedBottomRowData, onRowClicked: params.onRowClicked, onRowDoubleClicked: params.onRowDoubleClicked, suppressStartEditOnTab: true }) })] }));
|
|
3344
3376
|
};
|
|
3345
3377
|
const quickFilterParser = (filterStr) => {
|
|
3346
3378
|
// filter is exact matches exactly groups separated by commas
|
|
@@ -5604,7 +5636,7 @@ const GridContextProvider = (props) => {
|
|
|
5604
5636
|
* If you don't clear flex column widths ag-grid gets confused and does random sizing's.
|
|
5605
5637
|
* Then we size the flexed columns.
|
|
5606
5638
|
*/
|
|
5607
|
-
const autoSizeColumns = useCallback(({ skipHeader, colIds, userSizedColIds } = {}) => {
|
|
5639
|
+
const autoSizeColumns = useCallback(async ({ skipHeader, colIds, userSizedColIds } = {}) => {
|
|
5608
5640
|
if (!gridApi || !gridApi.getColumnState()) {
|
|
5609
5641
|
return null;
|
|
5610
5642
|
}
|
|
@@ -5618,23 +5650,34 @@ const GridContextProvider = (props) => {
|
|
|
5618
5650
|
};
|
|
5619
5651
|
const getFlexColStates = () => getVisibleColStates().filter(colStateFlexed);
|
|
5620
5652
|
const getNonFlexColStates = () => getVisibleColStates().filter(colStateNotFlexed);
|
|
5621
|
-
//
|
|
5622
|
-
|
|
5653
|
+
// You cannot autosize flex columns it will break layout randomly
|
|
5654
|
+
// So, a flex column is assumed to be 150 wide, unless width is provided
|
|
5655
|
+
const flexColumns = getFlexColStates().map(colStateId);
|
|
5623
5656
|
let width = 0;
|
|
5624
|
-
|
|
5625
|
-
gridApi.
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
}
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5657
|
+
flexColumns.forEach((colId) => {
|
|
5658
|
+
const colDef = gridApi.getColumnDef(colId);
|
|
5659
|
+
width += colDef?.flexAutoSizeWidth ?? 200;
|
|
5660
|
+
});
|
|
5661
|
+
const nonFlexColumns = getNonFlexColStates();
|
|
5662
|
+
const nonFlexColumnIds = nonFlexColumns.map(colStateId);
|
|
5663
|
+
gridApi.autoSizeColumns({ colIds: nonFlexColumnIds, skipHeader });
|
|
5664
|
+
const calcSubWidth = () => {
|
|
5665
|
+
const updatedFlexColumns = getVisibleColStates().filter((colState) => nonFlexColumnIds.includes(colState.colId));
|
|
5666
|
+
return sumBy(updatedFlexColumns.filter((col) => !col.hide), 'width');
|
|
5667
|
+
};
|
|
5668
|
+
// ag-grid updates widths asynchronously, so we wait here for the default calculated width to change
|
|
5669
|
+
let lastSubWidth = calcSubWidth();
|
|
5670
|
+
const endTime = Date.now() + 1000;
|
|
5671
|
+
while (Date.now() < endTime) {
|
|
5672
|
+
await wait(40);
|
|
5673
|
+
const newSubWidth = calcSubWidth();
|
|
5674
|
+
if (lastSubWidth !== newSubWidth) {
|
|
5675
|
+
lastSubWidth = newSubWidth;
|
|
5676
|
+
break;
|
|
5677
|
+
}
|
|
5637
5678
|
}
|
|
5679
|
+
width += lastSubWidth;
|
|
5680
|
+
gridApi.sizeColumnsToFit();
|
|
5638
5681
|
return {
|
|
5639
5682
|
width,
|
|
5640
5683
|
};
|