@redsift/ds-mcp-server 12.3.1-muiv6-alpha.2

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 (258) hide show
  1. package/README.md +203 -0
  2. package/consumer-instructions/.cursorrules +80 -0
  3. package/consumer-instructions/.windsurfrules +80 -0
  4. package/consumer-instructions/CLAUDE.md +87 -0
  5. package/consumer-instructions/redsift-design-system.instructions.md +87 -0
  6. package/data/demos/patterns/crossfiltered-datagrid-page/example.tsx +750 -0
  7. package/data/demos/patterns/crossfiltered-datagrid-page/with-empty-state.tsx +111 -0
  8. package/data/demos/patterns/crossfiltered-datagrid-page/with-error.tsx +122 -0
  9. package/data/demos/patterns/crossfiltered-datagrid-page/with-loading.tsx +88 -0
  10. package/data/demos/patterns/datagrid-page/example.tsx +521 -0
  11. package/data/demos/patterns/datagrid-page/with-empty-state.tsx +80 -0
  12. package/data/demos/patterns/datagrid-page/with-error.tsx +96 -0
  13. package/data/demos/patterns/datagrid-page/with-loading.tsx +57 -0
  14. package/data/demos/patterns/drilldown-datagrid-page/example.tsx +715 -0
  15. package/data/demos/patterns/drilldown-datagrid-page/with-empty-state.tsx +113 -0
  16. package/data/demos/patterns/drilldown-datagrid-page/with-error.tsx +125 -0
  17. package/data/demos/patterns/drilldown-datagrid-page/with-loading.tsx +90 -0
  18. package/data/demos/patterns/server-datagrid-page/example.tsx +757 -0
  19. package/data/demos/patterns/server-datagrid-page/with-empty-state.tsx +107 -0
  20. package/data/demos/patterns/server-datagrid-page/with-error.tsx +107 -0
  21. package/data/demos/patterns/server-datagrid-page/with-loading.tsx +63 -0
  22. package/data/docs/components/charts/Arc.json +179 -0
  23. package/data/docs/components/charts/Arcs.json +104 -0
  24. package/data/docs/components/charts/Axis.json +269 -0
  25. package/data/docs/components/charts/Bar.json +236 -0
  26. package/data/docs/components/charts/BarChart.json +852 -0
  27. package/data/docs/components/charts/BarChartBars.json +18 -0
  28. package/data/docs/components/charts/BarChartGroupedTooltip.json +9 -0
  29. package/data/docs/components/charts/BarChartOverlay.json +34 -0
  30. package/data/docs/components/charts/BarChartSection.json +94 -0
  31. package/data/docs/components/charts/BaseBarChart.json +852 -0
  32. package/data/docs/components/charts/ChartContainerTitle.json +574 -0
  33. package/data/docs/components/charts/DataPoint.json +160 -0
  34. package/data/docs/components/charts/Dot.json +191 -0
  35. package/data/docs/components/charts/EmptyBarChart.json +852 -0
  36. package/data/docs/components/charts/EmptyLineChart.json +753 -0
  37. package/data/docs/components/charts/EmptyPieChart.json +826 -0
  38. package/data/docs/components/charts/EmptyScatterPlot.json +802 -0
  39. package/data/docs/components/charts/Legend.json +510 -0
  40. package/data/docs/components/charts/LegendItem.json +128 -0
  41. package/data/docs/components/charts/Line.json +69 -0
  42. package/data/docs/components/charts/LineChart.json +753 -0
  43. package/data/docs/components/charts/LoadingBarChart.json +852 -0
  44. package/data/docs/components/charts/LoadingLineChart.json +753 -0
  45. package/data/docs/components/charts/LoadingPieChart.json +826 -0
  46. package/data/docs/components/charts/LoadingScatterPlot.json +802 -0
  47. package/data/docs/components/charts/PieChart.json +826 -0
  48. package/data/docs/components/charts/RenderedLineChart.json +753 -0
  49. package/data/docs/components/charts/RenderedLinearBarChart.json +823 -0
  50. package/data/docs/components/charts/RenderedOrdinalBarChart.json +852 -0
  51. package/data/docs/components/charts/RenderedPieChart.json +826 -0
  52. package/data/docs/components/charts/RenderedScatterPlot.json +802 -0
  53. package/data/docs/components/charts/ScatterPlot.json +802 -0
  54. package/data/docs/components/charts/getAxisType.json +9 -0
  55. package/data/docs/components/charts/getComponentPosition.json +9 -0
  56. package/data/docs/components/dashboard/ChartEmptyState.json +42 -0
  57. package/data/docs/components/dashboard/Dashboard.json +26 -0
  58. package/data/docs/components/dashboard/DataCard.json +300 -0
  59. package/data/docs/components/dashboard/DataCardBody.json +431 -0
  60. package/data/docs/components/dashboard/DataCardHeader.json +304 -0
  61. package/data/docs/components/dashboard/DataCardListbox.json +529 -0
  62. package/data/docs/components/dashboard/DataRow.json +539 -0
  63. package/data/docs/components/dashboard/DrilldownItem.json +342 -0
  64. package/data/docs/components/dashboard/FilterableBarChart.json +83 -0
  65. package/data/docs/components/dashboard/FilterableDataGrid.json +83 -0
  66. package/data/docs/components/dashboard/FilterablePieChart.json +83 -0
  67. package/data/docs/components/dashboard/FilterableScatterPlot.json +83 -0
  68. package/data/docs/components/dashboard/PdfDocument.json +58 -0
  69. package/data/docs/components/dashboard/PdfExportButton.json +458 -0
  70. package/data/docs/components/dashboard/TimeSeriesBarChart.json +172 -0
  71. package/data/docs/components/dashboard/WithFilters.json +83 -0
  72. package/data/docs/components/design-system/ActiveDescendantListbox.json +521 -0
  73. package/data/docs/components/design-system/Alert.json +349 -0
  74. package/data/docs/components/design-system/AppBar.json +64 -0
  75. package/data/docs/components/design-system/AppContainer.json +67 -0
  76. package/data/docs/components/design-system/AppContent.json +566 -0
  77. package/data/docs/components/design-system/AppSidePanel.json +87 -0
  78. package/data/docs/components/design-system/Badge.json +293 -0
  79. package/data/docs/components/design-system/BaseBreadcrumbs.json +298 -0
  80. package/data/docs/components/design-system/BaseGrid.json +543 -0
  81. package/data/docs/components/design-system/BaseSkeleton.json +338 -0
  82. package/data/docs/components/design-system/BreadcrumbItem.json +231 -0
  83. package/data/docs/components/design-system/Breadcrumbs.json +298 -0
  84. package/data/docs/components/design-system/Button.json +402 -0
  85. package/data/docs/components/design-system/ButtonGroup.json +415 -0
  86. package/data/docs/components/design-system/ButtonLink.json +568 -0
  87. package/data/docs/components/design-system/Card.json +328 -0
  88. package/data/docs/components/design-system/CardActions.json +431 -0
  89. package/data/docs/components/design-system/CardBody.json +431 -0
  90. package/data/docs/components/design-system/CardHeader.json +428 -0
  91. package/data/docs/components/design-system/Checkbox.json +426 -0
  92. package/data/docs/components/design-system/CheckboxGroup.json +382 -0
  93. package/data/docs/components/design-system/ConditionalWrapper.json +40 -0
  94. package/data/docs/components/design-system/DetailedCard.json +401 -0
  95. package/data/docs/components/design-system/DetailedCardCollapsibleSectionItems.json +29 -0
  96. package/data/docs/components/design-system/DetailedCardHeader.json +37 -0
  97. package/data/docs/components/design-system/DetailedCardSection.json +90 -0
  98. package/data/docs/components/design-system/DetailedCardSectionItem.json +109 -0
  99. package/data/docs/components/design-system/Flexbox.json +523 -0
  100. package/data/docs/components/design-system/FocusWithinGroup.json +9 -0
  101. package/data/docs/components/design-system/Grid.json +543 -0
  102. package/data/docs/components/design-system/GridItem.json +388 -0
  103. package/data/docs/components/design-system/Heading.json +390 -0
  104. package/data/docs/components/design-system/Icon.json +325 -0
  105. package/data/docs/components/design-system/IconButton.json +371 -0
  106. package/data/docs/components/design-system/IconButtonLink.json +588 -0
  107. package/data/docs/components/design-system/Item.json +554 -0
  108. package/data/docs/components/design-system/Link.json +552 -0
  109. package/data/docs/components/design-system/LinkButton.json +397 -0
  110. package/data/docs/components/design-system/Listbox.json +529 -0
  111. package/data/docs/components/design-system/Number.json +773 -0
  112. package/data/docs/components/design-system/NumberField.json +594 -0
  113. package/data/docs/components/design-system/Pill.json +378 -0
  114. package/data/docs/components/design-system/ProgressBar.json +121 -0
  115. package/data/docs/components/design-system/RadarSvgLinearGradient.json +9 -0
  116. package/data/docs/components/design-system/Radio.json +415 -0
  117. package/data/docs/components/design-system/RadioGroup.json +382 -0
  118. package/data/docs/components/design-system/RenderedListboxItem.json +18 -0
  119. package/data/docs/components/design-system/RovingTabindexListbox.json +521 -0
  120. package/data/docs/components/design-system/Shield.json +360 -0
  121. package/data/docs/components/design-system/SideNavigationMenu.json +144 -0
  122. package/data/docs/components/design-system/SideNavigationMenuBar.json +89 -0
  123. package/data/docs/components/design-system/SideNavigationMenuItem.json +319 -0
  124. package/data/docs/components/design-system/Skeleton.json +338 -0
  125. package/data/docs/components/design-system/SkeletonCircle.json +338 -0
  126. package/data/docs/components/design-system/SkeletonText.json +371 -0
  127. package/data/docs/components/design-system/Spinner.json +291 -0
  128. package/data/docs/components/design-system/Switch.json +415 -0
  129. package/data/docs/components/design-system/SwitchGroup.json +382 -0
  130. package/data/docs/components/design-system/Text.json +418 -0
  131. package/data/docs/components/design-system/TextArea.json +501 -0
  132. package/data/docs/components/design-system/TextField.json +539 -0
  133. package/data/docs/components/design-system/sizeToDimension.json +9 -0
  134. package/data/docs/components/pickers/BaseCombobox.json +320 -0
  135. package/data/docs/components/pickers/BaseComboboxContent.json +453 -0
  136. package/data/docs/components/pickers/BaseMenuButton.json +240 -0
  137. package/data/docs/components/pickers/BaseMenuButtonContent.json +442 -0
  138. package/data/docs/components/pickers/BaseSelect.json +258 -0
  139. package/data/docs/components/pickers/Combobox.json +320 -0
  140. package/data/docs/components/pickers/ComboboxContent.json +453 -0
  141. package/data/docs/components/pickers/ComboboxContentFooter.json +431 -0
  142. package/data/docs/components/pickers/ComboboxContentHeader.json +431 -0
  143. package/data/docs/components/pickers/ComboboxContentListbox.json +541 -0
  144. package/data/docs/components/pickers/ComboboxTrigger.json +336 -0
  145. package/data/docs/components/pickers/Item.json +554 -0
  146. package/data/docs/components/pickers/MenuButton.json +240 -0
  147. package/data/docs/components/pickers/MenuButtonContent.json +442 -0
  148. package/data/docs/components/pickers/MenuButtonContentFooter.json +431 -0
  149. package/data/docs/components/pickers/MenuButtonContentHeader.json +431 -0
  150. package/data/docs/components/pickers/MenuButtonContentMenu.json +523 -0
  151. package/data/docs/components/pickers/MenuButtonTrigger.json +287 -0
  152. package/data/docs/components/pickers/Select.json +258 -0
  153. package/data/docs/components/pickers/SelectContent.json +442 -0
  154. package/data/docs/components/pickers/SelectTrigger.json +298 -0
  155. package/data/docs/components/popovers/BaseDialog.json +114 -0
  156. package/data/docs/components/popovers/BaseDialogContent.json +21 -0
  157. package/data/docs/components/popovers/BasePopover.json +171 -0
  158. package/data/docs/components/popovers/BaseToggletip.json +184 -0
  159. package/data/docs/components/popovers/BaseTooltip.json +121 -0
  160. package/data/docs/components/popovers/Button.json +402 -0
  161. package/data/docs/components/popovers/ButtonLink.json +568 -0
  162. package/data/docs/components/popovers/Dialog.json +114 -0
  163. package/data/docs/components/popovers/DialogContent.json +21 -0
  164. package/data/docs/components/popovers/DialogContentActions.json +442 -0
  165. package/data/docs/components/popovers/DialogContentBody.json +442 -0
  166. package/data/docs/components/popovers/DialogContentHeader.json +76 -0
  167. package/data/docs/components/popovers/DialogTrigger.json +276 -0
  168. package/data/docs/components/popovers/IconButton.json +371 -0
  169. package/data/docs/components/popovers/IconButtonLink.json +588 -0
  170. package/data/docs/components/popovers/Link.json +552 -0
  171. package/data/docs/components/popovers/LinkButton.json +397 -0
  172. package/data/docs/components/popovers/Popover.json +171 -0
  173. package/data/docs/components/popovers/PopoverContent.json +442 -0
  174. package/data/docs/components/popovers/PopoverTrigger.json +276 -0
  175. package/data/docs/components/popovers/Toast.json +145 -0
  176. package/data/docs/components/popovers/ToastContainer.json +122 -0
  177. package/data/docs/components/popovers/Toggletip.json +184 -0
  178. package/data/docs/components/popovers/ToggletipContent.json +402 -0
  179. package/data/docs/components/popovers/ToggletipTrigger.json +276 -0
  180. package/data/docs/components/popovers/Tooltip.json +121 -0
  181. package/data/docs/components/popovers/TooltipContent.json +402 -0
  182. package/data/docs/components/popovers/TooltipTrigger.json +276 -0
  183. package/data/docs/components/products/Dialog.json +106 -0
  184. package/data/docs/components/products/MenuButton.json +232 -0
  185. package/data/docs/components/products/PulsedRadarImage.json +9 -0
  186. package/data/docs/components/products/RadarButton.json +402 -0
  187. package/data/docs/components/products/RadarItem.json +554 -0
  188. package/data/docs/components/table/ControlledPagination.json +9 -0
  189. package/data/docs/components/table/DataGrid.json +93 -0
  190. package/data/docs/components/table/GridToolbarFilterSemanticField.json +69 -0
  191. package/data/docs/components/table/ServerSideControlledPagination.json +9 -0
  192. package/data/docs/components/table/StatefulDataGrid.json +117 -0
  193. package/data/docs/components/table/TextCell.json +118 -0
  194. package/data/docs/components/table/Toolbar.json +145 -0
  195. package/data/docs/components/table/ToolbarWrapper.json +9 -0
  196. package/data/docs/components-index.json +1206 -0
  197. package/data/docs/components.json +55694 -0
  198. package/data/docs/llms-full.txt +8012 -0
  199. package/data/docs/llms.txt +234 -0
  200. package/data/docs/patterns-catalog.md +359 -0
  201. package/data/docs/patterns.json +712 -0
  202. package/data/metadata.json +4 -0
  203. package/data/patterns/crossfiltered-datagrid-page.mdx +386 -0
  204. package/data/patterns/datagrid-page.mdx +214 -0
  205. package/data/patterns/drilldown-datagrid-page.mdx +291 -0
  206. package/data/patterns/server-datagrid-page.mdx +301 -0
  207. package/data/tokens/properties/components/dark-components.json +1108 -0
  208. package/data/tokens/properties/components/light-components.json +1108 -0
  209. package/data/tokens/properties/core/border-radius.json +3 -0
  210. package/data/tokens/properties/core/color.json +280 -0
  211. package/data/tokens/properties/core/layout.json +14 -0
  212. package/data/tokens/properties/core/typography.json +199 -0
  213. package/data/tokens/redsift-design-tokens.css +1391 -0
  214. package/dist/data-store.d.ts +47 -0
  215. package/dist/data-store.d.ts.map +1 -0
  216. package/dist/data-store.js +152 -0
  217. package/dist/data-store.js.map +1 -0
  218. package/dist/index.d.ts +16 -0
  219. package/dist/index.d.ts.map +1 -0
  220. package/dist/index.js +50 -0
  221. package/dist/index.js.map +1 -0
  222. package/dist/init.d.ts +14 -0
  223. package/dist/init.d.ts.map +1 -0
  224. package/dist/init.js +137 -0
  225. package/dist/init.js.map +1 -0
  226. package/dist/paths.d.ts +30 -0
  227. package/dist/paths.d.ts.map +1 -0
  228. package/dist/paths.js +53 -0
  229. package/dist/paths.js.map +1 -0
  230. package/dist/pattern-store.d.ts +41 -0
  231. package/dist/pattern-store.d.ts.map +1 -0
  232. package/dist/pattern-store.js +177 -0
  233. package/dist/pattern-store.js.map +1 -0
  234. package/dist/prompts.d.ts +14 -0
  235. package/dist/prompts.d.ts.map +1 -0
  236. package/dist/prompts.js +762 -0
  237. package/dist/prompts.js.map +1 -0
  238. package/dist/resources.d.ts +14 -0
  239. package/dist/resources.d.ts.map +1 -0
  240. package/dist/resources.js +482 -0
  241. package/dist/resources.js.map +1 -0
  242. package/dist/scaffold.d.ts +31 -0
  243. package/dist/scaffold.d.ts.map +1 -0
  244. package/dist/scaffold.js +239 -0
  245. package/dist/scaffold.js.map +1 -0
  246. package/dist/token-store.d.ts +70 -0
  247. package/dist/token-store.d.ts.map +1 -0
  248. package/dist/token-store.js +196 -0
  249. package/dist/token-store.js.map +1 -0
  250. package/dist/tools.d.ts +15 -0
  251. package/dist/tools.d.ts.map +1 -0
  252. package/dist/tools.js +491 -0
  253. package/dist/tools.js.map +1 -0
  254. package/dist/types.d.ts +108 -0
  255. package/dist/types.d.ts.map +1 -0
  256. package/dist/types.js +17 -0
  257. package/dist/types.js.map +1 -0
  258. package/package.json +39 -0
@@ -0,0 +1,234 @@
1
+ # Red Sift Design System
2
+
3
+ > A React component library for Red Sift applications built with TypeScript and styled-components.
4
+
5
+ ## Overview
6
+
7
+ The Red Sift Design System provides reusable UI components including forms, navigation, charts, tables, and data visualization components.
8
+
9
+ - **Framework:** React 18 with TypeScript
10
+ - **Styling:** styled-components 6.x
11
+ - **Documentation:** https://design-system.redsift.io
12
+
13
+ ## Packages
14
+
15
+ - **@redsift/design-system** (60 components): Core UI components (buttons, forms, navigation, layout)
16
+ - **@redsift/popovers** (28 components): Popover, tooltip, dialog, and toast components
17
+ - **@redsift/pickers** (21 components): Selection components (combobox, menu button, select)
18
+ - **@redsift/charts** (32 components): D3.js-based chart components (bar, line, pie, scatter)
19
+ - **@redsift/table** (8 components): DataGrid components built on MUI X Data Grid
20
+ - **@redsift/dashboard** (16 components): Dashboard components with crossfilter integration
21
+ - **@redsift/products** (7 components): Product-specific component implementations
22
+
23
+ ## Components
24
+
25
+ ### design-system
26
+
27
+ - **ActiveDescendantListbox** (19 props)
28
+ - **Alert** (7 props): Alert displays a short, important message that attracts the user's attention
29
+ - **AppBar** (6 props): AppBar is the top navigation bar of the application. It displays the page title
30
+ - **AppContainer** (5 props): The AppContainer component.
31
+ - **AppContent** (11 props): AppContent is the main content area of a Red Sift application. It automatically
32
+ - **AppSidePanel** (8 props): AppSidePanel is the collapsible side navigation panel of a Red Sift application.
33
+ - **Badge** (5 props): Badge displays a small status indicator or count. Badges have two variants:
34
+ - **BaseBreadcrumbs** (2 props): Breadcrumbs display a list of links to parent pages in hierarchical order,
35
+ - **BaseGrid** (11 props): Grid provides a CSS Grid container for two-dimensional layouts with rows
36
+ - **BaseSkeleton** (2 props): Skeleton displays a placeholder animation while content is loading.
37
+ - **BreadcrumbItem** (4 props): BreadcrumbItem represents a single link in a Breadcrumbs navigation.
38
+ - **Breadcrumbs** (2 props)
39
+ - **Button** (12 props): The Button is a semantic button that looks like a button.
40
+ - **ButtonGroup** (3 props): ButtonGroup combines multiple related buttons into a single visual unit.
41
+ - **ButtonLink** (11 props): ButtonLink is a semantic link (`<a>`) styled to look like a button.
42
+ - **Card** (5 props)
43
+ - **CardActions** (10 props): CardActions is a container for action buttons at the bottom of a Card.
44
+ - **CardBody** (10 props): CardBody is the main content area of a Card. It can contain any content.
45
+ - **CardHeader** (6 props): CardHeader displays the title and optional subtitle of a Card.
46
+ - **Checkbox** (15 props): Checkbox allows users to select one or more items from a set, or to mark an
47
+ - **CheckboxGroup** (11 props): CheckboxGroup manages a group of related Checkbox components. It handles
48
+ - **ConditionalWrapper** (3 props): ConditionalWrapper conditionally wraps children in a wrapper component.
49
+ - **DetailedCard** (10 props)
50
+ - **DetailedCardCollapsibleSectionItems** (2 props): The DetailedCardCollapsibleSectionItems Section component.
51
+ - **DetailedCardHeader** (3 props): The DetailedCardHeader component.
52
+ - **DetailedCardSection** (6 props): The DetailedCardSection component.
53
+ - **DetailedCardSectionItem** (9 props): The DetailedCardSectionItems component.
54
+ - **Flexbox** (19 props): Flexbox provides a CSS Flexbox container with convenient props for common
55
+ - **FocusWithinGroup** (0 props): The FocusWithinGroup component.
56
+ - **Grid** (22 props)
57
+ - **GridItem** (9 props): GridItem is a child of Grid that can span multiple columns or rows.
58
+ - **Heading** (9 props): Heading renders semantic HTML heading elements (h1-h6) with consistent styling.
59
+ - **Icon** (8 props): Icon displays SVG icons from the Material Design Icons library or custom paths.
60
+ - **IconButton** (9 props): IconButton is a button containing only an icon, without text.
61
+ - **IconButtonLink** (13 props): IconButtonLink is a semantic link (`<a>`) styled to look like an icon button.
62
+ - **Item** (22 props): The Item component.
63
+ - **Link** (8 props): Link is a semantic link (`<a>`) styled as a text link. Use for internal
64
+ - **LinkButton** (10 props): LinkButton is a semantic button (`<button>`) styled to look like a text link.
65
+ - **Listbox** (20 props): Listbox displays a list of selectable options. Supports single or multiple
66
+ - **Number** (33 props): Number formats and displays numeric values with locale-aware formatting.
67
+ - **NumberField** (35 props): NumberField allows users to enter and adjust numeric values with increment
68
+ - **Pill** (8 props): Pill displays a small piece of information as a colored label. Commonly used
69
+ - **ProgressBar** (11 props): ProgressBar displays the progress of a task or operation as a horizontal bar.
70
+ - **Radio** (14 props): Radio allows users to select exactly one option from a set. Typically used
71
+ - **RadioGroup** (11 props): RadioGroup manages a group of Radio components, ensuring only one can be
72
+ - **RenderedListboxItem** (1 props)
73
+ - **RovingTabindexListbox** (19 props)
74
+ - **Shield** (7 props): The Shield component.
75
+ - **SideNavigationMenu** (14 props): SideNavigationMenu provides hierarchical navigation within the AppSidePanel.
76
+ - **SideNavigationMenuBar** (8 props): The SideNavigationMenuBar component.
77
+ - **SideNavigationMenuItem** (13 props): The SideNavigationMenuItem component.
78
+ - **Skeleton** (2 props)
79
+ - **SkeletonCircle** (2 props): The SkeletonCircle component.
80
+ - **SkeletonText** (5 props): The SkeletonText component.
81
+ - **Spinner** (6 props): Spinner displays a loading indicator for async operations.
82
+ - **Switch** (14 props): Switch is a toggle control for binary options (on/off, enabled/disabled).
83
+ - **SwitchGroup** (11 props): SwitchGroup manages a group of related Switch components. Provides a shared
84
+ - **Text** (11 props): Text renders text content with consistent styling. By default renders a
85
+ - **TextArea** (23 props): TextArea allows users to enter multi-line text. Supports auto-growing height,
86
+ - **TextField** (26 props): TextField allows users to enter single-line text input. Supports validation,
87
+
88
+ ### popovers
89
+
90
+ - **BaseDialog** (10 props): Dialog displays modal content that requires user attention or interaction.
91
+ - **BaseDialogContent** (1 props): The DialogContent component.
92
+ - **BasePopover** (15 props): Popover displays contextual content anchored to a trigger element.
93
+ - **BaseToggletip** (17 props): Toggletip displays supplementary content toggled by click/tap.
94
+ - **BaseTooltip** (11 props): Tooltip displays brief informational text on hover or focus.
95
+ - **Button** (12 props)
96
+ - **ButtonLink** (11 props)
97
+ - **Dialog** (10 props)
98
+ - **DialogContent** (1 props)
99
+ - **DialogContentActions** (11 props): The DialogContentActions component.
100
+ - **DialogContentBody** (11 props): The DialogContentBody component.
101
+ - **DialogContentHeader** (7 props): The DialogContentHeader component.
102
+ - **DialogTrigger** (0 props): The DialogTrigger component.
103
+ - **IconButton** (9 props)
104
+ - **IconButtonLink** (13 props)
105
+ - **Link** (8 props)
106
+ - **LinkButton** (10 props)
107
+ - **Popover** (15 props)
108
+ - **PopoverContent** (11 props): The PopoverContent component.
109
+ - **PopoverTrigger** (0 props): The PopoverTrigger component.
110
+ - **Toast** (4 props): Toast displays non-blocking feedback messages. Use with ToastContainer
111
+ - **ToastContainer** (10 props): ToastContainer provides the root element for toast notifications.
112
+ - **Toggletip** (17 props)
113
+ - **ToggletipContent** (11 props): The ToggletipContent component.
114
+ - **ToggletipTrigger** (0 props): The ToggletipTrigger component.
115
+ - **Tooltip** (11 props)
116
+ - **TooltipContent** (11 props): The TooltipContent component.
117
+ - **TooltipTrigger** (0 props): The TooltipTrigger component.
118
+
119
+ ### pickers
120
+
121
+ - **BaseCombobox** (31 props): Combobox combines a text input with a filterable dropdown list.
122
+ - **BaseComboboxContent** (12 props): The ComboboxContent component.
123
+ - **BaseMenuButton** (22 props): MenuButton displays a button that opens a menu of actions.
124
+ - **BaseMenuButtonContent** (11 props): The MenuButtonContent component.
125
+ - **BaseSelect** (24 props): Select allows users to choose a single option from a dropdown list.
126
+ - **Combobox** (31 props)
127
+ - **ComboboxContent** (12 props)
128
+ - **ComboboxContentFooter** (10 props): The ComboboxContentFooter component.
129
+ - **ComboboxContentHeader** (10 props): The ComboboxContentHeader component.
130
+ - **ComboboxContentListbox** (13 props): The ComboboxContentListbox component.
131
+ - **ComboboxTrigger** (6 props): The ComboboxTrigger component.
132
+ - **Item** (22 props): The Item component.
133
+ - **MenuButton** (22 props)
134
+ - **MenuButtonContent** (11 props)
135
+ - **MenuButtonContentFooter** (10 props): The MenuButtonContentFooter component.
136
+ - **MenuButtonContentHeader** (10 props): The MenuButtonContentHeader component.
137
+ - **MenuButtonContentMenu** (12 props): The MenuButtonContentMenu component.
138
+ - **MenuButtonTrigger** (1 props): The MenuButtonTrigger component.
139
+ - **Select** (24 props)
140
+ - **SelectContent** (11 props): The SelectContent component.
141
+ - **SelectTrigger** (2 props): The SelectTrigger component.
142
+
143
+ ### charts
144
+
145
+ - **Arc** (19 props)
146
+ - **Arcs** (10 props)
147
+ - **Axis** (28 props)
148
+ - **Bar** (26 props)
149
+ - **BarChart** (54 props)
150
+ - **BarChartBars** (1 props)
151
+ - **BarChartGroupedTooltip** (0 props)
152
+ - **BarChartOverlay** (3 props)
153
+ - **BarChartSection** (9 props)
154
+ - **BaseBarChart** (54 props): BarChart visualizes categorical data with rectangular bars.
155
+ - **ChartContainerTitle** (26 props)
156
+ - **DataPoint** (17 props)
157
+ - **Dot** (20 props)
158
+ - **EmptyBarChart** (54 props)
159
+ - **EmptyLineChart** (44 props)
160
+ - **EmptyPieChart** (50 props)
161
+ - **EmptyScatterPlot** (49 props)
162
+ - **Legend** (18 props)
163
+ - **LegendItem** (13 props)
164
+ - **Line** (6 props)
165
+ - **LineChart** (44 props): LineChart displays trends over time or continuous data.
166
+ - **LoadingBarChart** (54 props)
167
+ - **LoadingLineChart** (44 props)
168
+ - **LoadingPieChart** (50 props)
169
+ - **LoadingScatterPlot** (49 props)
170
+ - **PieChart** (50 props): PieChart displays proportional data as slices of a circle.
171
+ - **RenderedLinearBarChart** (51 props)
172
+ - **RenderedLineChart** (44 props)
173
+ - **RenderedOrdinalBarChart** (54 props)
174
+ - **RenderedPieChart** (50 props)
175
+ - **RenderedScatterPlot** (49 props)
176
+ - **ScatterPlot** (49 props): ScatterPlot displays relationships between two numeric variables.
177
+
178
+ ### table
179
+
180
+ - **ControlledPagination** (0 props)
181
+ - **DataGrid** (9 props): DataGrid displays tabular data with sorting, filtering, pagination, and row selection.
182
+ - **GridToolbarFilterSemanticField** (7 props): The GridToolbarFilterSemanticField component.
183
+ - **ServerSideControlledPagination** (0 props)
184
+ - **StatefulDataGrid** (12 props): StatefulDataGrid extends DataGrid with automatic state persistence to localStorage.
185
+ - **TextCell** (6 props): The Cell component.
186
+ - **Toolbar** (15 props): ------
187
+ - **ToolbarWrapper** (0 props)
188
+
189
+ ### dashboard
190
+
191
+ - **ChartEmptyState** (4 props)
192
+ - **Dashboard** (2 props): Dashboard provides a context for connected, filterable visualizations.
193
+ - **DataCard** (2 props)
194
+ - **DataCardBody** (10 props): DataCardBody is the main content area of a DataCard 。
195
+ - **DataCardHeader** (3 props): DataCardHeader displays an icon and title that floats on top of
196
+ - **DataCardListbox** (20 props): DataCardListbox is a styled Listbox for use inside a DataCard.
197
+ - **DataRow** (9 props): DataRow displays a formatted number alongside a legend label.
198
+ - **DrilldownItem** (7 props): DrilldownItem displays a numeric value with a legend label and an optional
199
+ - **FilterableBarChart** (8 props)
200
+ - **FilterableDataGrid** (8 props)
201
+ - **FilterablePieChart** (8 props)
202
+ - **FilterableScatterPlot** (8 props)
203
+ - **PdfDocument** (6 props)
204
+ - **PdfExportButton** (19 props)
205
+ - **TimeSeriesBarChart** (17 props)
206
+ - **WithFilters** (8 props)
207
+
208
+ ### products
209
+
210
+ - **Dialog** (10 props): RadarDialog displays Radar AI interactions in a branded modal dialog.
211
+ - **Dialog** (9 props)
212
+ - **MenuButton** (22 props): The RadarMenuButton component.
213
+ - **MenuButton** (21 props): The RadarSimpleMenuButton component.
214
+ - **PulsedRadarImage** (0 props)
215
+ - **RadarButton** (12 props): RadarButton is a pre-styled button for Radar AI features.
216
+ - **RadarItem** (22 props): The RadarItem component.
217
+
218
+ ## Links
219
+
220
+ - [Full Documentation](llms-full.txt): Complete component documentation with all props
221
+ - [Components JSON](components.json): Machine-readable component data
222
+ - [Patterns JSON](patterns.json): Machine-readable composition pattern data
223
+ - [Storybook](https://design-system.redsift.io/storybook): Interactive component examples
224
+
225
+ ## Composition Patterns
226
+
227
+ Proven component groupings for common UI scenarios, extracted from production applications.
228
+
229
+ | Pattern | Components | Packages |
230
+ |---------|-----------|----------|
231
+ | Datagrid Page | DataGrid, TextCell, StatefulDataGrid, Pill, Button, Flexbox, Text, Badge | @redsift/table, @redsift/design-system, @mui/x-data-grid-pro |
232
+ | Server Datagrid Page | DataGrid, TextCell, Pill, Button, Flexbox, Text, Badge, Icon, IconButtonLink | @redsift/table, @redsift/design-system, @mui/x-data-grid-pro |
233
+
234
+ For detailed pattern documentation with demos, visit: https://design-system.redsift.io/patterns/
@@ -0,0 +1,359 @@
1
+ # Composition Patterns
2
+
3
+ Page-level UI patterns observed across Red Sift product applications (OnDMARC, Brand Trust, Certificates).
4
+ Each pattern documents which Design System components to combine and how to lay them out to build a complete page.
5
+ These patterns serve as implementation specs — they give LLMs and developers everything needed to build a page from scratch.
6
+
7
+ ---
8
+
9
+ ## Datagrid Page
10
+
11
+ **When to use:**
12
+
13
+ - You need a filterable, sortable, paginated table of records
14
+ - The full dataset can be loaded upfront (typically under ~1,000 rows)
15
+ - All filtering, sorting, and pagination can happen client-side in the browser
16
+ - You want built-in column visibility, density, export, and quick search with zero backend work
17
+ - You need optional bulk selection with contextual action buttons
18
+
19
+ **When NOT to use:**
20
+
21
+ - The dataset has thousands or millions of rows — use **Server Datagrid Page** instead
22
+ - Sorting or filtering logic must live on the backend — use **Server Datagrid Page** instead
23
+
24
+ **Anatomy:**
25
+
26
+ 1. Toolbar — Flexbox wrapping GridToolbarContainer with filter, columns, density, export, quick search controls
27
+ 2. DataGrid — the table itself, configured with autoHeight, pagination, checkboxSelection, and GridColDef[] columns
28
+ 3. Bulk Action Bar — Flexbox row shown when selectionModel.length > 0, with Pill (count) and action Buttons
29
+
30
+ **Key imports:** `DataGrid`, `TextCell`, `StatefulDataGrid` from `@redsift/table`; `GridColDef`, `GridFilterModel`, `GridRowSelectionModel` from `@mui/x-data-grid-pro`; `Pill`, `Button`, `Flexbox` from `@redsift/design-system`
31
+ **Components:** DataGrid, TextCell, StatefulDataGrid (from @redsift/table), Flexbox, Button, Pill, Text, Badge, Icon, IconButton, IconButtonLink (from @redsift/design-system)
32
+ **Layout:** DataGrid with `autoHeight`, `pagination`, `pageSize`, built-in Toolbar (Columns | Filters | Density | Export | Search via `componentsProps.toolbar.showQuickFilter`). Columns use `GridColDef[]` with `type: 'rsString'` / `'rsNumber'` / `'rsSingleSelect'`, `renderCell` returning `TextCell`, `Pill`, `Badge`. Optional bulk actions bar above grid shown when `selectionModel.length > 0`.
33
+
34
+ **Features:**
35
+
36
+ | Feature | Required | Description |
37
+ | --------------------- | -------- | --------------------------------------------------------------------------------------------------- |
38
+ | Column definitions | Yes | GridColDef[] with custom types: rsString, rsNumber, rsSingleSelect, rsMultipleSelect, boolean, date |
39
+ | Toolbar | Yes | Built-in toolbar with filter, columns, density, export, and quick search controls |
40
+ | Pagination | Yes | Client-side pagination with configurable page size |
41
+ | Sorting | Yes | Client-side column sorting |
42
+ | Filtering | Yes | Client-side column filtering |
43
+ | Custom cell renderers | Yes | renderCell returning TextCell, Pill, Icon, IconButtonLink |
44
+ | Checkbox selection | No | checkboxSelection + rowSelectionModel + onRowSelectionModelChange |
45
+ | Bulk action bar | No | Contextual buttons shown when rows are selected |
46
+ | Actions column | No | Column with IconButtonLink for row-level navigation |
47
+ | Quick search | No | GridToolbarQuickFilter for text search across all columns |
48
+
49
+ **Data Contract:**
50
+
51
+ ```tsx
52
+ type Row = {
53
+ id: string;
54
+ label: string;
55
+ active: boolean;
56
+ status: 'active' | 'warning' | 'critical' | 'expired';
57
+ category: string;
58
+ score: number;
59
+ expiry: string;
60
+ tags: string[];
61
+ };
62
+ ```
63
+
64
+ **Implementation Checklist:**
65
+
66
+ 1. Define your row type — Create a TypeScript type Row. Every row must have a unique id field.
67
+ 2. Define column definitions — Create a GridColDef[] array with RS custom column types. Add renderCell for rich content.
68
+ 3. Create the toolbar — Build a CustomToolbar using GridToolbarContainer.
69
+ 4. Set up state — Add useState<GridSelectionModel>([]) for checkbox selection.
70
+ 5. Render the DataGrid — Pass rows, columns, autoHeight, pagination, pageSize, rowsPerPageOptions, checkboxSelection.
71
+ 6. Add bulk action bar — Conditionally render when selectionModel.length > 0.
72
+ 7. Handle edge cases — Add loading, empty, and error states.
73
+ 8. Verify — Test pagination breakpoints, filter operators, column visibility, density, and export.
74
+
75
+ **Variants:** Loading State, Empty State, Error State
76
+ **Related:** Server Datagrid Page — use when data is too large or filtering must be server-side
77
+ **Demo:** [Datagrid Page](/patterns/datagrid-page)
78
+
79
+ ---
80
+
81
+ ## Server Datagrid Page
82
+
83
+ **When to use:**
84
+
85
+ - The dataset has thousands or millions of records that cannot be loaded into the browser
86
+ - Filtering, sorting, or pagination logic must live on the backend (ElasticSearch, SQL, API)
87
+ - You need the server to return the total matching count alongside the current page of results
88
+ - Filter changes should be debounced to avoid excessive requests during rapid typing
89
+
90
+ **When NOT to use:**
91
+
92
+ - The dataset is small enough to load entirely (under ~1,000 rows) — use **Datagrid Page** instead
93
+ - All data is available upfront and filtering can happen in the browser — use **Datagrid Page** instead
94
+
95
+ **Anatomy:**
96
+
97
+ 1. Toolbar — Flexbox wrapping GridToolbarContainer with filter, columns, density, export, quick search controls
98
+ 2. DataGrid — the table configured with paginationMode='server', sortingMode='server', filterMode='server', loading, and rowCount
99
+ 3. Bulk Action Bar — Flexbox row shown when selectionModel.length > 0, with Pill (count) and action Buttons
100
+
101
+ **Key imports:** `DataGrid`, `TextCell` from `@redsift/table`; `GridColDef`, `GridFilterModel`, `GridSortModel`, `GridSelectionModel` from `@mui/x-data-grid-pro`; `Pill`, `Button`, `Flexbox`, `Icon`, `IconButtonLink` from `@redsift/design-system`
102
+ **Components:** DataGrid, TextCell (from @redsift/table), Flexbox, Button, Pill, Text, Badge, Icon, IconButton, IconButtonLink (from @redsift/design-system)
103
+ **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.
104
+
105
+ **Features:**
106
+
107
+ | Feature | Required | Description |
108
+ | ------------------------ | -------- | ------------------------------------------------------------------------ |
109
+ | Server-side pagination | Yes | paginationMode='server' with controlled page, pageSize, rowCount |
110
+ | Server-side sorting | Yes | sortingMode='server' with controlled sortModel + onSortModelChange |
111
+ | Server-side filtering | Yes | filterMode='server' with controlled filterModel + onFilterModelChange |
112
+ | Loading overlay | Yes | loading prop set to true during fetches |
113
+ | Row count | Yes | rowCount prop set to total matching records from server response |
114
+ | Debounced filter changes | Yes | 300ms debounce on onFilterModelChange |
115
+ | Column definitions | Yes | GridColDef[] with custom types |
116
+ | Toolbar | Yes | Built-in toolbar with filter, columns, density, export, and quick search |
117
+ | Custom cell renderers | Yes | renderCell returning TextCell, Pill, Icon, IconButtonLink |
118
+ | Checkbox selection | No | checkboxSelection + rowSelectionModel |
119
+ | Bulk action bar | No | Contextual buttons shown when rows are selected |
120
+ | Quick search | No | GridToolbarQuickFilter with server-side text search |
121
+
122
+ **State Hooks:**
123
+
124
+ | Hook | Type | Initial | Description |
125
+ | --------------- | ------------------------------------- | ------------- | ------------------------------------------ |
126
+ | rows | Row[] | [] | Rows returned from server for current page |
127
+ | totalRows | number | 0 | Total matching records |
128
+ | loading | boolean | true | Whether a fetch is in progress |
129
+ | page | number | 0 | 0-based current page index |
130
+ | pageSize | number | 10 | Rows per page |
131
+ | sortModel | GridSortModel | [] | Current sort configuration |
132
+ | filterModel | GridFilterModel | { items: [] } | Current filter configuration |
133
+ | selectionModel | GridSelectionModel | [] | Checked rows |
134
+ | quickFilterText | string | '' | Quick search text |
135
+ | debounceRef | useRef<ReturnType<typeof setTimeout>> | undefined | Debounce timer ref |
136
+
137
+ **Data Contract:**
138
+
139
+ ```tsx
140
+ type Row = {
141
+ id: string;
142
+ label: string;
143
+ active: boolean;
144
+ status: 'active' | 'warning' | 'critical' | 'expired';
145
+ category: string;
146
+ score: number;
147
+ expiry: string;
148
+ tags: string[];
149
+ };
150
+
151
+ type FetchParams = {
152
+ page: number;
153
+ pageSize: number;
154
+ sortModel: GridSortModel;
155
+ filterModel: GridFilterModel;
156
+ quickFilterText: string;
157
+ };
158
+
159
+ type FetchResult = {
160
+ rows: Row[];
161
+ totalRows: number;
162
+ };
163
+ ```
164
+
165
+ **Implementation Checklist:**
166
+
167
+ 1. Define your row type. Every row must have a unique id field.
168
+ 2. Create your fetch function — implement async FetchParams → FetchResult. If using React Query, wrap in useQuery.
169
+ 3. Define column definitions with RS custom column types. Add renderCell for rich content.
170
+ 4. Create the toolbar using GridToolbarContainer.
171
+ 5. Set up all state hooks: rows, totalRows, loading, page, pageSize, sortModel, filterModel, selectionModel, quickFilterText, debounce ref.
172
+ 6. Wire the fetch effect — useEffect triggers on page, pageSize, sortModel, filterModel, quickFilterText changes.
173
+ 7. Configure the DataGrid with paginationMode='server', sortingMode='server', filterMode='server', loading, rowCount.
174
+ 8. Debounce filter changes — 300ms setTimeout in onFilterModelChange. Reset to page 0 on filter change.
175
+ 9. Add bulk action bar — conditionally render when selectionModel.length > 0.
176
+ 10. Handle edge cases — loading, empty (custom NoRowsOverlay), and error states.
177
+ 11. Verify — Test page navigation, sort toggling, filter operators, debounce, loading overlay, empty results, error recovery.
178
+
179
+ **Key props:** `paginationMode="server"` + `page` + `pageSize` + `onPageChange` + `onPageSizeChange` + `rowCount` for pagination. `sortingMode="server"` + `sortModel` + `onSortModelChange` for sorting. `filterMode="server"` + `filterModel` + `onFilterModelChange` for filtering. `loading` for the built-in loading overlay during fetches. Filter changes should be debounced (~300ms) to avoid excessive requests.
180
+ **Mock server pattern:** A self-contained `fakeFetch` function simulates a 400ms network round-trip. It receives `{ page, pageSize, sortModel, filterModel }`, applies filtering (string, number, date, single-select, multi-select, boolean operators), sorting, and pagination server-side, then returns `{ rows, totalRows }`.
181
+ **Variants:** Loading State, Empty State, Error State
182
+ **Related:** Datagrid Page — use when all data can be loaded upfront and filtering/sorting can happen client-side
183
+ **Demo:** [Server Datagrid Page](/patterns/server-datagrid-page)
184
+
185
+ ---
186
+
187
+ ## Drilldown Datagrid Page
188
+
189
+ **When to use:**
190
+
191
+ - You want summary KPI cards above a filterable table
192
+ - Clicking a card value should add a filter to the datagrid as a convenience shortcut
193
+ - DataCard counts should always show totals from the full dataset, regardless of active filters
194
+ - The dataset is small enough to load entirely (under ~1,000 rows)
195
+
196
+ **When NOT to use:**
197
+
198
+ - DataCard counts should recalculate when filters change — use **Cross-filtered Datagrid Page** instead
199
+ - No summary cards are needed — use **Datagrid Page** instead
200
+ - The dataset is too large to load entirely — combine with **Server Datagrid Page** patterns
201
+
202
+ **Anatomy:**
203
+
204
+ 1. DataCard Row — Flexbox with 1-N DataCards, each containing DataCard.Header and DataCard.Listbox or DataCard.Body with DrilldownItem children
205
+ 2. Toolbar — Flexbox wrapping GridToolbarContainer with filter, columns, density, export, quick search controls
206
+ 3. DataGrid — the table with controlled filterModel + onFilterModelChange
207
+ 4. Bulk Action Bar — Flexbox row shown when selectionModel.length > 0, with Pill (count) and action Buttons
208
+
209
+ **Key imports:** `DataGrid`, `TextCell` from `@redsift/table`; `DataCard`, `DrilldownItem` from `@redsift/dashboard`; `GridColDef`, `GridFilterModel` from `@mui/x-data-grid-pro`; `Pill`, `Button`, `Flexbox`, `Icon` from `@redsift/design-system`
210
+ **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)
211
+ **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.
212
+
213
+ **Features:**
214
+
215
+ | Feature | Required | Description |
216
+ | ------------------------- | -------- | -------------------------------------------------------------------------------- |
217
+ | DataCard aggregation | Yes | DataCard components showing aggregate counts per field from the full dataset |
218
+ | DrilldownItem filter push | Yes | Clicking a DrilldownItem adds an isAnyOf filter to the DataGrid filterModel |
219
+ | Listbox multi-select | Yes | DataCard.Listbox with selectionMode=multiple and controlled values |
220
+ | is/isNot clearing | Yes | When filter panel has is/isNot for a card's field, the DataCard selection clears |
221
+ | Column definitions | Yes | GridColDef[] with custom types |
222
+ | Toolbar | Yes | Built-in toolbar with filter, columns, density, export, and quick search |
223
+ | Custom cell renderers | Yes | renderCell returning TextCell, Pill, Icon, IconButtonLink |
224
+ | Boolean toggle | No | DataCard.Body with DrilldownItem onClick for boolean fields |
225
+ | Checkbox selection | No | checkboxSelection + rowSelectionModel |
226
+ | Bulk action bar | No | Contextual buttons shown when rows are selected |
227
+
228
+ **Filter helpers:**
229
+
230
+ - `getSelectedFromFilterModel(filterModel, fieldName)` — reads isAnyOf values, returns [] for is/isNot operators
231
+ - `updateFilterModel(filterModel, fieldName, values)` — always writes isAnyOf, removes when empty. Never preserves incompatible operators.
232
+ - `updateBooleanFilter(filterModel, fieldName, value)` — uses 'is' operator with 'true'/'false' for boolean fields
233
+
234
+ **Data Contract:**
235
+
236
+ ```tsx
237
+ type Row = {
238
+ id: string;
239
+ label: string;
240
+ active: boolean;
241
+ status: 'active' | 'warning' | 'critical' | 'expired' | 'revoked';
242
+ category: 'primary' | 'secondary' | 'tertiary';
243
+ score: number;
244
+ expiry: string;
245
+ tags: string[];
246
+ };
247
+
248
+ type AggregateCounts = {
249
+ status: Record<string, number>;
250
+ category: Record<string, number>;
251
+ activeCount: number;
252
+ inactiveCount: number;
253
+ };
254
+ ```
255
+
256
+ **Implementation Checklist:**
257
+
258
+ 1. Define your row type — every row must have a unique id field.
259
+ 2. Compute aggregate counts — useAggregateCounts(allRows) counts from the full dataset.
260
+ 3. Build DataCards with DataCard.Header, DataCard.Listbox (multi-select) or DataCard.Body (boolean toggle) containing DrilldownItem children.
261
+ 4. Write filter helpers — getSelectedFromFilterModel and updateFilterModel.
262
+ 5. Wire DataCard handlers — onChange to updateFilterModel, onClick to updateBooleanFilter.
263
+ 6. Render the DataGrid with controlled filterModel and onFilterModelChange.
264
+ 7. Handle edge cases — loading, empty, and error states for both DataCards and DataGrid.
265
+
266
+ **Variants:** Loading State, Empty State, Error State
267
+ **Related:** Cross-filtered Datagrid Page — use when DataCard counts should recalculate as filters change; Datagrid Page — use when no summary cards are needed; Server Datagrid Page — use when data is too large
268
+ **Demo:** [Drilldown Datagrid Page](/patterns/drilldown-datagrid-page)
269
+
270
+ ---
271
+
272
+ ## Cross-filtered Datagrid Page
273
+
274
+ **When to use:**
275
+
276
+ - You want dashboard-style KPI cards that stay in sync with the table below
277
+ - DataCard counts should recalculate as filters change — reflecting the current filter context
278
+ - Clicking a card value should add a filter to the datagrid (bidirectional)
279
+ - Changing the filter panel should update the card selection
280
+ - The dataset is small enough to load entirely (under ~1,000 rows)
281
+
282
+ **When NOT to use:**
283
+
284
+ - DataCard counts should always show full-dataset totals — use **Drilldown Datagrid Page** instead
285
+ - No summary cards are needed — use **Datagrid Page** instead
286
+ - The dataset is too large to load entirely — combine with **Server Datagrid Page** patterns
287
+
288
+ **Anatomy:**
289
+
290
+ 1. DataCard Row — Flexbox with 1-N DataCards. Counts are cross-filtered: each card excludes its own field from the filter calculation
291
+ 2. Toolbar — Flexbox wrapping GridToolbarContainer with filter, columns, density, export, quick search controls
292
+ 3. DataGrid — the table with controlled filterModel + onFilterModelChange. Rows are pre-filtered client-side
293
+ 4. Bulk Action Bar — Flexbox row shown when selectionModel.length > 0, with Pill (count) and action Buttons
294
+
295
+ **Key imports:** `DataGrid`, `TextCell` from `@redsift/table`; `DataCard`, `DrilldownItem` from `@redsift/dashboard`; `GridColDef`, `GridFilterModel` from `@mui/x-data-grid-pro`; `Pill`, `Button`, `Flexbox`, `Icon` from `@redsift/design-system`
296
+ **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)
297
+ **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.
298
+
299
+ **Features:**
300
+
301
+ | Feature | Required | Description |
302
+ | -------------------------- | -------- | -------------------------------------------------------------------------------- |
303
+ | Cross-filtered aggregation | Yes | DataCard counts recompute from rows filtered by all fields except the card's own |
304
+ | Two-way filter sync | Yes | DataCard selections derive from filterModel; DataCard clicks update filterModel |
305
+ | DrilldownItem filter push | Yes | Clicking a DrilldownItem adds an isAnyOf filter to the DataGrid filterModel |
306
+ | Listbox multi-select | Yes | DataCard.Listbox with selectionMode=multiple and controlled values |
307
+ | is/isNot clearing | Yes | When filter panel has is/isNot for a card's field, the DataCard selection clears |
308
+ | Client-side row filtering | Yes | applyFilters function filters the full row set by the current filterModel |
309
+ | Column definitions | Yes | GridColDef[] with custom types |
310
+ | Toolbar | Yes | Built-in toolbar with filter, columns, density, export, and quick search |
311
+ | Custom cell renderers | Yes | renderCell returning TextCell, Pill, Icon, IconButtonLink |
312
+ | Boolean toggle | No | DataCard.Body with DrilldownItem onClick for boolean fields |
313
+ | Checkbox selection | No | checkboxSelection + rowSelectionModel |
314
+ | Bulk action bar | No | Contextual buttons shown when rows are selected |
315
+
316
+ **Cross-filtering logic:**
317
+
318
+ - `applyFilters(rows, filterModel, excludeField?)` — filters rows. When `excludeField` is provided, skips filters for that field.
319
+ - Each DataCard computes its counts via `computeCounts(applyFilters(allRows, filterModel, cardField))` — so the Status card excludes status filters, etc.
320
+ - DataGrid rows use `applyFilters(allRows, filterModel)` without exclusion — all filters applied.
321
+ - Same `getSelectedFromFilterModel` / `updateFilterModel` / `updateBooleanFilter` helpers as Drilldown Datagrid Page.
322
+
323
+ **Data Contract:**
324
+
325
+ ```tsx
326
+ type Row = {
327
+ id: string;
328
+ label: string;
329
+ active: boolean;
330
+ status: 'active' | 'warning' | 'critical' | 'expired' | 'revoked';
331
+ category: 'primary' | 'secondary' | 'tertiary';
332
+ score: number;
333
+ expiry: string;
334
+ tags: string[];
335
+ };
336
+
337
+ type AggregateCounts = {
338
+ status: Record<string, number>;
339
+ category: Record<string, number>;
340
+ activeCount: number;
341
+ inactiveCount: number;
342
+ };
343
+ ```
344
+
345
+ **Implementation Checklist:**
346
+
347
+ 1. Define your row type — every row must have a unique id field.
348
+ 2. Write the applyFilters function — supports isAnyOf, is, isNot. Accepts optional excludeField parameter.
349
+ 3. Write computeCounts — accepts a row array, returns aggregate counts per field value.
350
+ 4. Write filter helpers — getSelectedFromFilterModel and updateFilterModel.
351
+ 5. Compute cross-filtered counts — for each DataCard, call computeCounts(applyFilters(allRows, filterModel, cardField)).
352
+ 6. Compute filtered rows for DataGrid — applyFilters(allRows, filterModel) without excluding any field.
353
+ 7. Build DataCards with controlled values derived from filterModel.
354
+ 8. Render the DataGrid with rows={filteredRows}, controlled filterModel and onFilterModelChange.
355
+ 9. Handle edge cases — loading, empty, and error states.
356
+
357
+ **Variants:** Loading State, Empty State, Error State
358
+ **Related:** Drilldown Datagrid Page — use when DataCard counts should always show full-dataset totals; Datagrid Page — use when no summary cards are needed; Server Datagrid Page — use when data is too large
359
+ **Demo:** [Cross-filtered Datagrid Page](/patterns/crossfiltered-datagrid-page)