@redsift/ds-mcp-server 12.5.13-muiv6 → 12.5.13
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/data/demos/patterns/_shared/StateDebugPanel.tsx +2 -2
- package/data/demos/patterns/_shared/columns.tsx +12 -3
- package/data/demos/patterns/_shared/defaults.ts +1 -1
- package/data/demos/patterns/_shared/filter-helpers.ts +1 -1
- package/data/demos/patterns/_shared/helpers.tsx +1 -1
- package/data/demos/patterns/_shared/server-logic.ts +1 -1
- package/data/demos/patterns/_shared/story-helpers.ts +106 -22
- package/data/demos/patterns/crossfiltered-datagrid-client-side/CrossfilteredDatagridClientSide.interaction.stories.tsx +1 -18
- package/data/demos/patterns/crossfiltered-datagrid-server-side/CrossfilteredDatagridServerSide.interaction.stories.tsx +1 -1
- package/data/demos/patterns/crossfiltered-datagrid-server-side/example.tsx +10 -10
- package/data/demos/patterns/drilldowned-datagrid-client-side/example.tsx +1 -1
- package/data/demos/patterns/drilldowned-datagrid-server-side/example.tsx +1 -1
- package/data/demos/patterns/single-datagrid-client-side/SingleDatagridClientSide.interaction.stories.tsx +1 -1
- package/data/demos/patterns/single-datagrid-client-side/example.tsx +4 -4
- package/data/demos/patterns/single-datagrid-server-side/SingleDatagridServerSide.interaction.stories.tsx +1 -1
- package/data/demos/patterns/single-datagrid-server-side/example.tsx +4 -4
- package/data/demos/patterns/stateful-single-datagrid-client-side/StatefulSingleDatagridClientSide.interaction.stories.tsx +129 -1
- package/data/demos/patterns/stateful-single-datagrid-client-side/example.tsx +6 -5
- package/data/demos/patterns/stateful-single-datagrid-server-side/StatefulSingleDatagridServerSide.interaction.stories.tsx +134 -1
- package/data/demos/patterns/stateful-single-datagrid-server-side/example.tsx +6 -5
- package/data/demos/patterns/tabbed-datagrid-server-side/example.tsx +1 -1
- package/data/docs/components/dashboard/Dashboard.json +2 -2
- package/data/docs/components/products/DmarcSummaryBoxes.json +1 -1
- package/data/docs/components/table/DataGrid.json +6 -6
- package/data/docs/components/table/GridToolbarFilterSemanticField.json +1 -1
- package/data/docs/components/table/StatefulDataGrid.json +6 -6
- package/data/docs/components/table/Toolbar.json +8 -2
- package/data/docs/components/table-pro/ControlledPagination.json +9 -0
- package/data/docs/components/table-pro/DataGrid.json +114 -0
- package/data/docs/components/table-pro/GridToolbarFilterSemanticField.json +69 -0
- package/data/docs/components/table-pro/ServerSideControlledPagination.json +9 -0
- package/data/docs/components/table-pro/StatefulDataGrid.json +135 -0
- package/data/docs/components/table-pro/TextCell.json +118 -0
- package/data/docs/components/table-pro/Toolbar.json +151 -0
- package/data/docs/components/table-pro/ToolbarWrapper.json +9 -0
- package/data/docs/components-index.json +69 -0
- package/data/docs/components.json +626 -21
- package/data/docs/llms-full.txt +209 -45
- package/data/docs/llms.txt +17 -5
- package/data/docs/patterns-catalog.md +24 -25
- package/data/docs/patterns.json +4 -4
- package/data/metadata.json +2 -2
- package/data/patterns/crossfiltered-datagrid-server-side.mdx +1 -1
- package/data/patterns/drilldowned-datagrid-client-side.mdx +1 -1
- package/data/patterns/drilldowned-datagrid-server-side.mdx +1 -1
- package/data/patterns/single-datagrid-client-side.mdx +7 -7
- package/data/patterns/single-datagrid-server-side.mdx +4 -4
- package/data/patterns/stateful-single-datagrid-client-side.mdx +36 -21
- package/data/patterns/stateful-single-datagrid-server-side.mdx +46 -18
- package/data/patterns/tabbed-datagrid-server-side.mdx +1 -1
- package/package.json +2 -2
|
@@ -82,7 +82,7 @@ These mistakes apply across **all** patterns and components. Avoid them everywhe
|
|
|
82
82
|
2. DataGrid — the table itself, configured with autoHeight, pagination, checkboxSelection, and GridColDef[] columns
|
|
83
83
|
3. Bulk Action Bar — Flexbox row shown when selectionModel.length > 0, with Pill (count) and action Buttons
|
|
84
84
|
|
|
85
|
-
**Key imports:** `DataGrid`, `TextCell`, `StatefulDataGrid` from `@redsift/table`; `GridColDef`, `GridFilterModel`, `GridRowSelectionModel` from `@mui/x-data-grid-
|
|
85
|
+
**Key imports:** `DataGrid`, `TextCell`, `StatefulDataGrid` from `@redsift/table`; `GridColDef`, `GridFilterModel`, `GridRowSelectionModel` from `@mui/x-data-grid-premium`; `Pill`, `Button`, `Flexbox` from `@redsift/design-system`
|
|
86
86
|
**Components:** DataGrid, TextCell, StatefulDataGrid (from @redsift/table), Flexbox, Button, Pill, Text, Badge, Icon, IconButton, IconButtonLink (from @redsift/design-system)
|
|
87
87
|
**Layout:** DataGrid with `autoHeight`, `pagination`, `pageSize`, built-in Toolbar (Columns | Filters | Density | Export | Search via `componentsProps.toolbar.showQuickFilter`). Columns use `GridColDef[]` with `createColumn()` for typed filter operators (e.g. `...createColumn('string')`, `...createColumn('number')`, `...createColumn('singleSelect')`), `renderCell` returning `TextCell`, `Pill`, `Badge`. Optional bulk actions bar above grid shown when `selectionModel.length > 0`.
|
|
88
88
|
|
|
@@ -153,7 +153,7 @@ type Row = {
|
|
|
153
153
|
2. DataGrid — the table configured with paginationMode='server', sortingMode='server', filterMode='server', loading, and rowCount
|
|
154
154
|
3. Bulk Action Bar — Flexbox row shown when selectionModel.length > 0, with Pill (count) and action Buttons
|
|
155
155
|
|
|
156
|
-
**Key imports:** `DataGrid`, `TextCell` from `@redsift/table`; `GridColDef`, `GridFilterModel`, `GridSortModel`, `GridSelectionModel` from `@mui/x-data-grid-
|
|
156
|
+
**Key imports:** `DataGrid`, `TextCell` from `@redsift/table`; `GridColDef`, `GridFilterModel`, `GridSortModel`, `GridSelectionModel` from `@mui/x-data-grid-premium`; `Pill`, `Button`, `Flexbox`, `Icon`, `IconButtonLink` from `@redsift/design-system`
|
|
157
157
|
**Components:** DataGrid, TextCell (from @redsift/table), Flexbox, Button, Pill, Text, Badge, Icon, IconButton, IconButtonLink (from @redsift/design-system)
|
|
158
158
|
**Layout:** DataGrid with `autoHeight`, `paginationMode="server"`, `sortingMode="server"`, `filterMode="server"`, `rowCount`, `loading`, built-in Toolbar (Columns | Filters | Density | Export | Search). Same column types as Datagrid Page.
|
|
159
159
|
|
|
@@ -256,29 +256,29 @@ type FetchResult = {
|
|
|
256
256
|
|
|
257
257
|
**Anatomy:**
|
|
258
258
|
|
|
259
|
-
1. DataCard Row — Flexbox with 1-N DataCards, each containing DataCard.Header and DataCard.Listbox or DataCard.Body with
|
|
259
|
+
1. DataCard Row — Flexbox with 1-N DataCards, each containing DataCard.Header and DataCard.Listbox or DataCard.Body with DrilldownItem children
|
|
260
260
|
2. Toolbar — Flexbox wrapping GridToolbarContainer with filter, columns, density, export, quick search controls
|
|
261
261
|
3. DataGrid — the table with controlled filterModel + onFilterModelChange
|
|
262
262
|
4. Bulk Action Bar — Flexbox row shown when selectionModel.length > 0, with Pill (count) and action Buttons
|
|
263
263
|
|
|
264
|
-
**Key imports:** `DataGrid`, `TextCell` from `@redsift/table`; `DataCard`, `
|
|
265
|
-
**Components:** DataGrid, TextCell (from @redsift/table), DataCard, DataCard.Header, DataCard.Body, DataCard.Listbox,
|
|
264
|
+
**Key imports:** `DataGrid`, `TextCell` from `@redsift/table`; `DataCard`, `DrilldownItem` from `@redsift/dashboard`; `GridColDef`, `GridFilterModel` from `@mui/x-data-grid-premium`; `Pill`, `Button`, `Flexbox`, `Icon` from `@redsift/design-system`
|
|
265
|
+
**Components:** DataGrid, TextCell (from @redsift/table), DataCard, DataCard.Header, DataCard.Body, DataCard.Listbox, DrilldownItem (from @redsift/dashboard), Flexbox, Button, Pill, Text, Icon, IconButtonLink (from @redsift/design-system)
|
|
266
266
|
**Layout:** Flexbox column: DataCard row (Flexbox gap=12px flexWrap=wrap with 1-N DataCards), then DataGrid with autoHeight, pagination, controlled filterModel + onFilterModelChange. Optional bulk actions bar.
|
|
267
267
|
|
|
268
268
|
**Features:**
|
|
269
269
|
|
|
270
|
-
| Feature
|
|
271
|
-
|
|
|
272
|
-
| DataCard aggregation
|
|
273
|
-
|
|
|
274
|
-
| Listbox multi-select
|
|
275
|
-
| is/isNot clearing
|
|
276
|
-
| Column definitions
|
|
277
|
-
| Toolbar
|
|
278
|
-
| Custom cell renderers
|
|
279
|
-
| Boolean toggle
|
|
280
|
-
| Checkbox selection
|
|
281
|
-
| Bulk action bar
|
|
270
|
+
| Feature | Required | Description |
|
|
271
|
+
| ------------------------- | -------- | -------------------------------------------------------------------------------- |
|
|
272
|
+
| DataCard aggregation | Yes | DataCard components showing aggregate counts per field from the full dataset |
|
|
273
|
+
| DrilldownItem filter push | Yes | Clicking a DrilldownItem adds an isAnyOf filter to the DataGrid filterModel |
|
|
274
|
+
| Listbox multi-select | Yes | DataCard.Listbox with selectionMode=multiple and controlled values |
|
|
275
|
+
| is/isNot clearing | Yes | When filter panel has is/isNot for a card's field, the DataCard selection clears |
|
|
276
|
+
| Column definitions | Yes | GridColDef[] with custom types |
|
|
277
|
+
| Toolbar | Yes | Built-in toolbar with filter, columns, density, export, and quick search |
|
|
278
|
+
| Custom cell renderers | Yes | renderCell returning TextCell, Pill, Icon, IconButtonLink |
|
|
279
|
+
| Boolean toggle | No | DataCard.Body with DrilldownItem onClick for boolean fields |
|
|
280
|
+
| Checkbox selection | No | checkboxSelection + rowSelectionModel |
|
|
281
|
+
| Bulk action bar | No | Contextual buttons shown when rows are selected |
|
|
282
282
|
|
|
283
283
|
**Filter helpers:**
|
|
284
284
|
|
|
@@ -312,7 +312,7 @@ type AggregateCounts = {
|
|
|
312
312
|
|
|
313
313
|
1. Define your row type — every row must have a unique id field.
|
|
314
314
|
2. Compute aggregate counts — useAggregateCounts(allRows) counts from the full dataset.
|
|
315
|
-
3. Build DataCards with DataCard.Header, DataCard.Listbox (multi-select) or DataCard.Body (boolean toggle) containing
|
|
315
|
+
3. Build DataCards with DataCard.Header, DataCard.Listbox (multi-select) or DataCard.Body (boolean toggle) containing DrilldownItem children.
|
|
316
316
|
4. Write filter helpers — getSelectedFromFilterModel and updateFilterModel.
|
|
317
317
|
5. Wire DataCard handlers — onChange to updateFilterModel, onClick to updateBooleanFilter.
|
|
318
318
|
6. Render the DataGrid with controlled filterModel and onFilterModelChange.
|
|
@@ -332,7 +332,7 @@ type AggregateCounts = {
|
|
|
332
332
|
- DataCard counts should recalculate as filters change — reflecting the current filter context
|
|
333
333
|
- Clicking a card value should add a filter to the datagrid (bidirectional)
|
|
334
334
|
- Changing the filter panel should update the card selection
|
|
335
|
-
- The dataset is small enough to load entirely (under ~
|
|
335
|
+
- The dataset is small enough to load entirely (under ~1,000 rows)
|
|
336
336
|
|
|
337
337
|
**When NOT to use:**
|
|
338
338
|
|
|
@@ -345,11 +345,10 @@ type AggregateCounts = {
|
|
|
345
345
|
1. DataCard Row — Flexbox with 1-N DataCards. Counts are cross-filtered: each card excludes its own field from the filter calculation
|
|
346
346
|
2. Toolbar — Flexbox wrapping GridToolbarContainer with filter, columns, density, export, quick search controls
|
|
347
347
|
3. DataGrid — the table with controlled filterModel + onFilterModelChange. Rows are pre-filtered client-side
|
|
348
|
-
4.
|
|
349
|
-
5. Bulk Action Bar — Flexbox row shown when selectionModel.length > 0, with Pill (count) and action Buttons
|
|
348
|
+
4. Bulk Action Bar — Flexbox row shown when selectionModel.length > 0, with Pill (count) and action Buttons
|
|
350
349
|
|
|
351
|
-
**Key imports:** `DataGrid`, `TextCell` from `@redsift/table`; `DataCard`, `
|
|
352
|
-
**Components:** DataGrid, TextCell (from @redsift/table),
|
|
350
|
+
**Key imports:** `DataGrid`, `TextCell` from `@redsift/table`; `DataCard`, `DrilldownItem` from `@redsift/dashboard`; `GridColDef`, `GridFilterModel` from `@mui/x-data-grid-premium`; `Pill`, `Button`, `Flexbox`, `Icon` from `@redsift/design-system`
|
|
351
|
+
**Components:** DataGrid, TextCell (from @redsift/table), DataCard, DataCard.Header, DataCard.Body, DataCard.Listbox, DrilldownItem (from @redsift/dashboard), Flexbox, Button, Pill, Text, Icon, IconButtonLink (from @redsift/design-system)
|
|
353
352
|
**Layout:** Flexbox column: DataCard row (cross-filtered counts), then DataGrid with autoHeight, pagination, controlled filterModel + onFilterModelChange. Rows are pre-filtered client-side via applyFilters. Optional bulk actions bar.
|
|
354
353
|
|
|
355
354
|
**Features:**
|
|
@@ -358,14 +357,14 @@ type AggregateCounts = {
|
|
|
358
357
|
| -------------------------- | -------- | -------------------------------------------------------------------------------- |
|
|
359
358
|
| Cross-filtered aggregation | Yes | DataCard counts recompute from rows filtered by all fields except the card's own |
|
|
360
359
|
| Two-way filter sync | Yes | DataCard selections derive from filterModel; DataCard clicks update filterModel |
|
|
361
|
-
|
|
|
360
|
+
| DrilldownItem filter push | Yes | Clicking a DrilldownItem adds an isAnyOf filter to the DataGrid filterModel |
|
|
362
361
|
| Listbox multi-select | Yes | DataCard.Listbox with selectionMode=multiple and controlled values |
|
|
363
362
|
| is/isNot clearing | Yes | When filter panel has is/isNot for a card's field, the DataCard selection clears |
|
|
364
363
|
| Client-side row filtering | Yes | applyFilters function filters the full row set by the current filterModel |
|
|
365
364
|
| Column definitions | Yes | GridColDef[] with custom types |
|
|
366
365
|
| Toolbar | Yes | Built-in toolbar with filter, columns, density, export, and quick search |
|
|
367
366
|
| Custom cell renderers | Yes | renderCell returning TextCell, Pill, Icon, IconButtonLink |
|
|
368
|
-
| Boolean toggle | No | DataCard.Body with
|
|
367
|
+
| Boolean toggle | No | DataCard.Body with DrilldownItem onClick for boolean fields |
|
|
369
368
|
| Checkbox selection | No | checkboxSelection + rowSelectionModel |
|
|
370
369
|
| Bulk action bar | No | Contextual buttons shown when rows are selected |
|
|
371
370
|
|
package/data/docs/patterns.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"IconButton",
|
|
17
17
|
"IconButtonLink"
|
|
18
18
|
],
|
|
19
|
-
"packages": ["@redsift/table", "@redsift/design-system", "@mui/x-data-grid-
|
|
19
|
+
"packages": ["@redsift/table", "@redsift/design-system", "@mui/x-data-grid-premium"],
|
|
20
20
|
"layout": "DataGrid with autoHeight, pagination, pageSize, built-in Toolbar via componentsProps.toolbar.showQuickFilter. Optional bulk actions bar when selectionModel.length > 0.",
|
|
21
21
|
"tags": [
|
|
22
22
|
"table",
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
"IconButton",
|
|
182
182
|
"IconButtonLink"
|
|
183
183
|
],
|
|
184
|
-
"packages": ["@redsift/table", "@redsift/design-system", "@mui/x-data-grid-
|
|
184
|
+
"packages": ["@redsift/table", "@redsift/design-system", "@mui/x-data-grid-premium"],
|
|
185
185
|
"layout": "DataGrid with autoHeight, paginationMode='server', sortingMode='server', filterMode='server', rowCount, loading, built-in Toolbar. Optional bulk actions bar when selectionModel.length > 0.",
|
|
186
186
|
"tags": [
|
|
187
187
|
"table",
|
|
@@ -493,7 +493,7 @@
|
|
|
493
493
|
"Icon",
|
|
494
494
|
"IconButtonLink"
|
|
495
495
|
],
|
|
496
|
-
"packages": ["@redsift/table", "@redsift/design-system", "@redsift/dashboard", "@mui/x-data-grid-
|
|
496
|
+
"packages": ["@redsift/table", "@redsift/design-system", "@redsift/dashboard", "@mui/x-data-grid-premium"],
|
|
497
497
|
"layout": "Flexbox column: DataCard row (Flexbox gap=12px flexWrap=wrap with 1-N DataCards), then DataGrid with autoHeight, pagination, controlled filterModel + onFilterModelChange. Optional bulk actions bar when selectionModel.length > 0.",
|
|
498
498
|
"tags": [
|
|
499
499
|
"table",
|
|
@@ -662,7 +662,7 @@
|
|
|
662
662
|
"Icon",
|
|
663
663
|
"IconButtonLink"
|
|
664
664
|
],
|
|
665
|
-
"packages": ["@redsift/table", "@redsift/design-system", "@redsift/dashboard", "@mui/x-data-grid-
|
|
665
|
+
"packages": ["@redsift/table", "@redsift/design-system", "@redsift/dashboard", "@mui/x-data-grid-premium"],
|
|
666
666
|
"layout": "Flexbox column: DataCard row (cross-filtered counts), then DataGrid with autoHeight, pagination, controlled filterModel + onFilterModelChange. Rows are pre-filtered client-side via applyFilters. Optional bulk actions bar.",
|
|
667
667
|
"tags": [
|
|
668
668
|
"table",
|
package/data/metadata.json
CHANGED
|
@@ -99,7 +99,7 @@ When **not** to use:
|
|
|
99
99
|
## State Management
|
|
100
100
|
|
|
101
101
|
<CodeBlock codeString={`import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
102
|
-
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-
|
|
102
|
+
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
|
|
103
103
|
|
|
104
104
|
// Server-driven state
|
|
105
105
|
const [rows, setRows] = useState<Row[]>([]);
|
|
@@ -114,7 +114,7 @@ When **not** to use:
|
|
|
114
114
|
## State Management
|
|
115
115
|
|
|
116
116
|
<CodeBlock codeString={`import { useCallback, useMemo, useState } from 'react';
|
|
117
|
-
import { GridFilterModel } from '@mui/x-data-grid-
|
|
117
|
+
import { GridFilterModel } from '@mui/x-data-grid-premium';
|
|
118
118
|
|
|
119
119
|
// Filter state — controlled, shared between DataCards and DataGrid
|
|
120
120
|
const [filterModel, setFilterModel] = useState<GridFilterModel>({ items: [] });
|
|
@@ -91,7 +91,7 @@ When **not** to use:
|
|
|
91
91
|
## State Management
|
|
92
92
|
|
|
93
93
|
<CodeBlock codeString={`import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
94
|
-
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-
|
|
94
|
+
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
|
|
95
95
|
|
|
96
96
|
// Server-driven state
|
|
97
97
|
const [rows, setRows] = useState<Row[]>([]);
|
|
@@ -33,7 +33,7 @@ When **not** to use:
|
|
|
33
33
|
|
|
34
34
|
1. **Toolbar** — `Flexbox` wrapping MUI's `GridToolbarContainer` with `GridToolbarFilterButton`, `GridToolbarColumnsButton`, `GridToolbarDensitySelector`, `GridToolbarExport`, and `GridToolbarQuickFilter`
|
|
35
35
|
2. **DataGrid** — the table itself from `@redsift/table`, configured with `autoHeight`, `pagination`, `checkboxSelection`, and `GridColDef[]` columns
|
|
36
|
-
3. **Bulk Action Bar** — a `Flexbox` row shown when
|
|
36
|
+
3. **Bulk Action Bar** — a `Flexbox` row shown when rows are selected, containing a `Pill` with the selection count and action `Button` components
|
|
37
37
|
|
|
38
38
|
## Features
|
|
39
39
|
|
|
@@ -124,10 +124,10 @@ When **not** to use:
|
|
|
124
124
|
## State Management
|
|
125
125
|
|
|
126
126
|
<CodeBlock codeString={`import { useState } from 'react';
|
|
127
|
-
import {
|
|
127
|
+
import { GridRowSelectionModel } from '@mui/x-data-grid-premium';
|
|
128
128
|
|
|
129
129
|
// Selection state — tracks which rows are checked
|
|
130
|
-
const [selectionModel, setSelectionModel] = useState<
|
|
130
|
+
const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>([]);
|
|
131
131
|
|
|
132
132
|
// Page size — controlled if you need to persist it
|
|
133
133
|
// (DataGrid manages page/pageSize internally for client-side mode)
|
|
@@ -149,7 +149,7 @@ type Row = {
|
|
|
149
149
|
};
|
|
150
150
|
|
|
151
151
|
// Column definitions — use createColumn() for built-in filter operators
|
|
152
|
-
import { GridColDef } from '@mui/x-data-grid-
|
|
152
|
+
import { GridColDef } from '@mui/x-data-grid-premium';
|
|
153
153
|
import { createColumn } from '@redsift/table';
|
|
154
154
|
|
|
155
155
|
const columns: GridColDef[] = [
|
|
@@ -184,9 +184,9 @@ When data fetching fails, replace the DataGrid area with an error message and a
|
|
|
184
184
|
1. **Define your row type** — Create a TypeScript `type Row` per the Data Contract section. Every row must have a unique `id` field.
|
|
185
185
|
2. **Define column definitions** — Create a `GridColDef[]` array. Use `createColumn()` (e.g. `...createColumn('string')`, `...createColumn('number')`, `...createColumn('singleSelect')`, `...createColumn('multiSelect')`) for built-in filter operators. Add `renderCell` for rich content (pills, icons, links).
|
|
186
186
|
3. **Create the toolbar** — Build a `CustomToolbar` component using `GridToolbarContainer` with `GridToolbarFilterButton`, `GridToolbarColumnsButton`, `GridToolbarDensitySelector`, `GridToolbarExport`, and optionally `GridToolbarQuickFilter`.
|
|
187
|
-
4. **Set up state** — Add `useState<
|
|
188
|
-
5. **Render the DataGrid** — Pass `rows`, `columns`, `autoHeight`, `pagination`, `pageSize`, `rowsPerPageOptions`, `checkboxSelection`, `
|
|
189
|
-
6. **Add bulk action bar** — Conditionally render a `Flexbox` with a `Pill` (selection count) and action `Button` components when
|
|
187
|
+
4. **Set up state** — Add `useState<GridRowSelectionModel>` for checkbox selection (if needed).
|
|
188
|
+
5. **Render the DataGrid** — Pass `rows`, `columns`, `autoHeight`, `pagination`, `pageSize`, `rowsPerPageOptions`, `checkboxSelection`, `slots={{ toolbar: CustomToolbar }}`.
|
|
189
|
+
6. **Add bulk action bar** — Conditionally render a `Flexbox` with a `Pill` (selection count) and action `Button` components when rows are selected.
|
|
190
190
|
7. **Handle edge cases** — Add loading state (`loading` prop), empty state (custom `NoRowsOverlay`), and error state (conditional render with retry).
|
|
191
191
|
8. **Verify** — Test pagination breakpoints, filter operators, column visibility toggle, density switching, and export.
|
|
192
192
|
|
|
@@ -34,7 +34,7 @@ When **not** to use:
|
|
|
34
34
|
|
|
35
35
|
1. **Toolbar** — `Flexbox` wrapping MUI's `GridToolbarContainer` with `GridToolbarFilterButton`, `GridToolbarColumnsButton`, `GridToolbarDensitySelector`, `GridToolbarExport`, and `GridToolbarQuickFilter`
|
|
36
36
|
2. **DataGrid** — the table configured with `paginationMode="server"`, `sortingMode="server"`, `filterMode="server"`, `loading`, and `rowCount`
|
|
37
|
-
3. **Bulk Action Bar** — a `Flexbox` row shown when
|
|
37
|
+
3. **Bulk Action Bar** — a `Flexbox` row shown when rows are selected, containing a `Pill` with the selection count and action `Button` components
|
|
38
38
|
|
|
39
39
|
## Features
|
|
40
40
|
|
|
@@ -159,7 +159,7 @@ When **not** to use:
|
|
|
159
159
|
## State Management
|
|
160
160
|
|
|
161
161
|
<CodeBlock codeString={`import { useCallback, useEffect, useRef, useState } from 'react';
|
|
162
|
-
import { GridFilterModel,
|
|
162
|
+
import { GridFilterModel, GridRowSelectionModel, GridSortModel } from '@mui/x-data-grid-premium';
|
|
163
163
|
|
|
164
164
|
// Data state — rows returned from the server for the current page
|
|
165
165
|
const [rows, setRows] = useState<Row[]>([]);
|
|
@@ -175,7 +175,7 @@ const [sortModel, setSortModel] = useState<GridSortModel>([]);
|
|
|
175
175
|
const [filterModel, setFilterModel] = useState<GridFilterModel>({ items: [] });
|
|
176
176
|
|
|
177
177
|
// Selection state
|
|
178
|
-
const [selectionModel, setSelectionModel] = useState<
|
|
178
|
+
const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>([]);
|
|
179
179
|
|
|
180
180
|
// Quick search
|
|
181
181
|
const [quickFilterText, setQuickFilterText] = useState('');
|
|
@@ -269,7 +269,7 @@ The fetch function rejects with an error. The component shows an error banner ab
|
|
|
269
269
|
6. **Wire the fetch effect** — Use `useEffect` to call your fetch function whenever `page`, `pageSize`, `sortModel`, `filterModel`, or `quickFilterText` changes.
|
|
270
270
|
7. **Configure the DataGrid** — Pass `paginationMode="server"`, `sortingMode="server"`, `filterMode="server"`, `loading`, `rowCount={totalRows}`, and all controlled state handlers (`onPageChange`, `onPageSizeChange`, `onSortModelChange`, `onFilterModelChange`).
|
|
271
271
|
8. **Debounce filter changes** — Use a 300ms `setTimeout` in `onFilterModelChange` to avoid excessive requests during rapid typing. Reset to page 0 on filter change.
|
|
272
|
-
9. **Add bulk action bar** — Conditionally render when
|
|
272
|
+
9. **Add bulk action bar** — Conditionally render when rows are selected.
|
|
273
273
|
10. **Handle edge cases** — Add loading state (`loading` prop), empty state (custom `NoRowsOverlay`), and error state (conditional render with retry).
|
|
274
274
|
11. **Verify** — Test page navigation, sort toggling, filter operators, debounced quick search, loading overlay, empty results, and error recovery.
|
|
275
275
|
|
|
@@ -6,7 +6,7 @@ import { RouterLink } from '../../components/RouterLink';
|
|
|
6
6
|
|
|
7
7
|
## Introduction
|
|
8
8
|
|
|
9
|
-
The Stateful Datagrid Page extends the [Single Datagrid (client)](/patterns/single-datagrid-client-side) pattern with **automatic state persistence to URL and localStorage**. It uses `StatefulDataGrid` from `@redsift/table` instead of `DataGrid`. Filters, sorting, pagination, column visibility, column order, and density survive page refreshes and can be shared via URL — users bookmark a filtered view and anyone opening the link sees the same grid state.
|
|
9
|
+
The Stateful Datagrid Page extends the [Single Datagrid (client)](/patterns/single-datagrid-client-side) pattern with **automatic state persistence to URL and localStorage**. It uses `StatefulDataGrid` from `@redsift/table` instead of `DataGrid`. Filters, sorting, pagination, column visibility, column order, row grouping, aggregation, pivot, and density survive page refreshes and can be shared via URL — users bookmark a filtered view and anyone opening the link sees the same grid state.
|
|
10
10
|
|
|
11
11
|
All filtering, sorting, and pagination happen **client-side** — all rows are loaded at once. For server-side data handling with URL state persistence, see the [Stateful Single Datagrid (server)](/patterns/stateful-single-datagrid-server-side) pattern.
|
|
12
12
|
|
|
@@ -116,7 +116,21 @@ When **not** to use:
|
|
|
116
116
|
required: false,
|
|
117
117
|
description: 'Column arrangement persisted to URL and localStorage (only when different from default)',
|
|
118
118
|
},
|
|
119
|
-
|
|
119
|
+
{
|
|
120
|
+
feature: 'Row grouping persistence',
|
|
121
|
+
required: false,
|
|
122
|
+
description: 'Row grouping model persisted to URL and localStorage',
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
feature: 'Aggregation persistence',
|
|
126
|
+
required: false,
|
|
127
|
+
description: 'Aggregation functions per column persisted to URL and localStorage',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
feature: 'Pivot persistence',
|
|
131
|
+
required: false,
|
|
132
|
+
description: 'Pivot configuration (columns, rows, value aggregations) persisted to URL and localStorage',
|
|
133
|
+
},
|
|
120
134
|
{
|
|
121
135
|
feature: 'URL compression',
|
|
122
136
|
required: false,
|
|
@@ -126,8 +140,7 @@ When **not** to use:
|
|
|
126
140
|
</>
|
|
127
141
|
),
|
|
128
142
|
},
|
|
129
|
-
|
|
130
|
-
]}
|
|
143
|
+
]}
|
|
131
144
|
/>
|
|
132
145
|
|
|
133
146
|
### Components
|
|
@@ -209,18 +222,20 @@ export const useRouter = () => {
|
|
|
209
222
|
|
|
210
223
|
`StatefulDataGrid` writes grid state to URL query params in a human-readable display format.
|
|
211
224
|
|
|
212
|
-
| State | URL Parameter
|
|
213
|
-
| ----------------- |
|
|
214
|
-
| Filter (string) | `field.operator=value`
|
|
215
|
-
| Filter (list) | `field.operator=a,b,c`
|
|
216
|
-
| Sort | `_sortColumn=field.direction`
|
|
217
|
-
| Pagination | `_pagination=page.size.direction`
|
|
218
|
-
| Column visibility | `_columnVisibility=col1,col2,...`
|
|
219
|
-
| Column order | `_columnOrder=col1,col2,...`
|
|
220
|
-
| Pinned columns | `_pinnedColumnsLeft=col1,col2`
|
|
221
|
-
|
|
222
|
-
|
|
|
223
|
-
|
|
|
225
|
+
| State | URL Parameter | Example |
|
|
226
|
+
| ----------------- | ----------------------------------- | ----------------------------------------------- |
|
|
227
|
+
| Filter (string) | `field.operator=value` | `Items.contains=Bread` |
|
|
228
|
+
| Filter (list) | `field.operator=a,b,c` | `Category.isAnyOf=Bakery,Pastry` |
|
|
229
|
+
| Sort | `_sortColumn=field.direction` | `_sortColumn=DateTime.desc` |
|
|
230
|
+
| Pagination | `_pagination=page.size.direction` | `_pagination=0.10.next` |
|
|
231
|
+
| Column visibility | `_columnVisibility=col1,col2,...` | `_columnVisibility=Items,Category,Paid` |
|
|
232
|
+
| Column order | `_columnOrder=col1,col2,...` | `_columnOrder=Category,Items,Paid` |
|
|
233
|
+
| Pinned columns | `_pinnedColumnsLeft=col1,col2` | `_pinnedColumnsLeft=__check__,Items` |
|
|
234
|
+
| Row grouping | `_rowGrouping=col1,col2` | `_rowGrouping=Category` |
|
|
235
|
+
| Aggregation | `_aggregation=field.func,...` | `_aggregation=Paid.sum,Score.avg` |
|
|
236
|
+
| Pivot | `_pivot=cols:...;rows:...;vals:...` | `_pivot=cols:Category;rows:Items;vals:Paid.sum` |
|
|
237
|
+
| Density | `_density=value` | `_density=compact` |
|
|
238
|
+
| Version | `v=N` | `v=1` |
|
|
224
239
|
|
|
225
240
|
Special characters in values (`:`, `,`, `~`) are percent-encoded (`%3A`, `%2C`, `%7E`).
|
|
226
241
|
|
|
@@ -228,7 +243,7 @@ Column order is only written to the URL when it differs from the default column
|
|
|
228
243
|
|
|
229
244
|
### URL Compression
|
|
230
245
|
|
|
231
|
-
When the total URL length exceeds ~2,000 characters, `StatefulDataGrid` automatically compresses query params using `lz-string`. Parameters are compressed in priority order — column order and visibility first — so the most important configuration stays human-readable. Compressed values are prefixed with `~` for self-describing format.
|
|
246
|
+
When the total URL length exceeds ~2,000 characters, `StatefulDataGrid` automatically compresses query params using `lz-string`. Parameters are compressed in priority order — column order and visibility first, pivot last — so the most important configuration stays human-readable. Compressed values are prefixed with `~` for self-describing format.
|
|
232
247
|
|
|
233
248
|
## State Management
|
|
234
249
|
|
|
@@ -239,7 +254,7 @@ When the total URL length exceeds ~2,000 characters, `StatefulDataGrid` automati
|
|
|
239
254
|
|
|
240
255
|
// Persisted states:
|
|
241
256
|
// filters, sorting, pagination, column visibility, column order,
|
|
242
|
-
// pinned columns, density
|
|
257
|
+
// pinned columns, density, row grouping, aggregation, pivot
|
|
243
258
|
|
|
244
259
|
// On every interaction:
|
|
245
260
|
// grid updates internal state
|
|
@@ -266,7 +281,7 @@ type Row = {
|
|
|
266
281
|
};
|
|
267
282
|
|
|
268
283
|
// Column definitions — use createColumn() for built-in filter operators
|
|
269
|
-
import { GridColDef } from '@mui/x-data-grid-
|
|
284
|
+
import { GridColDef } from '@mui/x-data-grid-premium';
|
|
270
285
|
import { createColumn } from '@redsift/table';
|
|
271
286
|
|
|
272
287
|
const columns: GridColDef[] = [
|
|
@@ -302,11 +317,11 @@ When data fetching fails, replace the grid area with an error message and a retr
|
|
|
302
317
|
2. **Define column definitions** — Create a `GridColDef[]` array using `createColumn()` for built-in filter operators.
|
|
303
318
|
3. **Create a router adapter** — Implement a `useRouter` hook for your framework (react-router, Next.js, or plain browser). See the Router Adapter section above.
|
|
304
319
|
4. **Create the toolbar** — Build a `CustomToolbar` component using `GridToolbarContainer`.
|
|
305
|
-
5. **Render StatefulDataGrid** — Pass `useRouter`, `localStorageVersion`, `initialState` (filter, sort, pagination defaults), `pagination`, `pageSizeOptions`, `rows`, `columns`.
|
|
320
|
+
5. **Render StatefulDataGrid** — Pass `useRouter`, `localStorageVersion`, `initialState` (filter, sort, pagination, row grouping, aggregation, pivot defaults), `pagination`, `pageSizeOptions`, `rows`, `columns`.
|
|
306
321
|
6. **Add bulk action bar** — Conditionally render when `selectionModel.length > 0`.
|
|
307
322
|
7. **Handle edge cases** — Loading state (`loading` prop), empty state (custom `NoRowsOverlay`), and error state (conditional render with retry).
|
|
308
323
|
8. **Set localStorageVersion** — Increment when column definitions change to force a clean localStorage. Set `previousLocalStorageVersions` to clean up old keys.
|
|
309
|
-
9. **Verify** — Test pagination, filter operators, column visibility, density, column order, URL sharing (copy URL → paste in new tab), and page refresh persistence. Verify that long URLs trigger compression automatically.
|
|
324
|
+
9. **Verify** — Test pagination, filter operators, column visibility, density, column order, row grouping, aggregation, pivot, URL sharing (copy URL → paste in new tab), and page refresh persistence. Verify that long URLs trigger compression automatically.
|
|
310
325
|
|
|
311
326
|
## Keyboard & Accessibility
|
|
312
327
|
|
|
@@ -6,7 +6,7 @@ import { RouterLink } from '../../components/RouterLink';
|
|
|
6
6
|
|
|
7
7
|
## Introduction
|
|
8
8
|
|
|
9
|
-
The Stateful Server Datagrid Page extends the [Single Datagrid (server)](/patterns/single-datagrid-server-side) pattern with **automatic state persistence to URL and localStorage**. It uses `StatefulDataGrid` from `@redsift/table` instead of `DataGrid`. All filtering, sorting, and pagination happen **server-side**, and the grid state (filters, sort, page, column visibility, column order, pinned columns, and
|
|
9
|
+
The Stateful Server Datagrid Page extends the [Single Datagrid (server)](/patterns/single-datagrid-server-side) pattern with **automatic state persistence to URL and localStorage**. It uses `StatefulDataGrid` from `@redsift/table` instead of `DataGrid`. All filtering, sorting, and pagination happen **server-side**, and the grid state (filters, sort, page, column visibility, column order, pinned columns, density, row grouping, aggregation, and pivot) is written to the URL so users can share filtered views via bookmarks or links. When the URL exceeds 2 000 characters, state is automatically compressed with lz-string.
|
|
10
10
|
|
|
11
11
|
Because `StatefulDataGrid` manages filter/sort/pagination state internally, the consumer uses **refs to track the latest model values** and **fetches data from callbacks** rather than controlled state.
|
|
12
12
|
|
|
@@ -135,7 +135,33 @@ When **not** to use:
|
|
|
135
135
|
</>
|
|
136
136
|
),
|
|
137
137
|
},
|
|
138
|
-
|
|
138
|
+
{
|
|
139
|
+
feature: 'Row grouping',
|
|
140
|
+
required: false,
|
|
141
|
+
description: (
|
|
142
|
+
<>
|
|
143
|
+
<code>rowGroupingModel</code> persisted to URL via <code>_rowGrouping</code> param
|
|
144
|
+
</>
|
|
145
|
+
),
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
feature: 'Aggregation',
|
|
149
|
+
required: false,
|
|
150
|
+
description: (
|
|
151
|
+
<>
|
|
152
|
+
<code>aggregationModel</code> persisted to URL via <code>_aggregation</code> param
|
|
153
|
+
</>
|
|
154
|
+
),
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
feature: 'Pivot',
|
|
158
|
+
required: false,
|
|
159
|
+
description: (
|
|
160
|
+
<>
|
|
161
|
+
<code>pivotModel</code> persisted to URL via <code>_pivotModel</code> param. Forwarded to DataGridPremium.
|
|
162
|
+
</>
|
|
163
|
+
),
|
|
164
|
+
},
|
|
139
165
|
{
|
|
140
166
|
feature: 'URL compression',
|
|
141
167
|
required: false,
|
|
@@ -146,8 +172,7 @@ When **not** to use:
|
|
|
146
172
|
</>
|
|
147
173
|
),
|
|
148
174
|
},
|
|
149
|
-
|
|
150
|
-
]}
|
|
175
|
+
]}
|
|
151
176
|
/>
|
|
152
177
|
|
|
153
178
|
### Components
|
|
@@ -229,17 +254,20 @@ export const useRouter = () => {
|
|
|
229
254
|
|
|
230
255
|
`StatefulDataGrid` writes grid state to URL query params in a human-readable display format. The format is identical for both client-side and server-side grids.
|
|
231
256
|
|
|
232
|
-
| State | URL Parameter | Example
|
|
233
|
-
| ----------------- | --------------------------------- |
|
|
234
|
-
| Filter (string) | `field.operator=value` | `Items.contains=Bread`
|
|
235
|
-
| Filter (list) | `field.operator=a,b,c` | `Category.isAnyOf=Bakery,Pastry`
|
|
236
|
-
| Sort | `_sortColumn=field.direction` | `_sortColumn=DateTime.desc`
|
|
237
|
-
| Pagination | `_pagination=page.size.direction` | `_pagination=0.10.next`
|
|
238
|
-
| Column visibility | `_columnVisibility=col1,col2,...` | `_columnVisibility=Items,Category,Paid`
|
|
239
|
-
| Pinned columns | `_pinnedColumnsLeft=col1,col2` | `_pinnedColumnsLeft=__check__,Items`
|
|
240
|
-
| Column order | `_columnOrder=col1,col2,...` | `_columnOrder=Paid,Items,Category`
|
|
241
|
-
|
|
|
242
|
-
|
|
|
257
|
+
| State | URL Parameter | Example |
|
|
258
|
+
| ----------------- | --------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
259
|
+
| Filter (string) | `field.operator=value` | `Items.contains=Bread` |
|
|
260
|
+
| Filter (list) | `field.operator=a,b,c` | `Category.isAnyOf=Bakery,Pastry` |
|
|
261
|
+
| Sort | `_sortColumn=field.direction` | `_sortColumn=DateTime.desc` |
|
|
262
|
+
| Pagination | `_pagination=page.size.direction` | `_pagination=0.10.next` |
|
|
263
|
+
| Column visibility | `_columnVisibility=col1,col2,...` | `_columnVisibility=Items,Category,Paid` |
|
|
264
|
+
| Pinned columns | `_pinnedColumnsLeft=col1,col2` | `_pinnedColumnsLeft=__check__,Items` |
|
|
265
|
+
| Column order | `_columnOrder=col1,col2,...` | `_columnOrder=Paid,Items,Category` |
|
|
266
|
+
| Row grouping | `_rowGrouping=col1,col2` | `_rowGrouping=Category` |
|
|
267
|
+
| Aggregation | `_aggregation=col:func,...` | `_aggregation=Paid:sum,Quantity:avg` |
|
|
268
|
+
| Pivot model | `_pivotModel={json}` | `_pivotModel={"columns":["Category"],"rows":["Items"],"values":[{"field":"Paid","aggFunc":"sum"}]}` |
|
|
269
|
+
| Density | `_density=value` | `_density=compact` |
|
|
270
|
+
| Version | `v=N` | `v=1` |
|
|
243
271
|
|
|
244
272
|
### URL Compression
|
|
245
273
|
|
|
@@ -297,7 +325,7 @@ setLoading(false);
|
|
|
297
325
|
|
|
298
326
|
// Persisted states (URL + localStorage):
|
|
299
327
|
// filters, sort, pagination, column visibility, column order,
|
|
300
|
-
// pinned columns, density
|
|
328
|
+
// pinned columns, density, row grouping, aggregation, pivot
|
|
301
329
|
//
|
|
302
330
|
// URL compression:
|
|
303
331
|
// When the URL exceeds 2 000 chars, all state params are
|
|
@@ -353,11 +381,11 @@ When data fetching fails, replace the grid area with an error message and a retr
|
|
|
353
381
|
4. **Create the fetch function** — Accept filter/sort/page params, return `{ rows, totalRows }`.
|
|
354
382
|
5. **Set up refs** — `useRef` for filterModel, sortModel, page, pageSize.
|
|
355
383
|
6. **Create the toolbar** — Build a `CustomToolbar` component using `GridToolbarContainer`.
|
|
356
|
-
7. **Render StatefulDataGrid** — Pass `useRouter`, `localStorageVersion`, `initialState` (filter, sort, pagination defaults), `paginationMode="server"`, `sortingMode="server"`, `filterMode="server"`, `loading`, `rows`, `rowCount`, callbacks for `onFilterModelChange`/`onSortModelChange`/`onPaginationModelChange`.
|
|
384
|
+
7. **Render StatefulDataGrid** — Pass `useRouter`, `localStorageVersion`, `initialState` (filter, sort, pagination, row grouping, aggregation, pivot defaults), `paginationMode="server"`, `sortingMode="server"`, `filterMode="server"`, `loading`, `rows`, `rowCount`, callbacks for `onFilterModelChange`/`onSortModelChange`/`onPaginationModelChange`.
|
|
357
385
|
8. **Add bulk action bar** — Conditionally render when `selectionModel.length > 0`.
|
|
358
386
|
9. **Handle edge cases** — Loading overlay, empty state, and error state with retry.
|
|
359
387
|
10. **Set localStorageVersion** — Increment when column definitions change. Set `previousLocalStorageVersions` to clean up old keys.
|
|
360
|
-
11. **Verify** — Test pagination, filter operators, column visibility, density, column order, URL sharing, page refresh persistence. Verify that long URLs trigger compression automatically.
|
|
388
|
+
11. **Verify** — Test pagination, filter operators, column visibility, density, column order, row grouping, aggregation, pivot, URL sharing, page refresh persistence. Verify that long URLs trigger compression automatically.
|
|
361
389
|
|
|
362
390
|
## Keyboard & Accessibility
|
|
363
391
|
|
|
@@ -62,7 +62,7 @@ When **not** to use:
|
|
|
62
62
|
## State Management
|
|
63
63
|
|
|
64
64
|
<CodeBlock codeString={`import { useCallback, useEffect, useRef, useState } from 'react';
|
|
65
|
-
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-
|
|
65
|
+
import { GridFilterModel, GridSortModel } from '@mui/x-data-grid-premium';
|
|
66
66
|
|
|
67
67
|
// Active tab
|
|
68
68
|
const [activeTab, setActiveTab] = useState<string>('all');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redsift/ds-mcp-server",
|
|
3
|
-
"version": "12.5.13
|
|
3
|
+
"version": "12.5.13",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "MCP server for the Red Sift Design System — provides component lookup, prop documentation, and code generation tools for AI assistants.",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "55b7e4976e3595f1788080def19d08f5dcff2403"
|
|
41
41
|
}
|