@linzjs/step-ag-grid 17.5.2 → 17.6.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.
@@ -213,4 +213,39 @@ $grid-base-font-size: calc(#{lui.$base-font-size} - 1px);
213
213
  .ag-row-highlight-below::after {
214
214
  border-bottom: 2px dashed lui.$andrea;
215
215
  }
216
+
217
+ // .ag-header .ag-pinned-left-header:after,
218
+ // .ag-body-viewport .ag-pinned-left-cols-container:after {
219
+ // content: " ";
220
+ // height: 100%;
221
+ // position: absolute;
222
+ // z-index: 1;
223
+ // top: 0;
224
+ // width: 15px;
225
+ // box-shadow: -4px 0px 15px -4px rgba(0, 0, 0, 0.1);
226
+ // right: -4px;
227
+ // }
228
+
229
+ // div:after {
230
+ // box-shadow: 15px 0 15px -15px inset;
231
+ // right: -15px;
232
+ // }
233
+ .ag-pinned-left-header,
234
+ .ag-pinned-right-header,
235
+ .ag-pinned-right-cols-container,
236
+ .ag-pinned-left-cols-container {
237
+ position: relative;
238
+ z-index: 1;
239
+ box-shadow: 0 0 8px 2px rgb(0 0 0 / 10%);
240
+ }
241
+
242
+ .ag-pinned-left-header,
243
+ .ag-pinned-left-cols-container {
244
+ clip-path: polygon(0% 0%, 120% 0%, 120% 100%, 0% 100%);
245
+ }
246
+
247
+ .ag-pinned-right-header,
248
+ .ag-pinned-right-cols-container {
249
+ clip-path: polygon(-20% 0%, 100% 0%, 100% 100%, -20% 100%);
250
+ }
216
251
  }
@@ -72,4 +72,4 @@ export interface GridProps {
72
72
  /**
73
73
  * Wrapper for AgGrid to add commonly used functionality.
74
74
  */
75
- export declare const Grid: ({ "data-testid": dataTestId, rowSelection, suppressColumnVirtualization, theme, sizeColumns, selectColumnPinned, contextMenuSelectRow, singleClickEdit, rowHeight, ...params }: GridProps) => ReactElement;
75
+ export declare const Grid: ({ "data-testid": dataTestId, rowSelection, suppressColumnVirtualization, theme, sizeColumns, selectColumnPinned, contextMenuSelectRow, singleClickEdit, rowData, rowHeight, ...params }: GridProps) => ReactElement;
@@ -14,6 +14,7 @@ export type AutoSizeColumnsResult = {
14
14
  } | null;
15
15
  export interface GridContextType<RowType extends GridBaseRow> {
16
16
  gridReady: boolean;
17
+ gridRenderState: () => null | "empty" | "rows-visible";
17
18
  getColDef: (colId?: string) => ColDef | undefined;
18
19
  getColumns: (filter?: keyof ColDef | ((r: ColDef) => boolean | undefined | null | number | string)) => ColDefT<RowType>[];
19
20
  getColumnIds: (filter?: keyof ColDef | ((r: ColDef) => boolean | undefined | null | number | string)) => string[];
@@ -41,6 +41,7 @@ function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else i
41
41
 
42
42
  const GridContext = React.createContext({
43
43
  gridReady: false,
44
+ gridRenderState: () => null,
44
45
  getColDef: () => {
45
46
  console.error("no context provider for getColDef");
46
47
  return undefined;
@@ -2344,8 +2345,8 @@ const useGridContextMenu = ({ contextMenuSelectRow, contextMenu: ContextMenu, })
2344
2345
  /**
2345
2346
  * Wrapper for AgGrid to add commonly used functionality.
2346
2347
  */
2347
- const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressColumnVirtualization = true, theme = "ag-theme-step-default", sizeColumns = "auto", selectColumnPinned = null, contextMenuSelectRow = false, singleClickEdit = false, rowHeight = theme === "ag-theme-step-default" ? 40 : theme === "ag-theme-step-compact" ? 36 : undefined, ...params }) => {
2348
- const { gridReady, setApis, ensureRowVisible, getFirstRowId, selectRowsById, focusByRowById, ensureSelectedRowIsVisible, autoSizeColumns, sizeColumnsToFit, externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync, isExternalFilterPresent, doesExternalFilterPass, setOnCellEditingComplete, getColDef, } = React.useContext(GridContext);
2348
+ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressColumnVirtualization = true, theme = "ag-theme-step-default", sizeColumns = "auto", selectColumnPinned = null, contextMenuSelectRow = false, singleClickEdit = false, rowData, rowHeight = theme === "ag-theme-step-default" ? 40 : theme === "ag-theme-step-compact" ? 36 : undefined, ...params }) => {
2349
+ const { gridReady, gridRenderState, setApis, ensureRowVisible, getFirstRowId, selectRowsById, focusByRowById, ensureSelectedRowIsVisible, autoSizeColumns, sizeColumnsToFit, externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync, isExternalFilterPresent, doesExternalFilterPass, setOnCellEditingComplete, getColDef, } = React.useContext(GridContext);
2349
2350
  const { checkUpdating, updatedDep, updatingCols } = React.useContext(GridUpdatingContext);
2350
2351
  const { prePopupOps } = React.useContext(GridContext);
2351
2352
  const gridDivRef = React.useRef(null);
@@ -2360,42 +2361,45 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
2360
2361
  */
2361
2362
  const hasSetContentSize = React.useRef(false);
2362
2363
  const hasSetContentSizeEmpty = React.useRef(false);
2363
- const needsAutoSize = React.useRef(false);
2364
+ const needsAutoSize = React.useRef(true);
2364
2365
  const setInitialContentSize = React.useCallback(() => {
2365
- if (!gridDivRef.current?.clientWidth) {
2366
+ if (!gridDivRef.current?.clientWidth || rowData == null) {
2366
2367
  // Don't resize grids if they are offscreen as it doesn't work.
2367
2368
  needsAutoSize.current = true;
2368
2369
  return;
2369
2370
  }
2370
- const headerCellCount = gridDivRef.current?.getElementsByClassName("ag-header-cell-label")?.length;
2371
- if (headerCellCount < 2) {
2372
- // Don't resize grids until all the columns are visible
2373
- // as `autoSizeColumns` will fail silently in this case
2371
+ const gridRendered = gridRenderState();
2372
+ if (gridRendered === null) {
2373
+ // Don't resize until grid has rendered, or it has 0 rows.
2374
2374
  needsAutoSize.current = true;
2375
2375
  return;
2376
2376
  }
2377
- const skipHeader = sizeColumns === "auto-skip-headers" && !lodashEs.isEmpty(params.rowData);
2377
+ const skipHeader = sizeColumns === "auto-skip-headers" && gridRendered === "rows-visible";
2378
2378
  if (sizeColumns === "auto" || skipHeader) {
2379
2379
  const result = autoSizeColumns({ skipHeader, userSizedColIds: userSizedColIds.current, includeFlex: true });
2380
- if (lodashEs.isEmpty(params.rowData)) {
2380
+ if (gridRendered === "empty") {
2381
2381
  if (!hasSetContentSizeEmpty.current && result && !hasSetContentSize.current) {
2382
2382
  hasSetContentSizeEmpty.current = true;
2383
2383
  params.onContentSize && params.onContentSize(result);
2384
2384
  }
2385
2385
  }
2386
- else {
2386
+ else if (gridRendered === "rows-visible") {
2387
2387
  if (result && !hasSetContentSize.current) {
2388
2388
  hasSetContentSize.current = true;
2389
2389
  params.onContentSize && params.onContentSize(result);
2390
2390
  }
2391
2391
  }
2392
+ else {
2393
+ // It should be impossible to get here
2394
+ console.error("Unknown value returned from hasGridRendered");
2395
+ }
2392
2396
  }
2393
2397
  if (sizeColumns !== "none") {
2394
2398
  sizeColumnsToFit();
2395
2399
  }
2396
2400
  setAutoSized(true);
2397
2401
  needsAutoSize.current = false;
2398
- }, [autoSizeColumns, params, sizeColumns, sizeColumnsToFit]);
2402
+ }, [autoSizeColumns, gridRenderState, params, rowData, sizeColumns, sizeColumnsToFit]);
2399
2403
  const lastOwnerDocumentRef = React.useRef();
2400
2404
  /**
2401
2405
  * Auto-size windows that had deferred auto-size
@@ -2415,24 +2419,17 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
2415
2419
  setInitialContentSize();
2416
2420
  }
2417
2421
  },
2418
- timeoutMs: 1000,
2422
+ timeoutMs: 200,
2419
2423
  });
2420
- const previousGridReady = React.useRef(gridReady);
2421
- React.useEffect(() => {
2422
- if (!previousGridReady.current && gridReady) {
2423
- previousGridReady.current = true;
2424
- setInitialContentSize();
2425
- }
2426
- }, [gridReady, setInitialContentSize]);
2427
2424
  /**
2428
2425
  * On data load select the first row of the grid if required.
2429
2426
  */
2430
2427
  const hasSelectedFirstItem = React.useRef(false);
2431
2428
  React.useEffect(() => {
2432
- if (!gridReady || hasSelectedFirstItem.current || !params.rowData || !externallySelectedItemsAreInSync)
2429
+ if (!gridReady || hasSelectedFirstItem.current || !rowData || !externallySelectedItemsAreInSync)
2433
2430
  return;
2434
2431
  hasSelectedFirstItem.current = true;
2435
- if (isNotEmpty(params.rowData) && lodashEs.isEmpty(params.externalSelectedItems)) {
2432
+ if (isNotEmpty(rowData) && lodashEs.isEmpty(params.externalSelectedItems)) {
2436
2433
  const firstRowId = getFirstRowId();
2437
2434
  if (params.autoSelectFirstRow) {
2438
2435
  selectRowsById([firstRowId]);
@@ -2447,7 +2444,7 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
2447
2444
  gridReady,
2448
2445
  params.externalSelectedItems,
2449
2446
  params.autoSelectFirstRow,
2450
- params.rowData,
2447
+ rowData,
2451
2448
  selectRowsById,
2452
2449
  getFirstRowId,
2453
2450
  ]);
@@ -2588,7 +2585,7 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
2588
2585
  */
2589
2586
  const previousRowDataLength = React.useRef(0);
2590
2587
  const onRowDataChanged = React.useCallback(() => {
2591
- const length = params.rowData?.length ?? 0;
2588
+ const length = rowData?.length ?? 0;
2592
2589
  if (previousRowDataLength.current !== length) {
2593
2590
  setInitialContentSize();
2594
2591
  previousRowDataLength.current = length;
@@ -2602,7 +2599,7 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
2602
2599
  const skipHeader = sizeColumns === "auto-skip-headers";
2603
2600
  autoSizeColumns({ skipHeader, userSizedColIds: userSizedColIds.current, colIds: colIdsEdited.current });
2604
2601
  colIdsEdited.current.clear();
2605
- }, [autoSizeColumns, params.rowData?.length, setInitialContentSize, sizeColumns, updatedDep, updatingCols]);
2602
+ }, [autoSizeColumns, rowData?.length, setInitialContentSize, sizeColumns, updatedDep, updatingCols]);
2606
2603
  /**
2607
2604
  * Show/hide no rows overlay when model changes.
2608
2605
  */
@@ -2771,7 +2768,6 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
2771
2768
  const position = clientSideRowModel.getHighlightPosition(event.y, event.overNode);
2772
2769
  //we don't want to show the row highlight if it wouldn't result in the row moving
2773
2770
  const targetIndex = event.overIndex + position - (event.node.rowIndex < event.overIndex ? 1 : 0);
2774
- //console.log(targetIndex)
2775
2771
  if (event.node.rowIndex != targetIndex) {
2776
2772
  clientSideRowModel.highlightRowAtPixel(event.node, event.y);
2777
2773
  }
@@ -2800,9 +2796,9 @@ const Grid = ({ "data-testid": dataTestId, rowSelection = "multiple", suppressCo
2800
2796
  }, [params]);
2801
2797
  // This is setting a ref in the GridContext so won't be triggering an update loop
2802
2798
  setOnCellEditingComplete(params.onCellEditingComplete);
2803
- return (jsxRuntime.jsxs("div", { "data-testid": dataTestId, className: clsx("Grid-container", theme, "theme-specific", staleGrid && "Grid-sortIsStale", gridReady && params.rowData && autoSized && "Grid-ready"), children: [gridContextMenu.component, jsxRuntime.jsx("div", { style: { flex: 1 }, ref: gridDivRef, children: jsxRuntime.jsx(agGridReact.AgGridReact, { rowHeight: rowHeight, animateRows: params.animateRows, rowClassRules: params.rowClassRules, getRowId: (params) => `${params.data.id}`, suppressRowClickSelection: true, rowSelection: rowSelection, suppressBrowserResizeObserver: true, onGridSizeChanged: onGridSizeChanged, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onColumnVisible: () => {
2799
+ return (jsxRuntime.jsxs("div", { "data-testid": dataTestId, className: clsx("Grid-container", theme, "theme-specific", staleGrid && "Grid-sortIsStale", gridReady && rowData && autoSized && "Grid-ready"), children: [gridContextMenu.component, jsxRuntime.jsx("div", { style: { flex: 1 }, ref: gridDivRef, children: jsxRuntime.jsx(agGridReact.AgGridReact, { rowHeight: rowHeight, animateRows: params.animateRows, rowClassRules: params.rowClassRules, getRowId: (params) => `${params.data.id}`, suppressRowClickSelection: true, rowSelection: rowSelection, suppressBrowserResizeObserver: true, onGridSizeChanged: onGridSizeChanged, suppressColumnVirtualisation: suppressColumnVirtualization, suppressClickEdit: true, onColumnVisible: () => {
2804
2800
  setInitialContentSize();
2805
- }, onRowDataUpdated: onRowDataChanged, onCellKeyDown: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStarted: refreshSelectedRows, domLayout: params.domLayout, onColumnResized: onColumnResized, defaultColDef: { minWidth: 48, ...lodashEs.omit(params.defaultColDef, ["editable"]) }, columnDefs: columnDefsAdjusted, rowData: params.rowData, noRowsOverlayComponent: (event) => {
2801
+ }, onRowDataUpdated: onRowDataChanged, onCellKeyDown: onCellKeyPress, onCellClicked: onCellClicked, onCellDoubleClicked: onCellDoubleClick, onCellEditingStarted: refreshSelectedRows, domLayout: params.domLayout, onColumnResized: onColumnResized, defaultColDef: { minWidth: 48, ...lodashEs.omit(params.defaultColDef, ["editable"]) }, columnDefs: columnDefsAdjusted, rowData: rowData, noRowsOverlayComponent: (event) => {
2806
2802
  let rowCount = 0;
2807
2803
  event.api.forEachNode(() => rowCount++);
2808
2804
  return (jsxRuntime.jsx(GridNoRowsOverlay, { rowCount: rowCount, filteredRowCount: event.api.getDisplayedRowCount(), noRowsOverlayText: params.noRowsOverlayText }));
@@ -4614,6 +4610,19 @@ const GridContextProvider = (props) => {
4614
4610
  gridApi?.setQuickFilter(quickFilter);
4615
4611
  setGridReady(!!gridApi);
4616
4612
  }, [quickFilter]);
4613
+ /**
4614
+ * Used to check if it's OK to autosize.
4615
+ */
4616
+ const gridRenderState = React.useCallback(() => {
4617
+ if (!gridApi)
4618
+ return null;
4619
+ if (!gridApi.getModel().isRowsToRender())
4620
+ return "empty";
4621
+ if (!lodashEs.isEmpty(gridApi.getRenderedNodes()))
4622
+ return "rows-visible";
4623
+ // If there are rows to render, but there are no rendered nodes then we should wait
4624
+ return null;
4625
+ }, [gridApi]);
4617
4626
  /**
4618
4627
  * Expose scrollRowIntoView for playwright tests.
4619
4628
  */
@@ -5032,6 +5041,7 @@ const GridContextProvider = (props) => {
5032
5041
  });
5033
5042
  }, [columnApi, gridApi]);
5034
5043
  return (jsxRuntime.jsx(GridContext.Provider, { value: {
5044
+ gridRenderState,
5035
5045
  getColDef,
5036
5046
  getColumns,
5037
5047
  getColumnIds,