@redsift/ds-mcp-server 12.5.3-alpha.6 → 12.5.3-alpha.7

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 (81) hide show
  1. package/consumer-instructions/redsift-design-system.instructions.md +82 -1
  2. package/data/docs/components/charts/Axis.json +6 -1
  3. package/data/docs/components/charts/BarChart.json +7 -1
  4. package/data/docs/components/charts/ChartContainerTitle.json +5 -1
  5. package/data/docs/components/charts/Legend.json +6 -1
  6. package/data/docs/components/charts/LineChart.json +7 -1
  7. package/data/docs/components/charts/PieChart.json +6 -1
  8. package/data/docs/components/charts/ScatterPlot.json +6 -1
  9. package/data/docs/components/dashboard/ChartEmptyState.json +8 -1
  10. package/data/docs/components/dashboard/Dashboard.json +6 -1
  11. package/data/docs/components/dashboard/DataCard.json +12 -0
  12. package/data/docs/components/dashboard/DataCardBody.json +4 -0
  13. package/data/docs/components/dashboard/DataCardHeader.json +4 -0
  14. package/data/docs/components/dashboard/DataCardListbox.json +5 -0
  15. package/data/docs/components/dashboard/DataRow.json +7 -1
  16. package/data/docs/components/dashboard/PdfExportButton.json +6 -1
  17. package/data/docs/components/dashboard/TimeSeriesBarChart.json +6 -1
  18. package/data/docs/components/dashboard/WithFilters.json +5 -1
  19. package/data/docs/components/design-system/Alert.json +8 -1
  20. package/data/docs/components/design-system/AppBar.json +6 -1
  21. package/data/docs/components/design-system/AppContent.json +4 -0
  22. package/data/docs/components/design-system/AppSidePanel.json +5 -0
  23. package/data/docs/components/design-system/Badge.json +6 -1
  24. package/data/docs/components/design-system/Breadcrumbs.json +4 -0
  25. package/data/docs/components/design-system/Button.json +5 -0
  26. package/data/docs/components/design-system/Card.json +9 -0
  27. package/data/docs/components/design-system/CardActions.json +4 -0
  28. package/data/docs/components/design-system/CardBody.json +3 -0
  29. package/data/docs/components/design-system/CardHeader.json +4 -0
  30. package/data/docs/components/design-system/DetailedCard.json +6 -0
  31. package/data/docs/components/design-system/Flexbox.json +14 -1
  32. package/data/docs/components/design-system/Grid.json +6 -1
  33. package/data/docs/components/design-system/Heading.json +11 -0
  34. package/data/docs/components/design-system/Icon.json +6 -1
  35. package/data/docs/components/design-system/IconButton.json +9 -0
  36. package/data/docs/components/design-system/Pill.json +10 -0
  37. package/data/docs/components/design-system/Skeleton.json +10 -1
  38. package/data/docs/components/design-system/SkeletonCircle.json +6 -1
  39. package/data/docs/components/design-system/SkeletonText.json +6 -1
  40. package/data/docs/components/design-system/Tab.json +4 -0
  41. package/data/docs/components/design-system/TabPanel.json +4 -0
  42. package/data/docs/components/design-system/Tabs.json +6 -0
  43. package/data/docs/components/design-system/Text.json +9 -0
  44. package/data/docs/components/design-system/TextField.json +6 -1
  45. package/data/docs/components/pickers/Combobox.json +6 -0
  46. package/data/docs/components/pickers/MenuButton.json +5 -0
  47. package/data/docs/components/pickers/Select.json +5 -0
  48. package/data/docs/components/popovers/Dialog.json +6 -0
  49. package/data/docs/components/popovers/Toggletip.json +5 -0
  50. package/data/docs/components/popovers/Tooltip.json +4 -0
  51. package/data/docs/components/table/DataGrid.json +9 -1
  52. package/data/docs/components/table/StatefulDataGrid.json +6 -1
  53. package/data/docs/components-index.json +341 -51
  54. package/data/docs/components.json +2 -2
  55. package/data/docs/llms-full.txt +248 -1
  56. package/data/docs/llms.txt +50 -0
  57. package/data/docs/patterns-catalog.md +191 -0
  58. package/data/docs/patterns.json +365 -27
  59. package/data/metadata.json +2 -2
  60. package/data/prompts/ds-advisor.md +103 -0
  61. package/dist/data-store.d.ts +21 -1
  62. package/dist/data-store.d.ts.map +1 -1
  63. package/dist/data-store.js +65 -15
  64. package/dist/data-store.js.map +1 -1
  65. package/dist/pattern-store.d.ts +18 -1
  66. package/dist/pattern-store.d.ts.map +1 -1
  67. package/dist/pattern-store.js +64 -22
  68. package/dist/pattern-store.js.map +1 -1
  69. package/dist/prompts.d.ts.map +1 -1
  70. package/dist/prompts.js +56 -27
  71. package/dist/prompts.js.map +1 -1
  72. package/dist/resources.d.ts.map +1 -1
  73. package/dist/resources.js +26 -0
  74. package/dist/resources.js.map +1 -1
  75. package/dist/tools.d.ts.map +1 -1
  76. package/dist/tools.js +12 -0
  77. package/dist/tools.js.map +1 -1
  78. package/dist/types.d.ts +11 -0
  79. package/dist/types.d.ts.map +1 -1
  80. package/dist/types.js.map +1 -1
  81. package/package.json +4 -2
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "name": "Red Sift Design System",
4
- "version": "12.5.3-alpha.5",
5
- "generated": "2026-05-11T10:08:07.706Z",
4
+ "version": "12.5.3-alpha.6",
5
+ "generated": "2026-05-12T09:42:09.207Z",
6
6
  "repository": "https://github.com/redsift/design-system",
7
7
  "documentation": "https://design-system.redsift.io",
8
8
  "packages": [
@@ -3,7 +3,7 @@
3
3
  This file contains comprehensive documentation for all components in the Red Sift Design System.
4
4
  It is optimized for LLM consumption and includes props, types, defaults, and usage examples.
5
5
 
6
- Generated: 2026-05-11T10:08:07.700Z
6
+ Generated: 2026-05-12T09:42:09.200Z
7
7
  Total Components: 156
8
8
 
9
9
  ---
@@ -654,6 +654,14 @@ Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right
654
654
  - ⚠️ Card.Header has a fixed design. Use Card.Body for content and Card.Actions for button rows.
655
655
  - ⚠️ For collapsible cards, pass `isCollapsible` to Card. Use `isCollapsed`/`onCollapse` for controlled mode, or `defaultCollapsed` for uncontrolled.
656
656
 
657
+ #### Disambiguation
658
+
659
+ ⚠️ Card is a generic container with Header/Body/Actions. Do NOT use for KPI/metric tiles — use DataCard from @redsift/dashboard instead.
660
+
661
+ #### Common Anti-Patterns
662
+
663
+ - ❌ Using Card with inline styles for KPI tiles → ✅ Use DataCard from @redsift/dashboard for metric/KPI tiles.
664
+
657
665
  ---
658
666
 
659
667
  ### CardActions
@@ -927,6 +935,10 @@ Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right
927
935
  - ⚠️ DetailedCard.Header is extracted via partitionComponents — it must be a direct child, not wrapped.
928
936
  - ⚠️ DetailedCard.CollapsibleSectionItems must be a child of DetailedCard.Section for auto-detection of collapsible state.
929
937
 
938
+ #### Disambiguation
939
+
940
+ ⚠️ DetailedCard is a complex card with collapsible sections. Use for rich detail panels, not KPI tiles. For KPI tiles use DataCard from @redsift/dashboard.
941
+
930
942
  ---
931
943
 
932
944
  ### DetailedCardCollapsibleSectionItems
@@ -1063,6 +1075,11 @@ Inherits standard sizing props: `height`, `maxHeight`, `maxWidth`, `minHeight`,
1063
1075
 
1064
1076
  Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right`, `zIndex`
1065
1077
 
1078
+ #### Common Anti-Patterns
1079
+
1080
+ - ❌ gap={4} → ✅ gap="4px" — gap is a string prop (CSS value), not a number.
1081
+ - ❌ style={{ display: "flex", gap: 4 }} → ✅ <Flexbox gap="4px"> — use the Flexbox component instead of inline styles.
1082
+
1066
1083
  ---
1067
1084
 
1068
1085
  ### FocusWithinGroup
@@ -1206,6 +1223,10 @@ Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right
1206
1223
  - ⚠️ The `theme` prop is optional — inherited from context. Do NOT pass `theme` to every component.
1207
1224
  - ⚠️ Valid `color` values come from NeutralColorPalette ("black", "x-dark-grey", "dark-grey", "mid-grey", "light-grey", "x-light-grey", "white") and NotificationsColorPalette ("error", "warning", "success", "info", "question", "no-data"). You can also pass hex/rgb strings.
1208
1225
 
1226
+ #### Common Anti-Patterns
1227
+
1228
+ - ❌ color="#22c55e" or color="var(--rs-color-green-500)" → ✅ color="success" — use semantic color values from NeutralColorPalette / NotificationsColorPalette.
1229
+
1209
1230
  ---
1210
1231
 
1211
1232
  ### Icon
@@ -1247,6 +1268,15 @@ Inherits standard spacing props: `margin`, `marginBottom`, `marginLeft`, `margin
1247
1268
 
1248
1269
  Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right`, `zIndex`
1249
1270
 
1271
+ #### Disambiguation
1272
+
1273
+ ⚠️ Icon renders an SVG icon from a path string. Always import mdi* icons from @redsift/icons. NEVER use unicode glyphs (✓, ✕, ⚠, ›) and NEVER import from @mdi/js.
1274
+
1275
+ #### Common Anti-Patterns
1276
+
1277
+ - ❌ Unicode characters (✓, ✕, ⚠, ›) → ✅ <Icon path={mdiCheck} /> from @redsift/icons.
1278
+ - ❌ import { mdiPlus } from "@mdi/js" → ✅ import { mdiPlus } from "@redsift/icons".
1279
+
1250
1280
  ---
1251
1281
 
1252
1282
  ### IconButton
@@ -1297,6 +1327,15 @@ Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right
1297
1327
  - ⚠️ The `theme` prop is optional — inherited from context. Do NOT pass `theme` to every component.
1298
1328
  - ⚠️ Requires `icon` prop (SVG path string from @redsift/icons). Import icons from @redsift/icons, not @mdi/js.
1299
1329
 
1330
+ #### Disambiguation
1331
+
1332
+ ⚠️ IconButton renders a clickable icon. Requires icon prop (SVG path string). Import icons from @redsift/icons, not @mdi/js.
1333
+
1334
+ #### Common Anti-Patterns
1335
+
1336
+ - ❌ Unicode characters as icon content → ✅ icon={mdiPlus} prop with mdi imports from @redsift/icons.
1337
+ - ❌ import { mdiPlus } from "@mdi/js" → ✅ import { mdiPlus } from "@redsift/icons".
1338
+
1300
1339
  ---
1301
1340
 
1302
1341
  ### IconButtonLink
@@ -1734,6 +1773,10 @@ Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right
1734
1773
  - ⚠️ Content via `children`, NOT a `label` prop. Usage: `<Pill color="blue" size="small">Active</Pill>`
1735
1774
  - ⚠️ The `theme` prop is optional — inherited from context.
1736
1775
 
1776
+ #### Common Anti-Patterns
1777
+
1778
+ - ❌ <Pill label="Active" /> → ✅ <Pill color="success">Active</Pill> — Pill uses children for content, NOT a label prop.
1779
+
1737
1780
  ---
1738
1781
 
1739
1782
  ### ProgressBar
@@ -2057,6 +2100,14 @@ Inherits standard sizing props: `height`, `maxHeight`, `maxWidth`, `minHeight`,
2057
2100
 
2058
2101
  Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right`, `zIndex`
2059
2102
 
2103
+ #### Disambiguation
2104
+
2105
+ ⚠️ Always use Skeleton from @redsift/design-system. NEVER import Skeleton from @mui/material — it will not match the DS theme.
2106
+
2107
+ #### Common Anti-Patterns
2108
+
2109
+ - ❌ import { Skeleton } from "@mui/material" → ✅ import { Skeleton } from "@redsift/design-system" — always use the DS Skeleton.
2110
+
2060
2111
  ---
2061
2112
 
2062
2113
  ### SkeletonCircle
@@ -2089,6 +2140,10 @@ Inherits standard sizing props: `height`, `maxHeight`, `maxWidth`, `minHeight`,
2089
2140
 
2090
2141
  Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right`, `zIndex`
2091
2142
 
2143
+ #### Disambiguation
2144
+
2145
+ ⚠️ Use SkeletonCircle from @redsift/design-system for avatar/icon-shaped loading placeholders.
2146
+
2092
2147
  ---
2093
2148
 
2094
2149
  ### SkeletonText
@@ -2124,6 +2179,10 @@ Inherits standard sizing props: `height`, `maxHeight`, `maxWidth`, `minHeight`,
2124
2179
 
2125
2180
  Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right`, `zIndex`
2126
2181
 
2182
+ #### Disambiguation
2183
+
2184
+ ⚠️ Use SkeletonText from @redsift/design-system for paragraph-shaped loading placeholders.
2185
+
2127
2186
  ---
2128
2187
 
2129
2188
  ### Spinner
@@ -2440,6 +2499,10 @@ Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right
2440
2499
  - ⚠️ The `theme` prop is optional — inherited from context. Do NOT pass `theme` to every component.
2441
2500
  - ⚠️ The `slot` prop is NOT supported. Do not pass slot="heading" or similar — use Heading component or compound sub-component API instead.
2442
2501
 
2502
+ #### Common Anti-Patterns
2503
+
2504
+ - ❌ color="#22c55e" or color="var(--rs-color-green-500)" → ✅ color="success" — use semantic color values from NeutralColorPalette / NotificationsColorPalette.
2505
+
2443
2506
  ---
2444
2507
 
2445
2508
  ### TextArea
@@ -5071,6 +5134,14 @@ Inherits standard positioning props: `position`, `top`, `bottom`, `left`, `right
5071
5134
  - ⚠️ Use DataCard.Body for static/link DataRow children. Use DataCard.Listbox for interactive filter-selection DataRow children. Do not combine both in one DataCard.
5072
5135
  - ⚠️ The `slot` prop is not supported. Do not pass slot="heading" or similar — use the compound sub-component API instead.
5073
5136
 
5137
+ #### Disambiguation
5138
+
5139
+ ⚠️ DataCard is a purpose-built KPI/metric tile from @redsift/dashboard. This is the correct component 9 out of 10 times when building "a card with a big number" or "summary cards above a grid". Do NOT use Card or DetailedCard for this.
5140
+
5141
+ #### Common Anti-Patterns
5142
+
5143
+ - ❌ <Card style={{ borderLeft: "4px solid green" }}> for KPI tiles → ✅ <DataCard color="success"> — DataCard is purpose-built for metric tiles.
5144
+
5074
5145
  ---
5075
5146
 
5076
5147
  ### DataCardBody
@@ -8133,3 +8204,179 @@ export default () => {
8133
8204
  - **drilldown-datagrid-page**: The detail page a summary dashboard typically links to
8134
8205
  - **crossfiltered-datagrid-page**: Interactive version with cross-filtering and a DataGrid
8135
8206
  - **server-crossfiltered-datagrid-page**: Server-driven interactive dashboard
8207
+
8208
+ ## KPI Cards Above Charts
8209
+ **Description:** A row of metric tiles (DataCards) followed by one or two chart tiles, forming a dashboard overview page. Each DataCard shows a key metric; charts visualize trends or distributions. Users scan KPIs then drill into charts. This is the standard layout for 'Overview' pages across Red Sift products.
8210
+ **Components:** DataCard, DataCardHeader, DataCardBody, DataRow, BarChart, PieChart, ChartContainer, Flexbox, Heading, Text, Skeleton
8211
+ **Packages:** @redsift/dashboard, @redsift/charts, @redsift/design-system
8212
+ **Layout:** Flexbox column: top row = Flexbox row wrapping DataCards (flex: 1 each), bottom row = Flexbox row with one or two chart containers. Each DataCard has DataCardHeader + DataCardBody with DataRow children.
8213
+ **Tags:** dashboard, kpi, metric, chart, overview, summary, tiles, landing-page
8214
+
8215
+ ### When to Use
8216
+
8217
+ - Building an overview or landing page that shows key metrics at a glance
8218
+ - Users need to see aggregate KPIs and trend charts without interactive filtering
8219
+ - The page is read-only — clicking a DataRow navigates to a detail page
8220
+ - You want a standard two-row layout: metrics on top, charts below
8221
+
8222
+ **When NOT to use:**
8223
+
8224
+ - Users need to cross-filter between cards and a DataGrid — use Crossfiltered Datagrid Page instead
8225
+ - The page is primarily a table with summary KPIs — use Drilldown Datagrid Page instead
8226
+ - Only charts, no KPI tiles — use a simple Flexbox of ChartContainers
8227
+
8228
+ ### Anatomy
8229
+
8230
+ 1. Heading — Page title
8231
+ 2. KPI Row — Flexbox row of DataCards, each with DataCardHeader and DataCardBody containing DataRow items
8232
+ 3. Chart Row — Flexbox row of chart containers (BarChart, PieChart, etc.) wrapped in styled containers with titles
8233
+
8234
+ ## Chart Empty State
8235
+ **Description:** How to render loading, empty, and error states inside a DataCard or ChartContainer. Uses ChartEmptyState from @redsift/dashboard for consistent empty/error messaging, Skeleton for loading shimmer, and Alert + Button for error-with-retry.
8236
+ **Components:** ChartEmptyState, DataCard, DataCardHeader, DataCardBody, Skeleton, Alert, Button, Text
8237
+ **Packages:** @redsift/dashboard, @redsift/design-system
8238
+ **Layout:** DataCard with conditional content: loading (Skeleton), empty (ChartEmptyState), error (Alert + Button), or success (chart content).
8239
+ **Tags:** empty-state, loading, error, skeleton, chart, dashboard, retry
8240
+
8241
+ ### When to Use
8242
+
8243
+ - A chart or DataCard needs to show loading, empty, or error states
8244
+ - You want a consistent look across all chart tiles for non-happy-path states
8245
+ - The error state should include a retry action
8246
+
8247
+ **When NOT to use:**
8248
+
8249
+ - The component is a DataGrid — DataGrid has its own built-in loading/empty/error overlays
8250
+ - You only need a full-page loading spinner — use Spinner instead
8251
+
8252
+ ### Anatomy
8253
+
8254
+ 1. DataCard — Container for the chart tile
8255
+ 2. DataCardHeader — Title of the chart
8256
+ 3. DataCardBody — Conditional content based on state
8257
+ 4. Loading: Skeleton components matching the chart shape
8258
+ 5. Empty: ChartEmptyState with a message and optional illustration
8259
+ 6. Error: Alert variant='error' + Button variant='secondary' for retry
8260
+
8261
+ ## Error Banner with Retry
8262
+ **Description:** A section-level error display with a retry button, replacing hand-rolled styled.button and hex colors. Uses Alert from @redsift/design-system for the error message and Button variant='secondary' for the retry action. Never use styled.button or hardcoded rgba() values for this pattern.
8263
+ **Components:** Alert, Button, Flexbox, Text
8264
+ **Packages:** @redsift/design-system
8265
+ **Layout:** Flexbox column with Alert at top and optional Button below, or Alert with action prop containing the retry Button.
8266
+ **Tags:** error, retry, alert, banner, notification, failure
8267
+
8268
+ ### When to Use
8269
+
8270
+ - A section of the page failed to load and the user can retry
8271
+ - You need an inline error message with an action
8272
+ - Replacing a hand-rolled error banner with hardcoded styles
8273
+
8274
+ **When NOT to use:**
8275
+
8276
+ - The entire page failed — use a full-page error boundary instead
8277
+ - The error is inside a chart tile — use Chart Empty State pattern instead
8278
+
8279
+ ### Anatomy
8280
+
8281
+ 1. Alert — Displays the error message with severity='error'
8282
+ 2. Button — 'Retry' button with variant='secondary' and onClick handler
8283
+
8284
+ ## Host App Page Registration
8285
+ **Description:** Abstract contract for adding a new page to a Red Sift host application. Every new page requires a routing entry, a navigation entry in the sidebar, and a page title registered as an i18n key in ALL supported locales. Missing any locale mirror causes the page title to show as a raw key string. This is a framework pattern — concrete implementation depends on the host app's router and i18n system.
8286
+ **Components:** AppContainer, AppSidePanel, AppBar, AppContent
8287
+ **Packages:** @redsift/design-system
8288
+ **Layout:** AppContainer > AppSidePanel (nav entry) + AppContent (routed page component). AppBar displays the page title from i18n.
8289
+ **Tags:** host-app, page, routing, navigation, i18n, locale, title, setup
8290
+
8291
+ ### When to Use
8292
+
8293
+ - Adding a new page or view to a Red Sift application
8294
+ - The page needs a sidebar navigation entry
8295
+ - The page title must be translated across all supported locales
8296
+
8297
+ **When NOT to use:**
8298
+
8299
+ - Rendering a modal or dialog — no route needed
8300
+ - A sub-tab within an existing page — handled by the page's Tabs component
8301
+
8302
+ ### Anatomy
8303
+
8304
+ 1. Route definition — maps a URL path to a page component
8305
+ 2. Navigation entry — adds an item to AppSidePanel with icon, label i18n key, and route path
8306
+ 3. Page title i18n key — registered in EVERY locale file (e.g. en-US.json, fr-FR.json). If any locale is missing the key, the title renders as the raw key string.
8307
+ 4. Page component — wrapped in AppContent, receives route params
8308
+
8309
+ ### Implementation Checklist
8310
+
8311
+ 1. Define the route path and page component in the app's router configuration
8312
+ 2. Add a navigation entry to AppSidePanel with the route path and an i18n label key
8313
+ 3. Register the page title i18n key in ALL locale files (en-US, fr-FR, etc.)
8314
+ 4. Verify the title renders correctly by switching locales
8315
+ 5. Import @redsift/design-system/style/index.css at the app entry if not already done
8316
+
8317
+ ## Category Tabs Above Table
8318
+ **Description:** A row of Tabs above a DataGrid that filter the grid's rows by a category (e.g. All / Active / Expired / Critical). The selected tab becomes part of the grid's filterModel. Use this pattern when you have a small, well-known set of mutually exclusive row categories — it is a UX shortcut for the most common filter on the page. For arbitrary or many-valued filters, use the DataGrid's built-in column filter UI instead.
8319
+ **Components:** Tabs, Tab, TabPanel, DataGrid, Pill, Flexbox
8320
+ **Packages:** @redsift/design-system, @redsift/table
8321
+ **Layout:** Flexbox column: Tabs row + DataGrid below. Tabs are sticky-positioned above the grid; the active Tab drives a filterModel applied to the DataGrid.
8322
+ **Tags:** tabs, datagrid, filter, category, status-filter, segmented-control
8323
+
8324
+ ### When to Use
8325
+
8326
+ - You have a fixed, small set of mutually exclusive row categories (typically 2–6 tabs)
8327
+ - The category filter is the dominant user action on the page
8328
+ - Tabs should mirror an enum field on the row (e.g. status, severity)
8329
+
8330
+ **When NOT to use:**
8331
+
8332
+ - The filter values are dynamic or numerous — use the DataGrid's built-in column filter instead
8333
+ - Multiple simultaneous filters are required — Tabs are mutually exclusive by design
8334
+ - The categories themselves are not orthogonal (overlapping memberships)
8335
+
8336
+ ### Anatomy
8337
+
8338
+ 1. Tabs — DS Tabs from @redsift/design-system, one Tab per category plus an 'All' tab
8339
+ 2. Optional Pill — count badge inside each Tab label (e.g. 'Active (12)')
8340
+ 3. DataGrid — receives filterModel derived from the active tab
8341
+
8342
+ ### State Management
8343
+
8344
+ | Hook | Type | Initial | Description |
8345
+ |------|------|---------|-------------|
8346
+ | activeTab | string | 'all' | Slug of the currently selected tab; drives the DataGrid filterModel. |
8347
+
8348
+ ### Data Contract
8349
+
8350
+ ```tsx
8351
+ type Row = {
8352
+ id: string;
8353
+ status: 'active' | 'warning' | 'critical' | 'expired';
8354
+ // …other fields
8355
+ };
8356
+
8357
+ // activeTab → filterModel mapping
8358
+ const filterModelForTab = (tab: string): GridFilterModel =>
8359
+ tab === 'all'
8360
+ ? { items: [] }
8361
+ : { items: [{ columnField: 'status', operatorValue: 'equals', value: tab }] };
8362
+ ```
8363
+
8364
+ ### Implementation Checklist
8365
+
8366
+ 1. Define the tab list as a const array of { slug, label, filterValue } entries — one per category plus 'all'.
8367
+ 2. Add useState<string>('all') for activeTab.
8368
+ 3. Render <Tabs value={activeTab} onChange={setActiveTab}> with one <Tab> per entry. Inside the label, optionally show a count <Pill>.
8369
+ 4. Compute filterModel from activeTab via a pure helper.
8370
+ 5. Pass filterModel into <DataGrid filterModel={...} onFilterModelChange={...}>. Keep the DataGrid's own filter UI enabled so users can layer column filters on top.
8371
+ 6. Sync activeTab to the URL query string (?status=active) for shareable links.
8372
+
8373
+ ### Keyboard & Accessibility
8374
+
8375
+ - Tabs and Tab from @redsift/design-system already wire role="tablist" / role="tab" and arrow-key navigation
8376
+ - Use aria-controls to associate each Tab with the DataGrid id
8377
+ - Do not hide the DataGrid's built-in column filter — tab filters are a shortcut, not a replacement
8378
+
8379
+ ### Related Patterns
8380
+
8381
+ - **datagrid-page**: The underlying full-page grid. Add tabs on top when one enum field dominates filtering.
8382
+ - **tabbed-datagrid-client-side**: Closely related; this pattern is specifically the 'category filter' variant.
@@ -22,6 +22,25 @@ The Red Sift Design System provides reusable UI components including forms, navi
22
22
 
23
23
  ## Components
24
24
 
25
+ > **⚠️ Do NOT import from @mui/material, @mui/icons-material, or @mui/x-data-grid directly.**
26
+ > The Design System wraps or replaces every MUI component you need. Use these DS equivalents:
27
+ >
28
+ > | MUI component | DS equivalent | Package |
29
+ > |---------------|---------------|---------|
30
+ > | `Chip` | `Pill` | @redsift/design-system |
31
+ > | `Tabs` / `Tab` | `Tabs` / `Tab` | @redsift/design-system |
32
+ > | `Skeleton` | `Skeleton` | @redsift/design-system |
33
+ > | `Box` / `Stack` | `Flexbox` | @redsift/design-system |
34
+ > | `Typography` | `Heading` / `Text` | @redsift/design-system |
35
+ > | `Button` | `Button` | @redsift/design-system |
36
+ > | `Alert` | `Alert` | @redsift/design-system |
37
+ > | `Dialog` | `Dialog` | @redsift/popovers |
38
+ > | `Tooltip` | `Tooltip` | @redsift/popovers |
39
+ > | `Select` / `Autocomplete` | `Select` / `Combobox` | @redsift/pickers |
40
+ > | `Card` | `Card` (or `DataCard` for KPIs) | @redsift/design-system / @redsift/dashboard |
41
+ > | `DataGrid` / `DataGridPro` / `DataGridPremium` | `DataGrid` / `StatefulDataGrid` | @redsift/table |
42
+
43
+
25
44
  ### design-system
26
45
 
27
46
  - **ActiveDescendantListbox** (19 props)
@@ -223,6 +242,11 @@ Proven component groupings for common UI scenarios, extracted from production ap
223
242
  | Tabbed Datagrid Page | DataGrid, TextCell, Tabs, Tab, Flexbox, Pill, Number | @redsift/table, @redsift/design-system |
224
243
  | Server Tabbed Datagrid Page | DataGrid, TextCell, Tabs, Tab, Flexbox, Pill, Number | @redsift/table, @redsift/design-system, @mui/x-data-grid-pro |
225
244
  | Summary Dashboard | DataCard, DataRow, PieChart, BarChart, Flexbox, Icon, Text | @redsift/dashboard, @redsift/charts, @redsift/design-system |
245
+ | KPI Cards Above Charts | DataCard, DataCardHeader, DataCardBody, DataRow, BarChart, PieChart, ChartContainer, Flexbox, Heading, Text, Skeleton | @redsift/dashboard, @redsift/charts, @redsift/design-system |
246
+ | Chart Empty State | ChartEmptyState, DataCard, DataCardHeader, DataCardBody, Skeleton, Alert, Button, Text | @redsift/dashboard, @redsift/design-system |
247
+ | Error Banner with Retry | Alert, Button, Flexbox, Text | @redsift/design-system |
248
+ | Host App Page Registration | AppContainer, AppSidePanel, AppBar, AppContent | @redsift/design-system |
249
+ | Category Tabs Above Table | Tabs, Tab, TabPanel, DataGrid, Pill, Flexbox | @redsift/design-system, @redsift/table |
226
250
 
227
251
  **Datagrid Page** — when to use:
228
252
  - You need a filterable, sortable, paginated table of records
@@ -291,4 +315,30 @@ Proven component groupings for common UI scenarios, extracted from production ap
291
315
  - Navigation is the primary interaction — no inline filtering
292
316
  - No DataGrid needed on this page
293
317
 
318
+ **KPI Cards Above Charts** — when to use:
319
+ - Building an overview or landing page that shows key metrics at a glance
320
+ - Users need to see aggregate KPIs and trend charts without interactive filtering
321
+ - The page is read-only — clicking a DataRow navigates to a detail page
322
+ - You want a standard two-row layout: metrics on top, charts below
323
+
324
+ **Chart Empty State** — when to use:
325
+ - A chart or DataCard needs to show loading, empty, or error states
326
+ - You want a consistent look across all chart tiles for non-happy-path states
327
+ - The error state should include a retry action
328
+
329
+ **Error Banner with Retry** — when to use:
330
+ - A section of the page failed to load and the user can retry
331
+ - You need an inline error message with an action
332
+ - Replacing a hand-rolled error banner with hardcoded styles
333
+
334
+ **Host App Page Registration** — when to use:
335
+ - Adding a new page or view to a Red Sift application
336
+ - The page needs a sidebar navigation entry
337
+ - The page title must be translated across all supported locales
338
+
339
+ **Category Tabs Above Table** — when to use:
340
+ - You have a fixed, small set of mutually exclusive row categories (typically 2–6 tabs)
341
+ - The category filter is the dominant user action on the page
342
+ - Tabs should mirror an enum field on the row (e.g. status, severity)
343
+
294
344
  For detailed pattern documentation with demos, visit: https://design-system.redsift.io/patterns/
@@ -6,6 +6,61 @@ These patterns serve as implementation specs — they give LLMs and developers e
6
6
 
7
7
  ---
8
8
 
9
+ ## Quick Reference — Component Selection Cheat Sheet
10
+
11
+ Before picking a component, consult this table. It maps common UI intents to the correct component and package.
12
+
13
+ | UI Intent | Component(s) | Package | Do NOT Use |
14
+ | ------------------------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------- | ---------------------------------------- |
15
+ | KPI / metric tile (number + label + accent) | `DataCard` + `DataCard.Header` + `DataCard.Body` + `DataRow` | `@redsift/dashboard` | `Card` with inline styles |
16
+ | Set of KPI tiles above a grid | `<Flexbox flexDirection="row" flexWrap="wrap" gap="0">` wrapping `DataCard` tiles | `@redsift/dashboard` + `@redsift/design-system` | CSS Grid or inline flex styles |
17
+ | Status badge (Trusted / Pass / Fail) | `<Pill color="success\|warning\|error">Label</Pill>` | `@redsift/design-system` | `<Pill label="..." />` or unicode glyphs |
18
+ | Icon-only status indicator | `<Icon>` + `<Tooltip>` | `@redsift/design-system` + `@redsift/popovers` | Unicode characters (✓, ✕, ⚠) |
19
+ | Data grid / table | `DataGrid` | `@redsift/table` | Raw HTML table or MUI DataGrid directly |
20
+ | Loading placeholder | `Skeleton` / `SkeletonText` / `SkeletonCircle` | `@redsift/design-system` | `Skeleton` from `@mui/material` |
21
+ | Collapsible detail panel | `DetailedCard` + `DetailedCardSection` | `@redsift/design-system` | Custom accordion or Card |
22
+ | Generic container | `Card` + `Card.Header` + `Card.Body` | `@redsift/design-system` | Card for KPI tiles (use DataCard) |
23
+ | Modal / confirmation dialog | `Dialog` compound component | `@redsift/popovers` | Custom overlay |
24
+ | Tooltip on hover | `Tooltip` + `Tooltip.Trigger` + `Tooltip.Content` | `@redsift/popovers` | HTML `title` attribute |
25
+ | Dropdown selection | `Select` + `Select.Trigger` + `Select.Content` | `@redsift/pickers` | HTML `<select>` |
26
+ | Searchable selection | `Combobox` compound component | `@redsift/pickers` | Custom autocomplete |
27
+
28
+ ## Global Anti-Patterns
29
+
30
+ These mistakes apply across **all** patterns and components. Avoid them everywhere.
31
+
32
+ ### Semantic Colors — No Hex / RGB Literals
33
+
34
+ - **Wrong:** `color="#22c55e"`, `color="var(--rs-color-green-500, #22c55e)"`
35
+ - **Right:** `color="success"`, `color="warning"`, `color="error"`, `color="info"`
36
+ - DS components accept semantic color values. Never hardcode hex or CSS variable fallbacks.
37
+
38
+ ### Icons — mdi Only, No Unicode
39
+
40
+ - **Wrong:** `✓ Trusted`, `⚠ Warning`, `› Details`
41
+ - **Right:** `<Icon path={mdiCheck} />`, `<Icon path={mdiAlert} />`, `<Icon path={mdiChevronRight} />`
42
+ - Always import from `@redsift/icons`, never from `@mdi/js`.
43
+
44
+ ### DS Primitives over MUI Equivalents
45
+
46
+ - **Wrong:** `import { Skeleton } from '@mui/material'`
47
+ - **Right:** `import { Skeleton } from '@redsift/design-system'`
48
+ - The DS wraps or replaces MUI components. Always use the DS export.
49
+
50
+ ### Flexbox — String Props, No Inline Styles
51
+
52
+ - **Wrong:** `gap={4}`, `style={{ display: 'flex', gap: 4 }}`
53
+ - **Right:** `<Flexbox gap="4px" flexDirection="row" alignItems="center">`
54
+ - Use the `Flexbox` component with string props for layout.
55
+
56
+ ### Pill — Children, Not Label
57
+
58
+ - **Wrong:** `<Pill label="Active" />`
59
+ - **Right:** `<Pill color="success">Active</Pill>`
60
+ - Content goes in `children`. There is no `label` prop.
61
+
62
+ ---
63
+
9
64
  ## Datagrid Page
10
65
 
11
66
  **When to use:**
@@ -609,3 +664,139 @@ type FetchResult = {
609
664
  **Variants:** Loading State, Empty State, Error State
610
665
  **Related:** Drilldown Datagrid Page — the detail page a summary dashboard typically links to; Cross-filtered Datagrid Page — interactive version with cross-filtering and a DataGrid
611
666
  **Demo:** [Summary Dashboard](/patterns/summary-dashboard)
667
+
668
+ ---
669
+
670
+ ## KPI Cards Above Charts
671
+
672
+ A row of metric tiles (DataCards) followed by one or two chart tiles. The standard Overview page shape across Red Sift products.
673
+
674
+ **When to use:**
675
+
676
+ - Building an overview or landing page showing key metrics at a glance
677
+ - The page is read-only — clicking a DataRow navigates to a detail page
678
+ - Standard two-row layout: KPIs on top, charts below
679
+
680
+ **When NOT to use:**
681
+
682
+ - Users need to cross-filter between cards and a DataGrid — use **Cross-filtered Datagrid Page** instead
683
+ - The page is primarily a table with summary KPIs — use **Drilldown Datagrid Page** instead
684
+
685
+ **Key imports:** `DataCard`, `DataRow`, `BarChart`, `PieChart`, `Flexbox` from `@redsift/dashboard`, `@redsift/charts`, `@redsift/design-system`
686
+
687
+ **Anti-patterns:**
688
+
689
+ - styled.div with inline hex colors for tile borders → use `<DataCard color="success">`
690
+ - `<Card>` for KPI tiles → use `<DataCard>`
691
+ - MUI `Box` / `Stack` for the row layout → use `<Flexbox flexDirection="row" gap="16px">`
692
+
693
+ **Demo:** [/patterns/kpi-cards-above-charts](/patterns/kpi-cards-above-charts)
694
+
695
+ ---
696
+
697
+ ## Chart Empty State
698
+
699
+ Loading, empty, and error states inside a DataCard or ChartContainer. Uses `ChartEmptyState` for consistent messaging, `Skeleton` for loading shimmer, and `Alert` + `Button` for error-with-retry.
700
+
701
+ **When to use:**
702
+
703
+ - A chart or DataCard needs loading / empty / error states
704
+ - The error state should include a retry action
705
+
706
+ **Key imports:** `ChartEmptyState`, `DataCard` from `@redsift/dashboard`; `Skeleton`, `Alert`, `Button` from `@redsift/design-system`
707
+
708
+ **Anti-patterns:**
709
+
710
+ - styled.div with `border-radius: 4px; background: #f9fafb` for empty state → use `<ChartEmptyState>`
711
+ - `Skeleton` from `@mui/material` → use `Skeleton` from `@redsift/design-system`
712
+ - styled.button for retry → use `<Button variant="secondary">`
713
+
714
+ **Demo:** [/patterns/chart-empty-state](/patterns/chart-empty-state)
715
+
716
+ ---
717
+
718
+ ## Error Banner with Retry
719
+
720
+ Section-level error display with retry button. Replaces hand-rolled styled.button + hex colors with the canonical DS pattern.
721
+
722
+ **When to use:**
723
+
724
+ - A section of the page failed to load and the user can retry
725
+ - Inline error message with a single action
726
+
727
+ **When NOT to use:**
728
+
729
+ - Entire page failed — use a full-page error boundary instead
730
+ - Error inside a chart tile — use **Chart Empty State** pattern instead
731
+
732
+ **Key imports:** `Alert`, `Button` from `@redsift/design-system`
733
+
734
+ **Anti-patterns:**
735
+
736
+ - styled.button with `background: rgba(0,0,0,0.04)` → use `<Button variant="secondary">Retry</Button>`
737
+ - Plain `<div>` with hand-rolled error styling → use `<Alert severity="error">`
738
+ - Custom `rgba(0,0,0,0.12)` borders → use DS tokens via Alert's built-in styling
739
+
740
+ **Demo:** [/patterns/error-banner-with-retry](/patterns/error-banner-with-retry)
741
+
742
+ ---
743
+
744
+ ## Host App Page Registration
745
+
746
+ Abstract contract for adding a new page to a Red Sift host application. Every new page requires three things: a routing entry, a sidebar nav entry, and a page title registered as an i18n key in ALL supported locales.
747
+
748
+ **When to use:**
749
+
750
+ - Adding a new page or view to a Red Sift application
751
+ - The page needs a sidebar navigation entry
752
+ - The page title must be translated across all supported locales
753
+
754
+ **When NOT to use:**
755
+
756
+ - Rendering a modal or dialog — no route needed
757
+ - A sub-tab within an existing page — handled by the page's `Tabs` component
758
+
759
+ **Anatomy:**
760
+
761
+ 1. **Route definition** — maps a URL path to a page component
762
+ 2. **Navigation entry** — adds an item to `AppSidePanel` with icon, label i18n key, and route path
763
+ 3. **Page title i18n key** — registered in EVERY locale file (e.g. `en-US.json`, `fr-FR.json`). **If any locale is missing the key, the title renders as the raw key string** (e.g. "page.dashboard.title" instead of "Dashboard").
764
+ 4. **Page component** — wrapped in `AppContent`, receives route params
765
+
766
+ **Implementation Checklist:**
767
+
768
+ 1. Define the route path and page component in the app's router configuration
769
+ 2. Add a navigation entry to `AppSidePanel` with the route path and an i18n label key
770
+ 3. Register the page title i18n key in ALL locale files (en-US, fr-FR, etc.)
771
+ 4. Verify the title renders correctly by switching locales
772
+ 5. Import `@redsift/design-system/style/index.css` at the app entry if not already done
773
+
774
+ **Demo:** [/patterns/host-app-page-registration](/patterns/host-app-page-registration)
775
+
776
+ ---
777
+
778
+ ## Category Tabs Above Table
779
+
780
+ A `Tabs` row above a `DataGrid` that filters rows by a category enum (typically All / Active / Warning / Expired). The selected tab becomes part of the grid's `filterModel`.
781
+
782
+ **When to use:**
783
+
784
+ - You have a fixed, small set of mutually exclusive row categories (2–6 tabs)
785
+ - The category filter is the dominant user action on the page
786
+ - Tabs mirror an enum field on the row (status, severity, etc.)
787
+
788
+ **When NOT to use:**
789
+
790
+ - The filter values are dynamic or numerous — use the DataGrid's built-in column filter instead
791
+ - Multiple simultaneous filters are required — Tabs are mutually exclusive by design
792
+ - The categories overlap (a row could be in multiple categories at once)
793
+
794
+ **Anti-patterns:**
795
+
796
+ - `@mui/material` Tabs → use `Tabs` / `Tab` from `@redsift/design-system`
797
+ - `styled(Tab)` to fake a segmented control → DS Tabs already supports the visual variant; check `get_component_props('Tabs')`
798
+ - Separate `<DataGrid>` per tab → one DataGrid, swap `filterModel` based on the active tab
799
+ - Hard-coded counts in tab labels → derive from `rows` so they stay in sync
800
+ - Hiding column filters when tabs are added → tab filters and column filters compose; keep both
801
+
802
+ **Demo:** [/patterns/category-tabs-above-table](/patterns/category-tabs-above-table)