@linzjs/step-ag-grid 25.0.1 → 26.0.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/README.md +1 -1
- package/dist/GridTheme.scss +29 -61
- package/dist/src/components/Grid.d.ts +9 -7
- package/dist/src/components/GridCell.d.ts +4 -5
- package/dist/src/components/gridForm/GridFormDropDown.d.ts +1 -1
- package/dist/src/components/gridPopoverEdit/GridEditBoolean.d.ts +1 -1
- package/dist/src/components/index.d.ts +0 -2
- package/dist/src/contexts/GridContext.d.ts +1 -1
- package/dist/step-ag-grid.cjs +652 -265
- package/dist/step-ag-grid.cjs.map +1 -1
- package/dist/step-ag-grid.esm.js +658 -269
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +39 -45
- package/src/components/Grid.tsx +111 -139
- package/src/components/GridCell.tsx +4 -6
- package/src/components/gridForm/GridFormDropDown.tsx +1 -1
- package/src/components/gridHeader/GridHeaderSelect.tsx +1 -1
- package/src/components/gridPopoverEdit/GridEditBoolean.tsx +5 -1
- package/src/components/index.ts +0 -2
- package/src/contexts/GridContext.tsx +3 -2
- package/src/contexts/GridContextProvider.tsx +85 -48
- package/src/react-menu3/components/ControlledMenu.tsx +15 -2
- package/src/stories/grid/GridDragRow.stories.tsx +16 -13
- package/src/stories/grid/GridFilterButtons.stories.tsx +7 -1
- package/src/stories/grid/GridPopoverEditDropDown.stories.tsx +1 -1
- package/src/stories/grid/gridFormStatic/GridFormDropDown.stories.tsx +1 -1
- package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +6 -4
- package/src/styles/GridTheme.scss +29 -61
|
@@ -75,9 +75,9 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
75
75
|
const ensureRowVisible = useCallback(
|
|
76
76
|
(id: number | string): boolean => {
|
|
77
77
|
if (!gridApi) return false;
|
|
78
|
-
const node = gridApi
|
|
78
|
+
const node = gridApi.getRowNode(`${id}`);
|
|
79
79
|
if (!node) return false;
|
|
80
|
-
defer(() => gridApi.ensureNodeVisible(node));
|
|
80
|
+
defer(() => !gridApi.isDestroyed() && gridApi.ensureNodeVisible(node));
|
|
81
81
|
return true;
|
|
82
82
|
},
|
|
83
83
|
[gridApi],
|
|
@@ -141,16 +141,21 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
141
141
|
* Before a popup record the currently focused cell.
|
|
142
142
|
*/
|
|
143
143
|
const prePopupOps = useCallback(() => {
|
|
144
|
-
|
|
144
|
+
if (!gridApi || gridApi.isDestroyed()) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
prePopupFocusedCell.current = gridApi.getFocusedCell() ?? undefined;
|
|
145
148
|
}, [gridApi]);
|
|
146
149
|
|
|
147
150
|
/**
|
|
148
151
|
* After a popup refocus the cell.
|
|
149
152
|
*/
|
|
150
153
|
const postPopupOps = useCallback(() => {
|
|
151
|
-
if (!gridApi)
|
|
154
|
+
if (!gridApi || gridApi.isDestroyed()) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
152
157
|
if (prePopupFocusedCell.current) {
|
|
153
|
-
gridApi
|
|
158
|
+
gridApi.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
|
|
154
159
|
}
|
|
155
160
|
}, [gridApi]);
|
|
156
161
|
|
|
@@ -271,7 +276,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
271
276
|
);
|
|
272
277
|
const firstNode = rowsThatNeedSelecting[0];
|
|
273
278
|
if (firstNode) {
|
|
274
|
-
defer(() => gridApi.ensureNodeVisible(firstNode));
|
|
279
|
+
defer(() => !gridApi.isDestroyed() && gridApi.ensureNodeVisible(firstNode));
|
|
275
280
|
const colDefs = getColumns();
|
|
276
281
|
if (!isEmpty(colDefs)) {
|
|
277
282
|
const col = colDefs[0];
|
|
@@ -282,9 +287,16 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
282
287
|
// as they will start to edit the cell before this stuff has a chance to run
|
|
283
288
|
colId &&
|
|
284
289
|
delay(() => {
|
|
285
|
-
if (
|
|
286
|
-
|
|
290
|
+
if (
|
|
291
|
+
isEmpty(gridApi.getEditingCells()) &&
|
|
292
|
+
(!ifNoCellFocused || gridApi.getFocusedCell() == null) &&
|
|
293
|
+
!gridApi.isDestroyed()
|
|
294
|
+
) {
|
|
287
295
|
gridApi.setFocusedCell(rowIndex, colId);
|
|
296
|
+
// It may be that the first cell is the selection cell, this doesn't exist as a colDef
|
|
297
|
+
// so instead, I just try and select it. If it doesn't exist selection will stay on the
|
|
298
|
+
// previously focused cell
|
|
299
|
+
gridApi.setFocusedCell(rowIndex, 'ag-Grid-SelectionColumn');
|
|
288
300
|
}
|
|
289
301
|
}, 100);
|
|
290
302
|
}
|
|
@@ -303,7 +315,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
303
315
|
if (flash) {
|
|
304
316
|
delay(() => {
|
|
305
317
|
try {
|
|
306
|
-
gridApi.flashCells({ rowNodes });
|
|
318
|
+
!gridApi.isDestroyed && gridApi.flashCells({ rowNodes });
|
|
307
319
|
} catch {
|
|
308
320
|
// ignore, flash cells sometimes throws errors as nodes have gone out of scope
|
|
309
321
|
}
|
|
@@ -403,7 +415,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
403
415
|
gridApiOp((gridApi) => {
|
|
404
416
|
const selectedNodes = gridApi.getSelectedNodes();
|
|
405
417
|
if (isEmpty(selectedNodes)) return;
|
|
406
|
-
defer(() => gridApi.ensureNodeVisible(last(selectedNodes)));
|
|
418
|
+
defer(() => !gridApi.isDestroyed() && gridApi.ensureNodeVisible(last(selectedNodes)));
|
|
407
419
|
});
|
|
408
420
|
}, [gridApiOp]);
|
|
409
421
|
|
|
@@ -446,48 +458,67 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
446
458
|
}, [gridApi]);
|
|
447
459
|
|
|
448
460
|
const stopEditing = useCallback((): void => {
|
|
449
|
-
if (!gridApi)
|
|
450
|
-
|
|
451
|
-
gridApi?.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
|
|
461
|
+
if (!gridApi || gridApi.isDestroyed()) {
|
|
462
|
+
return;
|
|
452
463
|
}
|
|
453
464
|
gridApi.stopEditing();
|
|
465
|
+
if (prePopupFocusedCell.current) {
|
|
466
|
+
gridApi.setFocusedCell(prePopupFocusedCell.current.rowIndex, prePopupFocusedCell.current.column);
|
|
467
|
+
}
|
|
454
468
|
}, [gridApi]);
|
|
455
469
|
|
|
470
|
+
// waitForExternallySelectedItemsToBeInSync can't use the state as it won't be updated during function execution
|
|
471
|
+
const externallySelectedItemsAreInSyncRef = useRef(false);
|
|
472
|
+
useEffect(() => {
|
|
473
|
+
externallySelectedItemsAreInSyncRef.current = externallySelectedItemsAreInSync;
|
|
474
|
+
}, [externallySelectedItemsAreInSync]);
|
|
475
|
+
|
|
476
|
+
const waitForExternallySelectedItemsToBeInSync = useCallback(async () => {
|
|
477
|
+
// Wait for up to 5 seconds
|
|
478
|
+
for (let i = 0; i < 5000 / 200 && !externallySelectedItemsAreInSyncRef.current; i++) {
|
|
479
|
+
await wait(200);
|
|
480
|
+
}
|
|
481
|
+
}, []);
|
|
482
|
+
|
|
456
483
|
const startCellEditing = useCallback(
|
|
457
|
-
|
|
458
|
-
({ rowId, colId }: { rowId: number; colId: string }) => {
|
|
484
|
+
async ({ rowId, colId }: { rowId: number; colId: string }) => {
|
|
459
485
|
if (!gridApi) return;
|
|
460
486
|
|
|
461
487
|
const colDef = gridApi.getColumnDef(colId);
|
|
462
|
-
if (!colDef)
|
|
488
|
+
if (!colDef) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
463
491
|
|
|
464
|
-
prePopupOps();
|
|
465
492
|
const rowNode = gridApi.getRowNode(`${rowId}`);
|
|
466
493
|
if (!rowNode) {
|
|
467
494
|
return;
|
|
468
495
|
}
|
|
469
496
|
|
|
470
|
-
|
|
497
|
+
prePopupOps();
|
|
498
|
+
const shouldSelectNode = !rowNode.isSelected();
|
|
499
|
+
if (shouldSelectNode) {
|
|
500
|
+
externallySelectedItemsAreInSyncRef.current = false;
|
|
471
501
|
rowNode.setSelected(true, true);
|
|
502
|
+
await waitForExternallySelectedItemsToBeInSync();
|
|
472
503
|
}
|
|
473
504
|
|
|
474
505
|
// Cell already being edited, so don't re-edit until finished
|
|
475
|
-
if (checkUpdating([colDef.field ?? ''], rowId)) {
|
|
506
|
+
if (checkUpdating([colDef.field ?? colDef.colId ?? ''], rowId)) {
|
|
476
507
|
return;
|
|
477
508
|
}
|
|
478
509
|
|
|
479
510
|
const rowIndex = rowNode.rowIndex;
|
|
480
511
|
if (rowIndex != null) {
|
|
481
|
-
|
|
482
|
-
gridApi.
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
512
|
+
defer(() => {
|
|
513
|
+
!gridApi.isDestroyed() &&
|
|
514
|
+
gridApi.startEditingCell({
|
|
515
|
+
rowIndex,
|
|
516
|
+
colKey: colId,
|
|
517
|
+
});
|
|
518
|
+
});
|
|
488
519
|
}
|
|
489
520
|
},
|
|
490
|
-
[checkUpdating, gridApi, prePopupOps],
|
|
521
|
+
[checkUpdating, gridApi, prePopupOps, waitForExternallySelectedItemsToBeInSync],
|
|
491
522
|
);
|
|
492
523
|
|
|
493
524
|
/**
|
|
@@ -507,12 +538,12 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
507
538
|
* Returns true if an editable cell on same row was selected, else false.
|
|
508
539
|
*/
|
|
509
540
|
const selectNextEditableCell = useCallback(
|
|
510
|
-
(tabDirection: -1 | 1): boolean => {
|
|
541
|
+
async (tabDirection: -1 | 1): Promise<boolean> => {
|
|
511
542
|
// Pretend it succeeded to prevent unwanted cellEditingCompleteCallback
|
|
512
543
|
if (!gridApi) return true;
|
|
513
544
|
|
|
514
545
|
const focusedCellIsEditable = () => {
|
|
515
|
-
const focusedCell = gridApi.getFocusedCell();
|
|
546
|
+
const focusedCell = gridApi.isDestroyed() ? null : gridApi.getFocusedCell();
|
|
516
547
|
const nextColumn = focusedCell?.column;
|
|
517
548
|
const nextColDef = nextColumn?.getColDef();
|
|
518
549
|
const rowNode = focusedCell && gridApi.getDisplayedRowAtIndex(focusedCell?.rowIndex);
|
|
@@ -526,8 +557,23 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
526
557
|
|
|
527
558
|
// Just in case I've missed something, we don't want the loop to hang everything
|
|
528
559
|
for (let maxIterations = 0; maxIterations < 50; maxIterations++) {
|
|
560
|
+
if (gridApi.isDestroyed()) {
|
|
561
|
+
return true;
|
|
562
|
+
}
|
|
529
563
|
const preRow = gridApi.getFocusedCell();
|
|
530
|
-
tabDirection === 1
|
|
564
|
+
if (tabDirection === 1) {
|
|
565
|
+
gridApi.tabToNextCell();
|
|
566
|
+
} else {
|
|
567
|
+
gridApi.tabToPreviousCell();
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
// If we don't wait the tab to next element won't work
|
|
571
|
+
// I think this is due to the grid resizing
|
|
572
|
+
await wait(150);
|
|
573
|
+
|
|
574
|
+
if (gridApi.isDestroyed()) {
|
|
575
|
+
return true;
|
|
576
|
+
}
|
|
531
577
|
const postRow = gridApi.getFocusedCell();
|
|
532
578
|
if (preRow?.rowIndex !== postRow?.rowIndex || preRow?.column === postRow?.column) {
|
|
533
579
|
// We didn't find an editable cell in the same row, or the cell column didn't change
|
|
@@ -536,7 +582,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
536
582
|
}
|
|
537
583
|
|
|
538
584
|
if (focusedCellIsEditable()) {
|
|
539
|
-
const focusedCell = gridApi
|
|
585
|
+
const focusedCell = gridApi.getFocusedCell();
|
|
540
586
|
if (focusedCell) {
|
|
541
587
|
prePopupOps();
|
|
542
588
|
gridApi.startEditingCell({
|
|
@@ -569,8 +615,10 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
569
615
|
props.field ?? '',
|
|
570
616
|
selectedRows.map((data) => data.id),
|
|
571
617
|
async () => {
|
|
618
|
+
// MATT Disabled I don't believe these are needed anymore
|
|
619
|
+
// I've left them here just in case they are
|
|
572
620
|
// Need to refresh to get spinners to work on all rows
|
|
573
|
-
gridApi.refreshCells({ rowNodes: props.selectedRows as RowNode[], force: true });
|
|
621
|
+
// gridApi.refreshCells({ rowNodes: props.selectedRows as RowNode[], force: true });
|
|
574
622
|
ok = await fnUpdate(selectedRows).catch((ex) => {
|
|
575
623
|
console.error('Exception during modifyUpdating', ex);
|
|
576
624
|
return false;
|
|
@@ -578,13 +626,15 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
578
626
|
},
|
|
579
627
|
);
|
|
580
628
|
|
|
629
|
+
// MATT Disabled I don't believe these are needed anymore
|
|
630
|
+
// I've left them here just in case they are
|
|
581
631
|
// async processes need to refresh their own rows
|
|
582
|
-
gridApi.refreshCells({ rowNodes: selectedRows as RowNode[], force: true });
|
|
632
|
+
// gridApi.refreshCells({ rowNodes: selectedRows as RowNode[], force: true });
|
|
583
633
|
|
|
584
634
|
if (ok) {
|
|
585
635
|
const cell = gridApi.getFocusedCell();
|
|
586
636
|
if (cell && gridApi.getFocusedCell() == null) {
|
|
587
|
-
gridApi.setFocusedCell(cell.rowIndex, cell.column);
|
|
637
|
+
!gridApi.isDestroyed && gridApi.setFocusedCell(cell.rowIndex, cell.column);
|
|
588
638
|
}
|
|
589
639
|
// This is needed to trigger postSortRowsHook
|
|
590
640
|
gridApi.refreshClientSideRowModel();
|
|
@@ -601,7 +651,7 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
601
651
|
prePopupFocusedCell.current.rowIndex == postPopupFocusedCell.rowIndex &&
|
|
602
652
|
prePopupFocusedCell.current.column.getColId() == postPopupFocusedCell.column.getColId()
|
|
603
653
|
) {
|
|
604
|
-
if (!tabDirection || !selectNextEditableCell(tabDirection)) {
|
|
654
|
+
if (!tabDirection || !(await selectNextEditableCell(tabDirection))) {
|
|
605
655
|
cellEditingCompleteCallbackRef.current && cellEditingCompleteCallbackRef.current();
|
|
606
656
|
}
|
|
607
657
|
}
|
|
@@ -624,19 +674,6 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
|
|
|
624
674
|
[gridApi],
|
|
625
675
|
);
|
|
626
676
|
|
|
627
|
-
// waitForExternallySelectedItemsToBeInSync can't use the state as it won't be updated during function execution
|
|
628
|
-
const externallySelectedItemsAreInSyncRef = useRef(false);
|
|
629
|
-
useEffect(() => {
|
|
630
|
-
externallySelectedItemsAreInSyncRef.current = externallySelectedItemsAreInSync;
|
|
631
|
-
}, [externallySelectedItemsAreInSync]);
|
|
632
|
-
|
|
633
|
-
const waitForExternallySelectedItemsToBeInSync = useCallback(async () => {
|
|
634
|
-
// Wait for up to 5 seconds
|
|
635
|
-
for (let i = 0; i < 5000 / 200 && !externallySelectedItemsAreInSyncRef.current; i++) {
|
|
636
|
-
await wait(200);
|
|
637
|
-
}
|
|
638
|
-
}, []);
|
|
639
|
-
|
|
640
677
|
const onFilterChanged = useMemo(
|
|
641
678
|
() =>
|
|
642
679
|
debounce(() => {
|
|
@@ -120,8 +120,12 @@ export const ControlledMenuFr = (
|
|
|
120
120
|
(isDown: boolean) => (ev: KeyboardEvent) => {
|
|
121
121
|
const thisDocument = anchorRef?.current ? anchorRef?.current.ownerDocument : document;
|
|
122
122
|
const activeElement = thisDocument.activeElement;
|
|
123
|
-
if (!anchorRef?.current || !activeElement)
|
|
124
|
-
|
|
123
|
+
if (!anchorRef?.current || !activeElement) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (ev.key !== 'Tab' && ev.key !== 'Enter' && ev.key !== 'Esc') {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
125
129
|
|
|
126
130
|
if (ev.repeat) {
|
|
127
131
|
ev.preventDefault();
|
|
@@ -129,6 +133,13 @@ export const ControlledMenuFr = (
|
|
|
129
133
|
return;
|
|
130
134
|
}
|
|
131
135
|
|
|
136
|
+
if (ev.key === 'Esc') {
|
|
137
|
+
ev.preventDefault();
|
|
138
|
+
ev.stopPropagation();
|
|
139
|
+
safeCall(onClose, { key: ev.key, reason: CloseReason.CANCEL });
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
132
143
|
const invokeSave = (reason: string) => {
|
|
133
144
|
if (!saveButtonRef?.current) return;
|
|
134
145
|
saveButtonRef.current?.setAttribute('data-reason', reason);
|
|
@@ -265,6 +276,7 @@ export const ControlledMenuFr = (
|
|
|
265
276
|
);
|
|
266
277
|
|
|
267
278
|
const onKeyUp = (e: KeyboardEvent) => {
|
|
279
|
+
console.log(e);
|
|
268
280
|
switch (e.key) {
|
|
269
281
|
case Keys.ESC:
|
|
270
282
|
e.preventDefault();
|
|
@@ -319,6 +331,7 @@ export const ControlledMenuFr = (
|
|
|
319
331
|
externalRef={externalRef}
|
|
320
332
|
containerRef={containerRef}
|
|
321
333
|
onClose={onClose}
|
|
334
|
+
onBlur={() => console.log('blur')}
|
|
322
335
|
/>
|
|
323
336
|
</EventHandlersContext.Provider>
|
|
324
337
|
</ItemSettingsContext.Provider>
|
|
@@ -4,13 +4,14 @@ import '@linzjs/lui/dist/scss/base.scss';
|
|
|
4
4
|
import '@linzjs/lui/dist/fonts';
|
|
5
5
|
|
|
6
6
|
import { Meta, StoryFn } from '@storybook/react';
|
|
7
|
-
import { useMemo, useState } from 'react';
|
|
7
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
ColDefT,
|
|
11
11
|
Grid,
|
|
12
12
|
GridCell,
|
|
13
13
|
GridContextProvider,
|
|
14
|
+
GridOnRowDragEndProps,
|
|
14
15
|
GridProps,
|
|
15
16
|
GridUpdatingContextProvider,
|
|
16
17
|
GridWrapper,
|
|
@@ -52,12 +53,12 @@ interface ITestRow {
|
|
|
52
53
|
id: number;
|
|
53
54
|
position: string;
|
|
54
55
|
age: number;
|
|
55
|
-
height:
|
|
56
|
+
height: string;
|
|
56
57
|
desc: string;
|
|
57
58
|
dd: string;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
const GridDragRowTemplate: StoryFn<typeof Grid
|
|
61
|
+
const GridDragRowTemplate: StoryFn<typeof Grid<ITestRow>> = (props: GridProps<ITestRow>) => {
|
|
61
62
|
const columnDefs: ColDefT<ITestRow>[] = useMemo(
|
|
62
63
|
() => [
|
|
63
64
|
GridCell({
|
|
@@ -90,13 +91,23 @@ const GridDragRowTemplate: StoryFn<typeof Grid> = (props: GridProps) => {
|
|
|
90
91
|
[],
|
|
91
92
|
);
|
|
92
93
|
|
|
93
|
-
const [rowData, setRowData] = useState([
|
|
94
|
+
const [rowData, setRowData] = useState<ITestRow[]>([
|
|
94
95
|
{ id: 1000, position: 'Tester', age: 30, height: `6'4"`, desc: 'Tests application', dd: '1' },
|
|
95
96
|
{ id: 1001, position: 'Developer', age: 12, height: `5'3"`, desc: 'Develops application', dd: '2' },
|
|
96
97
|
{ id: 1002, position: 'Manager', age: 65, height: `5'9"`, desc: 'Manages', dd: '3' },
|
|
97
98
|
{ id: 1003, position: 'BA', age: 42, height: `5'7"`, desc: 'BAs', dd: '4' },
|
|
98
99
|
]);
|
|
99
100
|
|
|
101
|
+
const onRowDragEnd = useCallback(({ movedRow, targetRow }: GridOnRowDragEndProps<ITestRow>) => {
|
|
102
|
+
setRowData((rowData) =>
|
|
103
|
+
rowData.map((r) => {
|
|
104
|
+
if (r.id === movedRow.id) return targetRow;
|
|
105
|
+
if (r.id === targetRow.id) return movedRow;
|
|
106
|
+
return r;
|
|
107
|
+
}),
|
|
108
|
+
);
|
|
109
|
+
}, []);
|
|
110
|
+
|
|
100
111
|
return (
|
|
101
112
|
<GridWrapper maxHeight={300}>
|
|
102
113
|
<Grid
|
|
@@ -108,15 +119,7 @@ const GridDragRowTemplate: StoryFn<typeof Grid> = (props: GridProps) => {
|
|
|
108
119
|
columnDefs={columnDefs}
|
|
109
120
|
defaultColDef={{ sortable: false }}
|
|
110
121
|
rowData={rowData}
|
|
111
|
-
onRowDragEnd={
|
|
112
|
-
setRowData(
|
|
113
|
-
rowData.map((r) => {
|
|
114
|
-
if (r.id === movedRow.id) return targetRow;
|
|
115
|
-
if (r.id === targetRow.id) return movedRow;
|
|
116
|
-
return r;
|
|
117
|
-
}),
|
|
118
|
-
);
|
|
119
|
-
}}
|
|
122
|
+
onRowDragEnd={onRowDragEnd}
|
|
120
123
|
rowDragText={({ rowNode }) => `${rowNode?.data.id} - ${rowNode?.data.position}`}
|
|
121
124
|
/>
|
|
122
125
|
</GridWrapper>
|
|
@@ -98,7 +98,13 @@ const GridFilterButtonsTemplate: StoryFn<typeof Grid> = (props: GridProps) => {
|
|
|
98
98
|
]}
|
|
99
99
|
/>
|
|
100
100
|
</GridFilters>
|
|
101
|
-
<Grid
|
|
101
|
+
<Grid
|
|
102
|
+
{...props}
|
|
103
|
+
rowSelection={'multiple'}
|
|
104
|
+
columnDefs={columnDefs}
|
|
105
|
+
rowData={rowData}
|
|
106
|
+
sizeColumns={'auto-skip-headers'}
|
|
107
|
+
/>
|
|
102
108
|
</GridWrapper>
|
|
103
109
|
);
|
|
104
110
|
};
|
|
@@ -170,7 +170,7 @@ const GridEditDropDownTemplate: StoryFn<typeof Grid> = (props: GridProps) => {
|
|
|
170
170
|
),
|
|
171
171
|
GridPopoverEditDropDown(
|
|
172
172
|
{
|
|
173
|
-
|
|
173
|
+
field: 'position4',
|
|
174
174
|
headerName: 'Filtered (object)',
|
|
175
175
|
valueGetter: ({ data }) => data?.position4?.desc,
|
|
176
176
|
},
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
args: {},
|
|
16
16
|
} as Meta<typeof GridFormDropDown>;
|
|
17
17
|
|
|
18
|
-
const Template: StoryFn<typeof GridFormDropDown> = (props: GridFormDropDownProps<
|
|
18
|
+
const Template: StoryFn<typeof GridFormDropDown> = (props: GridFormDropDownProps<GridBaseRow>) => {
|
|
19
19
|
const configs: [string, GridFormDropDownProps<GridBaseRow>, string?][] = [
|
|
20
20
|
['No options', { options: [] }],
|
|
21
21
|
['Custom no options', { options: [], noOptionsMessage: 'Custom no options' }],
|
|
@@ -66,10 +66,12 @@ interface ITestRow {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
const multiEditAction = fn(async () => {
|
|
69
|
+
console.log('multiEditAction');
|
|
69
70
|
await wait(500);
|
|
70
71
|
});
|
|
71
72
|
|
|
72
73
|
const eAction = fn(() => {
|
|
74
|
+
console.log('eAction');
|
|
73
75
|
return true;
|
|
74
76
|
});
|
|
75
77
|
|
|
@@ -141,7 +143,7 @@ const GridKeyboardInteractionsTemplate: StoryFn<typeof Grid> = (props: GridProps
|
|
|
141
143
|
},
|
|
142
144
|
options: async (selectedItems) => {
|
|
143
145
|
// Just doing a timeout here to demonstrate deferred loading
|
|
144
|
-
await wait(
|
|
146
|
+
await wait(50);
|
|
145
147
|
return [
|
|
146
148
|
{
|
|
147
149
|
label: 'Single edit only',
|
|
@@ -223,8 +225,8 @@ const GridKeyboardInteractionsTemplate: StoryFn<typeof Grid> = (props: GridProps
|
|
|
223
225
|
|
|
224
226
|
export const GridKeyboardInteractions: StoryFn<typeof Grid> = GridKeyboardInteractionsTemplate.bind({});
|
|
225
227
|
GridKeyboardInteractions.play = async ({ canvasElement }) => {
|
|
226
|
-
multiEditAction.
|
|
227
|
-
eAction.
|
|
228
|
+
multiEditAction.mockClear();
|
|
229
|
+
eAction.mockClear();
|
|
228
230
|
|
|
229
231
|
await waitForGridReady({ canvasElement });
|
|
230
232
|
|
|
@@ -254,7 +256,7 @@ GridKeyboardInteractions.play = async ({ canvasElement }) => {
|
|
|
254
256
|
expect(activeCell).toHaveAttribute('aria-colindex', colId);
|
|
255
257
|
expect(activeCell?.parentElement).toHaveAttribute('row-index', rowId);
|
|
256
258
|
});
|
|
257
|
-
await wait(
|
|
259
|
+
await wait(200);
|
|
258
260
|
};
|
|
259
261
|
|
|
260
262
|
await test(() => userEvent.keyboard('{Enter}'), '8', '2');
|
|
@@ -58,6 +58,29 @@ $grid-base-font-size: calc(#{lui.$base-font-size} - 1px);
|
|
|
58
58
|
)
|
|
59
59
|
);
|
|
60
60
|
|
|
61
|
+
// Don't hide the drag handle
|
|
62
|
+
.ag-theme-step-default.theme-specific .ag-drag-handle.ag-row-drag, .ag-theme-step-compact.theme-specific div.ag-drag-handle.ag-row-drag {
|
|
63
|
+
opacity: 1 !important;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.ag-header-hide-default-select .ag-labeled {
|
|
67
|
+
display: none;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.ag-header-hide-default-select .ag-wrapper.ag-checkbox-input-wrapper {
|
|
71
|
+
margin-right: 9px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
div.ag-header-cell.ag-header-select-draggable[col-id='ag-Grid-SelectionColumn'] {
|
|
75
|
+
padding-left: 40px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.ag-drag-handle.ag-row-drag {
|
|
79
|
+
.ag-icon.ag-icon-grip {
|
|
80
|
+
margin: auto;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
61
84
|
.ag-theme-step-default.theme-specific,
|
|
62
85
|
.ag-theme-step-compact.theme-specific {
|
|
63
86
|
div.ag-center-cols-viewport {
|
|
@@ -70,61 +93,29 @@ $grid-base-font-size: calc(#{lui.$base-font-size} - 1px);
|
|
|
70
93
|
justify-content: center;
|
|
71
94
|
}
|
|
72
95
|
|
|
73
|
-
.ag-header-select-draggable .ag-header-cell-comp-wrapper {
|
|
74
|
-
justify-content: end;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
96
|
.ag-header-cell {
|
|
78
97
|
font-size: 14px;
|
|
79
98
|
font-weight: 600;
|
|
80
99
|
|
|
81
|
-
// fix: Display descender line
|
|
82
|
-
padding: 0 11px;
|
|
83
|
-
|
|
84
100
|
.LuiIcon {
|
|
85
101
|
fill: lui.$surfie;
|
|
86
102
|
}
|
|
87
103
|
}
|
|
88
|
-
|
|
89
|
-
.ag-header .ag-header-cell[aria-colindex="1"] {
|
|
90
|
-
padding-left: 17px;
|
|
91
|
-
padding-right: 15px;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
104
|
.ag-text-area-input:focus {
|
|
95
105
|
border-color: lui.$sea;
|
|
96
106
|
}
|
|
97
107
|
|
|
98
|
-
.ag-cell[col-id="selection"] {
|
|
99
|
-
display: flex; // Fix that when you click below checkbox it doesn't process a click
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Fix that when you click below checkbox it doesn't process a click
|
|
103
|
-
.ag-cell-wrapper > *:not(.ag-cell-value, .ag-group-value) {
|
|
104
|
-
height: auto;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
108
|
.ag-row:last-of-type {
|
|
108
109
|
border-bottom: 1px solid lui.$dew;
|
|
109
110
|
}
|
|
110
111
|
|
|
111
112
|
.ag-cell-label-container {
|
|
112
|
-
padding: 8px 0;
|
|
113
|
-
|
|
114
113
|
// Help ag-grid to calculate column height in react portal
|
|
115
114
|
height: fit-content;
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
padding-left: lui.$unit-rg;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.ag-cell {
|
|
124
|
-
padding-left: 11px;
|
|
125
|
-
padding-right: 11px;
|
|
126
|
-
display: flex;
|
|
127
|
-
align-items: center;
|
|
117
|
+
.ag-cell .ag-cell-wrapper {
|
|
118
|
+
width: 100%;
|
|
128
119
|
}
|
|
129
120
|
|
|
130
121
|
.ag-cell-wrap-text {
|
|
@@ -167,7 +158,10 @@ $grid-base-font-size: calc(#{lui.$base-font-size} - 1px);
|
|
|
167
158
|
}
|
|
168
159
|
}
|
|
169
160
|
|
|
161
|
+
|
|
170
162
|
.ag-cell {
|
|
163
|
+
display: flex;
|
|
164
|
+
align-items: center;
|
|
171
165
|
font-weight: 400;
|
|
172
166
|
}
|
|
173
167
|
|
|
@@ -217,25 +211,16 @@ $grid-base-font-size: calc(#{lui.$base-font-size} - 1px);
|
|
|
217
211
|
visibility: inherit;
|
|
218
212
|
}
|
|
219
213
|
|
|
220
|
-
.ag-cell-wrapper {
|
|
221
|
-
width: 100%;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
214
|
.ag-row-highlight-above::after, .ag-row-highlight-below::after {
|
|
225
215
|
content: '';
|
|
226
|
-
height:
|
|
216
|
+
height: 3px;
|
|
227
217
|
background-color: transparent;
|
|
228
218
|
}
|
|
229
219
|
|
|
230
220
|
.ag-row-highlight-above::after {
|
|
231
|
-
top:-3px; // moves the top highlight to the position of the bottom highlight
|
|
232
221
|
border-top: 2px dashed lui.$andrea;
|
|
233
222
|
}
|
|
234
223
|
|
|
235
|
-
.ag-row-highlight-above:first-of-type::after {
|
|
236
|
-
top:0; // the first row highlight needs to in the normal position otherwise it is cut off by the top of the table
|
|
237
|
-
}
|
|
238
|
-
|
|
239
224
|
.ag-row-highlight-below::after {
|
|
240
225
|
border-bottom: 2px dashed lui.$andrea;
|
|
241
226
|
}
|
|
@@ -266,19 +251,10 @@ $grid-base-font-size: calc(#{lui.$base-font-size} - 1px);
|
|
|
266
251
|
font-size: 14px;
|
|
267
252
|
font-weight: 600;
|
|
268
253
|
|
|
269
|
-
// fix: Display descender line
|
|
270
|
-
padding: 0 12px;
|
|
271
|
-
|
|
272
254
|
.LuiIcon {
|
|
273
255
|
fill: lui.$surfie;
|
|
274
256
|
}
|
|
275
257
|
}
|
|
276
|
-
|
|
277
|
-
.ag-header .ag-header-cell[aria-colindex="1"] {
|
|
278
|
-
padding-left: 32px;
|
|
279
|
-
padding-right: 12px;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
258
|
.ag-header-group-cell {
|
|
283
259
|
font-weight: normal;
|
|
284
260
|
font-size: 22px;
|
|
@@ -287,12 +263,4 @@ $grid-base-font-size: calc(#{lui.$base-font-size} - 1px);
|
|
|
287
263
|
.ag-header-cell {
|
|
288
264
|
font-size: 14px;
|
|
289
265
|
}
|
|
290
|
-
|
|
291
|
-
.ag-row .ag-cell:first-of-type {
|
|
292
|
-
padding-left: 32px;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
.ag-row .ag-cell:last-of-type {
|
|
296
|
-
padding-right: 32px;
|
|
297
|
-
}
|
|
298
266
|
}
|