@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,521 @@
1
+ import React, { useState } from 'react';
2
+ import { DataGrid, TextCell } from '@redsift/table';
3
+ import { Button, Flexbox, Icon, IconButtonLink, Pill } from '@redsift/design-system';
4
+ import { mdiArrowRight, mdiCheck, mdiClose, mdiShieldCheck, mdiLinkVariant, mdiLeaf } from '@redsift/icons';
5
+ import { GridColDef, GridRenderCellParams, GridRowSelectionModel } from '@mui/x-data-grid-pro';
6
+ import {
7
+ GridToolbarContainer,
8
+ GridToolbarColumnsButton,
9
+ GridToolbarDensitySelector,
10
+ GridToolbarFilterButton,
11
+ GridToolbarExport,
12
+ GridToolbarQuickFilter,
13
+ } from '@mui/x-data-grid-pro';
14
+
15
+ // -- Toolbar with text labels (not condensed icon-only mode) ----------------
16
+
17
+ const CustomToolbar = () => (
18
+ <GridToolbarContainer>
19
+ <Flexbox gap="0">
20
+ <GridToolbarFilterButton />
21
+ <GridToolbarColumnsButton />
22
+ <GridToolbarDensitySelector />
23
+ <GridToolbarExport />
24
+ <Flexbox marginLeft="8px">
25
+ <GridToolbarQuickFilter />
26
+ </Flexbox>
27
+ </Flexbox>
28
+ </GridToolbarContainer>
29
+ );
30
+
31
+ // -- Tag options for the rsMultipleSelect column ----------------------------
32
+
33
+ const TAG_OPTIONS = [
34
+ { value: 'production', label: 'Production' },
35
+ { value: 'staging', label: 'Staging' },
36
+ { value: 'legacy', label: 'Legacy' },
37
+ { value: 'infrastructure', label: 'Infrastructure' },
38
+ { value: 'cdn', label: 'CDN' },
39
+ { value: 'api', label: 'API' },
40
+ { value: 'auth', label: 'Auth' },
41
+ { value: 'ca', label: 'CA' },
42
+ { value: 'email', label: 'Email' },
43
+ { value: 'ecommerce', label: 'Ecommerce' },
44
+ { value: 'wildcard', label: 'Wildcard' },
45
+ { value: 'monitoring', label: 'Monitoring' },
46
+ { value: 'vpn', label: 'VPN' },
47
+ { value: 'billing', label: 'Billing' },
48
+ { value: 'ci', label: 'CI' },
49
+ { value: 'cms', label: 'CMS' },
50
+ ];
51
+
52
+ // -- 27 rows (tests pagination at 10 / 25 / 50) ----------------------------
53
+
54
+ const rows = [
55
+ {
56
+ id: 'a3f8c1d2',
57
+ label: 'cdn.acme.com',
58
+ active: true,
59
+ status: 'active',
60
+ category: 'primary',
61
+ score: 92,
62
+ expiry: '2027-06-15T00:00:00Z',
63
+ tags: ['production', 'cdn'],
64
+ },
65
+ {
66
+ id: 'b7e2d4f6',
67
+ label: 'api.globex.io',
68
+ active: true,
69
+ status: 'warning',
70
+ category: 'primary',
71
+ score: 74,
72
+ expiry: '2026-05-01T12:00:00Z',
73
+ tags: ['production', 'api'],
74
+ },
75
+ {
76
+ id: 'c1a9b5e3',
77
+ label: '*.staging.acme.com',
78
+ active: true,
79
+ status: 'critical',
80
+ category: 'secondary',
81
+ score: 45,
82
+ expiry: '2026-03-28T23:59:59Z',
83
+ tags: ['staging'],
84
+ },
85
+ {
86
+ id: 'd4f0c8a7',
87
+ label: 'mail.initech.dev',
88
+ active: false,
89
+ status: 'expired',
90
+ category: 'tertiary',
91
+ score: 12,
92
+ expiry: '2025-11-30T08:45:00Z',
93
+ tags: ['legacy', 'email'],
94
+ },
95
+ {
96
+ id: 'e6b3d1f9',
97
+ label: 'Acme Root CA',
98
+ active: true,
99
+ status: 'active',
100
+ category: 'primary',
101
+ score: 100,
102
+ expiry: '2035-06-01T00:00:00Z',
103
+ tags: ['infrastructure'],
104
+ },
105
+ {
106
+ id: 'f2c7a5e8',
107
+ label: 'Issuing CA G2',
108
+ active: true,
109
+ status: 'active',
110
+ category: 'secondary',
111
+ score: 98,
112
+ expiry: '2031-12-31T23:59:59Z',
113
+ tags: ['infrastructure', 'ca'],
114
+ },
115
+ {
116
+ id: 'a8d4f6b1',
117
+ label: 'auth.globex.io',
118
+ active: false,
119
+ status: 'revoked',
120
+ category: 'primary',
121
+ score: 0,
122
+ expiry: '2026-09-10T17:30:00Z',
123
+ tags: ['production', 'auth'],
124
+ },
125
+ {
126
+ id: 'b5e9c3a2',
127
+ label: 'shop.initech.dev',
128
+ active: true,
129
+ status: 'warning',
130
+ category: 'tertiary',
131
+ score: 63,
132
+ expiry: '2026-04-20T00:00:00Z',
133
+ tags: ['ecommerce'],
134
+ },
135
+ {
136
+ id: 'c0f7d2b4',
137
+ label: 'Sectigo DV CA',
138
+ active: true,
139
+ status: 'active',
140
+ category: 'secondary',
141
+ score: 95,
142
+ expiry: '2030-01-01T00:00:00Z',
143
+ tags: ['infrastructure', 'ca'],
144
+ },
145
+ {
146
+ id: 'd9a1e5c6',
147
+ label: 'vault.initech.dev',
148
+ active: false,
149
+ status: 'expired',
150
+ category: 'primary',
151
+ score: 8,
152
+ expiry: '2024-07-22T14:00:00Z',
153
+ tags: ['legacy'],
154
+ },
155
+ {
156
+ id: 'e3b8f0d7',
157
+ label: '*.acme.com',
158
+ active: true,
159
+ status: 'active',
160
+ category: 'primary',
161
+ score: 88,
162
+ expiry: '2027-08-05T12:00:00Z',
163
+ tags: ['production', 'wildcard'],
164
+ },
165
+ {
166
+ id: 'f6c2a4e1',
167
+ label: 'portal.globex.io',
168
+ active: true,
169
+ status: 'critical',
170
+ category: 'tertiary',
171
+ score: 51,
172
+ expiry: '2026-03-26T10:00:00Z',
173
+ tags: [],
174
+ },
175
+ {
176
+ id: 'a1d7f3b9',
177
+ label: 'logs.initech.dev',
178
+ active: true,
179
+ status: 'active',
180
+ category: 'secondary',
181
+ score: 81,
182
+ expiry: '2028-02-14T00:00:00Z',
183
+ tags: ['production', 'monitoring'],
184
+ },
185
+ {
186
+ id: 'b4e8c6a3',
187
+ label: 'cms.acme.com',
188
+ active: false,
189
+ status: 'expired',
190
+ category: 'tertiary',
191
+ score: 5,
192
+ expiry: '2025-06-10T00:00:00Z',
193
+ tags: ['legacy', 'cms'],
194
+ },
195
+ {
196
+ id: 'c7f2d0b5',
197
+ label: 'DigiCert EV CA',
198
+ active: true,
199
+ status: 'active',
200
+ category: 'secondary',
201
+ score: 99,
202
+ expiry: '2033-09-15T00:00:00Z',
203
+ tags: ['infrastructure', 'ca'],
204
+ },
205
+ {
206
+ id: 'd0a3e9f1',
207
+ label: 'vpn.globex.io',
208
+ active: true,
209
+ status: 'warning',
210
+ category: 'primary',
211
+ score: 68,
212
+ expiry: '2026-04-12T00:00:00Z',
213
+ tags: ['production', 'vpn'],
214
+ },
215
+ {
216
+ id: 'e5b1c4d8',
217
+ label: '*.initech.dev',
218
+ active: true,
219
+ status: 'active',
220
+ category: 'primary',
221
+ score: 85,
222
+ expiry: '2027-11-20T00:00:00Z',
223
+ tags: ['production', 'wildcard'],
224
+ },
225
+ {
226
+ id: 'f8c6a2e7',
227
+ label: 'docs.acme.com',
228
+ active: true,
229
+ status: 'active',
230
+ category: 'tertiary',
231
+ score: 90,
232
+ expiry: '2028-07-01T00:00:00Z',
233
+ tags: ['production'],
234
+ },
235
+ {
236
+ id: 'a2d5f9b0',
237
+ label: 'billing.globex.io',
238
+ active: false,
239
+ status: 'revoked',
240
+ category: 'primary',
241
+ score: 0,
242
+ expiry: '2026-01-15T00:00:00Z',
243
+ tags: ['production', 'billing'],
244
+ },
245
+ {
246
+ id: 'b6e0c3a1',
247
+ label: 'staging.initech.dev',
248
+ active: true,
249
+ status: 'critical',
250
+ category: 'secondary',
251
+ score: 42,
252
+ expiry: '2026-03-27T00:00:00Z',
253
+ tags: ['staging', 'ci'],
254
+ },
255
+ {
256
+ id: 'c9f4d7b2',
257
+ label: "Let's Encrypt R3",
258
+ active: true,
259
+ status: 'active',
260
+ category: 'secondary',
261
+ score: 97,
262
+ expiry: '2030-09-30T00:00:00Z',
263
+ tags: ['infrastructure', 'ca'],
264
+ },
265
+ {
266
+ id: 'd3a8e1f5',
267
+ label: 'analytics.acme.com',
268
+ active: true,
269
+ status: 'warning',
270
+ category: 'tertiary',
271
+ score: 59,
272
+ expiry: '2026-04-05T00:00:00Z',
273
+ tags: ['production', 'monitoring'],
274
+ },
275
+ {
276
+ id: 'e7b2c5d9',
277
+ label: 'sso.globex.io',
278
+ active: true,
279
+ status: 'active',
280
+ category: 'primary',
281
+ score: 91,
282
+ expiry: '2027-12-01T00:00:00Z',
283
+ tags: ['production', 'auth'],
284
+ },
285
+ {
286
+ id: 'f0c9a6e4',
287
+ label: 'wiki.initech.dev',
288
+ active: false,
289
+ status: 'expired',
290
+ category: 'tertiary',
291
+ score: 3,
292
+ expiry: '2024-12-31T00:00:00Z',
293
+ tags: ['legacy'],
294
+ },
295
+ {
296
+ id: 'a4d1f8b6',
297
+ label: 'proxy.acme.com',
298
+ active: true,
299
+ status: 'active',
300
+ category: 'primary',
301
+ score: 83,
302
+ expiry: '2028-03-22T00:00:00Z',
303
+ tags: ['production', 'cdn'],
304
+ },
305
+ {
306
+ id: 'b9e5c0a8',
307
+ label: 'dev.globex.io',
308
+ active: true,
309
+ status: 'critical',
310
+ category: 'secondary',
311
+ score: 38,
312
+ expiry: '2026-03-25T00:00:00Z',
313
+ tags: ['staging'],
314
+ },
315
+ {
316
+ id: 'c2f6d3b7',
317
+ label: 'GTS Root R1',
318
+ active: true,
319
+ status: 'active',
320
+ category: 'primary',
321
+ score: 100,
322
+ expiry: '2036-06-22T00:00:00Z',
323
+ tags: ['infrastructure'],
324
+ },
325
+ ];
326
+
327
+ // -- Helpers ----------------------------------------------------------------
328
+
329
+ const statusColor = (v: string) => {
330
+ switch (v) {
331
+ case 'active':
332
+ return 'success';
333
+ case 'warning':
334
+ return 'warning';
335
+ case 'critical':
336
+ return 'error';
337
+ case 'expired':
338
+ return 'grey';
339
+ case 'revoked':
340
+ return 'error-dark';
341
+ default:
342
+ return 'grey';
343
+ }
344
+ };
345
+
346
+ const categoryIcon = (v: string) => {
347
+ switch (v) {
348
+ case 'primary':
349
+ return { icon: mdiShieldCheck, color: 'success' };
350
+ case 'secondary':
351
+ return { icon: mdiLinkVariant, color: 'info' };
352
+ case 'tertiary':
353
+ return { icon: mdiLeaf, color: 'grey' };
354
+ default:
355
+ return { icon: mdiLeaf, color: 'grey' };
356
+ }
357
+ };
358
+
359
+ const formatDate = (d: Date) => (isNaN(d.getTime()) ? '—' : d.toISOString().replace('T', ' ').slice(0, 19));
360
+
361
+ // -- Columns (8 types) ------------------------------------------------------
362
+
363
+ const columns: GridColDef[] = [
364
+ // 1. String (monospace ID)
365
+ {
366
+ field: 'id',
367
+ headerName: 'ID',
368
+ width: 100,
369
+ type: 'rsString' as string,
370
+ renderCell: ({ value }: GridRenderCellParams) => <TextCell style={{ fontFamily: 'monospace' }}>{value}</TextCell>,
371
+ },
372
+ // 2. String (label)
373
+ {
374
+ field: 'label',
375
+ headerName: 'Label',
376
+ flex: 2,
377
+ type: 'rsString' as string,
378
+ renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value}</TextCell>,
379
+ },
380
+ // 3. Boolean (active)
381
+ {
382
+ field: 'active',
383
+ headerName: 'Active',
384
+ width: 80,
385
+ type: 'boolean',
386
+ renderCell: ({ value }: GridRenderCellParams) =>
387
+ value ? (
388
+ <Icon icon={mdiCheck} color="success" size="small" />
389
+ ) : (
390
+ <Icon icon={mdiClose} color="grey" size="small" />
391
+ ),
392
+ },
393
+ // 4. SingleSelect — rendered as status Pill
394
+ {
395
+ field: 'status',
396
+ headerName: 'Status',
397
+ flex: 1,
398
+ type: 'rsSingleSelect' as string,
399
+ valueOptions: [
400
+ { value: 'active', label: 'Active' },
401
+ { value: 'warning', label: 'Warning' },
402
+ { value: 'critical', label: 'Critical' },
403
+ { value: 'expired', label: 'Expired' },
404
+ { value: 'revoked', label: 'Revoked' },
405
+ ],
406
+ renderCell: ({ value }: GridRenderCellParams) => <Pill color={statusColor(value)}>{value}</Pill>,
407
+ } as GridColDef,
408
+ // 5. SingleSelect — rendered as icon
409
+ {
410
+ field: 'category',
411
+ headerName: 'Category',
412
+ width: 110,
413
+ type: 'rsSingleSelect' as string,
414
+ valueOptions: [
415
+ { value: 'primary', label: 'Primary' },
416
+ { value: 'secondary', label: 'Secondary' },
417
+ { value: 'tertiary', label: 'Tertiary' },
418
+ ],
419
+ renderCell: ({ value }: GridRenderCellParams) => {
420
+ const cfg = categoryIcon(value);
421
+ return <Icon icon={cfg.icon} color={cfg.color} size="small" />;
422
+ },
423
+ } as GridColDef,
424
+ // 6. Number
425
+ {
426
+ field: 'score',
427
+ headerName: 'Score',
428
+ width: 80,
429
+ type: 'rsNumber' as string,
430
+ },
431
+ // 7. Date
432
+ {
433
+ field: 'expiry',
434
+ headerName: 'Expiry',
435
+ width: 180,
436
+ type: 'date',
437
+ valueGetter: (value: unknown) => new Date(value as string),
438
+ renderCell: ({ value }: GridRenderCellParams) => {
439
+ if (!value) return <TextCell>—</TextCell>;
440
+ const d = value as Date;
441
+ const isPast = d < new Date();
442
+ return <TextCell style={isPast ? { color: 'var(--redsift-color-red-n)' } : undefined}>{formatDate(d)}</TextCell>;
443
+ },
444
+ },
445
+ // 8. MultipleSelect (tags) — uses has / hasAnyOf / doesNotHave operators
446
+ {
447
+ field: 'tags',
448
+ headerName: 'Tags',
449
+ flex: 2,
450
+ type: 'rsMultipleSelect' as string,
451
+ valueOptions: TAG_OPTIONS,
452
+ sortable: false,
453
+ renderCell: ({ value }: GridRenderCellParams) => {
454
+ const arr = value as string[];
455
+ if (!arr || arr.length === 0) return <TextCell>—</TextCell>;
456
+ return (
457
+ <Flexbox gap="4px" flexWrap="wrap" alignItems="center">
458
+ {arr.map((tag: string) => (
459
+ <Pill key={tag} color="blue">
460
+ {tag}
461
+ </Pill>
462
+ ))}
463
+ </Flexbox>
464
+ );
465
+ },
466
+ } as GridColDef,
467
+ // 9. Actions — link to detail page
468
+ {
469
+ field: 'actions',
470
+ headerName: '',
471
+ type: 'actions',
472
+ width: 56,
473
+ hideable: false,
474
+ sortable: false,
475
+ filterable: false,
476
+ renderCell: ({ row }: GridRenderCellParams) => (
477
+ <IconButtonLink
478
+ href="/patterns/datagrid-page"
479
+ icon={mdiArrowRight}
480
+ color="info"
481
+ aria-label={`View ${row.label}`}
482
+ />
483
+ ),
484
+ },
485
+ ];
486
+
487
+ export default () => {
488
+ const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>([]);
489
+
490
+ return (
491
+ <div style={{ width: '100%' }}>
492
+ <Flexbox flexDirection="column" gap="0px">
493
+ {/* Bulk actions bar — visible when rows are selected */}
494
+ {selectionModel.length > 0 && (
495
+ <Flexbox gap="8px" alignItems="center" style={{ padding: '8px 0' }}>
496
+ <Pill color="info">{selectionModel.length} selected</Pill>
497
+ <Button variant="secondary" onClick={() => console.log('Selected:', selectionModel)}>
498
+ Log Selection
499
+ </Button>
500
+ <Button variant="secondary" color="error" onClick={() => console.log('Delete:', selectionModel)}>
501
+ Delete
502
+ </Button>
503
+ </Flexbox>
504
+ )}
505
+
506
+ <DataGrid
507
+ autoHeight
508
+ pagination
509
+ paginationModel={{ page: 0, pageSize: 10 }}
510
+ pageSizeOptions={[10, 25, 50]}
511
+ rows={rows}
512
+ columns={columns}
513
+ checkboxSelection
514
+ rowSelectionModel={selectionModel}
515
+ onRowSelectionModelChange={setSelectionModel}
516
+ slots={{ toolbar: CustomToolbar }}
517
+ />
518
+ </Flexbox>
519
+ </div>
520
+ );
521
+ };
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import { DataGrid, TextCell } from '@redsift/table';
3
+ import { Flexbox, Text, Icon } from '@redsift/design-system';
4
+ import { mdiMagnify } from '@redsift/icons';
5
+ import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid-pro';
6
+ import {
7
+ GridToolbarContainer,
8
+ GridToolbarColumnsButton,
9
+ GridToolbarDensitySelector,
10
+ GridToolbarFilterButton,
11
+ GridToolbarExport,
12
+ GridToolbarQuickFilter,
13
+ } from '@mui/x-data-grid-pro';
14
+
15
+ const CustomToolbar = () => (
16
+ <GridToolbarContainer>
17
+ <Flexbox gap="0">
18
+ <GridToolbarFilterButton />
19
+ <GridToolbarColumnsButton />
20
+ <GridToolbarDensitySelector />
21
+ <GridToolbarExport />
22
+ <Flexbox marginLeft="8px">
23
+ <GridToolbarQuickFilter />
24
+ </Flexbox>
25
+ </Flexbox>
26
+ </GridToolbarContainer>
27
+ );
28
+
29
+ const columns: GridColDef[] = [
30
+ { field: 'id', headerName: 'ID', width: 100, type: 'rsString' as string },
31
+ {
32
+ field: 'label',
33
+ headerName: 'Label',
34
+ flex: 2,
35
+ type: 'rsString' as string,
36
+ renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value}</TextCell>,
37
+ },
38
+ { field: 'status', headerName: 'Status', flex: 1, type: 'rsSingleSelect' as string },
39
+ { field: 'score', headerName: 'Score', width: 80, type: 'rsNumber' as string },
40
+ { field: 'expiry', headerName: 'Expiry', width: 180, type: 'date' },
41
+ ];
42
+
43
+ // -- Custom empty state overlay ---------------------------------------------
44
+
45
+ const CustomNoRowsOverlay = () => (
46
+ <Flexbox
47
+ flexDirection="column"
48
+ alignItems="center"
49
+ justifyContent="center"
50
+ gap="12px"
51
+ style={{ height: '100%', padding: '48px 0' }}
52
+ >
53
+ <Icon icon={mdiMagnify} size="large" color="grey" />
54
+ <Text variant="body" color="grey">
55
+ No records found
56
+ </Text>
57
+ <Text variant="caption" color="grey">
58
+ Try adjusting your filters or search criteria.
59
+ </Text>
60
+ </Flexbox>
61
+ );
62
+
63
+ // -- Empty state: DataGrid with no rows and a custom overlay ----------------
64
+
65
+ export default () => (
66
+ <div style={{ width: '100%' }}>
67
+ <DataGrid
68
+ autoHeight
69
+ pagination
70
+ paginationModel={{ page: 0, pageSize: 10 }}
71
+ pageSizeOptions={[10, 25, 50]}
72
+ rows={[]}
73
+ columns={columns}
74
+ slots={{
75
+ toolbar: CustomToolbar,
76
+ noRowsOverlay: CustomNoRowsOverlay,
77
+ }}
78
+ />
79
+ </div>
80
+ );
@@ -0,0 +1,96 @@
1
+ import React, { useCallback, useState } from 'react';
2
+ import { DataGrid, TextCell } from '@redsift/table';
3
+ import { Button, Flexbox, Text, Icon } from '@redsift/design-system';
4
+ import { mdiAlertCircle, mdiRefresh } from '@redsift/icons';
5
+ import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid-pro';
6
+ import {
7
+ GridToolbarContainer,
8
+ GridToolbarColumnsButton,
9
+ GridToolbarDensitySelector,
10
+ GridToolbarFilterButton,
11
+ GridToolbarExport,
12
+ GridToolbarQuickFilter,
13
+ } from '@mui/x-data-grid-pro';
14
+
15
+ const CustomToolbar = () => (
16
+ <GridToolbarContainer>
17
+ <Flexbox gap="0">
18
+ <GridToolbarFilterButton />
19
+ <GridToolbarColumnsButton />
20
+ <GridToolbarDensitySelector />
21
+ <GridToolbarExport />
22
+ <Flexbox marginLeft="8px">
23
+ <GridToolbarQuickFilter />
24
+ </Flexbox>
25
+ </Flexbox>
26
+ </GridToolbarContainer>
27
+ );
28
+
29
+ const columns: GridColDef[] = [
30
+ { field: 'id', headerName: 'ID', width: 100, type: 'rsString' as string },
31
+ {
32
+ field: 'label',
33
+ headerName: 'Label',
34
+ flex: 2,
35
+ type: 'rsString' as string,
36
+ renderCell: ({ value }: GridRenderCellParams) => <TextCell>{value}</TextCell>,
37
+ },
38
+ { field: 'status', headerName: 'Status', flex: 1, type: 'rsSingleSelect' as string },
39
+ { field: 'score', headerName: 'Score', width: 80, type: 'rsNumber' as string },
40
+ { field: 'expiry', headerName: 'Expiry', width: 180, type: 'date' },
41
+ ];
42
+
43
+ // -- Error state: shows an error banner with a retry button -----------------
44
+
45
+ export default () => {
46
+ const [hasError, setHasError] = useState(true);
47
+
48
+ const handleRetry = useCallback(() => {
49
+ setHasError(false);
50
+ // Simulate a successful retry after a brief delay
51
+ setTimeout(() => setHasError(true), 1500);
52
+ }, []);
53
+
54
+ return (
55
+ <div style={{ width: '100%' }}>
56
+ <Flexbox flexDirection="column" gap="0px">
57
+ {hasError && (
58
+ <Flexbox
59
+ gap="12px"
60
+ alignItems="center"
61
+ style={{
62
+ padding: '12px 16px',
63
+ backgroundColor: 'var(--redsift-color-red-l3)',
64
+ borderRadius: '4px',
65
+ marginBottom: '8px',
66
+ }}
67
+ role="alert"
68
+ aria-live="polite"
69
+ >
70
+ <Icon icon={mdiAlertCircle} color="error" size="small" />
71
+ <Text variant="caption" style={{ flex: 1 }}>
72
+ Failed to load data. Please check your connection and try again.
73
+ </Text>
74
+ <Button variant="secondary" onClick={handleRetry}>
75
+ <Flexbox gap="4px" alignItems="center">
76
+ <Icon icon={mdiRefresh} size="small" />
77
+ Retry
78
+ </Flexbox>
79
+ </Button>
80
+ </Flexbox>
81
+ )}
82
+
83
+ <DataGrid
84
+ autoHeight
85
+ loading={!hasError ? true : false}
86
+ pagination
87
+ paginationModel={{ page: 0, pageSize: 10 }}
88
+ pageSizeOptions={[10, 25, 50]}
89
+ rows={[]}
90
+ columns={columns}
91
+ slots={{ toolbar: CustomToolbar }}
92
+ />
93
+ </Flexbox>
94
+ </div>
95
+ );
96
+ };