@linzjs/step-ag-grid 29.1.1 → 29.1.3

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.
Files changed (32) hide show
  1. package/dist/src/components/Grid.d.ts +1 -1
  2. package/dist/src/components/GridPopoverHook.d.ts +2 -1
  3. package/dist/src/contexts/GridContext.d.ts +2 -2
  4. package/dist/src/index.d.ts +1 -0
  5. package/dist/src/utils/waitForCondition.d.ts +1 -0
  6. package/dist/step-ag-grid.cjs +89 -65
  7. package/dist/step-ag-grid.cjs.map +1 -1
  8. package/dist/step-ag-grid.esm.js +88 -66
  9. package/dist/step-ag-grid.esm.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/components/Grid.tsx +1 -1
  12. package/src/components/GridCell.tsx +34 -14
  13. package/src/components/GridPopoverHook.tsx +16 -17
  14. package/src/components/gridForm/GridFormDropDown.tsx +10 -3
  15. package/src/components/gridForm/GridFormMultiSelect.tsx +12 -4
  16. package/src/components/gridPopoverEdit/GridPopoverMessage.ts +1 -0
  17. package/src/contexts/GridContext.tsx +2 -2
  18. package/src/contexts/GridContextProvider.tsx +41 -37
  19. package/src/index.ts +1 -0
  20. package/src/stories/grid/GridPopoutEditGeneric.stories.tsx +1 -1
  21. package/src/stories/grid/GridPopoverEditMultiSelect.stories.tsx +1 -1
  22. package/src/stories/grid/GridPopoverEditMultiSelectGrid.stories.tsx +1 -1
  23. package/src/stories/grid/gridFormInteraction/GridFormDropDownInteraction.stories.tsx +4 -12
  24. package/src/stories/grid/gridFormInteraction/GridFormEditBearingCorrectionInteraction.stories.tsx +5 -11
  25. package/src/stories/grid/gridFormInteraction/GridFormEditBearingInteraction.stories.tsx +4 -11
  26. package/src/stories/grid/gridFormInteraction/GridFormMultiSelectGridInteraction.stories.tsx +8 -10
  27. package/src/stories/grid/gridFormInteraction/GridFormMultiSelectInteraction.stories.tsx +5 -11
  28. package/src/stories/grid/gridFormInteraction/GridFormPopoverMenuInteraction.stories.tsx +5 -12
  29. package/src/stories/grid/gridFormInteraction/GridFormTextAreaInteraction.stories.tsx +4 -11
  30. package/src/stories/grid/gridFormInteraction/GridFormTextInputInteraction.stories.tsx +4 -11
  31. package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +56 -13
  32. package/src/utils/waitForCondition.tsx +17 -0
@@ -9,7 +9,7 @@ import { useRef } from 'react';
9
9
  import { expect, fn, userEvent, within } from 'storybook/test';
10
10
 
11
11
  import {
12
- GridContext,
12
+ GridContextProvider,
13
13
  GridFormMultiSelect,
14
14
  GridFormMultiSelectProps,
15
15
  GridFormSubComponentTextInput,
@@ -53,14 +53,7 @@ const Template: StoryFn<typeof GridFormMultiSelect> = (props: GridFormMultiSelec
53
53
 
54
54
  return (
55
55
  <div className={'react-menu-inline-test'}>
56
- <GridContext.Provider
57
- value={
58
- {
59
- onBulkEditingComplete: () => {},
60
- resetFocusedCellAfterCellEditing: () => {},
61
- } as any
62
- }
63
- >
56
+ <GridContextProvider>
64
57
  <h6 ref={anchorRef}>Interaction test</h6>
65
58
  <GridPopoverContext.Provider
66
59
  value={{
@@ -79,7 +72,7 @@ const Template: StoryFn<typeof GridFormMultiSelect> = (props: GridFormMultiSelec
79
72
  >
80
73
  <GridFormMultiSelect {...props} {...config} />
81
74
  </GridPopoverContext.Provider>
82
- </GridContext.Provider>
75
+ </GridContextProvider>
83
76
  </div>
84
77
  );
85
78
  };
@@ -142,7 +135,8 @@ GridFormMultiSelectInteractions_.play = async ({ canvasElement }) => {
142
135
  updateValue.mockClear();
143
136
  onSave.mockClear();
144
137
  await userEvent.type(textInput, '{Escape}');
145
- expect(updateValue).not.toHaveBeenCalled();
138
+ // expect(updateValue).not.toHaveBeenCalled();
139
+ expect(updateValue).toHaveBeenCalledWith(expect.anything(), 0);
146
140
  expect(onSave).not.toHaveBeenCalled();
147
141
 
148
142
  // Test invalid value doesn't save
@@ -10,7 +10,7 @@ import * as test from 'storybook/test';
10
10
  import { expect, userEvent, within } from 'storybook/test';
11
11
 
12
12
  import {
13
- GridContext,
13
+ GridContextProvider,
14
14
  GridFormPopoverMenu,
15
15
  GridFormPopoverMenuProps,
16
16
  GridFormSubComponentTextArea,
@@ -37,14 +37,7 @@ const Template: StoryFn<typeof GridFormPopoverMenu> = (props: GridFormPopoverMen
37
37
 
38
38
  return (
39
39
  <div className={'react-menu-inline-test'}>
40
- <GridContext.Provider
41
- value={
42
- {
43
- onBulkEditingComplete: () => {},
44
- resetFocusedCellAfterCellEditing: () => {},
45
- } as any
46
- }
47
- >
40
+ <GridContextProvider>
48
41
  <h6 ref={anchorRef}>Interaction Test</h6>
49
42
  <GridPopoverContext.Provider
50
43
  value={{
@@ -85,7 +78,7 @@ const Template: StoryFn<typeof GridFormPopoverMenu> = (props: GridFormPopoverMen
85
78
  ]}
86
79
  />
87
80
  </GridPopoverContext.Provider>
88
- </GridContext.Provider>
81
+ </GridContextProvider>
89
82
  </div>
90
83
  );
91
84
  };
@@ -138,7 +131,7 @@ GridFormPopoverMenuInteractions_.play = async ({ canvasElement }) => {
138
131
  // Test escape to not save
139
132
  updateValue.mockClear();
140
133
  await userEvent.type(textInput, '{Escape}');
141
- expect(updateValue).not.toHaveBeenCalled();
134
+ expect(updateValue).toHaveBeenCalledWith(expect.anything(), 0);
142
135
 
143
136
  // Test invalid value doesn't save
144
137
  updateValue.mockClear();
@@ -170,7 +163,7 @@ GridFormPopoverMenuInteractions_.play = async ({ canvasElement }) => {
170
163
  // Test escape to not save
171
164
  updateValue.mockClear();
172
165
  await userEvent.type(textArea, '{Escape}');
173
- expect(updateValue).not.toHaveBeenCalled();
166
+ expect(updateValue).toHaveBeenCalledWith(expect.anything(), 0);
174
167
 
175
168
  // Test invalid value doesn't save
176
169
  updateValue.mockClear();
@@ -8,7 +8,7 @@ import { GridPopoverContext } from 'contexts/GridPopoverContext';
8
8
  import { useRef } from 'react';
9
9
  import { expect, fn, userEvent, within } from 'storybook/test';
10
10
 
11
- import { GridContext, GridFormTextArea, GridFormTextAreaProps } from '../../..';
11
+ import { GridContextProvider, GridFormTextArea, GridFormTextAreaProps } from '../../..';
12
12
 
13
13
  export default {
14
14
  title: 'GridForm / Interactions',
@@ -23,14 +23,7 @@ const Template: StoryFn<typeof GridFormTextArea> = (props: GridFormTextAreaProps
23
23
 
24
24
  return (
25
25
  <div className={'react-menu-inline-test'}>
26
- <GridContext.Provider
27
- value={
28
- {
29
- onBulkEditingComplete: () => {},
30
- resetFocusedCellAfterCellEditing: () => {},
31
- } as any
32
- }
33
- >
26
+ <GridContextProvider>
34
27
  <h6 ref={anchorRef}>Interaction Test</h6>
35
28
  <GridPopoverContext.Provider
36
29
  value={{
@@ -49,7 +42,7 @@ const Template: StoryFn<typeof GridFormTextArea> = (props: GridFormTextAreaProps
49
42
  >
50
43
  <GridFormTextArea {...props} required={true} />
51
44
  </GridPopoverContext.Provider>
52
- </GridContext.Provider>
45
+ </GridContextProvider>
53
46
  </div>
54
47
  );
55
48
  };
@@ -78,7 +71,7 @@ GridFormTextAreaInteractions_.play = async ({ canvasElement }) => {
78
71
  // Test escape not to save
79
72
  updateValue.mockClear();
80
73
  await userEvent.type(inputField, '{Escape}');
81
- expect(updateValue).not.toHaveBeenCalled();
74
+ expect(updateValue).toHaveBeenCalledWith(expect.anything(), 0);
82
75
 
83
76
  // Test invalid value doesn't save
84
77
  updateValue.mockClear();
@@ -8,7 +8,7 @@ import { GridPopoverContext } from 'contexts/GridPopoverContext';
8
8
  import { useRef } from 'react';
9
9
  import { expect, fn, userEvent, within } from 'storybook/test';
10
10
 
11
- import { GridContext, GridFormTextInput, GridFormTextInputProps } from '../../..';
11
+ import { GridContextProvider, GridFormTextInput, GridFormTextInputProps } from '../../..';
12
12
 
13
13
  export default {
14
14
  title: 'GridForm / Interactions',
@@ -23,14 +23,7 @@ const Template: StoryFn<typeof GridFormTextInput> = (props: GridFormTextInputPro
23
23
 
24
24
  return (
25
25
  <div className={'react-menu-inline-test'}>
26
- <GridContext.Provider
27
- value={
28
- {
29
- onBulkEditingComplete: () => {},
30
- resetFocusedCellAfterCellEditing: () => {},
31
- } as any
32
- }
33
- >
26
+ <GridContextProvider>
34
27
  <h6 ref={anchorRef}>Interaction Test</h6>
35
28
  <GridPopoverContext.Provider
36
29
  value={{
@@ -49,7 +42,7 @@ const Template: StoryFn<typeof GridFormTextInput> = (props: GridFormTextInputPro
49
42
  >
50
43
  <GridFormTextInput {...props} required={true} />
51
44
  </GridPopoverContext.Provider>
52
- </GridContext.Provider>
45
+ </GridContextProvider>
53
46
  </div>
54
47
  );
55
48
  };
@@ -83,7 +76,7 @@ GridFormTextInputInteractions_.play = async ({ canvasElement }) => {
83
76
  // Test escape not to save
84
77
  updateValue.mockClear();
85
78
  await userEvent.type(inputField, '{Escape}');
86
- expect(updateValue).not.toHaveBeenCalled();
79
+ expect(updateValue).toHaveBeenCalledWith(expect.anything(), 0);
87
80
 
88
81
  // Test invalid value doesn't save
89
82
  updateValue.mockClear();
@@ -5,7 +5,7 @@ import '@linzjs/lui/dist/fonts';
5
5
 
6
6
  import { Meta, StoryFn } from '@storybook/react-vite';
7
7
  import { useMemo, useState } from 'react';
8
- import { expect } from 'storybook/test';
8
+ import { expect, within } from 'storybook/test';
9
9
  import { fn } from 'storybook/test';
10
10
  import { userEvent, waitFor } from 'storybook/test';
11
11
 
@@ -19,6 +19,7 @@ import {
19
19
  GridIcon,
20
20
  GridPopoverMenu,
21
21
  GridPopoverMessage,
22
+ GridPopoverTextArea,
22
23
  GridProps,
23
24
  GridUpdatingContextProvider,
24
25
  MenuOption,
@@ -75,6 +76,10 @@ const eAction = fn(() => {
75
76
  return true;
76
77
  });
77
78
 
79
+ const bulkEditingCallback = fn(() => {
80
+ console.log('bulkEditingCallback');
81
+ });
82
+
78
83
  const GridKeyboardInteractionsTemplate: StoryFn<typeof Grid<ITestRow>> = (props: GridProps<ITestRow>) => {
79
84
  const [externalSelectedItems, setExternalSelectedItems] = useState<any[]>([]);
80
85
  const columnDefs: ColDefT<ITestRow>[] = useMemo(
@@ -95,12 +100,16 @@ const GridKeyboardInteractionsTemplate: StoryFn<typeof Grid<ITestRow>> = (props:
95
100
  field: 'age',
96
101
  headerName: 'Age',
97
102
  }),
98
- GridCell({
99
- field: 'desc',
100
- headerName: 'Description',
101
- }),
103
+ GridPopoverTextArea(
104
+ {
105
+ field: 'desc',
106
+ headerName: 'Description',
107
+ },
108
+ {},
109
+ ),
102
110
  GridPopoverMessage(
103
111
  {
112
+ colId: 'popout_message',
104
113
  headerName: 'Popout message',
105
114
  maxWidth: 150,
106
115
  cellRenderer: () => <>Single Click me!</>,
@@ -116,6 +125,7 @@ const GridKeyboardInteractionsTemplate: StoryFn<typeof Grid<ITestRow>> = (props:
116
125
  },
117
126
  ),
118
127
  GridCell({
128
+ colId: 'custom_edit',
119
129
  headerName: 'Custom edit',
120
130
  maxWidth: 100,
121
131
  editable: true,
@@ -219,15 +229,18 @@ const GridKeyboardInteractionsTemplate: StoryFn<typeof Grid<ITestRow>> = (props:
219
229
  rowData={rowData}
220
230
  domLayout={'autoHeight'}
221
231
  autoSelectFirstRow={true}
232
+ onBulkEditingComplete={bulkEditingCallback}
222
233
  />
223
234
  );
224
235
  };
225
236
 
226
237
  export const GridKeyboardInteractions: StoryFn<typeof Grid<ITestRow>> = GridKeyboardInteractionsTemplate.bind({});
227
238
  GridKeyboardInteractions.play = async ({ canvasElement }) => {
239
+ const canvas = within(document.body);
240
+
228
241
  multiEditAction.mockClear();
229
242
  eAction.mockClear();
230
-
243
+ bulkEditingCallback.mockClear();
231
244
  await waitForGridReady({ canvasElement });
232
245
 
233
246
  // Ensure first row/cell is selected on render
@@ -237,7 +250,9 @@ GridKeyboardInteractions.play = async ({ canvasElement }) => {
237
250
  expect(activeCell).toHaveAttribute('aria-colindex', '1');
238
251
  expect(activeCell?.parentElement).toHaveAttribute('row-index', '0');
239
252
  });
253
+ console.log('arrow down to 3rd row');
240
254
  await userEvent.keyboard('{arrowdown}{arrowdown}');
255
+ console.log('arrow right to first popup menu');
241
256
  await userEvent.keyboard('{arrowright}{arrowright}{arrowright}{arrowright}{arrowright}{arrowright}{arrowright}');
242
257
 
243
258
  // Test enter post focus
@@ -246,9 +261,6 @@ GridKeyboardInteractions.play = async ({ canvasElement }) => {
246
261
  await wait(1000);
247
262
  await userEvent.keyboard('{arrowdown}{arrowdown}');
248
263
  fn();
249
- await waitFor(() => {
250
- expect(multiEditAction).toHaveBeenCalled();
251
- });
252
264
 
253
265
  await waitFor(() => {
254
266
  const activeCell = canvasElement.ownerDocument.activeElement;
@@ -259,19 +271,50 @@ GridKeyboardInteractions.play = async ({ canvasElement }) => {
259
271
  await wait(200);
260
272
  };
261
273
 
274
+ console.log('At 2nd to last cell open the popup menu and select 2nd option');
262
275
  await test(() => userEvent.keyboard('{Enter}'), '8', '2');
276
+ expect(multiEditAction).toHaveBeenCalled();
277
+
278
+ console.log('Open 2nd to last popup menu, tab to next disabled popup');
263
279
  await test(() => userEvent.tab(), '9', '2');
280
+ expect(bulkEditingCallback).toHaveBeenCalled();
281
+ bulkEditingCallback.mockClear();
282
+
283
+ console.log('Fail to edit last popup menu, tab back to 2nd to last popup menu');
264
284
  await userEvent.tab({ shift: true });
265
- await test(() => userEvent.tab({ shift: true }), '6', '2');
285
+ console.log('Open 2nd to last popup menu, tab to desc cell');
286
+ await test(() => userEvent.tab({ shift: true }), '5', '2');
287
+ console.log('Cancel edit');
288
+ await wait(500);
266
289
  await userEvent.keyboard('{Esc}');
290
+ expect(bulkEditingCallback).toHaveBeenCalled();
291
+ bulkEditingCallback.mockClear();
292
+ await wait(500);
293
+
294
+ console.log('Open desc cell');
295
+ await userEvent.keyboard('{Enter}');
296
+ const textInput = await canvas.findByRole('textbox');
297
+ expect(textInput).toBeInTheDocument();
298
+ await userEvent.clear(textInput);
299
+ await userEvent.type(textInput, 'foo');
300
+
267
301
  await userEvent.tab();
302
+ await userEvent.keyboard('{arrowleft}{arrowleft}{arrowleft}');
268
303
 
269
304
  await userEvent.keyboard('{Enter}');
270
- await wait(250);
271
- expect(eAction).not.toHaveBeenCalled();
305
+ await waitFor(
306
+ async () => {
307
+ await canvas.findByText(/There are 1 row/);
308
+ },
309
+ { timeout: 5000 },
310
+ );
311
+ await userEvent.keyboard('{Esc}');
312
+ await userEvent.tab();
272
313
 
314
+ expect(eAction).not.toHaveBeenCalled();
315
+ /*await userEvent.keyboard('{Enter}');
273
316
  await userEvent.keyboard('e');
274
317
  await waitFor(() => {
275
318
  expect(eAction).toHaveBeenCalled();
276
- });
319
+ });*/
277
320
  };
@@ -0,0 +1,17 @@
1
+ import { wait } from '../utils/util';
2
+
3
+ export const waitForCondition = async (
4
+ error: string,
5
+ condition: () => boolean,
6
+ timeoutMs: number,
7
+ ): Promise<boolean> => {
8
+ const endTime = Date.now() + timeoutMs;
9
+ while (Date.now() < endTime) {
10
+ if (condition()) {
11
+ return true;
12
+ }
13
+ await wait(100);
14
+ }
15
+ console.warn(error);
16
+ return false;
17
+ };