@redsift/ds-mcp-server 12.5.0-muiv6 → 12.5.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 (38) hide show
  1. package/data/demos/patterns/_shared/StateDebugPanel.tsx +2 -2
  2. package/data/demos/patterns/_shared/columns.tsx +12 -3
  3. package/data/demos/patterns/_shared/defaults.ts +1 -1
  4. package/data/demos/patterns/_shared/filter-helpers.ts +1 -1
  5. package/data/demos/patterns/_shared/helpers.tsx +1 -1
  6. package/data/demos/patterns/_shared/server-logic.ts +1 -1
  7. package/data/demos/patterns/_shared/story-helpers.ts +54 -23
  8. package/data/demos/patterns/crossfiltered-datagrid-server-side/example.tsx +10 -10
  9. package/data/demos/patterns/drilldowned-datagrid-client-side/example.tsx +1 -1
  10. package/data/demos/patterns/drilldowned-datagrid-server-side/example.tsx +1 -1
  11. package/data/demos/patterns/single-datagrid-client-side/SingleDatagridClientSide.interaction.stories.tsx +1 -1
  12. package/data/demos/patterns/single-datagrid-client-side/example.tsx +4 -4
  13. package/data/demos/patterns/single-datagrid-server-side/SingleDatagridServerSide.interaction.stories.tsx +1 -1
  14. package/data/demos/patterns/single-datagrid-server-side/example.tsx +4 -4
  15. package/data/demos/patterns/stateful-single-datagrid-client-side/StatefulSingleDatagridClientSide.interaction.stories.tsx +1 -1
  16. package/data/demos/patterns/stateful-single-datagrid-client-side/example.tsx +4 -4
  17. package/data/demos/patterns/stateful-single-datagrid-server-side/StatefulSingleDatagridServerSide.interaction.stories.tsx +1 -1
  18. package/data/demos/patterns/stateful-single-datagrid-server-side/example.tsx +4 -4
  19. package/data/demos/patterns/tabbed-datagrid-server-side/example.tsx +1 -1
  20. package/data/docs/components/dashboard/Dashboard.json +2 -2
  21. package/data/docs/components/table/DataGrid.json +7 -7
  22. package/data/docs/components/table/GridToolbarFilterSemanticField.json +1 -1
  23. package/data/docs/components/table/StatefulDataGrid.json +7 -7
  24. package/data/docs/components/table/Toolbar.json +8 -2
  25. package/data/docs/components.json +27 -21
  26. package/data/docs/llms-full.txt +44 -44
  27. package/data/docs/llms.txt +4 -4
  28. package/data/docs/patterns-catalog.md +24 -25
  29. package/data/docs/patterns.json +4 -4
  30. package/data/metadata.json +2 -2
  31. package/data/patterns/crossfiltered-datagrid-server-side.mdx +1 -1
  32. package/data/patterns/drilldowned-datagrid-client-side.mdx +1 -1
  33. package/data/patterns/drilldowned-datagrid-server-side.mdx +1 -1
  34. package/data/patterns/single-datagrid-client-side.mdx +7 -7
  35. package/data/patterns/single-datagrid-server-side.mdx +4 -4
  36. package/data/patterns/stateful-single-datagrid-client-side.mdx +1 -1
  37. package/data/patterns/tabbed-datagrid-server-side.mdx +1 -1
  38. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  import React, { useCallback, useEffect, useState } from 'react';
2
- import type { GridApiPro } from '@mui/x-data-grid-pro/models/gridApiPro';
2
+ import type { GridApiPremium } from '@mui/x-data-grid-premium';
3
3
 
4
4
  // localStorage key categories — must match @redsift/table internals
5
5
  const LS_CATEGORIES = [
@@ -13,7 +13,7 @@ const LS_CATEGORIES = [
13
13
  ];
14
14
 
15
15
  interface StateDebugPanelProps {
16
- apiRef: React.MutableRefObject<GridApiPro>;
16
+ apiRef: React.MutableRefObject<GridApiPremium | null>;
17
17
  useRouter: () => { pathname: string; search: string; historyReplace: (newSearch: string) => void };
18
18
  localStorageVersion?: number;
19
19
  }
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { createColumn, TextCell } from '@redsift/table';
3
3
  import { Flexbox, Icon, IconButtonLink, Pill } from '@redsift/design-system';
4
4
  import { mdiArrowRight, mdiCheck, mdiClose } from '@redsift/icons';
5
- import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid-pro';
5
+ import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid-premium';
6
6
  import { Row } from './data';
7
7
 
8
8
  // -- Option constants -------------------------------------------------------
@@ -80,6 +80,7 @@ export const columns: GridColDef<Row>[] = [
80
80
  field: 'Items',
81
81
  headerName: 'Item',
82
82
  flex: 1,
83
+ display: 'flex',
83
84
  ...createColumn('string'),
84
85
  renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value}</TextCell>,
85
86
  },
@@ -88,6 +89,7 @@ export const columns: GridColDef<Row>[] = [
88
89
  field: 'Category',
89
90
  headerName: 'Category',
90
91
  width: 120,
92
+ display: 'flex',
91
93
  ...createColumn('singleSelect'),
92
94
  valueOptions: CATEGORY_OPTIONS,
93
95
  renderCell: ({ value }: GridRenderCellParams) => <Pill color={categoryColor(value)}>{value}</Pill>,
@@ -97,6 +99,7 @@ export const columns: GridColDef<Row>[] = [
97
99
  field: 'Paid',
98
100
  headerName: 'Price',
99
101
  width: 100,
102
+ display: 'flex',
100
103
  ...createColumn('number'),
101
104
  renderCell: ({ value }: GridRenderCellParams) => <TextCell>{formatCurrency(value as number)}</TextCell>,
102
105
  },
@@ -105,8 +108,9 @@ export const columns: GridColDef<Row>[] = [
105
108
  field: 'Date',
106
109
  headerName: 'Date',
107
110
  width: 140,
111
+ display: 'flex',
108
112
  ...createColumn('date'),
109
- valueGetter: (params: any) => parseDate(params.value),
113
+ valueGetter: (value: string) => parseDate(value),
110
114
  renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value ? formatDate(value as Date) : '—'}</TextCell>,
111
115
  },
112
116
  // DateTime
@@ -114,8 +118,9 @@ export const columns: GridColDef<Row>[] = [
114
118
  field: 'DateTime',
115
119
  headerName: 'Date & Time',
116
120
  width: 180,
121
+ display: 'flex',
117
122
  ...createColumn('dateTime'),
118
- valueGetter: (params: any) => parseDate(params.value),
123
+ valueGetter: (value: string) => parseDate(value),
119
124
  renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value ? formatDateTime(value as Date) : '—'}</TextCell>,
120
125
  },
121
126
  // Boolean — in stock
@@ -123,6 +128,7 @@ export const columns: GridColDef<Row>[] = [
123
128
  field: 'InStock',
124
129
  headerName: 'In Stock',
125
130
  width: 90,
131
+ display: 'flex',
126
132
  type: 'boolean',
127
133
  renderCell: ({ value }: GridRenderCellParams) =>
128
134
  value ? (
@@ -136,6 +142,7 @@ export const columns: GridColDef<Row>[] = [
136
142
  field: 'Allergens',
137
143
  headerName: 'Allergens',
138
144
  flex: 1,
145
+ display: 'flex',
139
146
  ...createColumn('multiSelect'),
140
147
  valueOptions: ALLERGEN_OPTIONS,
141
148
  sortable: false,
@@ -158,6 +165,7 @@ export const columns: GridColDef<Row>[] = [
158
165
  field: 'Tags',
159
166
  headerName: 'Tags',
160
167
  flex: 1,
168
+ display: 'flex',
161
169
  ...createColumn('tags'),
162
170
  valueOptions: TAG_OPTIONS,
163
171
  sortable: false,
@@ -180,6 +188,7 @@ export const columns: GridColDef<Row>[] = [
180
188
  field: 'actions',
181
189
  headerName: '',
182
190
  width: 56,
191
+ display: 'flex',
183
192
  hideable: false,
184
193
  sortable: false,
185
194
  filterable: false,
@@ -1,4 +1,4 @@
1
- import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-pro';
1
+ import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
2
2
 
3
3
  /**
4
4
  * Default filter model applied to all pattern examples.
@@ -1,4 +1,4 @@
1
- import { GridFilterModel } from '@mui/x-data-grid-pro';
1
+ import { GridFilterModel } from '@mui/x-data-grid-premium';
2
2
  import { Row } from './data';
3
3
 
4
4
  // -- Types ------------------------------------------------------------------
@@ -8,7 +8,7 @@ import {
8
8
  GridToolbarExport,
9
9
  GridToolbarFilterButton,
10
10
  GridToolbarQuickFilter,
11
- } from '@mui/x-data-grid-pro';
11
+ } from '@mui/x-data-grid-premium';
12
12
 
13
13
  // -- Toolbar ----------------------------------------------------------------
14
14
 
@@ -1,4 +1,4 @@
1
- import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-pro';
1
+ import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
2
2
  import { Row, allRows } from './data';
3
3
  import { Aggregates, computeAggregates, applyFilters } from './filter-helpers';
4
4
 
@@ -320,25 +320,34 @@ export const clickHeaderCheckbox = async (canvasElement: HTMLElement) => {
320
320
  const headerCheckbox = canvasElement.querySelector('.MuiDataGrid-columnHeaderCheckbox input[type="checkbox"]');
321
321
  expect(headerCheckbox).toBeTruthy();
322
322
  },
323
- { timeout: 3000 }
323
+ { timeout: 5000 }
324
324
  );
325
325
  // Small yield to let React finish any pending microtask re-renders
326
326
  await new Promise((resolve) => setTimeout(resolve, 200));
327
327
  const headerCheckbox = canvasElement.querySelector('.MuiDataGrid-columnHeaderCheckbox input[type="checkbox"]')!;
328
- fireEvent.click(headerCheckbox);
328
+ // Use userEvent.click for reliable event dispatching — fireEvent.click on a hidden
329
+ // checkbox input doesn't trigger the native change event in Playwright/Chromium,
330
+ // causing server-side pagination grids to miss the selection update.
331
+ await userEvent.click(headerCheckbox);
329
332
  // Wait for React and MUI DataGrid to process the selection change
330
333
  await new Promise((resolve) => setTimeout(resolve, 200));
331
334
  };
332
335
 
333
336
  /** Click a row checkbox by row index (0-based, within the visible page). */
334
337
  export const clickRowCheckbox = async (canvasElement: HTMLElement, rowIndex: number) => {
335
- await waitFor(() => {
336
- const rows = canvasElement.querySelectorAll('.MuiDataGrid-row');
337
- expect(rows.length).toBeGreaterThan(rowIndex);
338
- });
338
+ // Wait for BOTH the row AND its checkbox to be present.
339
+ // Server-side grids may render rows before checkboxes are mounted.
340
+ await waitFor(
341
+ () => {
342
+ const rows = canvasElement.querySelectorAll('.MuiDataGrid-row');
343
+ expect(rows.length).toBeGreaterThan(rowIndex);
344
+ const cb = rows[rowIndex].querySelector('input[type="checkbox"]');
345
+ expect(cb).toBeTruthy();
346
+ },
347
+ { timeout: 5000 }
348
+ );
339
349
  const rows = canvasElement.querySelectorAll('.MuiDataGrid-row');
340
- const checkbox = rows[rowIndex].querySelector('input[type="checkbox"]');
341
- if (!checkbox) throw new Error(`Could not find checkbox in row ${rowIndex}`);
350
+ const checkbox = rows[rowIndex].querySelector('input[type="checkbox"]')!;
342
351
  await userEvent.click(checkbox);
343
352
  // Wait for React and MUI DataGrid to process the selection change
344
353
  await new Promise((resolve) => setTimeout(resolve, 200));
@@ -907,18 +916,39 @@ export const waitForPaginationEnabled = async (canvasElement: HTMLElement, direc
907
916
 
908
917
  /**
909
918
  * Change the page size via the MUI pagination "Rows per page" select.
910
- * The dropdown menu renders as a portal on document.body.
919
+ * MUI Material v7's `useSlot()` applies `.MuiTablePagination-select` to the
920
+ * Select wrapper, NOT the inner display div that has the `onMouseDown` handler.
921
+ * We target `[role="combobox"]` inside the pagination toolbar instead, which is
922
+ * the actual interactive element rendered by `SelectInput`.
923
+ * `userEvent.click` in the Storybook Playwright runner doesn't reliably
924
+ * trigger mouseDown on MUI Select, so we use `fireEvent.mouseDown` directly,
925
+ * then `userEvent.click` to select the option in the dropdown.
911
926
  */
912
927
  export const changePageSize = async (canvasElement: HTMLElement, newSize: number) => {
913
- const select = canvasElement.querySelector('.MuiTablePagination-select') as HTMLElement | null;
914
- if (!select) throw new Error('Could not find page size select');
915
- await userEvent.click(select);
916
- // The menu renders as a MUI Popper on document.body
917
- await waitFor(() => {
918
- const options = document.querySelectorAll('li[role="option"]');
919
- expect(options.length).toBeGreaterThan(0);
920
- });
921
- const options = document.querySelectorAll('li[role="option"]');
928
+ // Wait for the pagination combobox to be present
929
+ await waitFor(
930
+ () => {
931
+ const el = canvasElement.querySelector('.MuiTablePagination-toolbar [role="combobox"]');
932
+ expect(el).toBeTruthy();
933
+ },
934
+ { timeout: 5000 }
935
+ );
936
+
937
+ const select = canvasElement.querySelector('.MuiTablePagination-toolbar [role="combobox"]') as HTMLElement;
938
+
939
+ // Use fireEvent.mouseDown to reliably open MUI v7 Select dropdown
940
+ fireEvent.mouseDown(select);
941
+
942
+ // Wait for the dropdown to render (MUI uses a portal on document.body)
943
+ await waitFor(
944
+ () => {
945
+ const options = document.querySelectorAll('[role="option"]');
946
+ expect(options.length).toBeGreaterThan(0);
947
+ },
948
+ { timeout: 5000 }
949
+ );
950
+
951
+ const options = document.querySelectorAll('[role="option"]');
922
952
  const target = Array.from(options).find((opt) => opt.textContent === String(newSize));
923
953
  if (!target) throw new Error(`Could not find page size option "${newSize}"`);
924
954
  await userEvent.click(target);
@@ -937,17 +967,18 @@ export const openColumnsPanel = async (canvasElement: HTMLElement) => {
937
967
  await userEvent.click(btn);
938
968
  // Wait for the panel to appear on document.body
939
969
  await waitFor(() => {
940
- const panel = document.querySelector('.MuiDataGrid-columnsPanel');
970
+ const panel = document.querySelector('.MuiDataGrid-columnsManagement');
941
971
  expect(panel).toBeTruthy();
942
972
  });
943
973
  };
944
974
 
945
975
  /** Toggle a column's visibility in the columns panel by its label text. */
946
976
  export const toggleColumnInPanel = async (fieldLabel: string) => {
947
- const panel = document.querySelector('.MuiDataGrid-columnsPanel');
977
+ const panel = document.querySelector('.MuiDataGrid-columnsManagement');
948
978
  if (!panel) throw new Error('Columns panel is not open');
949
- const labels = Array.from(panel.querySelectorAll('.MuiFormControlLabel-root'));
950
- const target = labels.find((label) => label.textContent?.includes(fieldLabel));
979
+ // MUI v8 renders each column toggle as a baseCheckbox slot with class columnsManagementRow
980
+ const rows = Array.from(panel.querySelectorAll('.MuiDataGrid-columnsManagementRow'));
981
+ const target = rows.find((row) => row.textContent?.includes(fieldLabel));
951
982
  if (!target) throw new Error(`Could not find column "${fieldLabel}" in columns panel`);
952
983
  const checkbox = target.querySelector('input[type="checkbox"]') as HTMLElement | null;
953
984
  if (!checkbox) throw new Error(`Could not find checkbox for column "${fieldLabel}"`);
@@ -959,7 +990,7 @@ export const closeColumnsPanel = async () => {
959
990
  // Press Escape to close the panel
960
991
  await userEvent.keyboard('{Escape}');
961
992
  await waitFor(() => {
962
- const panel = document.querySelector('.MuiDataGrid-columnsPanel');
993
+ const panel = document.querySelector('.MuiDataGrid-columnsManagement');
963
994
  expect(panel).toBeFalsy();
964
995
  });
965
996
  };
@@ -2,9 +2,9 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
2
2
  import { DataGrid } from '@redsift/table';
3
3
  import { Flexbox } from '@redsift/design-system';
4
4
  import { DataCard, DataRow } from '@redsift/dashboard';
5
- import { BarChart, PieChart } from '@redsift/charts';
5
+ import { BarChart, PieChart, ArcDatum, BarDatum } from '@redsift/charts';
6
6
  import { mdiShapeOutline, mdiToggleSwitch, mdiFoodOff } from '@redsift/icons';
7
- import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-pro';
7
+ import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
8
8
  import { Row } from '../_shared/data';
9
9
  import { columns, CATEGORY_OPTIONS, ALLERGEN_OPTIONS } from '../_shared/columns';
10
10
  import { fetchBakeryData, FetchResult } from '../_shared/api-client';
@@ -207,8 +207,8 @@ export default () => {
207
207
  }}
208
208
  data={itemsChartData}
209
209
  sliceRole="option"
210
- onSliceClick={(datum: any) => {
211
- const key = datum.data.key as string;
210
+ onSliceClick={(datum: ArcDatum) => {
211
+ const key = datum.data.key;
212
212
  setFilterModel((prev) => {
213
213
  const selected = getSelectedFromFilterModel(prev, 'Items');
214
214
  const next = selected.includes(key) ? selected.filter((v) => v !== key) : [...selected, key];
@@ -216,8 +216,8 @@ export default () => {
216
216
  });
217
217
  setPage(0);
218
218
  }}
219
- isSliceSelected={(datum: any) =>
220
- itemsSelection.length === 0 || itemsSelection.includes(datum.data.key as string)
219
+ isSliceSelected={(datum: ArcDatum) =>
220
+ itemsSelection.length === 0 || itemsSelection.includes(datum.data.key)
221
221
  }
222
222
  />
223
223
 
@@ -238,8 +238,8 @@ export default () => {
238
238
  barProps={{ gap: 20 }}
239
239
  data={tagsChartData}
240
240
  barRole="option"
241
- onBarClick={(datum: any) => {
242
- const key = datum.data.key as string;
241
+ onBarClick={(datum: BarDatum) => {
242
+ const key = String(datum.data.key);
243
243
  setFilterModel((prev) => {
244
244
  const selected = getSelectedFromFilterModel(prev, 'Tags');
245
245
  const next = selected.includes(key) ? selected.filter((v) => v !== key) : [...selected, key];
@@ -247,8 +247,8 @@ export default () => {
247
247
  });
248
248
  setPage(0);
249
249
  }}
250
- isBarSelected={(datum: any) =>
251
- tagsSelection.length === 0 || tagsSelection.includes(datum.data.key as string)
250
+ isBarSelected={(datum: BarDatum) =>
251
+ tagsSelection.length === 0 || tagsSelection.includes(String(datum.data.key))
252
252
  }
253
253
  />
254
254
  </Flexbox>
@@ -3,7 +3,7 @@ import { DataGrid } from '@redsift/table';
3
3
  import { Flexbox } from '@redsift/design-system';
4
4
  import { DataCard, DataRow } from '@redsift/dashboard';
5
5
  import { mdiShapeOutline, mdiToggleSwitch, mdiFoodOff } from '@redsift/icons';
6
- import { GridFilterModel } from '@mui/x-data-grid-pro';
6
+ import { GridFilterModel } from '@mui/x-data-grid-premium';
7
7
  import { rows } from '../_shared/data';
8
8
  import { columns, CATEGORY_OPTIONS, ALLERGEN_OPTIONS } from '../_shared/columns';
9
9
  import { CustomToolbar } from '../_shared/helpers';
@@ -3,7 +3,7 @@ import { DataGrid } from '@redsift/table';
3
3
  import { Flexbox } from '@redsift/design-system';
4
4
  import { DataCard, DataRow } from '@redsift/dashboard';
5
5
  import { mdiShapeOutline, mdiToggleSwitch, mdiFoodOff } from '@redsift/icons';
6
- import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-pro';
6
+ import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
7
7
  import { Row } from '../_shared/data';
8
8
  import { columns, CATEGORY_OPTIONS, ALLERGEN_OPTIONS } from '../_shared/columns';
9
9
  import { fetchBakeryData, FetchResult } from '../_shared/api-client';
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { within, userEvent } from '@storybook/testing-library';
4
4
  import { expect } from '@storybook/jest';
5
- import { GridFilterModel } from '@mui/x-data-grid-pro';
5
+ import { GridFilterModel } from '@mui/x-data-grid-premium';
6
6
 
7
7
  import Example from './example';
8
8
  import WithLoadingExample from './with-loading';
@@ -1,20 +1,20 @@
1
1
  import React, { useState } from 'react';
2
- import { DataGrid } from '@redsift/table';
2
+ import { DataGrid, EMPTY_ROW_SELECTION_MODEL, getSelectionCount } from '@redsift/table';
3
3
  import { Flexbox } from '@redsift/design-system';
4
- import { GridFilterModel, GridRowSelectionModel } from '@mui/x-data-grid-pro';
4
+ import { GridFilterModel, GridRowSelectionModel } from '@mui/x-data-grid-premium';
5
5
  import { rows } from '../_shared/data';
6
6
  import { columns } from '../_shared/columns';
7
7
  import { CustomToolbar, BulkActionBar } from '../_shared/helpers';
8
8
  import { DEFAULT_FILTER_MODEL, DEFAULT_SORT_MODEL } from '../_shared/defaults';
9
9
 
10
10
  export default ({ initialFilterModel }: { initialFilterModel?: GridFilterModel }) => {
11
- const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>([]);
11
+ const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(EMPTY_ROW_SELECTION_MODEL);
12
12
 
13
13
  return (
14
14
  <div style={{ width: '100%' }}>
15
15
  <Flexbox flexDirection="column" gap="0px">
16
16
  <BulkActionBar
17
- count={selectionModel.length}
17
+ count={getSelectionCount(selectionModel)}
18
18
  onLog={() => console.log('Selected:', selectionModel)}
19
19
  onDelete={() => console.log('Delete:', selectionModel)}
20
20
  />
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { within, userEvent } from '@storybook/testing-library';
4
4
  import { expect } from '@storybook/jest';
5
- import { GridFilterModel } from '@mui/x-data-grid-pro';
5
+ import { GridFilterModel } from '@mui/x-data-grid-premium';
6
6
 
7
7
  import Example from './example';
8
8
  import WithLoadingExample from './with-loading';
@@ -1,7 +1,7 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import { DataGrid } from '@redsift/table';
2
+ import { DataGrid, EMPTY_ROW_SELECTION_MODEL, getSelectionCount } from '@redsift/table';
3
3
  import { Flexbox } from '@redsift/design-system';
4
- import { GridFilterModel, GridRowSelectionModel, GridSortModel } from '@mui/x-data-grid-pro';
4
+ import { GridFilterModel, GridRowSelectionModel, GridSortModel } from '@mui/x-data-grid-premium';
5
5
  import { Row } from '../_shared/data';
6
6
  import { columns } from '../_shared/columns';
7
7
  import { fetchBakeryData } from '../_shared/api-client';
@@ -16,7 +16,7 @@ export default ({ initialFilterModel }: { initialFilterModel?: GridFilterModel }
16
16
  const [pageSize, setPageSize] = useState(10);
17
17
  const [sortModel, setSortModel] = useState<GridSortModel>(DEFAULT_SORT_MODEL);
18
18
  const [filterModel, setFilterModel] = useState<GridFilterModel>(initialFilterModel ?? DEFAULT_FILTER_MODEL);
19
- const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>([]);
19
+ const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(EMPTY_ROW_SELECTION_MODEL);
20
20
 
21
21
  const quickFilterText = (filterModel as { quickFilterValues?: string[] }).quickFilterValues?.join(' ') || '';
22
22
  const debounceRef = useRef<ReturnType<typeof setTimeout>>();
@@ -54,7 +54,7 @@ export default ({ initialFilterModel }: { initialFilterModel?: GridFilterModel }
54
54
  <div style={{ width: '100%' }}>
55
55
  <Flexbox flexDirection="column" gap="0px">
56
56
  <BulkActionBar
57
- count={selectionModel.length}
57
+ count={getSelectionCount(selectionModel)}
58
58
  onLog={() => console.log('Selected:', selectionModel)}
59
59
  onDelete={() => console.log('Delete:', selectionModel)}
60
60
  />
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { within, userEvent } from '@storybook/testing-library';
4
4
  import { expect } from '@storybook/jest';
5
- import { GridFilterModel } from '@mui/x-data-grid-pro';
5
+ import { GridFilterModel } from '@mui/x-data-grid-premium';
6
6
 
7
7
  import Example from './example';
8
8
  import WithLoadingExample from './with-loading';
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from 'react';
2
- import { StatefulDataGrid } from '@redsift/table';
2
+ import { StatefulDataGrid, EMPTY_ROW_SELECTION_MODEL, getSelectionCount } from '@redsift/table';
3
3
  import { Flexbox } from '@redsift/design-system';
4
- import { GridFilterModel, GridRowSelectionModel, useGridApiRef } from '@mui/x-data-grid-pro';
4
+ import { GridFilterModel, GridRowSelectionModel, useGridApiRef } from '@mui/x-data-grid-premium';
5
5
  import { rows } from '../_shared/data';
6
6
  import { columns } from '../_shared/columns';
7
7
  import { CustomToolbar, BulkActionBar } from '../_shared/helpers';
@@ -16,14 +16,14 @@ interface Props {
16
16
 
17
17
  export default ({ initialFilterModel, useRouter = useRouterAdapter }: Props) => {
18
18
  const apiRef = useGridApiRef();
19
- const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>([]);
19
+ const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(EMPTY_ROW_SELECTION_MODEL);
20
20
 
21
21
  return (
22
22
  <div style={{ width: '100%' }}>
23
23
  <StateDebugPanel apiRef={apiRef} useRouter={useRouter} localStorageVersion={1} />
24
24
  <Flexbox flexDirection="column" gap="0px">
25
25
  <BulkActionBar
26
- count={selectionModel.length}
26
+ count={getSelectionCount(selectionModel)}
27
27
  onLog={() => console.log('Selected:', selectionModel)}
28
28
  onDelete={() => console.log('Delete:', selectionModel)}
29
29
  />
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { within, userEvent } from '@storybook/testing-library';
4
4
  import { expect } from '@storybook/jest';
5
- import { GridFilterModel } from '@mui/x-data-grid-pro';
5
+ import { GridFilterModel } from '@mui/x-data-grid-premium';
6
6
 
7
7
  import Example from './example';
8
8
  import WithLoadingExample from './with-loading';
@@ -1,7 +1,7 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import { StatefulDataGrid } from '@redsift/table';
2
+ import { StatefulDataGrid, EMPTY_ROW_SELECTION_MODEL, getSelectionCount } from '@redsift/table';
3
3
  import { Flexbox } from '@redsift/design-system';
4
- import { GridFilterModel, GridRowSelectionModel, GridSortModel, useGridApiRef } from '@mui/x-data-grid-pro';
4
+ import { GridFilterModel, GridRowSelectionModel, GridSortModel, useGridApiRef } from '@mui/x-data-grid-premium';
5
5
  import { Row } from '../_shared/data';
6
6
  import { columns } from '../_shared/columns';
7
7
  import { fetchBakeryData } from '../_shared/api-client';
@@ -20,7 +20,7 @@ export default ({ initialFilterModel, useRouter = useRouterAdapter }: Props) =>
20
20
  const [rows, setRows] = useState<Row[]>([]);
21
21
  const [totalRows, setTotalRows] = useState(0);
22
22
  const [loading, setLoading] = useState(true);
23
- const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>([]);
23
+ const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>(EMPTY_ROW_SELECTION_MODEL);
24
24
 
25
25
  // Refs track the latest model values so fetchData() always reads current state.
26
26
  // StatefulDataGrid manages filter/sort/pagination internally — we use callbacks
@@ -55,7 +55,7 @@ export default ({ initialFilterModel, useRouter = useRouterAdapter }: Props) =>
55
55
  <StateDebugPanel apiRef={apiRef} useRouter={useRouter} localStorageVersion={1} />
56
56
  <Flexbox flexDirection="column" gap="0px">
57
57
  <BulkActionBar
58
- count={selectionModel.length}
58
+ count={getSelectionCount(selectionModel)}
59
59
  onLog={() => console.log('Selected:', selectionModel)}
60
60
  onDelete={() => console.log('Delete:', selectionModel)}
61
61
  />
@@ -1,7 +1,7 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { DataGrid } from '@redsift/table';
3
3
  import { Flexbox, Pill, Number, Text, Tabs, Tab } from '@redsift/design-system';
4
- import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-pro';
4
+ import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
5
5
  import { Row } from '../_shared/data';
6
6
  import { columns, CATEGORY_OPTIONS } from '../_shared/columns';
7
7
  import { fetchBakeryData } from '../_shared/api-client';
@@ -14,8 +14,8 @@
14
14
  },
15
15
  {
16
16
  "name": "dataGridApiRef",
17
- "description": "Datagrid API Ref.",
18
- "type": "MutableRefObject<GridApiPro>",
17
+ "description": "Datagrid API Ref. MUI v8: can be null initially.",
18
+ "type": "MutableRefObject<GridApiPremium | null>",
19
19
  "required": false,
20
20
  "defaultValue": null,
21
21
  "category": "props"
@@ -55,7 +55,7 @@
55
55
  {
56
56
  "name": "paginationProps",
57
57
  "description": "Props to forward to the pagination component.",
58
- "type": "Omit<TablePaginationProps, \"paginationMode\" | \"component\" | \"page\" | \"count\" | \"onPageChange\" | \"onRowsPerPageChange\" | \"rowsPerPage\" | \"rowsPerPageOptions\">",
58
+ "type": "Omit<TablePaginationProps, \"paginationMode\" | \"component\" | \"count\" | \"onPageChange\" | \"onRowsPerPageChange\" | \"page\" | \"rowsPerPage\" | \"rowsPerPageOptions\">",
59
59
  "required": false,
60
60
  "defaultValue": null,
61
61
  "category": "props"
@@ -72,17 +72,17 @@
72
72
  "category": "props"
73
73
  },
74
74
  {
75
- "name": "className",
76
- "description": "",
77
- "type": "string",
75
+ "name": "getTreeDataPath",
76
+ "description": "Determines the path of a row in the tree data.\nFor instance, a row with the path [\"A\", \"B\"] is the child of the row with the path [\"A\"].\nNote that all paths must contain at least one element.\n@template R\n@param row The row from which we want the path.\n@returns The path to the row.",
77
+ "type": "(row: any) => readonly string[]",
78
78
  "required": false,
79
79
  "defaultValue": null,
80
80
  "category": "props"
81
81
  },
82
82
  {
83
- "name": "style",
84
- "description": "",
85
- "type": "CSSProperties",
83
+ "name": "setTreeDataPath",
84
+ "description": "Updates the tree path in a row model.\nUsed when reordering rows across different parents in tree data.\n@template R\n@param path The new path for the row.\n@param row The row model to update.\n@returns The updated row model with the new path.",
85
+ "type": "(path: string[], row: any) => any",
86
86
  "required": false,
87
87
  "defaultValue": null,
88
88
  "category": "props"
@@ -16,7 +16,7 @@
16
16
  "name": "onFilterModelChange",
17
17
  "description": "",
18
18
  "type": "(filterModel: GridFilterModel) => void",
19
- "required": true,
19
+ "required": false,
20
20
  "defaultValue": null,
21
21
  "category": "props"
22
22
  },
@@ -79,7 +79,7 @@
79
79
  {
80
80
  "name": "paginationProps",
81
81
  "description": "Props to forward to the pagination component.",
82
- "type": "Omit<TablePaginationProps, \"paginationMode\" | \"component\" | \"page\" | \"count\" | \"onPageChange\" | \"onRowsPerPageChange\" | \"rowsPerPage\" | \"rowsPerPageOptions\">",
82
+ "type": "Omit<TablePaginationProps, \"paginationMode\" | \"component\" | \"count\" | \"onPageChange\" | \"onRowsPerPageChange\" | \"page\" | \"rowsPerPage\" | \"rowsPerPageOptions\">",
83
83
  "required": false,
84
84
  "defaultValue": null,
85
85
  "category": "props"
@@ -96,17 +96,17 @@
96
96
  "category": "props"
97
97
  },
98
98
  {
99
- "name": "className",
100
- "description": "",
101
- "type": "string",
99
+ "name": "getTreeDataPath",
100
+ "description": "Determines the path of a row in the tree data.\nFor instance, a row with the path [\"A\", \"B\"] is the child of the row with the path [\"A\"].\nNote that all paths must contain at least one element.\n@template R\n@param row The row from which we want the path.\n@returns The path to the row.",
101
+ "type": "(row: any) => readonly string[]",
102
102
  "required": false,
103
103
  "defaultValue": null,
104
104
  "category": "props"
105
105
  },
106
106
  {
107
- "name": "style",
108
- "description": "",
109
- "type": "CSSProperties",
107
+ "name": "setTreeDataPath",
108
+ "description": "Updates the tree path in a row model.\nUsed when reordering rows across different parents in tree data.\n@template R\n@param path The new path for the row.\n@param row The row model to update.\n@returns The updated row model with the new path.",
109
+ "type": "(path: string[], row: any) => any",
110
110
  "required": false,
111
111
  "defaultValue": null,
112
112
  "category": "props"
@@ -7,7 +7,10 @@
7
7
  {
8
8
  "name": "columnsButtonProps",
9
9
  "description": "Props to forward to the column button.",
10
- "type": "GridToolbarColumnsProps",
10
+ "type": [
11
+ "GridToolbarColumnsButtonProps",
12
+ "GridToolbarColumnsButtonProps & RefAttributes<HTMLButtonElement>"
13
+ ],
11
14
  "required": false,
12
15
  "defaultValue": null,
13
16
  "category": "props"
@@ -23,7 +26,10 @@
23
26
  {
24
27
  "name": "densityButtonProps",
25
28
  "description": "Props to forward to the density button.",
26
- "type": "GridToolbarDensityProps",
29
+ "type": [
30
+ "GridToolbarDensitySelectorProps",
31
+ "GridToolbarDensitySelectorProps & RefAttributes<HTMLButtonElement>"
32
+ ],
27
33
  "required": false,
28
34
  "defaultValue": null,
29
35
  "category": "props"