@linzjs/step-ag-grid 29.2.0 → 29.2.1

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": "29.2.0",
5
+ "version": "29.2.1",
6
6
  "keywords": [
7
7
  "aggrid",
8
8
  "ag-grid",
@@ -83,6 +83,7 @@
83
83
  "@chromatic-com/storybook": "^4.1.1",
84
84
  "@linzjs/lui": "^23.11.1",
85
85
  "@linzjs/style": "^5.4.0",
86
+ "@linzjs/windows": "^5.5.1",
86
87
  "@rollup/plugin-commonjs": "^28.0.6",
87
88
  "@rollup/plugin-json": "^6.1.0",
88
89
  "@rollup/plugin-node-resolve": "^16.0.1",
@@ -14,6 +14,8 @@ import {
14
14
  GetRowIdParams,
15
15
  GridOptions,
16
16
  GridReadyEvent,
17
+ GridSizeChangedEvent,
18
+ IColumnLimit,
17
19
  ModelUpdatedEvent,
18
20
  ModuleRegistry,
19
21
  RowClickedEvent,
@@ -124,6 +126,7 @@ export interface GridProps<TData extends GridBaseRow = GridBaseRow> {
124
126
  pinnedBottomRowData?: GridOptions['pinnedBottomRowData'];
125
127
  onRowClicked?: (event: RowClickedEvent) => void;
126
128
  onRowDoubleClicked?: (event: RowDoubleClickedEvent) => void;
129
+ allowResizeInStorybook?: boolean;
127
130
  }
128
131
 
129
132
  /**
@@ -142,6 +145,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
142
145
  rowData,
143
146
  rowHeight = theme === 'ag-theme-step-default' ? 40 : theme === 'ag-theme-step-compact' ? 36 : 40,
144
147
  selectable,
148
+ allowResizeInStorybook,
145
149
  onCellFocused: paramsOnCellFocused,
146
150
  ...params
147
151
  }: GridProps<TData>): ReactElement => {
@@ -204,7 +208,11 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
204
208
 
205
209
  const skipHeader = sizeColumns === 'auto-skip-headers' && gridRendered === 'rows-visible';
206
210
  if (sizeColumns === 'auto' || skipHeader) {
207
- const result = autoSizeColumns({ skipHeader, userSizedColIds: userSizedColIds.current, includeFlex: true });
211
+ const result = autoSizeColumns({
212
+ skipHeader,
213
+ userSizedColIds: new Set(userSizedColIds.current.keys()),
214
+ includeFlex: true,
215
+ });
208
216
  if (!result) {
209
217
  needsAutoSize.current = true;
210
218
  return;
@@ -425,7 +433,11 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
425
433
 
426
434
  const skipHeader = sizeColumns === 'auto-skip-headers';
427
435
  if (hasSetContentSize.current) {
428
- autoSizeColumns({ skipHeader, userSizedColIds: userSizedColIds.current, colIds: colIdsEdited.current });
436
+ autoSizeColumns({
437
+ skipHeader,
438
+ userSizedColIds: new Set(userSizedColIds.current.keys()),
439
+ colIds: colIdsEdited.current,
440
+ });
429
441
  }
430
442
  colIdsEdited.current.clear();
431
443
  }, [autoSizeColumns, rowData?.length, setInitialContentSize, sizeColumns, updatedDep, updatingCols]);
@@ -543,7 +555,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
543
555
  if (hasSetContentSize.current) {
544
556
  autoSizeColumns({
545
557
  skipHeader,
546
- userSizedColIds: userSizedColIds.current,
558
+ userSizedColIds: new Set(userSizedColIds.current.keys()),
547
559
  colIds: colIdsEdited.current,
548
560
  });
549
561
  }
@@ -573,26 +585,43 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
573
585
  /**
574
586
  * Resize columns to fit if required on window/container resize
575
587
  */
576
- const onGridSizeChanged = useCallback(() => {
577
- if (sizeColumns !== 'none') {
578
- sizeColumnsToFit();
579
- }
580
- }, [sizeColumns, sizeColumnsToFit]);
588
+ const onGridSizeChanged = useCallback(
589
+ (event: GridSizeChangedEvent<TData>) => {
590
+ if (sizeColumns !== 'none' && (!(window as any).__STORYBOOK_PREVIEW__ || allowResizeInStorybook)) {
591
+ const columnLimits = [
592
+ ...userSizedColIds.current.entries().map(
593
+ ([c, w]): IColumnLimit => ({
594
+ key: c,
595
+ minWidth: w,
596
+ }),
597
+ ),
598
+ ];
599
+ event.api.sizeColumnsToFit({ columnLimits });
600
+ }
601
+ },
602
+ [allowResizeInStorybook, sizeColumns],
603
+ );
581
604
 
582
605
  /**
583
606
  * Set of column I'd's that are prevented from auto-sizing as they are user set
584
607
  */
585
- const userSizedColIds = useRef(new Set<string>());
608
+ const userSizedColIds = useRef(new Map<string, number>());
586
609
 
587
610
  /**
588
611
  * Lock/unlock column width on user edit/reset.
589
612
  */
590
613
  const onColumnResized = useCallback((e: ColumnResizedEvent) => {
591
614
  const colId = e.column?.getColId();
592
- if (colId == null) return;
615
+ if (colId == null) {
616
+ return;
617
+ }
618
+ const width = e.column?.getActualWidth();
619
+ if (width == null) {
620
+ return;
621
+ }
593
622
  switch (e.source) {
594
- case 'uiColumnDragged':
595
- userSizedColIds.current.add(colId);
623
+ case 'uiColumnResized':
624
+ userSizedColIds.current.set(colId, width);
596
625
  break;
597
626
  case 'autosizeColumns':
598
627
  userSizedColIds.current.delete(colId);
@@ -660,7 +689,7 @@ export const Grid = <TData extends GridBaseRow = GridBaseRow>({
660
689
  // Prevent repeated callbacks to cell focus when focus didn't change
661
690
  const { sourceEvent } = event;
662
691
  if (sourceEvent) {
663
- const cell = (sourceEvent.target as unknown as Element).closest('.ag-cell');
692
+ const cell = (sourceEvent.target as Element | undefined)?.closest?.('.ag-cell') ?? null;
664
693
  if ((window as any).__stepaggrid_lastfocuseventtarget === cell) {
665
694
  return;
666
695
  }
@@ -424,7 +424,9 @@ export const GridContextProvider = <TData extends GridBaseRow>(props: PropsWithC
424
424
  */
425
425
  const autoSizeColumns = useCallback(
426
426
  ({ skipHeader, colIds, userSizedColIds, includeFlex }: AutoSizeColumnsProps = {}): AutoSizeColumnsResult => {
427
- if (!gridApi || !gridApi.getColumnState()) return null;
427
+ if (!gridApi || !gridApi.getColumnState()) {
428
+ return null;
429
+ }
428
430
  const colIdsSet = colIds instanceof Set ? colIds : new Set(colIds);
429
431
  const colsToResize = gridApi.getColumnState()?.filter?.((colState) => {
430
432
  const colId = colState.colId;
@@ -0,0 +1,28 @@
1
+ import { PanelsContextProvider } from '@linzjs/windows';
2
+ import type { Meta, StoryObj } from '@storybook/react-vite';
3
+
4
+ import { TestShowPanelResizingAgGrid } from './ShowPanelResizingStepAgGrid';
5
+
6
+ const meta: Meta<typeof TestShowPanelResizingAgGrid> = {
7
+ title: 'Components/Panel',
8
+ component: TestShowPanelResizingAgGrid,
9
+ argTypes: {
10
+ backgroundColor: { control: 'color' },
11
+ },
12
+ decorators: [
13
+ (Story) => (
14
+ <div>
15
+ <PanelsContextProvider baseZIndex={500}>
16
+ <Story />
17
+ </PanelsContextProvider>
18
+ </div>
19
+ ),
20
+ ],
21
+ };
22
+
23
+ export default meta;
24
+ type Story = StoryObj<typeof meta>;
25
+
26
+ export const PanelResizing: Story = {
27
+ args: {},
28
+ };
@@ -0,0 +1,169 @@
1
+ // import '../story.scss';
2
+ import '@linzjs/lui/dist/scss/base.scss';
3
+ import '../../../../styles/Grid.scss';
4
+
5
+ import {
6
+ OpenPanelButton,
7
+ Panel,
8
+ PanelContent,
9
+ PanelContext,
10
+ PanelHeader,
11
+ PanelsContextProvider,
12
+ } from '@linzjs/windows';
13
+ import { useContext, useMemo, useState } from 'react';
14
+
15
+ import {
16
+ ColDefT,
17
+ Grid,
18
+ GridCell,
19
+ GridContextProvider,
20
+ GridIcon,
21
+ GridPopoverMenu,
22
+ GridPopoverMessage,
23
+ GridUpdatingContextProvider,
24
+ GridWrapper,
25
+ } from '../../../../../src';
26
+
27
+ // #Example: Panel Context Provider
28
+ // Don't forget to add a PanelContextProvider at the root of your project
29
+ export const App = () => (
30
+ <PanelsContextProvider baseZIndex={500}>
31
+ <div>...the rest of your app...</div>
32
+ </PanelsContextProvider>
33
+ );
34
+
35
+ // #Example: Panel Component
36
+ export interface TestPanelProps {
37
+ data: number;
38
+ }
39
+
40
+ export const TestPanelResizing = ({ data }: TestPanelProps) => {
41
+ return (
42
+ <Panel title={`Panel resizing demo ${data}`} size={{ width: 320, height: 400 }} className={'WindowPanel-blue'}>
43
+ <PanelHeader />
44
+ <PanelContent>
45
+ <PanelContentsWithResize />
46
+ </PanelContent>
47
+ </Panel>
48
+ );
49
+ };
50
+
51
+ // #Example: Panel Invocation
52
+ export const TestShowPanelResizingAgGrid = () => (
53
+ <>
54
+ <OpenPanelButton buttonText={'TestPanel resizing 1'} componentFn={() => <TestPanelResizing data={1} />} />{' '}
55
+ <OpenPanelButton buttonText={'TestPanel resizing 2'} componentFn={() => <TestPanelResizing data={2} />} />
56
+ </>
57
+ );
58
+
59
+ /* exclude */
60
+ interface ITestRow {
61
+ id: number;
62
+ position: string;
63
+ age: number;
64
+ desc: string;
65
+ dd: string;
66
+ }
67
+
68
+ /* exclude */
69
+
70
+ // #Example: Resizing panel to content after load
71
+ // Note: Resize can only be used from within the panel content.
72
+ export const PanelContentsWithResize = () => {
73
+ // This is the first important bit
74
+ const { resizePanel } = useContext(PanelContext);
75
+
76
+ const columnDefs: ColDefT<ITestRow>[] = useMemo(
77
+ () => [
78
+ /* Your grid ColDefs */
79
+ /* exclude */
80
+ GridCell({
81
+ field: 'id',
82
+ headerName: 'Id',
83
+ lockVisible: true,
84
+ }),
85
+ GridCell({
86
+ field: 'position',
87
+ headerName: 'Position',
88
+ cellRendererParams: {
89
+ warning: (props) => props.value === 'Tester' && 'Testers are testing',
90
+ info: (props) => props.value === 'Developer' && 'Developers are awesome',
91
+ },
92
+ }),
93
+ GridCell({
94
+ field: 'age',
95
+ headerName: 'Age',
96
+ }),
97
+ GridCell({
98
+ field: 'desc',
99
+ headerName: 'Description',
100
+ flex: 1,
101
+ }),
102
+ GridPopoverMessage(
103
+ {
104
+ headerName: 'Popout message',
105
+ cellRenderer: () => <>Single Click me!</>,
106
+ exportable: false,
107
+ },
108
+ {
109
+ multiEdit: true,
110
+ editorParams: {
111
+ // eslint-disable-next-line @typescript-eslint/require-await
112
+ message: async (selectedRows): Promise<string> => {
113
+ return `There are ${selectedRows.length} row(s) selected`;
114
+ },
115
+ },
116
+ },
117
+ ),
118
+ GridCell({
119
+ headerName: 'Custom edit',
120
+ editable: true,
121
+ valueFormatter: () => 'Press E',
122
+ cellRendererParams: {
123
+ rightHoverElement: (
124
+ <GridIcon icon={'ic_launch_modal'} title={'Title text'} className={'GridCell-editableIcon'} />
125
+ ),
126
+ editAction: (selectedRows) => {
127
+ alert(`Custom edit ${selectedRows.map((r) => r.id).join()} rowId(s) selected`);
128
+ },
129
+ shortcutKeys: {
130
+ e: () => {
131
+ alert('Hi');
132
+ },
133
+ },
134
+ },
135
+ }),
136
+ GridPopoverMenu(
137
+ {},
138
+ {
139
+ multiEdit: true,
140
+ editorParams: {
141
+ // eslint-disable-next-line @typescript-eslint/require-await
142
+ options: async () => [],
143
+ },
144
+ },
145
+ ),
146
+ /* exclude */
147
+ ],
148
+ [],
149
+ );
150
+
151
+ const [rowData] = useState([
152
+ /* Your grid row data */
153
+ /* exclude */
154
+ { id: 1000, position: 'Tester', age: 30, desc: 'Tests application', dd: '1' },
155
+ { id: 1001, position: 'Developer', age: 12, desc: 'Develops application', dd: '2' },
156
+ { id: 1002, position: 'Manager', age: 65, desc: 'Manages', dd: '3' },
157
+ /* exclude */
158
+ ]);
159
+
160
+ return (
161
+ <GridUpdatingContextProvider>
162
+ <GridContextProvider>
163
+ <GridWrapper>
164
+ <Grid columnDefs={columnDefs} rowData={rowData} onContentSize={resizePanel} allowResizeInStorybook={true} />
165
+ </GridWrapper>
166
+ </GridContextProvider>
167
+ </GridUpdatingContextProvider>
168
+ );
169
+ };