@linzjs/step-ag-grid 29.1.5 → 29.2.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/dist/src/components/Grid.d.ts +1 -1
- package/dist/src/contexts/GridContext.d.ts +5 -4
- package/dist/step-ag-grid.cjs +38 -32
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +38 -32
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Grid.tsx +33 -4
- package/src/components/GridCell.tsx +5 -24
- package/src/contexts/GridContext.tsx +6 -1
- package/src/contexts/GridContextProvider.tsx +3 -5
- package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +4 -6
package/package.json
CHANGED
package/src/components/Grid.tsx
CHANGED
|
@@ -142,6 +142,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
142
142
|
rowData,
|
|
143
143
|
rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40,
|
|
144
144
|
selectable,
|
|
145
|
+
onCellFocused: paramsOnCellFocused,
|
|
145
146
|
...params
|
|
146
147
|
}: GridProps<TData>): ReactElement => {
|
|
147
148
|
const {
|
|
@@ -237,11 +238,29 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
237
238
|
}, [autoSizeColumns, gridRenderState, params, rowData, sizeColumns, sizeColumnsToFit]);
|
|
238
239
|
|
|
239
240
|
const lastOwnerDocumentRef = useRef<Document>();
|
|
241
|
+
const wasVisibleRef = useRef(false);
|
|
240
242
|
|
|
241
243
|
/**
|
|
242
244
|
* Auto-size windows that had deferred auto-size
|
|
245
|
+
* Reset focus if panel went from invisible to visible.
|
|
243
246
|
*/
|
|
244
247
|
useInterval(() => {
|
|
248
|
+
// If grid has become visible after previously being hidden, then refocus the last focused cell.
|
|
249
|
+
const visible = !!gridDivRef.current?.checkVisibility();
|
|
250
|
+
if (visible && !wasVisibleRef.current) {
|
|
251
|
+
wasVisibleRef.current = true;
|
|
252
|
+
const el = (window as any).__stepaggrid_lastfocuseventtarget;
|
|
253
|
+
if (el) {
|
|
254
|
+
// Setting this to null will cause a new refocus event
|
|
255
|
+
(window as any).__stepaggrid_lastfocuseventtarget = null;
|
|
256
|
+
// Check element is still part of document
|
|
257
|
+
if (el.checkVisibility()) {
|
|
258
|
+
el.focus();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
wasVisibleRef.current = visible;
|
|
263
|
+
|
|
245
264
|
// Check if window has been popped out and needs resize
|
|
246
265
|
const currentDocument = gridDivRef.current?.ownerDocument;
|
|
247
266
|
if (currentDocument !== lastOwnerDocumentRef.current) {
|
|
@@ -450,7 +469,6 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
450
469
|
const invokeEditAction = (e: CellDoubleClickedEvent | CellKeyDownEvent): boolean => {
|
|
451
470
|
const editAction = e.colDef?.cellRendererParams?.editAction;
|
|
452
471
|
if (!editAction) return false;
|
|
453
|
-
|
|
454
472
|
const editable = fnOrVar(e.colDef?.editable, e);
|
|
455
473
|
if (editable) {
|
|
456
474
|
if (!e.node.isSelected()) {
|
|
@@ -625,7 +643,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
625
643
|
|
|
626
644
|
const onCellFocused = useCallback(
|
|
627
645
|
(event: CellFocusedEvent<TData>) => {
|
|
628
|
-
if (
|
|
646
|
+
if (event.rowIndex == null) {
|
|
629
647
|
return;
|
|
630
648
|
}
|
|
631
649
|
const api = event.api;
|
|
@@ -639,9 +657,19 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
639
657
|
if (!colDef || typeof colDef === 'string') {
|
|
640
658
|
return;
|
|
641
659
|
}
|
|
642
|
-
|
|
660
|
+
// Prevent repeated callbacks to cell focus when focus didn't change
|
|
661
|
+
const { sourceEvent } = event;
|
|
662
|
+
if (sourceEvent) {
|
|
663
|
+
const cell = (sourceEvent.target as unknown as Element).closest('.ag-cell');
|
|
664
|
+
if ((window as any).__stepaggrid_lastfocuseventtarget === cell) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
(window as any).__stepaggrid_lastfocuseventtarget = cell;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
paramsOnCellFocused?.({ colDef, data });
|
|
643
671
|
},
|
|
644
|
-
[
|
|
672
|
+
[paramsOnCellFocused],
|
|
645
673
|
);
|
|
646
674
|
|
|
647
675
|
const onRowDragEnd = useCallback(
|
|
@@ -812,6 +840,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
|
|
|
812
840
|
pinnedBottomRowData={params.pinnedBottomRowData}
|
|
813
841
|
onRowClicked={params.onRowClicked}
|
|
814
842
|
onRowDoubleClicked={params.onRowDoubleClicked}
|
|
843
|
+
suppressStartEditOnTab={true}
|
|
815
844
|
/>
|
|
816
845
|
</div>
|
|
817
846
|
</div>
|
|
@@ -11,8 +11,7 @@ import {
|
|
|
11
11
|
ValueFormatterParams,
|
|
12
12
|
ValueGetterFunc,
|
|
13
13
|
} from 'ag-grid-community';
|
|
14
|
-
import {
|
|
15
|
-
import { forwardRef, ReactElement, useContext, useEffect } from 'react';
|
|
14
|
+
import { forwardRef, ReactElement, useContext } from 'react';
|
|
16
15
|
|
|
17
16
|
import { GridPopoverContextProvider } from '../contexts/GridPopoverContextProvider';
|
|
18
17
|
import { GridUpdatingContext } from '../contexts/GridUpdatingContext';
|
|
@@ -155,14 +154,10 @@ export const GridCell = <TData extends GridBaseRow, TValue = any, Props extends
|
|
|
155
154
|
resizable: true,
|
|
156
155
|
valueSetter: custom?.editor ? blockValueSetter : undefined,
|
|
157
156
|
editable: props.editable ?? !!custom?.editor,
|
|
158
|
-
...(custom?.editor
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
: {
|
|
164
|
-
cellEditor: CellEditorToBlockEditing,
|
|
165
|
-
}),
|
|
157
|
+
...(custom?.editor && {
|
|
158
|
+
cellClassRules: GridCellMultiSelectClassRules,
|
|
159
|
+
cellEditor: GenericCellEditorComponentWrapper(custom?.editor),
|
|
160
|
+
}),
|
|
166
161
|
suppressKeyboardEvent: suppressCellKeyboardEvents,
|
|
167
162
|
...(custom?.editorParams
|
|
168
163
|
? {
|
|
@@ -190,20 +185,6 @@ export const GridCell = <TData extends GridBaseRow, TValue = any, Props extends
|
|
|
190
185
|
};
|
|
191
186
|
};
|
|
192
187
|
|
|
193
|
-
/**
|
|
194
|
-
* Ag-grid will start its own editor if editable is true and there is no cell editor
|
|
195
|
-
* like in the case of a cell that is editable because it triggers a modal.
|
|
196
|
-
* This will block that editor.
|
|
197
|
-
*/
|
|
198
|
-
const CellEditorToBlockEditing = ({ stopEditing }: { stopEditing: () => void }) => {
|
|
199
|
-
useEffect(() => {
|
|
200
|
-
defer(() => {
|
|
201
|
-
stopEditing();
|
|
202
|
-
});
|
|
203
|
-
}, [stopEditing]);
|
|
204
|
-
return <></>;
|
|
205
|
-
};
|
|
206
|
-
|
|
207
188
|
export interface CellEditorCommon {
|
|
208
189
|
className?: string | undefined;
|
|
209
190
|
}
|
|
@@ -15,6 +15,11 @@ export interface AutoSizeColumnsProps {
|
|
|
15
15
|
|
|
16
16
|
export type AutoSizeColumnsResult = { width: number } | null;
|
|
17
17
|
|
|
18
|
+
export interface StartCellEditingProps {
|
|
19
|
+
rowId: number;
|
|
20
|
+
colId: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
export interface GridContextType<TData extends GridBaseRow> {
|
|
19
24
|
gridReady: boolean;
|
|
20
25
|
gridRenderState: () => null | 'empty' | 'rows-visible';
|
|
@@ -43,7 +48,7 @@ export interface GridContextType<TData extends GridBaseRow> {
|
|
|
43
48
|
getFirstRowId: () => number;
|
|
44
49
|
autoSizeColumns: (props?: AutoSizeColumnsProps) => AutoSizeColumnsResult;
|
|
45
50
|
sizeColumnsToFit: () => void;
|
|
46
|
-
startCellEditing: ({ rowId, colId }:
|
|
51
|
+
startCellEditing: ({ rowId, colId }: StartCellEditingProps) => Promise<void>;
|
|
47
52
|
// Restores the previous focus after cell editing
|
|
48
53
|
resetFocusedCellAfterCellEditing: () => void;
|
|
49
54
|
updatingCells: (
|
|
@@ -596,11 +596,9 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
596
596
|
const preRow = gridApi.getFocusedCell();
|
|
597
597
|
// If we don't do this ag-grid will do its own continuation of an edit on tab, we don't want that as
|
|
598
598
|
// we are managing it ourselves
|
|
599
|
-
gridApi.
|
|
600
|
-
if (
|
|
601
|
-
|
|
602
|
-
} else {
|
|
603
|
-
gridApi.tabToPreviousCell();
|
|
599
|
+
const didTab = tabDirection === 1 ? gridApi.tabToNextCell() : gridApi.tabToPreviousCell();
|
|
600
|
+
if (!didTab) {
|
|
601
|
+
break;
|
|
604
602
|
}
|
|
605
603
|
|
|
606
604
|
if (gridApi.isDestroyed()) {
|
|
@@ -275,13 +275,11 @@ GridKeyboardInteractions.play = async ({ canvasElement }) => {
|
|
|
275
275
|
await test(() => userEvent.keyboard('{Enter}'), '8', '2');
|
|
276
276
|
expect(multiEditAction).toHaveBeenCalled();
|
|
277
277
|
|
|
278
|
-
console.log('Open 2nd to last popup menu, tab to next disabled popup');
|
|
279
|
-
await test(() => userEvent.tab(), '
|
|
278
|
+
console.log('Open 2nd to last popup menu, tab to next disabled popup should fail');
|
|
279
|
+
await test(() => userEvent.tab(), '8', '2');
|
|
280
280
|
expect(bulkEditingCallback).toHaveBeenCalled();
|
|
281
281
|
bulkEditingCallback.mockClear();
|
|
282
282
|
|
|
283
|
-
console.log('Fail to edit last popup menu, tab back to 2nd to last popup menu');
|
|
284
|
-
await userEvent.tab({ shift: true });
|
|
285
283
|
console.log('Open 2nd to last popup menu, tab to desc cell');
|
|
286
284
|
await test(() => userEvent.tab({ shift: true }), '5', '2');
|
|
287
285
|
console.log('Cancel edit');
|
|
@@ -312,9 +310,9 @@ GridKeyboardInteractions.play = async ({ canvasElement }) => {
|
|
|
312
310
|
await userEvent.tab();
|
|
313
311
|
|
|
314
312
|
expect(eAction).not.toHaveBeenCalled();
|
|
315
|
-
|
|
313
|
+
await userEvent.keyboard('{Enter}');
|
|
316
314
|
await userEvent.keyboard('e');
|
|
317
315
|
await waitFor(() => {
|
|
318
316
|
expect(eAction).toHaveBeenCalled();
|
|
319
|
-
})
|
|
317
|
+
});
|
|
320
318
|
};
|