@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.
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": "17.5.2",
5
+ "version": "17.6.0",
6
6
  "keywords": [
7
7
  "aggrid",
8
8
  "ag-grid",
@@ -115,11 +115,13 @@ export const Grid = ({
115
115
  selectColumnPinned = null,
116
116
  contextMenuSelectRow = false,
117
117
  singleClickEdit = false,
118
+ rowData,
118
119
  rowHeight = theme === "ag-theme-step-default" ? 40 : theme === "ag-theme-step-compact" ? 36 : undefined,
119
120
  ...params
120
121
  }: GridProps): ReactElement => {
121
122
  const {
122
123
  gridReady,
124
+ gridRenderState,
123
125
  setApis,
124
126
  ensureRowVisible,
125
127
  getFirstRowId,
@@ -153,36 +155,38 @@ export const Grid = ({
153
155
  */
154
156
  const hasSetContentSize = useRef(false);
155
157
  const hasSetContentSizeEmpty = useRef(false);
156
- const needsAutoSize = useRef(false);
158
+ const needsAutoSize = useRef(true);
157
159
 
158
160
  const setInitialContentSize = useCallback(() => {
159
- if (!gridDivRef.current?.clientWidth) {
161
+ if (!gridDivRef.current?.clientWidth || rowData == null) {
160
162
  // Don't resize grids if they are offscreen as it doesn't work.
161
163
  needsAutoSize.current = true;
162
164
  return;
163
165
  }
164
166
 
165
- const headerCellCount = gridDivRef.current?.getElementsByClassName("ag-header-cell-label")?.length;
166
- if (headerCellCount < 2) {
167
- // Don't resize grids until all the columns are visible
168
- // as `autoSizeColumns` will fail silently in this case
167
+ const gridRendered = gridRenderState();
168
+ if (gridRendered === null) {
169
+ // Don't resize until grid has rendered, or it has 0 rows.
169
170
  needsAutoSize.current = true;
170
171
  return;
171
172
  }
172
173
 
173
- const skipHeader = sizeColumns === "auto-skip-headers" && !isEmpty(params.rowData);
174
+ const skipHeader = sizeColumns === "auto-skip-headers" && gridRendered === "rows-visible";
174
175
  if (sizeColumns === "auto" || skipHeader) {
175
176
  const result = autoSizeColumns({ skipHeader, userSizedColIds: userSizedColIds.current, includeFlex: true });
176
- if (isEmpty(params.rowData)) {
177
+ if (gridRendered === "empty") {
177
178
  if (!hasSetContentSizeEmpty.current && result && !hasSetContentSize.current) {
178
179
  hasSetContentSizeEmpty.current = true;
179
180
  params.onContentSize && params.onContentSize(result);
180
181
  }
181
- } else {
182
+ } else if (gridRendered === "rows-visible") {
182
183
  if (result && !hasSetContentSize.current) {
183
184
  hasSetContentSize.current = true;
184
185
  params.onContentSize && params.onContentSize(result);
185
186
  }
187
+ } else {
188
+ // It should be impossible to get here
189
+ console.error("Unknown value returned from hasGridRendered");
186
190
  }
187
191
  }
188
192
 
@@ -191,7 +195,7 @@ export const Grid = ({
191
195
  }
192
196
  setAutoSized(true);
193
197
  needsAutoSize.current = false;
194
- }, [autoSizeColumns, params, sizeColumns, sizeColumnsToFit]);
198
+ }, [autoSizeColumns, gridRenderState, params, rowData, sizeColumns, sizeColumnsToFit]);
195
199
 
196
200
  const lastOwnerDocumentRef = useRef<Document>();
197
201
 
@@ -213,25 +217,17 @@ export const Grid = ({
213
217
  setInitialContentSize();
214
218
  }
215
219
  },
216
- timeoutMs: 1000,
220
+ timeoutMs: 200,
217
221
  });
218
222
 
219
- const previousGridReady = useRef(gridReady);
220
- useEffect(() => {
221
- if (!previousGridReady.current && gridReady) {
222
- previousGridReady.current = true;
223
- setInitialContentSize();
224
- }
225
- }, [gridReady, setInitialContentSize]);
226
-
227
223
  /**
228
224
  * On data load select the first row of the grid if required.
229
225
  */
230
226
  const hasSelectedFirstItem = useRef(false);
231
227
  useEffect(() => {
232
- if (!gridReady || hasSelectedFirstItem.current || !params.rowData || !externallySelectedItemsAreInSync) return;
228
+ if (!gridReady || hasSelectedFirstItem.current || !rowData || !externallySelectedItemsAreInSync) return;
233
229
  hasSelectedFirstItem.current = true;
234
- if (isNotEmpty(params.rowData) && isEmpty(params.externalSelectedItems)) {
230
+ if (isNotEmpty(rowData) && isEmpty(params.externalSelectedItems)) {
235
231
  const firstRowId = getFirstRowId();
236
232
  if (params.autoSelectFirstRow) {
237
233
  selectRowsById([firstRowId]);
@@ -245,7 +241,7 @@ export const Grid = ({
245
241
  gridReady,
246
242
  params.externalSelectedItems,
247
243
  params.autoSelectFirstRow,
248
- params.rowData,
244
+ rowData,
249
245
  selectRowsById,
250
246
  getFirstRowId,
251
247
  ]);
@@ -402,7 +398,7 @@ export const Grid = ({
402
398
  const previousRowDataLength = useRef(0);
403
399
 
404
400
  const onRowDataChanged = useCallback(() => {
405
- const length = params.rowData?.length ?? 0;
401
+ const length = rowData?.length ?? 0;
406
402
  if (previousRowDataLength.current !== length) {
407
403
  setInitialContentSize();
408
404
  previousRowDataLength.current = length;
@@ -417,7 +413,7 @@ export const Grid = ({
417
413
  const skipHeader = sizeColumns === "auto-skip-headers";
418
414
  autoSizeColumns({ skipHeader, userSizedColIds: userSizedColIds.current, colIds: colIdsEdited.current });
419
415
  colIdsEdited.current.clear();
420
- }, [autoSizeColumns, params.rowData?.length, setInitialContentSize, sizeColumns, updatedDep, updatingCols]);
416
+ }, [autoSizeColumns, rowData?.length, setInitialContentSize, sizeColumns, updatedDep, updatingCols]);
421
417
 
422
418
  /**
423
419
  * Show/hide no rows overlay when model changes.
@@ -619,7 +615,6 @@ export const Grid = ({
619
615
 
620
616
  //we don't want to show the row highlight if it wouldn't result in the row moving
621
617
  const targetIndex = event.overIndex + position - (event.node.rowIndex < event.overIndex ? 1 : 0);
622
- //console.log(targetIndex)
623
618
  if (event.node.rowIndex != targetIndex) {
624
619
  clientSideRowModel.highlightRowAtPixel(event.node as RowNode<any>, event.y);
625
620
  }
@@ -663,7 +658,7 @@ export const Grid = ({
663
658
  theme,
664
659
  "theme-specific",
665
660
  staleGrid && "Grid-sortIsStale",
666
- gridReady && params.rowData && autoSized && "Grid-ready",
661
+ gridReady && rowData && autoSized && "Grid-ready",
667
662
  )}
668
663
  >
669
664
  {gridContextMenu.component}
@@ -691,7 +686,7 @@ export const Grid = ({
691
686
  onColumnResized={onColumnResized}
692
687
  defaultColDef={{ minWidth: 48, ...omit(params.defaultColDef, ["editable"]) }}
693
688
  columnDefs={columnDefsAdjusted}
694
- rowData={params.rowData}
689
+ rowData={rowData}
695
690
  noRowsOverlayComponent={(event: AgGridEvent) => {
696
691
  let rowCount = 0;
697
692
  event.api.forEachNode(() => rowCount++);
@@ -17,6 +17,7 @@ export type AutoSizeColumnsResult = { width: number } | null;
17
17
 
18
18
  export interface GridContextType<RowType extends GridBaseRow> {
19
19
  gridReady: boolean;
20
+ gridRenderState: () => null | "empty" | "rows-visible";
20
21
  getColDef: (colId?: string) => ColDef | undefined;
21
22
  getColumns: (
22
23
  filter?: keyof ColDef | ((r: ColDef) => boolean | undefined | null | number | string),
@@ -68,6 +69,7 @@ export interface GridContextType<RowType extends GridBaseRow> {
68
69
 
69
70
  export const GridContext = createContext<GridContextType<any>>({
70
71
  gridReady: false,
72
+ gridRenderState: () => null,
71
73
  getColDef: () => {
72
74
  console.error("no context provider for getColDef");
73
75
  return undefined;
@@ -104,6 +104,17 @@ export const GridContextProvider = <RowType extends GridBaseRow>(props: PropsWit
104
104
  [quickFilter],
105
105
  );
106
106
 
107
+ /**
108
+ * Used to check if it's OK to autosize.
109
+ */
110
+ const gridRenderState = useCallback((): null | "empty" | "rows-visible" => {
111
+ if (!gridApi) return null;
112
+ if (!gridApi.getModel().isRowsToRender()) return "empty";
113
+ if (!isEmpty(gridApi.getRenderedNodes())) return "rows-visible";
114
+ // If there are rows to render, but there are no rendered nodes then we should wait
115
+ return null;
116
+ }, [gridApi]);
117
+
107
118
  /**
108
119
  * Expose scrollRowIntoView for playwright tests.
109
120
  */
@@ -701,6 +712,7 @@ export const GridContextProvider = <RowType extends GridBaseRow>(props: PropsWit
701
712
  return (
702
713
  <GridContext.Provider
703
714
  value={{
715
+ gridRenderState,
704
716
  getColDef,
705
717
  getColumns,
706
718
  getColumnIds,
@@ -66,7 +66,7 @@ interface ITestRow {
66
66
  id: number;
67
67
  position: string;
68
68
  age: number;
69
- height: number;
69
+ height: string;
70
70
  desc: string;
71
71
  dd: string;
72
72
  }
@@ -215,7 +215,7 @@ const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) =>
215
215
  { id: 1000, position: "Tester", age: 30, height: `6'4"`, desc: "Tests application", dd: "1" },
216
216
  { id: 1001, position: "Developer", age: 12, height: `5'3"`, desc: "Develops application", dd: "2" },
217
217
  { id: 1002, position: "Manager", age: 65, height: `5'9"`, desc: "Manages", dd: "3" },
218
- ]);
218
+ ] as ITestRow[]);
219
219
 
220
220
  return (
221
221
  <GridWrapper maxHeight={300}>
@@ -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
  }