@linzjs/step-ag-grid 29.13.0 → 29.14.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.
Files changed (44) hide show
  1. package/dist/index.css +26 -2
  2. package/dist/src/components/Grid.d.ts +36 -61
  3. package/dist/src/components/GridRangeSelectContextMenu.d.ts +10 -0
  4. package/dist/src/components/gridForm/GridFormDropDown.d.ts +1 -1
  5. package/dist/src/components/gridForm/GridFormPopoverMenu.d.ts +2 -1
  6. package/dist/src/components/gridHook/useGridContextMenu.d.ts +12 -7
  7. package/dist/src/components/gridHook/useGridCopy.d.ts +15 -0
  8. package/dist/src/components/gridHook/useGridCopySettings.d.ts +11 -0
  9. package/dist/src/components/gridHook/useGridRangeSelection.d.ts +25 -0
  10. package/dist/src/components/gridPopoverEdit/GridPopoverEditBearing.d.ts +2 -0
  11. package/dist/src/components/types.d.ts +1 -0
  12. package/dist/src/contexts/GridContext.d.ts +1 -0
  13. package/dist/src/lui/timeoutHook.d.ts +0 -6
  14. package/dist/src/lui/tsUtils.d.ts +5 -0
  15. package/dist/src/utils/__tests__/random.ts +19 -0
  16. package/dist/src/utils/util.d.ts +1 -0
  17. package/dist/step-ag-grid.cjs +560 -79
  18. package/dist/step-ag-grid.cjs.map +1 -1
  19. package/dist/step-ag-grid.esm.js +561 -82
  20. package/dist/step-ag-grid.esm.js.map +1 -1
  21. package/package.json +1 -1
  22. package/src/components/Grid.tsx +249 -179
  23. package/src/components/GridRangeSelectContextMenu.tsx +73 -0
  24. package/src/components/gridForm/GridFormDropDown.tsx +1 -3
  25. package/src/components/gridForm/GridFormPopoverMenu.tsx +2 -1
  26. package/src/components/gridHook/useGridContextMenu.tsx +22 -9
  27. package/src/components/gridHook/useGridCopy.ts +279 -0
  28. package/src/components/gridHook/useGridCopySettings.ts +28 -0
  29. package/src/components/gridHook/useGridRangeSelection.ts +235 -0
  30. package/src/components/gridPopoverEdit/GridPopoverEditBearing.ts +3 -0
  31. package/src/components/types.ts +2 -0
  32. package/src/contexts/GridContext.tsx +2 -0
  33. package/src/contexts/GridContextProvider.tsx +5 -2
  34. package/src/lui/timeoutHook.tsx +0 -19
  35. package/src/lui/tsUtils.ts +8 -0
  36. package/src/stories/grid/GridCopy.stories.tsx +175 -0
  37. package/src/stories/grid/GridPopoverEditBearing.stories.tsx +4 -4
  38. package/src/stories/grid/GridReadOnly.stories.tsx +1 -0
  39. package/src/stories/grid/interactions/GridKeyboardInteractions.stories.tsx +2 -2
  40. package/src/styles/ContextMenu.scss +61 -0
  41. package/src/styles/Grid.scss +26 -2
  42. package/src/utils/__tests__/random.ts +19 -0
  43. package/src/utils/bearing.ts +2 -2
  44. package/src/utils/util.ts +2 -0
package/dist/index.css CHANGED
@@ -320,8 +320,12 @@
320
320
  margin-right: auto;
321
321
  }
322
322
 
323
- .ag-unselectable .ag-cell:not([col-id=ag-Grid-SelectionColumn]) {
324
- user-select: text !important;
323
+ .ag-cell:not([col-id=ag-Grid-SelectionColumn]) {
324
+ user-select: text;
325
+ }
326
+
327
+ .rangeSelectingMultiple .ag-cell {
328
+ user-select: none;
325
329
  }
326
330
 
327
331
  .LabelPreferencesPanelGridCellAlignCenter .ag-cell-wrapper, .LabelPreferencesPanelGridCellAlignCenter .GridCell-container {
@@ -463,6 +467,26 @@ div.ag-ltr div.ag-header-cell-resize {
463
467
  font-weight: normal;
464
468
  }
465
469
 
470
+ div.ag-row div.ag-cell.rangeSelect {
471
+ background-color: rgba(72, 160, 244, 0.2);
472
+ }
473
+
474
+ div.ag-row div.ag-cell.rangeSelectLeft {
475
+ border-left: 3px solid #48a0f4;
476
+ }
477
+
478
+ div.ag-row div.ag-cell.rangeSelectRight {
479
+ border-right: 3px solid #48a0f4;
480
+ }
481
+
482
+ div.ag-row div.ag-cell.rangeSelectTop {
483
+ border-top: 3px solid #48a0f4;
484
+ }
485
+
486
+ div.ag-row div.ag-cell.rangeSelectBottom {
487
+ border-bottom: 3px solid #48a0f4;
488
+ }
489
+
466
490
  .GridCell-container {
467
491
  overflow: hidden;
468
492
  text-overflow: ellipsis;
@@ -3,89 +3,64 @@ import { ReactElement } from 'react';
3
3
  import { GridContextMenuComponent } from './gridHook';
4
4
  import { GridBaseRow, GridOnRowDragEndProps } from './types';
5
5
  export interface GridProps<TData extends GridBaseRow = GridBaseRow> {
6
+ ['data-testid']?: string;
7
+ theme?: string;
8
+ loading?: boolean;
6
9
  readOnly?: boolean;
10
+ suppressReadOnlyStyle?: boolean;
11
+ columnDefs: ColDef<TData>[] | ColGroupDef<TData>[];
12
+ defaultColDef?: GridOptions['defaultColDef'];
7
13
  defaultPostSort?: boolean;
8
- selectable?: boolean;
9
- enableClickSelection?: boolean;
10
- enableSelectionWithoutKeys?: boolean;
11
- hideSelectColumn?: boolean;
12
- theme?: string;
13
- ['data-testid']?: string;
14
14
  domLayout?: GridOptions['domLayout'];
15
- externalSelectedItems?: TData[];
16
- externalSelectedIds?: TData['id'][];
17
- setExternalSelectedItems?: (items: TData[]) => void;
18
- setExternalSelectedIds?: (ids: TData['id'][]) => void;
19
- defaultColDef?: GridOptions['defaultColDef'];
20
- columnDefs: ColDef<TData>[] | ColGroupDef<TData>[];
15
+ pinnedBottomRowData?: GridOptions['pinnedBottomRowData'];
16
+ pinnedTopRowData?: GridOptions['pinnedTopRowData'];
21
17
  rowData: GridOptions['rowData'];
22
- selectColumnPinned?: ColDef['pinned'];
23
- noRowsOverlayText?: string;
24
- noRowsMatchingOverlayText?: string;
25
- animateRows?: boolean;
26
- rowHeight?: number;
27
18
  rowClassRules?: GridOptions['rowClassRules'];
19
+ rowHeight?: number;
28
20
  rowSelection?: 'single' | 'multiple';
21
+ sizeColumns?: 'fit' | 'auto' | 'auto-skip-headers' | 'none';
29
22
  autoSelectFirstRow?: boolean;
23
+ enableClickSelection?: boolean;
24
+ enableRangeSelection?: boolean;
25
+ enableSelectionWithoutKeys?: boolean;
26
+ externalSelectedIds?: TData['id'][];
27
+ externalSelectedItems?: TData[];
28
+ hideSelectColumn?: boolean;
29
+ selectColumnPinned?: ColDef['pinned'];
30
+ selectable?: boolean;
31
+ setExternalSelectedIds?: (ids: TData['id'][]) => void;
32
+ setExternalSelectedItems?: (items: TData[]) => void;
33
+ onBulkEditingComplete?: () => Promise<void> | void;
34
+ singleClickEdit?: boolean;
35
+ contextMenu?: GridContextMenuComponent<TData>;
36
+ contextMenuSelectRow?: boolean;
30
37
  onCellFocused?: (props: {
31
38
  colDef: ColDef<TData>;
32
39
  data: TData;
33
40
  }) => void;
34
41
  onColumnMoved?: GridOptions['onColumnMoved'];
35
- rowDragText?: GridOptions['rowDragText'];
36
- onRowDragEnd?: (props: GridOnRowDragEndProps<TData>) => Promise<void> | void;
37
- alwaysShowVerticalScroll?: boolean;
38
- suppressColumnVirtualization?: GridOptions['suppressColumnVirtualisation'];
39
- suppressReadOnlyStyle?: boolean;
40
- /**
41
- * When the grid is rendered using sizeColumns=="auto" this is called initially with the required container size to fit all content.
42
- * This allows you set the size of the panel to fit perfectly.
43
- */
44
42
  onContentSize?: (props: {
45
43
  width: number;
46
44
  }) => void;
47
45
  /**
48
- * <ul>
49
- * <li>"none" to use aggrid defaults.</li>
50
- * <li>"fit" will adjust columns to fit within panel via min/max/initial sizing.
51
- * <b>Note:</b> This is only really needed if you have auto-height columns which prevents "auto" from working.
52
- * </li>
53
- * <li>"auto" will size columns based on their content but still obeying min/max sizing.</li>
54
- * <li>"auto-skip-headers" (default) same as auto but does not take headers into account.</li>
55
- * </ul>
56
- *
57
- * If you want to stretch to container width if width is greater than the container add a flex column.
46
+ * @deprecated You should drive your app off selection states. This will be deleted.
58
47
  */
59
- sizeColumns?: 'fit' | 'auto' | 'auto-skip-headers' | 'none';
48
+ onRowClicked?: (event: RowClickedEvent) => void;
60
49
  /**
61
- * On first don't return a content size larger than this.
50
+ * @deprecated You should drive your app off selection states. This will be deleted.
62
51
  */
52
+ onRowDoubleClicked?: (event: RowDoubleClickedEvent) => void;
53
+ onRowDragEnd?: (props: GridOnRowDragEndProps<TData>) => Promise<void> | void;
54
+ animateRows?: boolean;
55
+ alwaysShowVerticalScroll?: boolean;
56
+ rowDragText?: GridOptions['rowDragText'];
57
+ noRowsOverlayText?: string;
58
+ noRowsMatchingOverlayText?: string;
63
59
  maxInitialWidth?: number;
64
- /**
65
- * When pressing tab whilst editing the grid will select and edit the next cell if available.
66
- * Once the last cell to edit closes this callback is called.
67
- */
68
- onBulkEditingComplete?: () => Promise<void> | void;
69
- /**
70
- * Context menu definition if required.
71
- */
72
- contextMenu?: GridContextMenuComponent<TData>;
73
- /**
74
- * Whether to select row on context menu.
75
- */
76
- contextMenuSelectRow?: boolean;
77
- /**
78
- * Defaults to false.
79
- */
80
- singleClickEdit?: boolean;
81
- loading?: boolean;
82
60
  suppressCellFocus?: boolean;
83
- pinnedTopRowData?: GridOptions['pinnedTopRowData'];
84
- pinnedBottomRowData?: GridOptions['pinnedBottomRowData'];
85
- onRowClicked?: (event: RowClickedEvent) => void;
86
- onRowDoubleClicked?: (event: RowDoubleClickedEvent) => void;
61
+ suppressColumnVirtualization?: GridOptions['suppressColumnVirtualisation'];
87
62
  }
88
63
  /**
89
64
  * Wrapper for AgGrid to add commonly used functionality.
90
65
  */
91
- export declare const Grid: <TData extends GridBaseRow = GridBaseRow>({ "data-testid": dataTestId, defaultPostSort, rowSelection, suppressColumnVirtualization, theme, sizeColumns, selectColumnPinned, contextMenuSelectRow, singleClickEdit, rowData, rowHeight, selectable, autoSelectFirstRow, onCellFocused: paramsOnCellFocused, maxInitialWidth, suppressReadOnlyStyle, externalSelectedItems, setExternalSelectedItems, externalSelectedIds, setExternalSelectedIds, ...params }: GridProps<TData>) => ReactElement;
66
+ export declare const Grid: <TData extends GridBaseRow = GridBaseRow>({ theme, "data-testid": dataTestId, suppressReadOnlyStyle, defaultPostSort, rowData, rowHeight, rowSelection, sizeColumns, autoSelectFirstRow, enableRangeSelection, externalSelectedIds, externalSelectedItems, selectColumnPinned, selectable, setExternalSelectedIds, setExternalSelectedItems, singleClickEdit, contextMenuSelectRow, contextMenu, onCellFocused: paramsOnCellFocused, onColumnMoved, suppressColumnVirtualization, maxInitialWidth, ...params }: GridProps<TData>) => ReactElement;
@@ -0,0 +1,10 @@
1
+ import { ReactElement } from 'react';
2
+ import { GridContextMenuComponentProps } from './gridHook';
3
+ import { CopyOptionsKey } from './gridHook/useGridCopySettings';
4
+ import { GridBaseRow } from './types';
5
+ export interface CopyOptionsContext {
6
+ onCopy: (type?: CopyOptionsKey) => void;
7
+ copyType: CopyOptionsKey;
8
+ setCopyType: (copyType: CopyOptionsKey) => void;
9
+ }
10
+ export declare const GridRangeSelectContextMenu: <TData extends GridBaseRow>({ event, context, }: GridContextMenuComponentProps<TData, CopyOptionsContext>) => ReactElement;
@@ -1,4 +1,5 @@
1
1
  import { ReactElement } from 'react';
2
+ import { MaybePromise } from '../../utils/util';
2
3
  import { CellEditorCommon } from '../GridCell';
3
4
  import { GridBaseRow } from '../types';
4
5
  export interface GridPopoutEditDropDownSelectedItem<TData extends GridBaseRow, TOption> {
@@ -24,7 +25,6 @@ export declare const MenuHeaderItem: (title: string) => {
24
25
  value: string;
25
26
  };
26
27
  export type SelectOption<TOptionValue = any> = FinalSelectOption<TOptionValue>;
27
- export type MaybePromise<T> = T | Promise<T>;
28
28
  export interface GridFormDropDownProps<TData extends GridBaseRow, TOptionValue> extends CellEditorCommon {
29
29
  className?: 'GridPopoverEditDropDown-containerSmall' | 'GridPopoverEditDropDown-containerMedium' | 'GridPopoverEditDropDown-containerLarge' | 'GridPopoverEditDropDown-containerUnlimited' | 'GridPopoverEditDropDown-containerAutoWidth' | string | undefined;
30
30
  filtered?: 'local' | 'reload';
@@ -1,4 +1,5 @@
1
1
  import { ReactElement } from 'react';
2
+ import { MaybePromise } from '../../utils/util';
2
3
  import { CellEditorCommon } from '../GridCell';
3
4
  import { GridBaseRow } from '../types';
4
5
  export interface GridFormPopoverMenuProps<TData extends GridBaseRow> extends CellEditorCommon {
@@ -23,7 +24,7 @@ export interface MenuOption<TData extends GridBaseRow> {
23
24
  action?: (props: {
24
25
  selectedRows: TData[];
25
26
  menuOption: SelectedMenuOptionResult<TData>;
26
- }) => Promise<void>;
27
+ }) => MaybePromise<void>;
27
28
  disabled?: string | boolean;
28
29
  hidden?: boolean;
29
30
  subComponent?: (props: any) => ReactElement;
@@ -1,19 +1,24 @@
1
+ import '../../styles/ContextMenu.scss';
1
2
  import { ColDef } from 'ag-grid-community';
2
3
  import { CellContextMenuEvent } from 'ag-grid-community';
3
4
  import { ReactElement } from 'react';
4
5
  import { GridBaseRow } from '../types';
5
- export interface GridContextMenuComponentProps<TData extends GridBaseRow> {
6
+ export interface GridContextMenuComponentProps<TData extends GridBaseRow, Context extends object = object> {
6
7
  selectedRows: TData[];
7
8
  clickedRow: TData;
8
9
  colDef: ColDef;
9
10
  close: () => void;
11
+ event?: CellContextMenuEvent;
12
+ context?: Context;
10
13
  }
11
- export type GridContextMenuComponent<TData extends GridBaseRow> = (props: GridContextMenuComponentProps<TData>) => ReactElement | null;
12
- export declare const useGridContextMenu: <TData extends GridBaseRow>({ contextMenuSelectRow, contextMenu: ContextMenu, }: {
13
- contextMenuSelectRow: boolean;
14
- contextMenu?: GridContextMenuComponent<TData>;
15
- }) => {
14
+ export type GridContextMenuComponent<TData extends GridBaseRow, Context extends object = object> = (props: GridContextMenuComponentProps<TData, Context>) => ReactElement | null;
15
+ export interface useGridContextMenuProps<TData extends GridBaseRow, Context extends object = object> {
16
+ contextMenuSelectRow?: boolean;
17
+ contextMenu?: GridContextMenuComponent<TData, Context>;
18
+ context?: Context;
19
+ }
20
+ export declare const useGridContextMenu: <TData extends GridBaseRow, Context extends object = object>({ contextMenuSelectRow, contextMenu: ContextMenu, context, }: useGridContextMenuProps<TData, Context>) => {
16
21
  openMenu: (e: PointerEvent | null | undefined) => void;
17
22
  cellContextMenu: (event: CellContextMenuEvent) => void;
18
- component: import("react/jsx-runtime").JSX.Element | null;
23
+ contextMenuComponent: import("react/jsx-runtime").JSX.Element | null;
19
24
  };
@@ -0,0 +1,15 @@
1
+ import { CellContextMenuEvent } from 'ag-grid-community';
2
+ import { ClipboardEvent as ReactClipboardEvent, MutableRefObject } from 'react';
3
+ import { GridBaseRow } from '../types';
4
+ import { CellLocation, GridRanges } from './useGridRangeSelection';
5
+ export declare const useGridCopy: <TData extends GridBaseRow>({ ranges, rangeStartRef, rangeEndRef, hasSelectedMoreThanOneCellRef, cellContextMenu, }: {
6
+ ranges: () => GridRanges<TData>;
7
+ rangeStartRef: MutableRefObject<CellLocation | null>;
8
+ rangeEndRef: MutableRefObject<CellLocation | null>;
9
+ hasSelectedMoreThanOneCellRef: MutableRefObject<boolean>;
10
+ cellContextMenu: (event: CellContextMenuEvent) => void;
11
+ }) => {
12
+ onCopyEvent: (e: ReactClipboardEvent<HTMLDivElement>) => void;
13
+ rangeSelectInterceptContextMenu: (event: CellContextMenuEvent<TData>) => void;
14
+ rangeSelectContextMenuComponent: import("react/jsx-runtime").JSX.Element | null;
15
+ };
@@ -0,0 +1,11 @@
1
+ import { IconName } from '@linzjs/lui/dist/components/LuiIcon/LuiIcon';
2
+ export declare const gridCopyOptions: Record<string, {
3
+ text: string;
4
+ icon: IconName;
5
+ developer?: boolean;
6
+ }>;
7
+ export type CopyOptionsKey = keyof typeof gridCopyOptions;
8
+ export declare const useGridCopySettings: () => {
9
+ copyType: string;
10
+ setCopyType: (key: CopyOptionsKey) => void;
11
+ };
@@ -0,0 +1,25 @@
1
+ import { CellMouseDownEvent, CellMouseOverEvent, IRowNode } from 'ag-grid-community';
2
+ import { MutableRefObject, RefObject } from 'react';
3
+ import { GridBaseRow } from '../types';
4
+ export interface CellLocation {
5
+ rowId: string;
6
+ colId: string;
7
+ timestamp: number;
8
+ }
9
+ export interface GridRanges<TData extends GridBaseRow> {
10
+ selectedColIds: string[];
11
+ selectedNodes: IRowNode<TData>[];
12
+ }
13
+ export declare const useGridRangeSelection: <TData extends GridBaseRow>({ enableRangeSelection, gridDivRef, rangeStartRef, rangeEndRef, hasSelectedMoreThanOneCellRef, rangeSortedNodesRef, }: {
14
+ enableRangeSelection: boolean;
15
+ gridDivRef: RefObject<HTMLDivElement>;
16
+ rangeStartRef: MutableRefObject<CellLocation | null>;
17
+ rangeEndRef: MutableRefObject<CellLocation | null>;
18
+ hasSelectedMoreThanOneCellRef: MutableRefObject<boolean>;
19
+ rangeSortedNodesRef: MutableRefObject<IRowNode<TData>[] | null>;
20
+ }) => {
21
+ clearRangeSelection: () => void;
22
+ ranges: () => GridRanges<TData>;
23
+ onCellMouseDown: (e: CellMouseDownEvent) => void;
24
+ onCellMouseOver: (e: CellMouseOverEvent, mouseDown?: boolean) => void;
25
+ };
@@ -1,7 +1,9 @@
1
+ import { ValueFormatterParams } from 'ag-grid-community';
1
2
  import { GenericCellEditorProps } from '../GridCell';
2
3
  import { GridFormEditBearingProps } from '../gridForm/GridFormEditBearing';
3
4
  import { GenericCellColDef } from '../gridRender/GridRenderGenericCell';
4
5
  import { ColDefT, GridBaseRow } from '../types';
6
+ export declare const GridCellBearingValueFormatter: (params: ValueFormatterParams) => string;
5
7
  export declare const GridPopoverEditBearingEditorParams: {
6
8
  placeHolder: string;
7
9
  formatValue: (value: any) => string;
@@ -1,5 +1,6 @@
1
1
  import { ColDef, EditableCallback, ICellRendererParams, ValueFormatterFunc, ValueGetterFunc } from 'ag-grid-community';
2
2
  import { ReactElement } from 'react';
3
+ export declare const agGridSelectRowColId = "ag-Grid-SelectionColumn";
3
4
  export interface GridBaseRow {
4
5
  id: string | number;
5
6
  }
@@ -60,6 +60,7 @@ export interface GridContextType<TData extends GridBaseRow> {
60
60
  onBulkEditingComplete: () => Promise<void> | void;
61
61
  setOnBulkEditingComplete: (callback: (() => Promise<void> | void) | undefined) => void;
62
62
  showNoRowsOverlay: () => void;
63
+ getCellValue: GridApi['getCellValue'];
63
64
  }
64
65
  export declare const GridContext: import("react").Context<GridContextType<any>>;
65
66
  export declare const useGridContext: <TData extends GridBaseRow>() => GridContextType<TData>;
@@ -6,9 +6,3 @@
6
6
  * but there's no way to enforce that, so it would lead to bugs.
7
7
  */
8
8
  export declare const useTimeoutHook: () => (fn: () => void, waitTimeMs: number) => void;
9
- interface IntervalHookProps {
10
- timeoutMs: number;
11
- callback: () => void;
12
- }
13
- export declare const useIntervalHook: ({ callback, timeoutMs }: IntervalHookProps) => void;
14
- export {};
@@ -0,0 +1,5 @@
1
+ export type KeysOfType<TObject, TValue> = {
2
+ [K in keyof TObject]: TObject[K] extends TValue ? K : never;
3
+ }[keyof TObject];
4
+ export declare const typedKeys: <T extends object>(obj: T) => (keyof T)[];
5
+ export declare const typedEntries: <T extends object>(obj: T) => { [K in keyof T]-?: [K, T[K]]; }[keyof T][];
@@ -0,0 +1,19 @@
1
+ export class SeededRandomForTests {
2
+ value: number;
3
+ constructor(seed: number) {
4
+ this.value = seed % 2147483647;
5
+ }
6
+
7
+ next(maxInc?: number) {
8
+ this.value = (this.value * 16807) % 2147483647;
9
+ const result = (this.value - 1) / 2147483646;
10
+ if (maxInc == null) {
11
+ return result;
12
+ }
13
+ return ((result * (maxInc + 1)) | 0) % (maxInc + 1);
14
+ }
15
+
16
+ fromArray<T>(arr: T[]): T {
17
+ return arr[this.next(arr.length - 1)];
18
+ }
19
+ }
@@ -1,3 +1,4 @@
1
+ export type MaybePromise<T> = T | Promise<T>;
1
2
  export declare const isNotEmpty: (value?: any) => boolean;
2
3
  export declare const wait: (timeoutMs: number) => Promise<(string | null)[]>;
3
4
  export declare const isFloat: (value: string) => boolean;