@assure-one/design-system 1.35.0 → 1.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1586 @@
1
+ {
2
+ "$comment": "Hand-maintained half of docs/components.md. `pnpm docs:catalogue` joins it with api/*.api.md; `pnpm docs:catalogue --check` (in test:contracts) fails when a public export has no row here or a row names an export that no longer exists. One row per component family: `parts` are the compound sub-components documented under the row, `helpers` the non-component exports of the family (cva tables, maps, formatters), `hooks` its hooks. `status` is derived (@deprecated from the API report, @experimental from the source JSDoc) unless set here. `story` defaults to the .stories.tsx next to the module. Categories: actions, forms, selection, feedback, overlays, navigation, layout, typography, data display, media, icons, shell/screens, hooks/utilities.",
3
+ "categories": {
4
+ "actions": "Things you press. Every clickable control is one of these; a `<button>`, `<a role=\"button\">` or `<div onClick>` in product code is a bug.",
5
+ "forms": "Controls that carry a value into a form. Every one binds to `Field` through `useFieldControl` (label, description, error, ids) and participates in native form submission (ADR-006); wrap them in `Field`, never in a hand-rolled label + input pair.",
6
+ "selection": "Pick one or many from a set: dropdowns, comboboxes, toggle groups, chips and filters.",
7
+ "feedback": "Tell the user what is happening: status messages, progress, loading and empty states.",
8
+ "overlays": "Layers above the page: dialogs, sheets, menus, popovers and tooltips. All portal, trap or manage focus, close on Escape and respect reduced motion.",
9
+ "navigation": "Move between places: tabs, breadcrumbs, pagination, steppers, trees and rails.",
10
+ "layout": "Arrange content: stacks, surfaces, cards, separators, section and page framing.",
11
+ "typography": "Text roles. Use these instead of bare `<h*>`, `<p>`, `<code>` and `<kbd>` so type scale, colour and letterspacing come from tokens.",
12
+ "data display": "Show records and status: tables, key/value grids, badges, dots, avatars, lists and cards for domain objects.",
13
+ "media": "Charts, previews and brand artwork.",
14
+ "shell/screens": "The application frame and full-screen composites: shell, sidebar, header, brand scope and product surfaces shared by more than one app.",
15
+ "hooks/utilities": "Non-rendering exports: hooks, class-name helpers, formatters and token objects."
16
+ },
17
+ "needs": [
18
+ { "need": "Trigger an action", "use": ["Button", "IconButton"], "notes": "`IconButton` when the control is only an icon (it requires an accessible name and shows a tooltip). Same `variant` × `intent` × `size` axes." },
19
+ { "need": "Navigate somewhere with a button look", "use": ["LinkButton"], "notes": "Renders an `<a href>`; `Button asChild` around your router's `Link` is the alternative." },
20
+ { "need": "Submit a form", "use": ["SubmitButton"], "notes": "Full-width by default; `type=\"submit\"` and pending state handled." },
21
+ { "need": "Make something that is not a button clickable", "use": ["Pressable"], "notes": "Keyboard, focus ring, disabled handling, no button chrome. Never `<div onClick>`." },
22
+ { "need": "Confirm a destructive action", "use": ["ConfirmActionButton", "AlertDialog"], "notes": "`ConfirmActionButton` wraps the dialog around any trigger; `AlertDialog` when you compose the copy yourself." },
23
+ { "need": "Act on selected rows", "use": ["BulkActionBar"], "notes": "Floating bar with the count and the row actions." },
24
+ { "need": "Keep Save / Cancel visible at the bottom of a long form", "use": ["StickyActionBar"] },
25
+ { "need": "Label + help + error around any control", "use": ["Field"], "notes": "`Label`, `FieldDescription`, `FieldError` inside; controls bind automatically. `Fieldset` groups several. `FieldControl` wires a non-DS control." },
26
+ { "need": "Free text, one line", "use": ["Input"], "notes": "`SearchInput` for search boxes, `NumberInput` for numbers, `PhoneField` for phone numbers, `OTPInput` for codes." },
27
+ { "need": "A phone number", "use": ["PhoneField"], "notes": "Country picker + national number, E.164 value. `PhoneInput` and `PhoneCountryInput` are deprecated." },
28
+ { "need": "Free text, several lines", "use": ["Textarea"] },
29
+ { "need": "A number with formatting or steppers", "use": ["NumberInput"] },
30
+ { "need": "A date, or a date range", "use": ["DatePicker", "DateRangePicker"], "notes": "`Calendar` alone when the picker should be inline rather than in a popover." },
31
+ { "need": "Upload files", "use": ["FileUpload"], "notes": "`DocumentRequestUpload` for the client-portal request flow." },
32
+ { "need": "Yes / no", "use": ["Checkbox", "Switch"], "notes": "`Switch` when the change applies immediately, `Checkbox` when it is submitted with the form or is one of several." },
33
+ { "need": "One of a few visible options", "use": ["RadioGroup", "ToggleGroup"], "notes": "`RadioGroup` in forms; `ToggleGroup` for view/mode switches with immediate effect." },
34
+ { "need": "One of many options in a dropdown", "use": ["Select", "Combobox"], "notes": "`Select` for short static lists; `Combobox` when the user should type to filter or the list is large or async." },
35
+ { "need": "Several of many options", "use": ["MultiSelect", "MultiSelectField"], "notes": "`MultiSelect` is the searchable dropdown; `MultiSelectField` a visible pill toggle row for a handful of options." },
36
+ { "need": "Pick a client or a team member", "use": ["ClientSelect", "TeamMemberSelect"] },
37
+ { "need": "Filter a list", "use": ["Toolbar", "MultiFilterPill", "DisplayMenu"], "notes": "`FilterChip` inside `Toolbar` for one-value filters, `MultiFilterPill` for multi-value, `DisplayMenu` for the Linear-style filter/group/sort/columns menu." },
38
+ { "need": "Removable or toggleable tokens (tags, applied filters)", "use": ["Chip"], "notes": "`DismissibleChip` is the older single-purpose removable chip." },
39
+ { "need": "A slider value", "use": ["Slider"] },
40
+ { "need": "Show a message inline (success, warning, error, info)", "use": ["Alert"] },
41
+ { "need": "Notify after an action", "use": ["ToastProvider"], "notes": "`useToast()` from inside the provider." },
42
+ { "need": "Show loading", "use": ["Spinner", "Skeleton", "LoadingRows"], "notes": "`Spinner` inside a control or small area, `Skeleton` for a shape, `LoadingRows` for list/table rows." },
43
+ { "need": "Show progress", "use": ["ProgressBar", "ProgressRing", "SegmentedProgress", "Stepper"], "notes": "`Stepper` when the steps have names; `SuiteProgress` for the suite's segmented percent meter." },
44
+ { "need": "Nothing to show yet", "use": ["EmptyState", "ComingSoon"] },
45
+ { "need": "A modal task or message", "use": ["Dialog", "ResponsiveDialog"], "notes": "`ResponsiveDialog` becomes a `Sheet` on small screens." },
46
+ { "need": "A side panel", "use": ["Sheet", "SideDrawer"], "notes": "`Sheet` is the Radix-based standard; `SideDrawer` is the older API kept for existing call sites." },
47
+ { "need": "A contextual menu of actions", "use": ["DropdownMenu", "ContextMenu", "NewMenu"], "notes": "`ContextMenu` on right-click; `NewMenu` is the ready-made \"+ New\" creation menu." },
48
+ { "need": "Extra content on hover or click", "use": ["Tooltip", "Popover", "HoverCard"], "notes": "`Tooltip` for a short label, `Popover` for interactive content, `HoverCard` for a rich preview on hover." },
49
+ { "need": "A global command / search box", "use": ["CommandPalette", "KeyboardShortcutsDialog"] },
50
+ { "need": "Switch between views", "use": ["Tabs", "ChannelTabs", "BottomNav"], "notes": "`BottomNav` is the mobile tab bar." },
51
+ { "need": "Where am I", "use": ["Breadcrumb", "PageHeader", "AppHeader"] },
52
+ { "need": "Page through results", "use": ["Pagination"], "notes": "`DataTablePagination` inside a `DataTable`." },
53
+ { "need": "A tree or a rail of items", "use": ["FolderTree", "ClientRailItem"] },
54
+ { "need": "Space things out", "use": ["Stack", "Inline"], "notes": "Tokenised gap and alignment; never ad-hoc `flex gap-*` in product code." },
55
+ { "need": "A bordered box or card", "use": ["Surface", "Card"], "notes": "`Card` adds header/title/description/footer parts and an interactive variant." },
56
+ { "need": "A divider", "use": ["Separator", "CategoryDivider"] },
57
+ { "need": "Collapse content", "use": ["Collapsible", "Accordion"] },
58
+ { "need": "Scroll a region", "use": ["ScrollArea"] },
59
+ { "need": "Title a page or a section", "use": ["PageHeader", "SectionHeader", "Heading"] },
60
+ { "need": "Body text, captions, code, keys", "use": ["Text", "Code", "Kbd", "Blockquote"] },
61
+ { "need": "A number with a caption", "use": ["Stat", "KpiCard"], "notes": "`KpiCard` is the dashboard tile with tone and hint." },
62
+ { "need": "A table of records", "use": ["DataTableView", "DataTable", "Table"], "notes": "`DataTableView` is config-driven (columns + data, owns search/sort/pagination); `DataTable` the composable parts; `Table` the bare semantic table." },
63
+ { "need": "Label / value pairs", "use": ["MetadataGrid"] },
64
+ { "need": "A status word or count", "use": ["StatusBadge", "Badge", "StatusPill", "StatusDot"], "notes": "`StatusBadge` for statuses (use `defineStatusMap`), `Badge` for counts and neutral labels, `StatusDot` for a dot alone." },
65
+ { "need": "A person or a file", "use": ["Avatar", "FileTypeBadge", "FileChip", "AttachmentChip"] },
66
+ { "need": "An activity feed or notifications", "use": ["ActivityList", "NotificationPanel"] },
67
+ { "need": "A chart", "use": ["AreaChart", "DonutChart", "StackedBarChart", "RankedBars"] },
68
+ { "need": "Preview a document", "use": ["PdfPreview", "SpreadsheetPreview"] },
69
+ { "need": "An icon", "use": ["Icons"], "notes": "From the catalogue only, never an inline `<svg>`; brand marks from the brand icon family or `Logo`." },
70
+ { "need": "The application frame", "use": ["Shell", "Sidebar", "AppHeader"], "notes": "`DesignSystemProvider` (or `/next`'s `NextDesignSystemProvider`) once in the root layout; `BrandScope` sets the product theme of a subtree." },
71
+ { "need": "Configure strings, locale, links or the portal container", "use": ["DesignSystemProvider"], "notes": "Once, in the root layout. `useDsMessages` reads the resolved strings." },
72
+ { "need": "Theme one subtree (scheme, brand, density) including its overlays", "use": ["ThemeScope", "BrandScope"], "notes": "`ThemeScope` re-stamps portalled overlays; `BrandScope` is product brand only." },
73
+ { "need": "Hide text visually but keep it for screen readers", "use": ["VisuallyHidden"] },
74
+ { "need": "Merge class names", "use": ["cn"], "notes": "Consumer classes win over component classes by cascade; `cn` only dedupes." }
75
+ ],
76
+ "iconFamilies": [
77
+ {
78
+ "name": "Icons",
79
+ "pattern": "Icon$",
80
+ "exclude": "BrandIcon$",
81
+ "helpers": ["createIcon"],
82
+ "description": "The UI glyph catalogue: 24-unit grid, `currentColor` 1.5 strokes, `aria-hidden` unless titled. Import from `@assure-one/design-system/icons` (server-safe) or the root.",
83
+ "useWhen": "Any glyph in a control, a list row, a status, an empty state; `createIcon` to register a one-off glyph in the same contract.",
84
+ "dontUseWhen": "You need a product mark (brand icon family or `Logo`), a state-driven glyph (`StatusIcon`, `PriorityIcon`) or an illustration.",
85
+ "replacesRawHtml": ["<svg>", "lucide-react"],
86
+ "story": "src/primitives/icons.stories.tsx",
87
+ "status": "experimental"
88
+ },
89
+ {
90
+ "name": "Brand icons",
91
+ "pattern": "BrandIcon$",
92
+ "description": "Product and third-party marks: the Assure products plus Google and Microsoft. The `BrandIcon` suffix is the contract disclosure that the drawing is a trademark.",
93
+ "useWhen": "A product switcher, a sign-in provider button, a suite tile.",
94
+ "dontUseWhen": "A generic glyph is meant (use the icon catalogue) or the full wordmark is wanted (`Logo`).",
95
+ "replacesRawHtml": ["<img src=\"…logo.svg\">"],
96
+ "story": "src/primitives/logo.stories.tsx"
97
+ }
98
+ ],
99
+ "components": {
100
+ "Button": {
101
+ "category": "actions",
102
+ "helpers": ["buttonVariants", "resolveButtonStyle"],
103
+ "useWhen": "Any action the user triggers: `variant` (solid, soft, outline, ghost, link) × `intent` (brand, neutral, success, danger) × `size` (xs…xl); `loading`, `iconStart`/`iconEnd`, `asChild` for a router link.",
104
+ "dontUseWhen": "The control is icon-only (`IconButton`), navigates (`LinkButton`), submits a form (`SubmitButton`) or is a clickable non-button surface (`Pressable`).",
105
+ "replacesRawHtml": ["<button>", "<a role=\"button\">", "<div onClick>", "<input type=\"button\">"],
106
+ "related": ["IconButton", "LinkButton", "SubmitButton", "Pressable", "PrimaryAction"],
107
+ "since": "0.0.0",
108
+ "docs": ["docs/adr/007-variant-intent-vocabulary.md"]
109
+ },
110
+ "IconButton": {
111
+ "category": "actions",
112
+ "helpers": ["iconButtonVariants"],
113
+ "useWhen": "An icon-only action (close, edit, more): square control-scale geometry, a required accessible name, a tooltip by default, the Button family's variants and intents.",
114
+ "dontUseWhen": "The action has a visible text label (`Button` with `iconStart`) or is a menu trigger that shows the chosen value.",
115
+ "replacesRawHtml": ["<button><svg/></button>"],
116
+ "related": ["Button", "Tooltip"],
117
+ "since": "1.35.0"
118
+ },
119
+ "LinkButton": {
120
+ "category": "actions",
121
+ "useWhen": "Navigation that should look like a button: an `<a href>` with the Button variants, intents, sizes and icon slots.",
122
+ "dontUseWhen": "The action does not change the URL (`Button`) or the link should read as inline text (`Text asChild` around your router link).",
123
+ "replacesRawHtml": ["<a class=\"btn\">"],
124
+ "related": ["Button", "LinkAction"],
125
+ "since": "0.0.0"
126
+ },
127
+ "SubmitButton": {
128
+ "category": "actions",
129
+ "useWhen": "The primary submit of a form: `type=\"submit\"`, full width by default (`fullWidth={false}` inline), shows `pendingText` while the form's `useFormStatus` is pending.",
130
+ "dontUseWhen": "The button is not a form submit or you need a secondary action next to the submit (`Button`).",
131
+ "replacesRawHtml": ["<button type=\"submit\">", "<input type=\"submit\">"],
132
+ "related": ["Button", "Field"],
133
+ "since": "0.0.0"
134
+ },
135
+ "Pressable": {
136
+ "category": "actions",
137
+ "useWhen": "A clickable region without button chrome: a card, a row, a tile. Renders a `<button>` (or `asChild`) with keyboard activation, focus ring and disabled handling.",
138
+ "dontUseWhen": "A visible button is meant (`Button`) or the region contains its own interactive controls (use `Card variant=\"interactive\"` with an explicit action).",
139
+ "replacesRawHtml": ["<div onClick>", "<span role=\"button\">", "<li onClick>"],
140
+ "related": ["Button", "Card"],
141
+ "since": "1.35.0"
142
+ },
143
+ "CopyButton": {
144
+ "category": "actions",
145
+ "useWhen": "Copy a value to the clipboard with check-mark feedback (ids, codes, links).",
146
+ "dontUseWhen": "The copy needs a confirmation toast or copies rich content — compose `IconButton` + `useToast`.",
147
+ "replacesRawHtml": ["navigator.clipboard.writeText + useState"],
148
+ "related": ["IconButton", "ToastProvider"],
149
+ "since": "0.0.0"
150
+ },
151
+ "ConfirmActionButton": {
152
+ "category": "actions",
153
+ "useWhen": "A destructive or irreversible action that needs a confirmation step: wraps `AlertDialog` around any trigger and retires `window.confirm()`.",
154
+ "dontUseWhen": "The confirmation needs a form or custom body (`AlertDialog` composed directly) or the action is reversible (act, then offer undo in a toast).",
155
+ "replacesRawHtml": ["window.confirm()", "useState + AlertDialog boilerplate"],
156
+ "related": ["AlertDialog", "DangerAction"],
157
+ "since": "0.3.0"
158
+ },
159
+ "PrimaryAction": {
160
+ "category": "actions",
161
+ "label": "Intent actions",
162
+ "parts": ["SecondaryAction", "DangerAction", "LinkAction", "IconAction"],
163
+ "useWhen": "Intent-named `Button` wrappers for product code that reads by role: primary, secondary, danger, link-styled, icon-only.",
164
+ "dontUseWhen": "You need the full variant × intent matrix or a size outside the defaults (`Button`, `IconButton`).",
165
+ "related": ["Button", "IconButton", "LinkButton"],
166
+ "since": "0.3.0"
167
+ },
168
+ "BulkActionBar": {
169
+ "category": "actions",
170
+ "parts": ["BulkActionBarAction", "BulkActionBarSeparator"],
171
+ "useWhen": "A floating bar that appears when rows are selected: selection count, actions, separators, clear.",
172
+ "dontUseWhen": "Actions apply to one record (row menu via `DropdownMenu`) or belong to the page (`PageHeader` actions).",
173
+ "related": ["DataTable", "StickyActionBar"],
174
+ "since": "0.15.0"
175
+ },
176
+ "StickyActionBar": {
177
+ "category": "actions",
178
+ "useWhen": "Save / Cancel that stays visible at the bottom of a long form or settings page, with an optional hint and mobile-nav offset.",
179
+ "dontUseWhen": "The form fits the viewport (put the `SubmitButton` at the end) or the actions belong to a dialog (`DialogFooter`).",
180
+ "replacesRawHtml": ["<div class=\"sticky bottom-0\">"],
181
+ "related": ["SubmitButton", "BulkActionBar"],
182
+ "since": "1.3.0"
183
+ },
184
+ "NewMenu": {
185
+ "category": "actions",
186
+ "useWhen": "The \"+ New\" creation menu of an app: grouped actions with icons and shortcuts on a `DropdownMenu`.",
187
+ "dontUseWhen": "The menu is contextual to one record (`DropdownMenu`) or has a single action (`Button`).",
188
+ "related": ["DropdownMenu", "AppHeader"],
189
+ "since": "1.2.0"
190
+ },
191
+ "DisplayMenu": {
192
+ "category": "actions",
193
+ "useWhen": "The Linear-style Display control of a list surface: filters, grouping, ordering and column visibility in one searchable menu, driven by a `sections` array.",
194
+ "dontUseWhen": "There is one filter (`FilterChip`) or one multi-value filter (`MultiFilterPill`).",
195
+ "related": ["Toolbar", "MultiFilterPill", "DataTableView"],
196
+ "since": "1.25.0"
197
+ },
198
+ "Toolbar": {
199
+ "category": "actions",
200
+ "parts": ["FilterChip"],
201
+ "helpers": ["filterChipVariants"],
202
+ "useWhen": "The row of controls above a list or dashboard; `FilterChip` for a single-value filter toggle inside it. Controls share one control size so the row reads as one line.",
203
+ "dontUseWhen": "The controls belong to a table card (`DataTableToolbar`) or the filter is multi-value (`MultiFilterPill`).",
204
+ "replacesRawHtml": ["<div class=\"flex items-center gap-2\"> above a list"],
205
+ "related": ["MultiFilterPill", "DisplayMenu", "DataTable"],
206
+ "since": "0.3.0"
207
+ },
208
+ "SuggestionPills": {
209
+ "category": "actions",
210
+ "useWhen": "A strip of AI quick-reply pills floated above a composer; renders nothing when empty and not loading, so mount it unconditionally.",
211
+ "dontUseWhen": "The choices are a form value (`MultiSelectField`) or filters (`FilterChip`).",
212
+ "related": ["MessageComposer", "AiDraftCard"],
213
+ "since": "1.5.0"
214
+ },
215
+
216
+ "Field": {
217
+ "category": "forms",
218
+ "parts": ["FieldDescription", "FieldError"],
219
+ "useWhen": "Every form control: owns ids, states and ARIA wiring for one control and its `Label`, `FieldDescription` and `FieldError`; design-system controls bind automatically.",
220
+ "dontUseWhen": "Grouping several controls (`Fieldset`) or wiring a control the design system does not ship (`FieldControl`).",
221
+ "replacesRawHtml": ["<label for> + <input id> + <p id> aria-describedby", "<p class=\"text-red-500\">"],
222
+ "related": ["Label", "Fieldset", "FieldControl", "useFieldControl"],
223
+ "since": "unreleased",
224
+ "docs": ["docs/forms.md", "docs/adr/006-field-native-form-participation.md"]
225
+ },
226
+ "FieldControl": {
227
+ "category": "forms",
228
+ "useWhen": "A control that is not a design-system component (a rich-text editor, a canvas, a plain `<input>`) that must still get the `Field` wiring; a Slot that renders no element of its own.",
229
+ "dontUseWhen": "The control is a design-system component — it already calls `useFieldControl`.",
230
+ "related": ["Field", "useFieldControl"],
231
+ "since": "unreleased"
232
+ },
233
+ "Fieldset": {
234
+ "category": "forms",
235
+ "parts": ["FieldsetLegend"],
236
+ "useWhen": "Group related controls under one legend (a radio group, a set of checkboxes, a date range, a composite field): native `<fieldset>`/`<legend>`, `disabled` disables all.",
237
+ "dontUseWhen": "There is a single control (`Field`) or the grouping is only visual (`Section`, `Card`).",
238
+ "replacesRawHtml": ["<fieldset>", "<legend>", "<div role=\"group\">"],
239
+ "related": ["Field", "RadioGroup", "FormSection"],
240
+ "since": "unreleased"
241
+ },
242
+ "Label": {
243
+ "category": "forms",
244
+ "helpers": ["labelVariants"],
245
+ "useWhen": "The visible name of a control, inside a `Field` (binds automatically) or with an explicit `htmlFor`.",
246
+ "dontUseWhen": "The text is not a control's name (`Text`) or a heading (`Heading`).",
247
+ "replacesRawHtml": ["<label>"],
248
+ "related": ["Field", "Input"],
249
+ "since": "0.0.0"
250
+ },
251
+ "Input": {
252
+ "category": "forms",
253
+ "helpers": ["inputVariants"],
254
+ "useWhen": "Single-line text, email, password, url, tel, file: `size` on the control scale, `variant` default/ghost, invalid state, start/end adornments, `label`/`description`/`error` sugar, `classNames` per part.",
255
+ "dontUseWhen": "Multi-line (`Textarea`), numbers (`NumberInput`), search (`SearchInput`), phone (`PhoneField`), codes (`OTPInput`), dates (`DatePicker`), files with drop zone (`FileUpload`).",
256
+ "replacesRawHtml": ["<input>", "<input type=\"text\">", "<input type=\"email\">", "<input type=\"password\">"],
257
+ "related": ["Field", "Textarea", "NumberInput", "SearchInput"],
258
+ "since": "0.0.0",
259
+ "docs": ["docs/design-system/control-sizes.md"]
260
+ },
261
+ "Textarea": {
262
+ "category": "forms",
263
+ "helpers": ["textareaVariants"],
264
+ "useWhen": "Multi-line free text with the Input chrome, sizes, invalid state and Field binding.",
265
+ "dontUseWhen": "Rich text (bring your editor inside `FieldControl` or `MessageComposer`) or a single line (`Input`).",
266
+ "replacesRawHtml": ["<textarea>"],
267
+ "related": ["Input", "Field", "MessageComposer"],
268
+ "since": "0.0.0"
269
+ },
270
+ "NumberInput": {
271
+ "category": "forms",
272
+ "useWhen": "A `number | null` value with locale formatting, min/max/step, optional stepper buttons and a text fallback while typing.",
273
+ "dontUseWhen": "Money entered as text with a mask (`Input` + your formatter) or a bounded visual value (`Slider`).",
274
+ "replacesRawHtml": ["<input type=\"number\">"],
275
+ "related": ["Input", "Slider"],
276
+ "since": "unreleased"
277
+ },
278
+ "SearchInput": {
279
+ "category": "forms",
280
+ "helpers": ["searchInputVariants"],
281
+ "useWhen": "A search box: search icon, clear affordance, `size`, debounced `onValueChange`.",
282
+ "dontUseWhen": "The search filters a dropdown's options (`Combobox`) or the whole app (`CommandPalette`).",
283
+ "replacesRawHtml": ["<input type=\"search\">"],
284
+ "related": ["Input", "Combobox", "DataTable"],
285
+ "since": "0.0.0"
286
+ },
287
+ "OTPInput": {
288
+ "category": "forms",
289
+ "useWhen": "A one-time code split into cells: paste handling, auto-advance, one hidden form value, named by the surrounding `Label`.",
290
+ "dontUseWhen": "A plain numeric field (`NumberInput`) or a password (`Input type=\"password\"`).",
291
+ "replacesRawHtml": ["six <input maxlength=\"1\">"],
292
+ "related": ["Input", "Field"],
293
+ "since": "0.0.0"
294
+ },
295
+ "PhoneField": {
296
+ "category": "forms",
297
+ "helpers": ["DEFAULT_PHONE_FIELD_MESSAGES"],
298
+ "useWhen": "The one phone control: a `Combobox` country picker beside the national-number input on the shared control chrome; E.164 value (`+14155550100` or `null`), `onValueChange(value, { country, nationalNumber })`, lazy-loaded flags, Field binding and native submission; `DEFAULT_PHONE_FIELD_MESSAGES` to localise its strings.",
299
+ "dontUseWhen": "The value is not a phone number (`Input type=\"tel\"` is never right either — an extension or a PIN is an `Input`/`OTPInput`).",
300
+ "replacesRawHtml": ["<input type=\"tel\">", "<select> of dial codes + <input type=\"tel\">"],
301
+ "related": ["Combobox", "Field", "PhoneInput", "PhoneCountryInput"],
302
+ "since": "unreleased"
303
+ },
304
+ "PhoneInput": {
305
+ "category": "forms",
306
+ "useWhen": "Only in code that already uses it: US-only phone formatting on the `Input` chrome.",
307
+ "dontUseWhen": "New code — `PhoneField` (deprecated, removed in 3.0).",
308
+ "related": ["PhoneField", "Input"],
309
+ "since": "0.0.0"
310
+ },
311
+ "PhoneCountryInput": {
312
+ "category": "forms",
313
+ "parts": ["CountrySelect", "CountryFlag"],
314
+ "useWhen": "Only in code that already uses it: the pre-PhoneField country `Select` + `tel` input pair; `parsePhoneForEditing` seeds it from a stored E.164 string.",
315
+ "dontUseWhen": "New code — `PhoneField` (its country picker is a `Combobox`; deprecated, removed in 3.0).",
316
+ "related": ["PhoneField", "COUNTRY_CODES"],
317
+ "since": "1.1.0"
318
+ },
319
+ "FileUpload": {
320
+ "category": "forms",
321
+ "useWhen": "Pick or drop files: accept/multiple/max size, file list with remove, keyboard-focusable input, Field binding.",
322
+ "dontUseWhen": "The upload belongs to a client document request (`DocumentRequestUpload`) or you only show already-uploaded files (`AttachmentChip`, `FileChip`).",
323
+ "replacesRawHtml": ["<input type=\"file\">", "drop-zone div with onDrop"],
324
+ "related": ["DocumentRequestUpload", "AttachmentChip", "FileTypeBadge"],
325
+ "since": "0.0.0"
326
+ },
327
+ "DatePicker": {
328
+ "category": "forms",
329
+ "useWhen": "One date (or a year in year mode) typed with a mask or picked from a `Calendar` popover; ISO `YYYY-MM-DD` value, `onValueChange`, deterministic `en-US` display.",
330
+ "dontUseWhen": "A range (`DateRangePicker`) or an always-visible calendar (`Calendar`).",
331
+ "replacesRawHtml": ["<input type=\"date\">"],
332
+ "related": ["DateRangePicker", "Calendar", "isoToDisplay"],
333
+ "since": "0.0.0"
334
+ },
335
+ "DateRangePicker": {
336
+ "category": "forms",
337
+ "useWhen": "A from/to pair in one control; posts `${name}_from` / `${name}_to`.",
338
+ "dontUseWhen": "A single date (`DatePicker`) or two independent dates in a form (two `DatePicker`s in a `Fieldset`).",
339
+ "replacesRawHtml": ["two <input type=\"date\">"],
340
+ "related": ["DatePicker", "Calendar"],
341
+ "since": "0.11.0"
342
+ },
343
+ "Calendar": {
344
+ "category": "forms",
345
+ "useWhen": "An inline month grid (react-day-picker) for choosing a day or range without a popover.",
346
+ "dontUseWhen": "The date belongs in a form field (`DatePicker`, `DateRangePicker`).",
347
+ "related": ["DatePicker", "DateRangePicker"],
348
+ "since": "0.0.0"
349
+ },
350
+ "Checkbox": {
351
+ "category": "forms",
352
+ "useWhen": "A boolean or one of several independent choices; `checked` accepts `\"indeterminate\"` for select-all; native form participation.",
353
+ "dontUseWhen": "The change applies immediately as a setting (`Switch`) or the choices are exclusive (`RadioGroup`).",
354
+ "replacesRawHtml": ["<input type=\"checkbox\">"],
355
+ "related": ["Switch", "RadioGroup", "DataTable"],
356
+ "since": "0.0.0"
357
+ },
358
+ "RadioGroup": {
359
+ "category": "forms",
360
+ "parts": ["RadioGroupItem"],
361
+ "useWhen": "Exclusive choice among a few visible options in a form; wrap in `Fieldset` for the legend.",
362
+ "dontUseWhen": "More than about six options (`Select`) or an immediate view switch (`ToggleGroup`).",
363
+ "replacesRawHtml": ["<input type=\"radio\">"],
364
+ "related": ["Fieldset", "ToggleGroup", "Select"],
365
+ "since": "0.0.0"
366
+ },
367
+ "Switch": {
368
+ "category": "forms",
369
+ "useWhen": "An on/off setting that takes effect immediately.",
370
+ "dontUseWhen": "The value is submitted with the form (`Checkbox`).",
371
+ "replacesRawHtml": ["<input type=\"checkbox\" role=\"switch\">"],
372
+ "related": ["Checkbox"],
373
+ "since": "0.0.0"
374
+ },
375
+ "Slider": {
376
+ "category": "forms",
377
+ "useWhen": "A bounded numeric value chosen by dragging (one or two thumbs).",
378
+ "dontUseWhen": "Exact numbers matter (`NumberInput`).",
379
+ "replacesRawHtml": ["<input type=\"range\">"],
380
+ "related": ["NumberInput"],
381
+ "since": "0.0.0"
382
+ },
383
+ "MultiSelectField": {
384
+ "category": "forms",
385
+ "useWhen": "A visible row of pill buttons that toggle membership in a comma-separated value: a handful of options everyone should see.",
386
+ "dontUseWhen": "Many options or search (`MultiSelect`), or the pills are filters rather than a form value (`FilterChip`).",
387
+ "replacesRawHtml": ["<input type=\"checkbox\"> styled as pills"],
388
+ "related": ["MultiSelect", "ToggleGroup", "Chip"],
389
+ "since": "0.0.0"
390
+ },
391
+ "Grid": {
392
+ "category": "forms",
393
+ "useWhen": "A matrix of typed cells (rows × columns of text, number, select, checkbox) edited as one controlled value with an accessible name per cell.",
394
+ "dontUseWhen": "Read-only data (`Table`, `DataTable`) or a single column of fields (`Stack` of `Field`s).",
395
+ "replacesRawHtml": ["<table> of <input>s"],
396
+ "related": ["Table", "Questions"],
397
+ "since": "1.20.0"
398
+ },
399
+ "Questions": {
400
+ "category": "forms",
401
+ "useWhen": "One questionnaire question card: index, title, description, type, required flag, `chrome` card or plain.",
402
+ "dontUseWhen": "You are laying out the whole questionnaire (`QuestionnairePanel`) or a plain form field (`Field`).",
403
+ "related": ["QuestionnairePanel", "Field"],
404
+ "since": "1.17.0"
405
+ },
406
+ "QuestionnairePanel": {
407
+ "category": "forms",
408
+ "useWhen": "The questionnaire container of the client portal: `cards` or `navigation` variant with eyebrow and title.",
409
+ "dontUseWhen": "A settings form (`Fieldset` inside `Card`).",
410
+ "related": ["Questions", "Fieldset"],
411
+ "since": "1.17.0"
412
+ },
413
+ "MessageComposer": {
414
+ "category": "forms",
415
+ "useWhen": "The chat input of a thread: one card chrome, optional quick-reply chips, your editor as `children`, a footer with a built-in Send.",
416
+ "dontUseWhen": "A plain multi-line field (`Textarea`) or an email signature editor (`SignatureEditor`).",
417
+ "related": ["Textarea", "SuggestionPills", "AiDraftCard", "MessageBubble"],
418
+ "since": "0.14.0"
419
+ },
420
+ "SignatureEditor": {
421
+ "category": "forms",
422
+ "useWhen": "The panel chrome for editing a personal email signature: header with Add image, your editor as `children`, Save / Insert footer; drop it in a `Popover` or use standalone.",
423
+ "dontUseWhen": "Capturing a drawn e-signature (`ProposalSignatureBlock`).",
424
+ "related": ["MessageComposer", "Popover"],
425
+ "since": "1.5.0"
426
+ },
427
+ "DocumentRequestField": {
428
+ "category": "forms",
429
+ "useWhen": "One row of a document request form: a slot for your document-type select plus description and required toggle.",
430
+ "dontUseWhen": "A generic form field (`Field`).",
431
+ "related": ["DocumentRequestDetail", "Field", "Select"],
432
+ "since": "1.4.0"
433
+ },
434
+ "DocumentRequestUpload": {
435
+ "category": "forms",
436
+ "useWhen": "The client-portal upload for a requested document: drop zone, progress and states tied to the request.",
437
+ "dontUseWhen": "A generic file field (`FileUpload`).",
438
+ "related": ["FileUpload", "DocumentChecklist", "DocumentRequestDetail"],
439
+ "since": "1.20.0"
440
+ },
441
+ "ProposalSignatureBlock": {
442
+ "category": "forms",
443
+ "label": "Proposal signing",
444
+ "parts": ["ProposalConsentGate", "ProposalPaymentCapture"],
445
+ "useWhen": "The signing step of a proposal: consent gate, signature capture, payment capture.",
446
+ "dontUseWhen": "An email signature (`SignatureEditor`).",
447
+ "related": ["AgreementViewer", "ProposalPackageCard"],
448
+ "since": "1.12.0"
449
+ },
450
+ "FormSection": {
451
+ "category": "forms",
452
+ "useWhen": "Only in code that already uses it: a titled `<fieldset>` block of a settings form with description and trailing action.",
453
+ "dontUseWhen": "New code — use `Fieldset` + `FieldsetLegend` (deprecated, removed in 3.0).",
454
+ "related": ["Fieldset", "Field"],
455
+ "since": "0.4.1"
456
+ },
457
+ "FormError": {
458
+ "category": "forms",
459
+ "label": "FormError / FormSuccess",
460
+ "parts": ["FormSuccess"],
461
+ "useWhen": "Only in code that already uses them: the pre-Field inline error and success messages (contract C-FORM-MSG).",
462
+ "dontUseWhen": "New code — `FieldError` and `FieldDescription` inside a `Field`, or a toast for a saved form (deprecated, removed in 3.0).",
463
+ "related": ["Field", "ToastProvider"],
464
+ "since": "0.0.0"
465
+ },
466
+
467
+ "Select": {
468
+ "category": "selection",
469
+ "parts": ["SelectRoot", "SelectTrigger", "SelectValue", "SelectContent", "SelectItem", "SelectGroup", "SelectLabel", "SelectSeparator", "SelectScrollUpButton", "SelectScrollDownButton"],
470
+ "useWhen": "One of a short static list in a dropdown: the sealed `Select` takes `options`; the `Select*` parts compose custom items. Empty value is a real empty (no sentinel option), `size`, `classNames`, Field binding.",
471
+ "dontUseWhen": "The user should type to filter, the list is long or async (`Combobox`), several values (`MultiSelect`), or a few options that can all be visible (`RadioGroup`, `ToggleGroup`).",
472
+ "replacesRawHtml": ["<select>", "<option>"],
473
+ "related": ["Combobox", "MultiSelect", "ClientSelect", "TeamMemberSelect"],
474
+ "since": "0.0.0"
475
+ },
476
+ "Combobox": {
477
+ "category": "selection",
478
+ "helpers": ["DEFAULT_COMBOBOX_MESSAGES"],
479
+ "useWhen": "A searchable pick: one input, a portalled listbox, the `Option<T>` model (`{ value, label }`), async loading and empty messages, single or `multiple`.",
480
+ "dontUseWhen": "A short static list (`Select`) or free text with suggestions that need not match (`Input` + `Popover`).",
481
+ "replacesRawHtml": ["<input list> + <datalist>", "<select> with a search box"],
482
+ "related": ["Select", "MultiSelect", "SearchSelect"],
483
+ "since": "unreleased"
484
+ },
485
+ "MultiSelect": {
486
+ "category": "selection",
487
+ "useWhen": "Several of many options with search: `Combobox` in `multiple` mode with selected chips.",
488
+ "dontUseWhen": "A handful of options that should all be visible (`MultiSelectField`) or one value (`Combobox`, `Select`).",
489
+ "replacesRawHtml": ["<select multiple>"],
490
+ "related": ["Combobox", "MultiSelectField", "Chip"],
491
+ "since": "unreleased"
492
+ },
493
+ "SearchSelect": {
494
+ "category": "selection",
495
+ "useWhen": "Only in code that already uses it: the pre-Combobox searchable select with `{ id, label }` options (contract C-SEARCHSELECT).",
496
+ "dontUseWhen": "New code — `Combobox` with `Option` (deprecated, removed in 3.0; CM-08 rewrites single-mode call sites).",
497
+ "related": ["Combobox", "MultiSelect"],
498
+ "since": "0.0.0"
499
+ },
500
+ "ClientSelect": {
501
+ "category": "selection",
502
+ "useWhen": "Pick one client: avatar, name and email rows on the `Select` primitive, long names truncated.",
503
+ "dontUseWhen": "Searching thousands of clients (`Combobox` with async options) or any other entity (`Select`).",
504
+ "related": ["Select", "TeamMemberSelect", "Combobox"],
505
+ "since": "0.0.0"
506
+ },
507
+ "TeamMemberSelect": {
508
+ "category": "selection",
509
+ "useWhen": "Pick an assignee: avatar and name rows on the `Select` primitive, with an unassigned option.",
510
+ "dontUseWhen": "Several assignees (`MultiSelect`) or any other entity (`Select`).",
511
+ "related": ["Select", "ClientSelect", "DataTableView"],
512
+ "since": "0.0.0"
513
+ },
514
+ "ToggleGroup": {
515
+ "category": "selection",
516
+ "parts": ["ToggleGroupItem"],
517
+ "useWhen": "A view or mode switch with immediate effect (list/grid, day/week), single or multiple, roving focus.",
518
+ "dontUseWhen": "The choice is a form value (`RadioGroup`, `MultiSelectField`) or navigation between panels (`Tabs`).",
519
+ "replacesRawHtml": ["group of <button aria-pressed>"],
520
+ "related": ["Tabs", "RadioGroup", "DocumentSourceFilter"],
521
+ "since": "0.0.0"
522
+ },
523
+ "Chip": {
524
+ "category": "selection",
525
+ "helpers": ["chipVariants", "resolveChipStyle"],
526
+ "useWhen": "A removable, toggleable or clickable token: applied filters, tags, selected values; `variant` × `intent` × `size`, `onRemove`, `pressed`.",
527
+ "dontUseWhen": "A static label (`Badge`), a status (`StatusBadge`) or a file (`FileChip`, `AttachmentChip`).",
528
+ "replacesRawHtml": ["<span class=\"rounded-full …\"><button>×</button></span>"],
529
+ "related": ["DismissibleChip", "Badge", "Toolbar", "MultiSelect"],
530
+ "since": "1.35.0"
531
+ },
532
+ "DismissibleChip": {
533
+ "category": "selection",
534
+ "useWhen": "Only in code that already uses it: a label with a remove button.",
535
+ "dontUseWhen": "New code — `Chip` with `onRemove` covers it with the shared variants and sizes.",
536
+ "related": ["Chip"],
537
+ "since": "0.4.0"
538
+ },
539
+ "MultiFilterPill": {
540
+ "category": "selection",
541
+ "useWhen": "A toolbar filter with a multi-select dropdown and a count of applied values.",
542
+ "dontUseWhen": "A single-value filter (`FilterChip`) or the full display menu (`DisplayMenu`).",
543
+ "related": ["Toolbar", "DisplayMenu", "MultiSelect"],
544
+ "since": "0.0.0"
545
+ },
546
+ "DocumentSourceFilter": {
547
+ "category": "selection",
548
+ "useWhen": "Scope a document list to a provenance bucket (all, uploaded, emailed, …) with counts: a `ToggleGroup` that reuses `DocumentSourceTag`'s glyphs.",
549
+ "dontUseWhen": "Any other segmented filter (`ToggleGroup`).",
550
+ "related": ["ToggleGroup", "DocumentSourceTag", "DocumentDetailPanel"],
551
+ "since": "1.12.0"
552
+ },
553
+
554
+ "Alert": {
555
+ "category": "feedback",
556
+ "parts": ["AlertTitle", "AlertDescription"],
557
+ "helpers": ["alertVariants"],
558
+ "useWhen": "An inline banner in the page flow: success, warning, danger or info, with title, description and optional action.",
559
+ "dontUseWhen": "Feedback after an action that should disappear (`ToastProvider`), a per-field error (`FieldError`) or a blocking message (`AlertDialog`).",
560
+ "replacesRawHtml": ["<div role=\"alert\">", "coloured bordered div"],
561
+ "related": ["ToastProvider", "Field", "AlertDialog"],
562
+ "since": "0.0.0"
563
+ },
564
+ "ToastProvider": {
565
+ "category": "feedback",
566
+ "hooks": ["useToast"],
567
+ "useWhen": "Transient notifications after an action: mount `ToastProvider` once, call `useToast()` anywhere below; `/testing` ships `createToastRecorder`.",
568
+ "dontUseWhen": "The message must stay until read (`Alert`) or is tied to a field (`FieldError`).",
569
+ "replacesRawHtml": ["alert()", "hand-rolled toast portal"],
570
+ "related": ["Alert", "CopyButton"],
571
+ "since": "0.0.0"
572
+ },
573
+ "Spinner": {
574
+ "category": "feedback",
575
+ "helpers": ["spinnerVariants", "SPINNER_TONE_TO_INTENT"],
576
+ "useWhen": "Indeterminate activity in a small area or inside a control; inherits `currentColor` unless an `intent` is set.",
577
+ "dontUseWhen": "Loading content with a known shape (`Skeleton`, `LoadingRows`) or a button's own pending state (`Button loading`).",
578
+ "replacesRawHtml": ["animate-spin svg"],
579
+ "related": ["Skeleton", "LoadingRows", "ProgressBar"],
580
+ "since": "0.15.0"
581
+ },
582
+ "Skeleton": {
583
+ "category": "feedback",
584
+ "parts": ["SkeletonText", "SkeletonCircle"],
585
+ "useWhen": "A placeholder in the shape of the content that is loading: block, text lines, circle.",
586
+ "dontUseWhen": "Rows of a list or table (`LoadingRows`) or an operation with no layout to reserve (`Spinner`).",
587
+ "replacesRawHtml": ["<div class=\"animate-pulse bg-…\">"],
588
+ "related": ["LoadingRows", "Spinner"],
589
+ "since": "0.0.0"
590
+ },
591
+ "LoadingRows": {
592
+ "category": "feedback",
593
+ "useWhen": "N uniform skeleton rows while a list or table loads.",
594
+ "dontUseWhen": "A single shape (`Skeleton`).",
595
+ "replacesRawHtml": ["Array.from({ length }).map(<Skeleton/>)"],
596
+ "related": ["Skeleton", "DataTable"],
597
+ "since": "0.4.1"
598
+ },
599
+ "ProgressBar": {
600
+ "category": "feedback",
601
+ "helpers": ["progressBarVariants", "PROGRESS_LEGACY_TO_INTENT"],
602
+ "useWhen": "A determinate (or indeterminate) horizontal meter; `intent` sets the colour, otherwise it follows the value.",
603
+ "dontUseWhen": "A compact circular meter (`ProgressRing`), discrete steps (`SegmentedProgress`, `Stepper`) or the suite's percent readout (`SuiteProgress`).",
604
+ "replacesRawHtml": ["<progress>", "nested div with width:%"],
605
+ "related": ["ProgressRing", "SegmentedProgress", "SuiteProgress"],
606
+ "since": "0.0.0"
607
+ },
608
+ "ProgressRing": {
609
+ "category": "feedback",
610
+ "helpers": ["progressRingVariants"],
611
+ "useWhen": "A circular meter for a card or tile, with the same `intent` and value-driven colour rule as `ProgressBar`.",
612
+ "dontUseWhen": "A wide layout (`ProgressBar`) or a donut of several series (`DonutChart`).",
613
+ "related": ["ProgressBar", "DonutChart"],
614
+ "since": "0.0.0"
615
+ },
616
+ "SegmentedProgress": {
617
+ "category": "feedback",
618
+ "useWhen": "Progress through a known number of steps as filled segments (onboarding, checklists).",
619
+ "dontUseWhen": "The steps have names (`Stepper`) or the value is continuous (`ProgressBar`).",
620
+ "related": ["Stepper", "ProgressBar", "SuiteProgress"],
621
+ "since": "1.2.0"
622
+ },
623
+ "SuiteProgress": {
624
+ "category": "feedback",
625
+ "helpers": ["suiteProgressFillVariants"],
626
+ "useWhen": "The suite's discrete segmented meter with a percent readout, tinted per product or `intent`.",
627
+ "dontUseWhen": "A generic segmented meter (`SegmentedProgress`) or a continuous one (`ProgressBar`).",
628
+ "related": ["SegmentedProgress", "ProgressBar"],
629
+ "since": "1.34.0"
630
+ },
631
+ "EmptyState": {
632
+ "category": "feedback",
633
+ "useWhen": "A list or panel has nothing to show: icon, title, description and one action.",
634
+ "dontUseWhen": "The feature does not exist yet (`ComingSoon`) or content is loading (`Skeleton`).",
635
+ "replacesRawHtml": ["centred div with an icon and grey text"],
636
+ "related": ["ComingSoon", "LoadingRows"],
637
+ "since": "0.0.0"
638
+ },
639
+ "ComingSoon": {
640
+ "category": "feedback",
641
+ "useWhen": "A placeholder for a feature that is not available yet: icon, title, description and a feature list.",
642
+ "dontUseWhen": "The feature exists but has no data (`EmptyState`).",
643
+ "related": ["EmptyState"],
644
+ "since": "0.0.0"
645
+ },
646
+ "AttentionItem": {
647
+ "category": "feedback",
648
+ "useWhen": "One row of an attention queue: icon, title, description, service tone and trailing action.",
649
+ "dontUseWhen": "A notification (`NotificationPanel` items) or an activity event (`ActivityList` items).",
650
+ "related": ["NotificationPanel", "ActivityList", "KpiCard"],
651
+ "since": "1.2.0"
652
+ },
653
+ "MissingDocumentsPanel": {
654
+ "category": "feedback",
655
+ "useWhen": "The firm-side panel listing documents a client has not provided, with a Request action.",
656
+ "dontUseWhen": "The client-side checklist (`DocumentChecklist`).",
657
+ "related": ["DocumentChecklist", "DocumentRequestDetail"],
658
+ "since": "1.4.0"
659
+ },
660
+ "AiDraftCard": {
661
+ "category": "feedback",
662
+ "useWhen": "Present an AI-generated draft inside a composer: one `state` prop drives loading, refining, error and ready (collapsible); you pass the body and actions.",
663
+ "dontUseWhen": "A human message (`MessageBubble`) or AI quick replies (`SuggestionPills`).",
664
+ "related": ["MessageComposer", "SuggestionPills", "AIReceiptPanel"],
665
+ "since": "1.5.0"
666
+ },
667
+ "AIReceiptPanel": {
668
+ "category": "feedback",
669
+ "useWhen": "The receipt-reading panel: idle, reading and done states with the extracted result and an Attach action.",
670
+ "dontUseWhen": "A generic upload (`FileUpload`) or a draft message (`AiDraftCard`).",
671
+ "related": ["AiDraftCard", "FileUpload"],
672
+ "since": "1.2.0"
673
+ },
674
+
675
+ "Dialog": {
676
+ "category": "overlays",
677
+ "parts": ["DialogTrigger", "DialogPortal", "DialogOverlay", "DialogContent", "DialogHeader", "DialogTitle", "DialogDescription", "DialogBody", "DialogFooter", "DialogClose"],
678
+ "useWhen": "A modal task or message: focus trap, Escape, overlay, `DialogTitle` required for the accessible name; `size` up to `xl` (or the `--ds-dialog-width` variable), `height`, and `DialogBody` as the scrolling region between header and footer.",
679
+ "dontUseWhen": "A confirmation that must be answered (`AlertDialog`), a side panel (`Sheet`), a mobile-friendly modal (`ResponsiveDialog`) or non-modal content (`Popover`).",
680
+ "replacesRawHtml": ["<dialog>", "fixed inset-0 div"],
681
+ "related": ["AlertDialog", "Sheet", "ResponsiveDialog", "CommandPalette"],
682
+ "since": "0.0.0",
683
+ "docs": ["docs/adr/012-overlay-presence-motion.md"]
684
+ },
685
+ "AlertDialog": {
686
+ "category": "overlays",
687
+ "parts": ["AlertDialogTrigger", "AlertDialogPortal", "AlertDialogOverlay", "AlertDialogContent", "AlertDialogHeader", "AlertDialogTitle", "AlertDialogDescription", "AlertDialogFooter", "AlertDialogAction", "AlertDialogCancel"],
688
+ "useWhen": "A decision the user must make before continuing (delete, discard): no outside-click dismiss, explicit Action and Cancel.",
689
+ "dontUseWhen": "A dismissible task (`Dialog`) or a one-line confirm around a trigger (`ConfirmActionButton`).",
690
+ "replacesRawHtml": ["window.confirm()"],
691
+ "related": ["Dialog", "ConfirmActionButton"],
692
+ "since": "0.0.0"
693
+ },
694
+ "Sheet": {
695
+ "category": "overlays",
696
+ "parts": ["SheetTrigger", "SheetPortal", "SheetOverlay", "SheetContent", "SheetHeader", "SheetTitle", "SheetDescription", "SheetBody", "SheetFooter", "SheetClose"],
697
+ "useWhen": "A panel sliding in from an edge for a secondary task or detail: `side`, sizes, the Dialog accessibility model, `SheetBody` as the scrolling region between header and footer.",
698
+ "dontUseWhen": "Centred content (`Dialog`) or a persistent split view (`MasterDetailLayout`).",
699
+ "replacesRawHtml": ["fixed right-0 h-full div"],
700
+ "related": ["SideDrawer", "Dialog", "ResponsiveDialog"],
701
+ "since": "0.0.0"
702
+ },
703
+ "SideDrawer": {
704
+ "category": "overlays",
705
+ "useWhen": "Only in code that already uses it: the earlier slide-in panel API (`open`, `onClose`, `title`, `width`).",
706
+ "dontUseWhen": "New code — `Sheet` has the same behaviour with composable parts.",
707
+ "related": ["Sheet"],
708
+ "since": "0.0.0"
709
+ },
710
+ "ResponsiveDialog": {
711
+ "category": "overlays",
712
+ "useWhen": "A modal that should be a `Dialog` on desktop and a bottom `Sheet` below the `sm` breakpoint, decided after mount.",
713
+ "dontUseWhen": "The presentation must be fixed (`Dialog`, `Sheet`).",
714
+ "related": ["Dialog", "Sheet"],
715
+ "since": "1.3.0"
716
+ },
717
+ "Popover": {
718
+ "category": "overlays",
719
+ "parts": ["PopoverTrigger", "PopoverAnchor", "PopoverPortal", "PopoverContent", "PopoverClose"],
720
+ "useWhen": "Interactive content anchored to a trigger: a small form, a picker, a filter panel.",
721
+ "dontUseWhen": "A short non-interactive label (`Tooltip`), a preview on hover (`HoverCard`) or a list of actions (`DropdownMenu`).",
722
+ "replacesRawHtml": ["absolute-positioned div toggled by state"],
723
+ "related": ["Tooltip", "HoverCard", "DropdownMenu"],
724
+ "since": "0.0.0"
725
+ },
726
+ "HoverCard": {
727
+ "category": "overlays",
728
+ "parts": ["HoverCardTrigger", "HoverCardPortal", "HoverCardContent"],
729
+ "useWhen": "A rich preview when hovering a link or name (a person card, a record summary), for sighted pointer users.",
730
+ "dontUseWhen": "The content is essential (it is hover-only) or interactive (`Popover`).",
731
+ "related": ["Popover", "Tooltip"],
732
+ "since": "0.0.0"
733
+ },
734
+ "Tooltip": {
735
+ "category": "overlays",
736
+ "parts": ["TooltipProvider", "TooltipTrigger", "TooltipPortal", "TooltipContent"],
737
+ "useWhen": "A short label for a control on hover and focus; the sealed `Tooltip` takes `content`, the parts compose.",
738
+ "dontUseWhen": "The text is essential to use the control (make it visible) or interactive (`Popover`).",
739
+ "replacesRawHtml": ["title=\"…\""],
740
+ "related": ["IconButton", "Popover", "Kbd"],
741
+ "since": "0.0.0"
742
+ },
743
+ "DropdownMenu": {
744
+ "category": "overlays",
745
+ "parts": ["DropdownMenuTrigger", "DropdownMenuPortal", "DropdownMenuContent", "DropdownMenuItem", "DropdownMenuCheckboxItem", "DropdownMenuRadioGroup", "DropdownMenuRadioItem", "DropdownMenuGroup", "DropdownMenuLabel", "DropdownMenuSeparator", "DropdownMenuShortcut", "DropdownMenuSub", "DropdownMenuSubTrigger", "DropdownMenuSubContent"],
746
+ "useWhen": "A menu of actions from a button: items, checkbox and radio items, groups, shortcuts, submenus; `/testing` ships `openMenu`.",
747
+ "dontUseWhen": "Choosing a form value (`Select`), right-click (`ContextMenu`) or a form inside (`Popover`).",
748
+ "replacesRawHtml": ["<ul> shown on click", "<select> used as a menu"],
749
+ "related": ["ContextMenu", "NewMenu", "Select", "Popover"],
750
+ "since": "0.0.0"
751
+ },
752
+ "ContextMenu": {
753
+ "category": "overlays",
754
+ "parts": ["ContextMenuTrigger", "ContextMenuPortal", "ContextMenuContent", "ContextMenuItem", "ContextMenuCheckboxItem", "ContextMenuRadioGroup", "ContextMenuRadioItem", "ContextMenuGroup", "ContextMenuLabel", "ContextMenuSeparator", "ContextMenuShortcut", "ContextMenuSub", "ContextMenuSubTrigger", "ContextMenuSubContent"],
755
+ "useWhen": "Actions on right-click or long-press over a region, with the same item model as `DropdownMenu`.",
756
+ "dontUseWhen": "The actions must be discoverable (`DropdownMenu` from a visible trigger).",
757
+ "replacesRawHtml": ["onContextMenu + positioned div"],
758
+ "related": ["DropdownMenu"],
759
+ "since": "0.0.0"
760
+ },
761
+ "CommandPalette": {
762
+ "category": "overlays",
763
+ "useWhen": "The ⌘K command and search dialog: `cmdk` inside `Dialog`, groups, shortcuts, async results.",
764
+ "dontUseWhen": "Searching one list (`SearchInput`) or picking a form value (`Combobox`).",
765
+ "related": ["Dialog", "KeyboardShortcutsDialog", "Combobox"],
766
+ "since": "0.0.0"
767
+ },
768
+ "KeyboardShortcutsDialog": {
769
+ "category": "overlays",
770
+ "useWhen": "The \"?\" help dialog listing keyboard shortcuts by section; no props shows the universal General section.",
771
+ "dontUseWhen": "Showing one shortcut next to a control (`Kbd`, `KbdHint`).",
772
+ "related": ["Kbd", "CommandPalette"],
773
+ "since": "0.0.0"
774
+ },
775
+
776
+ "Tabs": {
777
+ "category": "navigation",
778
+ "parts": ["TabsList", "TabsTrigger", "TabsContent"],
779
+ "useWhen": "Switch between panels of one page; roving focus, `value`/`onValueChange`.",
780
+ "dontUseWhen": "The switch changes a mode rather than showing another panel (`ToggleGroup`), or it is the mobile app-level bar (`BottomNav`).",
781
+ "replacesRawHtml": ["<ul role=\"tablist\">", "buttons toggling useState panels"],
782
+ "related": ["ToggleGroup", "ChannelTabs", "BottomNav"],
783
+ "since": "0.0.0"
784
+ },
785
+ "ChannelTabs": {
786
+ "category": "navigation",
787
+ "useWhen": "Pill tabs switching between communication channels on a thread, each with a toned status dot and unread count; fully controlled.",
788
+ "dontUseWhen": "Generic panels (`Tabs`).",
789
+ "related": ["Tabs", "StatusDot", "MessageBubble"],
790
+ "since": "1.5.0"
791
+ },
792
+ "Breadcrumb": {
793
+ "category": "navigation",
794
+ "parts": ["BreadcrumbList", "BreadcrumbItem", "BreadcrumbLink", "BreadcrumbPage", "BreadcrumbSeparator"],
795
+ "useWhen": "The path to the current page; `BreadcrumbPage` marks the current one, `BreadcrumbLink asChild` wraps your router link.",
796
+ "dontUseWhen": "The page title itself (`PageHeader`) or the app-level bar (`AppHeaderBreadcrumb` inside `AppHeader`).",
797
+ "replacesRawHtml": ["<nav aria-label=\"breadcrumb\"><ol>"],
798
+ "related": ["PageHeader", "AppHeader"],
799
+ "since": "0.0.0"
800
+ },
801
+ "Pagination": {
802
+ "category": "navigation",
803
+ "useWhen": "Page controls for a paged list: current/total pages, sibling count, optional total items.",
804
+ "dontUseWhen": "Inside a `DataTable` (`DataTablePagination`) or infinite scroll.",
805
+ "replacesRawHtml": ["<nav> of page number buttons"],
806
+ "related": ["DataTable", "DataTableView"],
807
+ "since": "0.0.0"
808
+ },
809
+ "Stepper": {
810
+ "category": "navigation",
811
+ "useWhen": "Named steps of a multi-step flow, horizontal or vertical, with the current step marked.",
812
+ "dontUseWhen": "Unnamed progress (`SegmentedProgress`) or a timeline of past events (`EngagementTimeline`).",
813
+ "related": ["SegmentedProgress", "EngagementTimeline"],
814
+ "since": "0.0.0"
815
+ },
816
+ "BottomNav": {
817
+ "category": "navigation",
818
+ "useWhen": "The mobile tab bar at the bottom of the app: tabs with icons and badges, controlled `value`.",
819
+ "dontUseWhen": "Desktop navigation (`Sidebar`) or in-page panels (`Tabs`).",
820
+ "related": ["Sidebar", "Tabs", "StickyActionBar"],
821
+ "since": "1.2.0"
822
+ },
823
+ "FolderTree": {
824
+ "category": "navigation",
825
+ "useWhen": "A collapsible tree of folders with an active node, default-open ids and selection callback.",
826
+ "dontUseWhen": "A flat list (`ClientRailItem`) or a file list (`DocumentList`).",
827
+ "related": ["DocumentsWorkspaceLayout", "ClientRailItem", "Collapsible"],
828
+ "since": "1.2.0"
829
+ },
830
+ "ClientRailItem": {
831
+ "category": "navigation",
832
+ "parts": ["ClientRailGroupHeader"],
833
+ "useWhen": "One client row in the Documents left rail (avatar, name, counts) plus the section label above a group.",
834
+ "dontUseWhen": "Picking a client in a form (`ClientSelect`) or the main navigation (`SidebarLink`).",
835
+ "related": ["DocumentsWorkspaceLayout", "ClientSelect", "Sidebar"],
836
+ "since": "1.4.0"
837
+ },
838
+
839
+ "Stack": {
840
+ "category": "layout",
841
+ "useWhen": "A vertical (or `direction=\"row\"`) flex container that owns the gap between its children with tokenised `gap` and alignment.",
842
+ "dontUseWhen": "A wrapping horizontal row (`Inline`) or a bordered box (`Surface`).",
843
+ "replacesRawHtml": ["<div class=\"flex flex-col gap-4\">"],
844
+ "related": ["Inline", "Surface"],
845
+ "since": "1.33.0"
846
+ },
847
+ "Inline": {
848
+ "category": "layout",
849
+ "useWhen": "A horizontal wrapping row with children centred on the baseline and a tokenised gap: a row of chips, a button row, meta items.",
850
+ "dontUseWhen": "A column (`Stack`) or a toolbar of controls that must share one control size (`Toolbar`).",
851
+ "replacesRawHtml": ["<div class=\"flex flex-wrap items-center gap-2\">"],
852
+ "related": ["Stack", "Toolbar"],
853
+ "since": "1.33.0"
854
+ },
855
+ "Surface": {
856
+ "category": "layout",
857
+ "useWhen": "The bordered box content sits on: surface background, 1px rule, radius, `padding` role (none/sm/md/lg).",
858
+ "dontUseWhen": "You need header/title/footer parts or an interactive variant (`Card`).",
859
+ "replacesRawHtml": ["<div class=\"rounded-xl border bg-white p-4\">"],
860
+ "related": ["Card", "Stack"],
861
+ "since": "1.33.0"
862
+ },
863
+ "Card": {
864
+ "category": "layout",
865
+ "parts": ["CardHeader", "CardTitle", "CardDescription", "CardAction", "CardContent", "CardFooter"],
866
+ "helpers": ["cardVariants"],
867
+ "useWhen": "A surface with structure: header, title, description, trailing action, content, footer; `variant` default, interactive (hover border) or flat (nested).",
868
+ "dontUseWhen": "A plain box without parts (`Surface`), a KPI tile (`KpiCard`) or a domain card that already exists (`EngagementCard`, `DocumentFileRow`).",
869
+ "replacesRawHtml": ["<div class=\"rounded-xl border shadow\">"],
870
+ "related": ["Surface", "KpiCard", "Pressable"],
871
+ "since": "0.0.0"
872
+ },
873
+ "Separator": {
874
+ "category": "layout",
875
+ "useWhen": "A horizontal or vertical rule between groups, decorative or semantic.",
876
+ "dontUseWhen": "The divider carries a category label (`CategoryDivider`) or sits inside a menu (`DropdownMenuSeparator`).",
877
+ "replacesRawHtml": ["<hr>", "<div class=\"border-t\">"],
878
+ "related": ["CategoryDivider"],
879
+ "since": "0.0.0"
880
+ },
881
+ "AspectRatio": {
882
+ "category": "layout",
883
+ "useWhen": "Reserve a fixed ratio box for an image, video or embed.",
884
+ "dontUseWhen": "The media has intrinsic size (plain `<img>` with width/height).",
885
+ "replacesRawHtml": ["padding-top percentage hack"],
886
+ "related": ["PdfPreview"],
887
+ "since": "0.0.0"
888
+ },
889
+ "ScrollArea": {
890
+ "category": "layout",
891
+ "parts": ["ScrollBar"],
892
+ "useWhen": "A scrollable region with styled, consistent scrollbars (panels, menus, side rails).",
893
+ "dontUseWhen": "The document scrolls (leave it to the browser).",
894
+ "replacesRawHtml": ["<div class=\"overflow-auto\">"],
895
+ "related": ["Sheet", "Sidebar"],
896
+ "since": "0.0.0"
897
+ },
898
+ "Collapsible": {
899
+ "category": "layout",
900
+ "parts": ["CollapsibleTrigger", "CollapsibleContent"],
901
+ "useWhen": "Show/hide one region from a trigger, animated and reduced-motion aware.",
902
+ "dontUseWhen": "Several mutually exclusive sections (`Accordion`).",
903
+ "replacesRawHtml": ["<details>/<summary>", "useState toggle"],
904
+ "related": ["Accordion", "FolderTree"],
905
+ "since": "0.0.0"
906
+ },
907
+ "Accordion": {
908
+ "category": "layout",
909
+ "parts": ["AccordionItem", "AccordionTrigger", "AccordionContent"],
910
+ "useWhen": "A list of expandable sections, single or multiple open.",
911
+ "dontUseWhen": "One region (`Collapsible`) or navigation between panels (`Tabs`).",
912
+ "replacesRawHtml": ["stack of <details>"],
913
+ "related": ["Collapsible", "Tabs"],
914
+ "since": "0.0.0"
915
+ },
916
+ "Section": {
917
+ "category": "layout",
918
+ "parts": ["SectionHead"],
919
+ "useWhen": "A max-width centred content section with the canonical `--content-pad` gutter and a `SectionHead` title row.",
920
+ "dontUseWhen": "The page already sits in `Content` of the `Shell` and needs a page title (`PageHeader`).",
921
+ "replacesRawHtml": ["<section class=\"mx-auto max-w-… px-8\">"],
922
+ "related": ["SectionHeader", "PageHeader", "Shell"],
923
+ "since": "0.0.0"
924
+ },
925
+ "SectionHeader": {
926
+ "category": "layout",
927
+ "useWhen": "A title + description block for a marketing-style or settings section.",
928
+ "dontUseWhen": "The top of a page (`PageHeader`) or a form group (`FieldsetLegend`).",
929
+ "replacesRawHtml": ["<h2> + <p> pair"],
930
+ "related": ["PageHeader", "Heading", "Section"],
931
+ "since": "0.0.0"
932
+ },
933
+ "PageHeader": {
934
+ "category": "layout",
935
+ "parts": ["PageHeaderSpec", "PageHeaderSep"],
936
+ "useWhen": "The top-of-page title block: eyebrow, headline with trailing actions, description and a meta row (`PageHeaderSpec` items separated by `PageHeaderSep`).",
937
+ "dontUseWhen": "The sticky app bar (`AppHeader`) or a section inside the page (`SectionHeader`).",
938
+ "replacesRawHtml": ["<div class=\"flex items-center justify-between\"><h1>"],
939
+ "related": ["AppHeader", "SectionHeader", "Breadcrumb"],
940
+ "since": "0.3.0"
941
+ },
942
+ "CategoryDivider": {
943
+ "category": "layout",
944
+ "parts": ["CategoryTag"],
945
+ "useWhen": "Separate a run of items by service line: a tone-tinted category pill, a hairline and an optional count — the one place per-service colour is allowed.",
946
+ "dontUseWhen": "A plain rule (`Separator`) or a status (`StatusBadge`).",
947
+ "related": ["Separator", "serviceToneStyle"],
948
+ "since": "1.3.0"
949
+ },
950
+ "StickyStack": {
951
+ "category": "layout",
952
+ "parts": ["StickyStackLayer", "StickyStackSticky", "StickyStackSectionHeader"],
953
+ "useWhen": "Several fixed layers (app header, toolbar, section headers) that must stack without overlapping: layers are measured and sticky regions consume the offset.",
954
+ "dontUseWhen": "One sticky element (`position: sticky` on it) or a bottom bar (`StickyActionBar`).",
955
+ "replacesRawHtml": ["hard-coded top-[56px] sticky offsets"],
956
+ "related": ["AppHeader", "StickyActionBar"],
957
+ "since": "1.30.1"
958
+ },
959
+ "DetailGrid": {
960
+ "category": "layout",
961
+ "label": "Detail layout",
962
+ "parts": ["DetailSpine", "DetailSpineHeader", "DetailSpineSection", "DetailSpineStats", "DetailMain"],
963
+ "useWhen": "A record detail page: a sticky 320px spine (identity, key facts, stats) and a scrolling main column for tabs, sections and feeds.",
964
+ "dontUseWhen": "A list with a selected item beside it (`MasterDetailLayout`) or a plain page (`Section`).",
965
+ "replacesRawHtml": ["<div class=\"grid grid-cols-[320px_1fr]\">"],
966
+ "related": ["MasterDetailLayout", "MetadataGrid", "Tabs"],
967
+ "since": "0.3.0"
968
+ },
969
+ "MasterDetailLayout": {
970
+ "category": "layout",
971
+ "useWhen": "A list on the left and the selected item's detail on the right, collapsing to one pane on small screens.",
972
+ "dontUseWhen": "A record page with a spine (`DetailGrid`) or the three-pane documents workspace (`DocumentsWorkspaceLayout`).",
973
+ "related": ["DetailGrid", "DocumentsWorkspaceLayout"],
974
+ "since": "1.3.0"
975
+ },
976
+ "DocumentsWorkspaceLayout": {
977
+ "category": "layout",
978
+ "useWhen": "The three-pane documents workspace: clients rail, folder tree and files area as slots.",
979
+ "dontUseWhen": "Two panes (`MasterDetailLayout`).",
980
+ "related": ["ClientRailItem", "FolderTree", "DocumentDetailPanel", "MasterDetailLayout"],
981
+ "since": "1.4.0"
982
+ },
983
+ "DashGrid": {
984
+ "category": "layout",
985
+ "useWhen": "A dashboard of reorderable widgets in 2–4 columns with the order persisted under `storageKey`.",
986
+ "dontUseWhen": "A static grid of cards (CSS grid of `Card`s).",
987
+ "related": ["KpiCard", "Card"],
988
+ "since": "1.2.0"
989
+ },
990
+ "RouteTransition": {
991
+ "category": "layout",
992
+ "useWhen": "Fade and slide a page panel in when `routeKey` changes; respects reduced motion.",
993
+ "dontUseWhen": "Animating a component's own presence (the overlays already do) or a list (leave static).",
994
+ "related": ["Shell"],
995
+ "since": "1.3.0"
996
+ },
997
+ "VisuallyHidden": {
998
+ "category": "layout",
999
+ "useWhen": "Text for assistive technology that must not be seen: the name of an icon-only control you compose yourself, a live-region message.",
1000
+ "dontUseWhen": "Hiding from everyone (`hidden`) or an `IconButton` (it names itself).",
1001
+ "replacesRawHtml": ["class=\"sr-only\""],
1002
+ "related": ["IconButton"],
1003
+ "since": "0.0.0"
1004
+ },
1005
+
1006
+ "Heading": {
1007
+ "category": "typography",
1008
+ "useWhen": "A heading: `level` sets the element (h1–h6), `size` the visual role when it differs; h1 once per screen.",
1009
+ "dontUseWhen": "A label for a control (`Label`) or emphasised body text (`Text weight`).",
1010
+ "replacesRawHtml": ["<h1>", "<h2>", "<h3>", "<h4>"],
1011
+ "related": ["Text", "PageHeader", "SectionHeader"],
1012
+ "since": "1.33.0",
1013
+ "docs": ["docs/design-system/typography-roles.md"]
1014
+ },
1015
+ "Text": {
1016
+ "category": "typography",
1017
+ "useWhen": "Body, caption and label text: `size` is the typography role, `color` the token, `asChild` renders your element (a link, a `<p>`).",
1018
+ "dontUseWhen": "A heading (`Heading`), an identifier or snippet (`Code`) or a control's label (`Label`).",
1019
+ "replacesRawHtml": ["<p>", "<span class=\"text-sm text-gray-500\">"],
1020
+ "related": ["Heading", "Code", "Eyebrow"],
1021
+ "since": "1.33.0"
1022
+ },
1023
+ "Code": {
1024
+ "category": "typography",
1025
+ "useWhen": "Monospace text: an identifier, a path, a value, a snippet (inline or block); server-safe.",
1026
+ "dontUseWhen": "A keyboard key (`Kbd`) or tabular figures in body text (`Numeric`).",
1027
+ "replacesRawHtml": ["<code>", "<pre>"],
1028
+ "related": ["Kbd", "Eyebrow"],
1029
+ "since": "1.33.0"
1030
+ },
1031
+ "Kbd": {
1032
+ "category": "typography",
1033
+ "useWhen": "A keyboard key or shortcut, with platform spelling decided after mount (⌘ vs Ctrl).",
1034
+ "dontUseWhen": "A hint next to a control in the intent-atom style (`KbdHint`) or code (`Code`).",
1035
+ "replacesRawHtml": ["<kbd>"],
1036
+ "related": ["Eyebrow", "KeyboardShortcutsDialog"],
1037
+ "since": "1.33.0"
1038
+ },
1039
+ "Blockquote": {
1040
+ "category": "typography",
1041
+ "useWhen": "A quoted passage with the design system's rule and spacing.",
1042
+ "dontUseWhen": "A callout with an intent (`Alert`).",
1043
+ "replacesRawHtml": ["<blockquote>"],
1044
+ "related": ["Alert", "Text"],
1045
+ "since": "0.0.0"
1046
+ },
1047
+ "Eyebrow": {
1048
+ "category": "typography",
1049
+ "label": "Intent atoms",
1050
+ "parts": ["MutedSpec", "Numeric", "KbdHint"],
1051
+ "useWhen": "Intent-named text atoms that bake in typography and colour tokens: `Eyebrow` (small caps label), `MutedSpec` (secondary spec text), `Numeric` (tabular figures), `KbdHint` (a key hint).",
1052
+ "dontUseWhen": "General body text with a chosen role (`Text`) or a heading (`Heading`).",
1053
+ "related": ["Text", "Kbd", "Stat"],
1054
+ "since": "0.3.0"
1055
+ },
1056
+ "StarRating": {
1057
+ "category": "data display",
1058
+ "helpers": ["starRatingVariants"],
1059
+ "useWhen": "A display-only rating: fractional stars, `max`, sized variants.",
1060
+ "dontUseWhen": "Capturing a rating (compose `RadioGroup` or `ToggleGroup` with star icons).",
1061
+ "related": ["Badge", "KpiCard"],
1062
+ "since": "0.0.0"
1063
+ },
1064
+ "Stat": {
1065
+ "category": "typography",
1066
+ "useWhen": "A large number with a caption in display type.",
1067
+ "dontUseWhen": "A dashboard tile with tone, icon and hint (`KpiCard`).",
1068
+ "related": ["KpiCard", "Eyebrow"],
1069
+ "since": "0.0.0"
1070
+ },
1071
+
1072
+ "Table": {
1073
+ "category": "data display",
1074
+ "parts": ["TableHeader", "TableBody", "TableFooter", "TableRow", "TableHead", "TableCell", "TableCaption"],
1075
+ "useWhen": "A bare semantic table with the design system's row, header and caption styling.",
1076
+ "dontUseWhen": "A records table with toolbar, sorting and pagination (`DataTable`, `DataTableView`) or an editable matrix (`Grid`).",
1077
+ "replacesRawHtml": ["<table>", "<tr>", "<td>", "<th>"],
1078
+ "related": ["DataTable", "DataTableView", "MetadataGrid"],
1079
+ "since": "0.0.0"
1080
+ },
1081
+ "DataTable": {
1082
+ "category": "data display",
1083
+ "parts": ["DataTableToolbar", "DataTableSearch", "DataTableSpacer", "DataTableResultsCount", "DataTableHead", "DataTableHeader", "DataTableBody", "DataTableRow", "DataTableCell", "DataTableCellName", "DataTableCellMono", "DataTableCellId", "DataTableCellDue", "DataTableCheckbox", "DataTablePagination"],
1084
+ "useWhen": "The composable records table: card frame, toolbar with search and count, sortable headers, typed cells (name, mono, id, due), row checkbox, pagination.",
1085
+ "dontUseWhen": "A config-driven table is enough (`DataTableView`) or the table is a plain semantic one (`Table`).",
1086
+ "replacesRawHtml": ["<table> + hand-rolled toolbar and pager"],
1087
+ "related": ["DataTableView", "Table", "BulkActionBar", "LoadingRows"],
1088
+ "since": "0.3.0"
1089
+ },
1090
+ "DataTableView": {
1091
+ "category": "data display",
1092
+ "parts": ["StagePill", "Assignee", "MoneyCell", "TagsCell", "Dash"],
1093
+ "useWhen": "A list screen as configuration: `columns` + `data` (+ filters, search keys, sort); owns search/filter/sort/pagination state. Cell renderers `StagePill`, `Assignee`, `MoneyCell`, `TagsCell`, `Dash` for `column.render`.",
1094
+ "dontUseWhen": "You need custom table composition (`DataTable`).",
1095
+ "related": ["DataTable", "DisplayMenu", "Toolbar"],
1096
+ "since": "1.6.0"
1097
+ },
1098
+ "MetadataGrid": {
1099
+ "category": "data display",
1100
+ "parts": ["DataItem"],
1101
+ "useWhen": "Label / value pairs on a detail surface as a semantic `<dl>`; `DataItem span={2}` for full-row values.",
1102
+ "dontUseWhen": "Tabular records (`Table`) or a stat tile (`KpiCard`).",
1103
+ "replacesRawHtml": ["<dl>", "two-column label/value divs"],
1104
+ "related": ["DetailGrid", "Table"],
1105
+ "since": "0.4.1"
1106
+ },
1107
+ "KpiCard": {
1108
+ "category": "data display",
1109
+ "parts": ["SelectableKpiCard"],
1110
+ "useWhen": "A single-stat dashboard tile: label, value, optional tone, icon and hint; `SelectableKpiCard` when tiles act as filters.",
1111
+ "dontUseWhen": "A number inside running content (`Stat`) or a chart (`DonutChart`).",
1112
+ "related": ["Stat", "DashGrid", "Card"],
1113
+ "since": "0.4.1"
1114
+ },
1115
+ "Badge": {
1116
+ "category": "data display",
1117
+ "helpers": ["badgeVariants", "resolveBadgeAppearance"],
1118
+ "useWhen": "A short static label or count: `variant` (solid, soft, outline) × `intent`.",
1119
+ "dontUseWhen": "A status with a shared vocabulary (`StatusBadge`), a removable token (`Chip`) or a machine-suggested intent (`IntentBadge`).",
1120
+ "replacesRawHtml": ["<span class=\"rounded-full px-2 text-xs\">"],
1121
+ "related": ["StatusBadge", "Chip", "IntentBadge", "StatusDot"],
1122
+ "since": "0.0.0"
1123
+ },
1124
+ "StatusBadge": {
1125
+ "category": "data display",
1126
+ "helpers": ["defineStatusMap"],
1127
+ "useWhen": "The presentation of a status: soft badge, indicator dot, icon; define the product's statuses once with `defineStatusMap` and spread an entry onto it.",
1128
+ "dontUseWhen": "A count or neutral label (`Badge`) or a stage pill inside `DataTableView` (`StagePill`).",
1129
+ "related": ["Badge", "StatusDot", "StatusPill", "DataTableView"],
1130
+ "since": "1.35.0"
1131
+ },
1132
+ "StatusPill": {
1133
+ "category": "data display",
1134
+ "useWhen": "Only in code that already uses it: the fixed-vocabulary pill (`status`, optional dot) for authoritative state.",
1135
+ "dontUseWhen": "New code — `StatusBadge` with `defineStatusMap`.",
1136
+ "related": ["StatusBadge", "IntentBadge"],
1137
+ "since": "1.2.0"
1138
+ },
1139
+ "IntentBadge": {
1140
+ "category": "data display",
1141
+ "useWhen": "A dashed-outline badge for an AI-classified intent: signals machine-suggested, not yet confirmed.",
1142
+ "dontUseWhen": "Authoritative state (`StatusBadge`).",
1143
+ "related": ["StatusBadge", "Badge", "AiDraftCard"],
1144
+ "since": "1.5.0"
1145
+ },
1146
+ "StatusDot": {
1147
+ "category": "data display",
1148
+ "helpers": ["statusDotVariants", "STATUS_DOT_TONE_TO_INTENT"],
1149
+ "useWhen": "A standalone attention / unread / presence dot on non-avatar surfaces: nav rails, bells, list rows; `intent` colours it.",
1150
+ "dontUseWhen": "Next to an avatar (`Avatar` renders its own presence dot) or with a label (`StatusBadge`).",
1151
+ "replacesRawHtml": ["<span class=\"h-2 w-2 rounded-full bg-red-500\">"],
1152
+ "related": ["StatusBadge", "Avatar", "Sidebar"],
1153
+ "since": "1.3.0"
1154
+ },
1155
+ "StatusIcon": {
1156
+ "category": "icons",
1157
+ "useWhen": "A progress-aware state circle for pipeline stages (`state`, optional `progress`).",
1158
+ "dontUseWhen": "A status with text (`StatusBadge`) or a fixed glyph (icon catalogue).",
1159
+ "related": ["PriorityIcon", "StatusBadge", "ProgressRing"],
1160
+ "since": "0.8.0",
1161
+ "story": "src/primitives/priority-status-icons.stories.tsx"
1162
+ },
1163
+ "PriorityIcon": {
1164
+ "category": "icons",
1165
+ "useWhen": "The glyph for the fixed none/low/medium/high/urgent priority scale.",
1166
+ "dontUseWhen": "A generic arrow or flag (icon catalogue) or a status (`StatusIcon`).",
1167
+ "related": ["StatusIcon", "StackedBarChart"],
1168
+ "since": "0.8.0",
1169
+ "story": "src/primitives/priority-status-icons.stories.tsx"
1170
+ },
1171
+ "IconTile": {
1172
+ "category": "data display",
1173
+ "helpers": ["iconTileVariants", "ICON_TILE_TONE_TO_INTENT"],
1174
+ "useWhen": "The tinted rounded-square icon chip that leads a list row or card: `intent` tints the square and the glyph.",
1175
+ "dontUseWhen": "An action (`IconButton`) or a file type (`FileTypeBadge`).",
1176
+ "replacesRawHtml": ["<div class=\"grid place-items-center rounded-lg bg-…\"><svg/>"],
1177
+ "related": ["FileTypeBadge", "Avatar", "IconButton"],
1178
+ "since": "1.3.0"
1179
+ },
1180
+ "Avatar": {
1181
+ "category": "data display",
1182
+ "useWhen": "A person or organisation: image with initials fallback, sizes, optional presence dot.",
1183
+ "dontUseWhen": "A file (`FileTypeBadge`) or a product mark (brand icons, `Logo`).",
1184
+ "replacesRawHtml": ["<img class=\"rounded-full\">"],
1185
+ "related": ["StatusDot", "DataTableView", "TeamMemberSelect"],
1186
+ "since": "0.0.0"
1187
+ },
1188
+ "FileTypeBadge": {
1189
+ "category": "data display",
1190
+ "helpers": ["fileTypeBadgeVariants", "fileTypeFromName"],
1191
+ "useWhen": "The coloured format square (PDF, IMG, DOC…) for a file; `fileTypeFromName` derives the type.",
1192
+ "dontUseWhen": "A whole file row (`AttachmentChip`, `FileChip`, `DocumentFileRow`).",
1193
+ "related": ["AttachmentChip", "FileChip", "IconTile"],
1194
+ "since": "1.3.0"
1195
+ },
1196
+ "FileChip": {
1197
+ "category": "data display",
1198
+ "useWhen": "A compact file token: name, meta, kind icon, one action.",
1199
+ "dontUseWhen": "A full attachment row with view/download (`AttachmentChip`) or a document in the portal (`DocumentFileRow`).",
1200
+ "related": ["AttachmentChip", "FileTypeBadge", "Chip"],
1201
+ "since": "1.2.0"
1202
+ },
1203
+ "AttachmentChip": {
1204
+ "category": "data display",
1205
+ "helpers": ["attachmentChipVariants"],
1206
+ "useWhen": "A full attachment row: `FileTypeBadge`, truncated name with meta, trailing view/download and your actions; presentational.",
1207
+ "dontUseWhen": "A compact token (`FileChip`) or an upload control (`FileUpload`).",
1208
+ "related": ["FileChip", "FileTypeBadge", "FileUpload"],
1209
+ "since": "1.3.0"
1210
+ },
1211
+ "DocumentSourceTag": {
1212
+ "category": "data display",
1213
+ "useWhen": "Where a document came from (uploaded, emailed, scanned…): glyph + label tag.",
1214
+ "dontUseWhen": "Filtering by source (`DocumentSourceFilter`).",
1215
+ "related": ["DocumentSourceFilter", "DocumentDetailPanel"],
1216
+ "since": "1.12.0"
1217
+ },
1218
+ "ActivityList": {
1219
+ "category": "data display",
1220
+ "parts": ["ActivityItem", "ActivityEventItem"],
1221
+ "useWhen": "An activity feed: actor/text/target rows (`ActivityItem`) and titled events with a time and coloured dot (`ActivityEventItem`).",
1222
+ "dontUseWhen": "Notifications with filters and read state (`NotificationPanel`) or a process timeline (`EngagementTimeline`).",
1223
+ "replacesRawHtml": ["<ul> of hand-styled feed rows"],
1224
+ "related": ["NotificationPanel", "EngagementTimeline", "AttentionItem"],
1225
+ "since": "0.3.0"
1226
+ },
1227
+ "NotificationPanel": {
1228
+ "category": "data display",
1229
+ "parts": ["NotificationPanelHeader", "NotificationFilter", "NotificationList", "NotificationItem", "NotificationPanelFooter"],
1230
+ "useWhen": "The notifications flyout: header, filter, list of items with read state, footer actions.",
1231
+ "dontUseWhen": "A page-level activity feed (`ActivityList`).",
1232
+ "related": ["ActivityList", "StatusDot", "Popover"],
1233
+ "since": "0.7.0"
1234
+ },
1235
+ "Kanban": {
1236
+ "category": "data display",
1237
+ "parts": ["KanbanColumn", "KanbanCard"],
1238
+ "useWhen": "A board of columns and cards for stage-based work.",
1239
+ "dontUseWhen": "The data is tabular (`DataTableView`).",
1240
+ "related": ["DataTableView"],
1241
+ "since": "0.3.0"
1242
+ },
1243
+ "EngagementCard": {
1244
+ "category": "data display",
1245
+ "useWhen": "The client-portal card for one engagement: service, tone, title, progress and next step.",
1246
+ "dontUseWhen": "A generic card (`Card`) or a KPI (`KpiCard`).",
1247
+ "related": ["EngagementTimeline", "Card", "serviceToneStyle"],
1248
+ "since": "1.2.0"
1249
+ },
1250
+ "EngagementTimeline": {
1251
+ "category": "data display",
1252
+ "parts": ["EngagementTimelineStep"],
1253
+ "useWhen": "The steps of an engagement as a toned vertical timeline.",
1254
+ "dontUseWhen": "A flow the user navigates (`Stepper`) or an activity feed (`ActivityList`).",
1255
+ "related": ["EngagementCard", "Stepper", "ActivityList"],
1256
+ "since": "1.2.0"
1257
+ },
1258
+ "MessageBubble": {
1259
+ "category": "data display",
1260
+ "parts": ["MessageBubbleAction", "MessageBubbleTombstone"],
1261
+ "useWhen": "One chat message in a thread, inbound or outbound, with hover actions and a tombstone for deleted messages.",
1262
+ "dontUseWhen": "An email (`EmailMessageCard`) or an AI draft (`AiDraftCard`).",
1263
+ "related": ["EmailMessageCard", "MessageComposer", "ChannelTabs"],
1264
+ "since": "0.12.0"
1265
+ },
1266
+ "EmailMessageCard": {
1267
+ "category": "data display",
1268
+ "useWhen": "An email in a thread as an envelope card (header, readable body, footer) with auto-clamp and show-full toggle; you sanitise the HTML.",
1269
+ "dontUseWhen": "A chat message (`MessageBubble`).",
1270
+ "related": ["MessageBubble", "AttachmentChip"],
1271
+ "since": "1.5.0"
1272
+ },
1273
+ "DocumentChecklist": {
1274
+ "category": "data display",
1275
+ "useWhen": "The client's view of requested documents by lifecycle: awaiting, in review, received, complete.",
1276
+ "dontUseWhen": "The firm's missing-documents view (`MissingDocumentsPanel`).",
1277
+ "related": ["MissingDocumentsPanel", "DocumentRequestUpload"],
1278
+ "since": "1.21.0"
1279
+ },
1280
+ "DocumentDetailPanel": {
1281
+ "category": "data display",
1282
+ "parts": ["DocumentDetailHeader", "DocumentDetailTitle", "DocumentDetailRequester", "DocumentDetailMetaRow", "DocumentDetailBody", "DocumentDetailActions", "DocumentList", "DocumentListSection", "DocumentRow"],
1283
+ "useWhen": "The document detail side panel and the document list it opens from: header, title, requester, meta, body, actions; `DocumentList` sections of `DocumentRow`s.",
1284
+ "dontUseWhen": "A file outside the documents workspace (`AttachmentChip`).",
1285
+ "related": ["DocumentsWorkspaceLayout", "DocumentFileRow", "DocumentSourceTag"],
1286
+ "since": "1.8.0"
1287
+ },
1288
+ "DocumentFileRow": {
1289
+ "category": "data display",
1290
+ "parts": ["DocumentFileCard", "DocumentFileLine"],
1291
+ "useWhen": "A file in the documents workspace as a row, a card or a selectable line (named checkbox).",
1292
+ "dontUseWhen": "An attachment outside the workspace (`AttachmentChip`).",
1293
+ "related": ["DocumentDetailPanel", "FileTypeBadge", "AttachmentChip"],
1294
+ "since": "1.4.0"
1295
+ },
1296
+ "DocumentRequestDetail": {
1297
+ "category": "data display",
1298
+ "parts": ["DocumentRequestCard"],
1299
+ "useWhen": "A document request as a card in a list and as the expanded detail.",
1300
+ "dontUseWhen": "The request form field (`DocumentRequestField`) or the client's upload (`DocumentRequestUpload`).",
1301
+ "related": ["DocumentRequestField", "DocumentRequestUpload", "MissingDocumentsPanel"],
1302
+ "since": "1.9.0"
1303
+ },
1304
+ "TimeLogger": {
1305
+ "category": "data display",
1306
+ "parts": ["TimeLoggerHeader", "TimeLoggerTimer", "TimeLoggerContextRow", "TimeLoggerField", "TimeLoggerBillable", "TimeLoggerNotes", "TimeLoggerEntryList", "TimeLoggerEntry", "TimeLoggerActions", "TimeLoggerFooter"],
1307
+ "helpers": ["formatClock", "formatDuration", "parseDuration", "formatCurrency"],
1308
+ "hooks": ["useStopwatch"],
1309
+ "useWhen": "The compact time-entry panel: compose only the rows a surface needs (timer, context, billable, notes, entries); `useStopwatch` and the duration formatters drive it.",
1310
+ "dontUseWhen": "A single duration field (`Input` + `parseDuration`).",
1311
+ "related": ["Popover", "NumberInput"],
1312
+ "since": "0.15.0"
1313
+ },
1314
+ "ProposalPackageCard": {
1315
+ "category": "data display",
1316
+ "label": "Proposal pricing",
1317
+ "parts": ["ProposalServiceRow", "ProposalAddOn", "ProposalBillingTerms", "ProposalPricingSummary"],
1318
+ "useWhen": "The Services & Pricing blocks of a proposal preview: package card, service rows, add-ons, billing terms, summary; inherit the firm accent inside `AgreementViewer`.",
1319
+ "dontUseWhen": "Anything outside a proposal (`Card`, `MetadataGrid`).",
1320
+ "related": ["AgreementViewer", "ProposalSignatureBlock", "ProposalSignerList"],
1321
+ "since": "1.12.0"
1322
+ },
1323
+ "ProposalSignerList": {
1324
+ "category": "data display",
1325
+ "label": "Proposal content",
1326
+ "parts": ["ProposalNote", "ProposalCustomPage"],
1327
+ "useWhen": "The content blocks of a proposal: signer list, notes, custom pages.",
1328
+ "dontUseWhen": "Anything outside a proposal.",
1329
+ "related": ["AgreementViewer", "ProposalPackageCard"],
1330
+ "since": "1.12.0"
1331
+ },
1332
+
1333
+ "AreaChart": {
1334
+ "category": "media",
1335
+ "useWhen": "A trend over time as a filled area, in design-system colours.",
1336
+ "dontUseWhen": "Parts of a whole (`DonutChart`) or category comparison (`StackedBarChart`, `RankedBars`).",
1337
+ "replacesRawHtml": ["ad-hoc recharts with hex colours"],
1338
+ "related": ["DonutChart", "StackedBarChart", "RankedBars"],
1339
+ "since": "1.2.0"
1340
+ },
1341
+ "DonutChart": {
1342
+ "category": "media",
1343
+ "useWhen": "Parts of a whole with a centre label.",
1344
+ "dontUseWhen": "One value's progress (`ProgressRing`).",
1345
+ "related": ["ProgressRing", "AreaChart"],
1346
+ "since": "1.2.0"
1347
+ },
1348
+ "StackedBarChart": {
1349
+ "category": "media",
1350
+ "useWhen": "Composition per category as stacked bars (e.g. work by priority).",
1351
+ "dontUseWhen": "A ranked list of values (`RankedBars`).",
1352
+ "related": ["RankedBars", "AreaChart", "PriorityIcon"],
1353
+ "since": "1.6.0"
1354
+ },
1355
+ "RankedBars": {
1356
+ "category": "media",
1357
+ "useWhen": "A ranked list of labelled values as horizontal bars.",
1358
+ "dontUseWhen": "Stacked composition (`StackedBarChart`).",
1359
+ "related": ["StackedBarChart"],
1360
+ "since": "1.2.0"
1361
+ },
1362
+ "PdfPreview": {
1363
+ "category": "media",
1364
+ "useWhen": "Render a PDF inline with paging and zoom.",
1365
+ "dontUseWhen": "A spreadsheet (`SpreadsheetPreview`) or just a file row (`AttachmentChip`).",
1366
+ "related": ["SpreadsheetPreview", "AttachmentChip", "AspectRatio"],
1367
+ "since": "1.7.0"
1368
+ },
1369
+ "SpreadsheetPreview": {
1370
+ "category": "media",
1371
+ "useWhen": "Render a spreadsheet's sheets and cells inline.",
1372
+ "dontUseWhen": "A PDF (`PdfPreview`) or an editable grid (`Grid`).",
1373
+ "related": ["PdfPreview", "Table"],
1374
+ "since": "1.7.0"
1375
+ },
1376
+ "Logo": {
1377
+ "category": "media",
1378
+ "useWhen": "The Assure suite or product wordmark: official artwork with a glyph + text fallback; `assetPath` resolves the artwork base.",
1379
+ "dontUseWhen": "A small product mark alone (brand icon family).",
1380
+ "replacesRawHtml": ["<img src=\"/brand/….svg\">"],
1381
+ "related": ["Sidebar", "assetPath"],
1382
+ "since": "0.0.0"
1383
+ },
1384
+
1385
+ "Shell": {
1386
+ "category": "shell/screens",
1387
+ "parts": ["Main", "Content"],
1388
+ "useWhen": "The application frame: `Shell` holds the `Sidebar` and `Main`; `Main` holds `AppHeader` and `Content`.",
1389
+ "dontUseWhen": "A public or marketing page (`Section`).",
1390
+ "replacesRawHtml": ["<div class=\"flex h-screen\">"],
1391
+ "related": ["Sidebar", "AppHeader", "BrandScope"],
1392
+ "since": "0.3.0"
1393
+ },
1394
+ "Sidebar": {
1395
+ "category": "shell/screens",
1396
+ "parts": ["SidebarProvider", "SidebarTrigger", "SidebarBrand", "SidebarBrandText", "SidebarSection", "SidebarLinkGroup", "SidebarLink", "SidebarLinkLabel", "SidebarLinkBadge", "SidebarLinkAction", "SidebarPinButton", "SidebarUser", "SidebarFooter"],
1397
+ "helpers": ["sidebarLinkBadgeVariants"],
1398
+ "hooks": ["useSidebarState", "useSidebarPeekLock"],
1399
+ "useWhen": "The app navigation rail: expanded/collapsed/peek states from `SidebarProvider`, brand, sections, link groups with badges and actions, user and footer.",
1400
+ "dontUseWhen": "Mobile (`BottomNav`) or a rail of records (`ClientRailItem`).",
1401
+ "replacesRawHtml": ["<aside> + <nav> hand-rolled"],
1402
+ "related": ["Shell", "SidebarBrandSwitcher", "BottomNav"],
1403
+ "since": "0.3.0"
1404
+ },
1405
+ "SidebarBrandSwitcher": {
1406
+ "category": "shell/screens",
1407
+ "parts": ["SidebarBrandSwitcherTile"],
1408
+ "useWhen": "Switch between Assure products from the sidebar brand slot: tiles for available, current and coming-soon products.",
1409
+ "dontUseWhen": "A single-product app (`SidebarBrand`).",
1410
+ "related": ["Sidebar", "BrandScope", "Logo"],
1411
+ "since": "0.11.2"
1412
+ },
1413
+ "AppHeader": {
1414
+ "category": "shell/screens",
1415
+ "parts": ["AppHeaderBreadcrumb", "AppHeaderTitle", "AppHeaderSearch", "AppHeaderActions"],
1416
+ "useWhen": "The sticky 56px top bar inside `Main`: breadcrumb, title, search and actions slots in any order.",
1417
+ "dontUseWhen": "The page's own title block (`PageHeader`).",
1418
+ "related": ["Shell", "PageHeader", "NewMenu", "NotificationPanel"],
1419
+ "since": "0.3.0"
1420
+ },
1421
+ "DesignSystemProvider": {
1422
+ "category": "shell/screens",
1423
+ "hooks": ["useDsMessages"],
1424
+ "useWhen": "Mount once in the root layout to configure the whole design system: `messages` overrides for the generic strings components render, `locale` (default `en-US`, pass the one your app knows server-side), `dir`, the portal container, the router `linkComponent` and `imageComponent` for `LinkButton` and `Logo`, and the tooltip provider. `useDsMessages(namespace, override?)` reads the resolved strings inside your own components.",
1425
+ "dontUseWhen": "You are on Next.js — `NextDesignSystemProvider` from `/next` fills in the adapters. Theming a subtree is `ThemeScope` / `BrandScope`, not a nested provider.",
1426
+ "replacesRawHtml": ["hand-rolled i18n or router context for design-system strings and links"],
1427
+ "related": ["ThemeScope", "BrandScope", "Tooltip", "LinkButton", "Logo"],
1428
+ "since": "unreleased",
1429
+ "story": "src/foundation/provider/design-system-provider.stories.tsx"
1430
+ },
1431
+ "ThemeScope": {
1432
+ "category": "shell/screens",
1433
+ "useWhen": "A subtree that renders with its own colour `scheme`, `brand`, `density`, `dir` or runtime brand theme: stamps the `data-ds-*` attributes on its element and registers them so portalled overlays opened from inside (Dialog, Popover, menus) come up in the same theme; nested scopes merge.",
1434
+ "dontUseWhen": "The whole app shares one theme (set the attributes on the document root) or only the product brand changes (`BrandScope`).",
1435
+ "replacesRawHtml": ["<div data-ds-scheme=\"dark\"> whose dialogs come up in the root theme"],
1436
+ "related": ["BrandScope", "DesignSystemProvider", "Dialog", "Popover"],
1437
+ "since": "unreleased",
1438
+ "story": "src/primitives/behavior/portal.stories.tsx",
1439
+ "docs": ["docs/integration/css.md"]
1440
+ },
1441
+ "BrandScope": {
1442
+ "category": "shell/screens",
1443
+ "parts": ["BrandScopeProvider"],
1444
+ "helpers": ["BRAND_PRODUCTS", "brandLabel", "brandScope"],
1445
+ "hooks": ["useBrandScope"],
1446
+ "useWhen": "Theme a subtree as a product: stamps `data-brand` and provides it so portalled surfaces re-stamp themselves; `brandScope(product)` for the attribute alone.",
1447
+ "dontUseWhen": "Colouring by service line (`serviceToneStyle`) or by status (`intent`).",
1448
+ "related": ["Shell", "SidebarBrandSwitcher"],
1449
+ "since": "1.18.0",
1450
+ "docs": ["docs/integration/css.md"]
1451
+ },
1452
+ "AgreementViewer": {
1453
+ "category": "shell/screens",
1454
+ "parts": ["AgreementPaneHeading"],
1455
+ "useWhen": "The client-facing agreement / proposal viewer: cover, steps, firm accent scope for the proposal blocks.",
1456
+ "dontUseWhen": "Previewing a PDF (`PdfPreview`).",
1457
+ "related": ["ProposalPackageCard", "ProposalSignatureBlock", "ProposalSignerList"],
1458
+ "since": "1.12.0"
1459
+ },
1460
+
1461
+ "cn": {
1462
+ "category": "hooks/utilities",
1463
+ "useWhen": "Merge class names (clsx + tailwind-merge) when composing `className`; consumer classes still win by cascade, `cn` only dedupes.",
1464
+ "dontUseWhen": "Overriding a component part — pass `className`/`classNames` instead of rebuilding its classes.",
1465
+ "related": ["Button"],
1466
+ "since": "0.0.0",
1467
+ "docs": ["docs/integration/css.md"]
1468
+ },
1469
+ "useFieldControl": {
1470
+ "category": "hooks/utilities",
1471
+ "useWhen": "Building your own form control that should bind to `Field` like the design-system ones: returns ids, `aria-*`, invalid/disabled/required wiring; explicit props win.",
1472
+ "dontUseWhen": "Wrapping an existing element once (`FieldControl`).",
1473
+ "related": ["Field", "FieldControl"],
1474
+ "since": "1.32.0",
1475
+ "docs": ["docs/adr/006-field-native-form-participation.md"]
1476
+ },
1477
+ "isoToDisplay": {
1478
+ "category": "hooks/utilities",
1479
+ "label": "Date utilities",
1480
+ "helpers": ["displayToIso", "applyMask", "applyYearMask", "isoToDate", "dateToIso", "isoToYear", "yearToIso", "DATE_DISPLAY_PLACEHOLDER", "YEAR_DISPLAY_PLACEHOLDER"],
1481
+ "useWhen": "Convert between ISO `YYYY-MM-DD`, the `MM/DD/YYYY` display format and JS `Date` the way `DatePicker` does, and apply its typing masks.",
1482
+ "dontUseWhen": "Locale-aware formatting for display text (`Intl.DateTimeFormat`).",
1483
+ "related": ["DatePicker", "DateRangePicker"],
1484
+ "since": "0.11.0"
1485
+ },
1486
+ "COUNTRY_CODES": {
1487
+ "category": "hooks/utilities",
1488
+ "label": "Country codes",
1489
+ "helpers": ["getFlagEmoji", "parsePhoneForEditing"],
1490
+ "useWhen": "The ISO country / dial-code table behind `PhoneCountryInput`, a flag emoji fallback, and splitting a stored phone string for editing.",
1491
+ "dontUseWhen": "Full phone validation (bring libphonenumber).",
1492
+ "related": ["PhoneField", "PhoneCountryInput"],
1493
+ "since": "1.1.0"
1494
+ },
1495
+ "serviceToneStyle": {
1496
+ "category": "hooks/utilities",
1497
+ "label": "Service tones",
1498
+ "helpers": ["SERVICE_TONES", "serviceToneLabel"],
1499
+ "useWhen": "Tone a portal surface per service line by setting `--tone` / `--tone-bg` once on its root; labels for chips and headings.",
1500
+ "dontUseWhen": "Status colour (`intent`) or product theming (`BrandScope`).",
1501
+ "related": ["CategoryDivider", "EngagementCard", "BrandScope"],
1502
+ "since": "1.2.0"
1503
+ },
1504
+ "assetPath": {
1505
+ "category": "hooks/utilities",
1506
+ "label": "Asset base path",
1507
+ "helpers": ["getAssetBasePath", "setAssetBasePath"],
1508
+ "useWhen": "The app is served from a subpath: call `setAssetBasePath` once so the design system's own artwork (`Logo`) resolves.",
1509
+ "dontUseWhen": "Your own assets (use your framework's base path).",
1510
+ "related": ["Logo"],
1511
+ "since": "1.33.0"
1512
+ },
1513
+ "systemTokens": {
1514
+ "category": "hooks/utilities",
1515
+ "label": "Tokens (root re-export)",
1516
+ "helpers": ["reference", "colors", "spacing", "radii", "shadows", "surfaces", "typography"],
1517
+ "useWhen": "Token objects from JavaScript when a utility class cannot reach (inline styles, charts, motion); prefer the `/tokens` entry for a smaller import.",
1518
+ "dontUseWhen": "Styling components — use the `--ds-*` custom properties and utilities; never read `reference`/`colors` in component code.",
1519
+ "related": ["BrandScope"],
1520
+ "since": "0.0.0",
1521
+ "docs": ["docs/design-system/shape-roles.md"]
1522
+ }
1523
+ },
1524
+ "entries": {
1525
+ "next": {
1526
+ "NextDesignSystemProvider": "`DesignSystemProvider` with `next/link` and `next/image` filled in; takes every other provider prop."
1527
+ },
1528
+ "tokens": {
1529
+ "BRAND_THEME_PROPERTIES": "The custom-property names a brand theme sets.",
1530
+ "breakpoints": "Viewport breakpoints as numbers.",
1531
+ "colors": "Reference palette (programmatic access; never for component styling).",
1532
+ "createBrandTheme": "Build a runtime brand theme from a seed (`docs/integration/css.md` §5). Experimental.",
1533
+ "iconSizes": "The icon size scale in pixels.",
1534
+ "layout": "Layout constants (sidebar width, header height, content pad).",
1535
+ "motion": "Durations and easings.",
1536
+ "overlays": "Overlay constants (z-index tiers, backdrop).",
1537
+ "radii": "Radius scale.",
1538
+ "reference": "All reference tokens in one object.",
1539
+ "shadows": "Shadow scale.",
1540
+ "spacing": "The 4px spacing scale.",
1541
+ "surfaces": "The four canonical surface layers.",
1542
+ "systemTokens": "System (semantic) tokens as CSS variable references — the ones components consume.",
1543
+ "typography": "Font families, sizes, weights and letterspacing.",
1544
+ "zIndex": "Z-index tiers."
1545
+ },
1546
+ "testing": {
1547
+ "withAssureDesignSystem": "Jest config wrapper that makes the real package load (resolution, ESM transform, jsdom shims).",
1548
+ "installDomPolyfills": "The jsdom shims alone, for Vitest or a custom setup file.",
1549
+ "createToastRecorder": "Records the toasts a real `ToastProvider` shows.",
1550
+ "selectOption": "Chooses an option in a design-system `Select` through the DOM.",
1551
+ "openMenu": "Opens a design-system `DropdownMenu` and returns a handle to its items.",
1552
+ "fillField": "Types into a text control found by its `Field` label.",
1553
+ "pickDate": "Sets a design-system `DatePicker` to an ISO date through the DOM."
1554
+ }
1555
+ },
1556
+ "deprecatedAliases": [
1557
+ { "deprecated": "`Button variant=\"primary\"`", "replacement": "`variant=\"solid\" intent=\"brand\"` (the default)", "codemod": "CM-04", "contract": "C-BTN-VARIANT" },
1558
+ { "deprecated": "`Button variant=\"secondary\"`", "replacement": "`variant=\"soft\" intent=\"neutral\"`", "codemod": "CM-04", "contract": "C-BTN-VARIANT" },
1559
+ { "deprecated": "`Button variant=\"destructive\"`", "replacement": "`variant=\"solid\" intent=\"danger\"`", "codemod": "CM-04", "contract": "C-BTN-VARIANT" },
1560
+ { "deprecated": "`Button variant=\"success\"`", "replacement": "`variant=\"solid\" intent=\"success\"`", "codemod": "CM-04", "contract": "C-BTN-VARIANT" },
1561
+ { "deprecated": "`Button variant=\"accent\"` / `\"dashed\"`", "replacement": "Reported by CM-04 for review: `accent` is a brand look, `dashed` an outline look; both keep rendering until 3.0", "codemod": "CM-04 (report)", "contract": "C-BTN-VARIANT" },
1562
+ { "deprecated": "`Button intent=\"destructive\"`", "replacement": "`intent=\"danger\"`", "codemod": "—", "contract": "C-BTN-VARIANT" },
1563
+ { "deprecated": "`Button size=\"compact\"` / `\"default\"` / `\"comfortable\"`, `\"icon-xs\"` / `\"icon-sm\"` / `\"icon\"`", "replacement": "`size=\"sm\"` / `\"md\"` / `\"lg\"`; icon sizes → `IconButton size`", "codemod": "CM-02 (explicit `size=\"md\"`)", "contract": "C-BTN-SIZE" },
1564
+ { "deprecated": "`Button` / `LinkButton` / `SubmitButton` `iconLeft` / `iconRight`", "replacement": "`iconStart` / `iconEnd`", "codemod": "CM-05", "contract": "C-BTN-ICONPROPS" },
1565
+ { "deprecated": "`Button` without `type` inside a form", "replacement": "`type=\"submit\"` where evident, or `SubmitButton`", "codemod": "CM-12", "contract": "—" },
1566
+ { "deprecated": "`Input` / `Textarea` / `SearchInput` `inputSize`", "replacement": "`size`", "codemod": "CM-07", "contract": "C-INPUT-SIZE" },
1567
+ { "deprecated": "`InputSizeAlias` `compact` / `default` / `comfortable`", "replacement": "`sm` / `md` / `lg`", "codemod": "—", "contract": "C-INPUT-SIZE" },
1568
+ { "deprecated": "`Select` `triggerClassName` / `contentClassName`", "replacement": "`classNames={{ trigger, content }}`", "codemod": "—", "contract": "C-SELECT-CLASSNAMES" },
1569
+ { "deprecated": "`Select searchable`", "replacement": "`Combobox`", "codemod": "—", "contract": "—" },
1570
+ { "deprecated": "`Select` sentinel option values standing in for \"no value\"", "replacement": "A real empty value (`value=\"\"`, `clearable`)", "codemod": "CM-20 (finder)", "contract": "C-SELECT-EMPTY" },
1571
+ { "deprecated": "`SearchSelect` (`{ id, label }` options)", "replacement": "`Combobox` with `Option` (`{ value, label }`)", "codemod": "CM-08", "contract": "C-SEARCHSELECT" },
1572
+ { "deprecated": "`Checkbox indeterminate`", "replacement": "`checked=\"indeterminate\"`", "codemod": "—", "contract": "C-CHECKBOX-INDET" },
1573
+ { "deprecated": "`DatePicker onChange={e => f(e.target.value)}` (fake event)", "replacement": "`onValueChange={value => f(value)}`", "codemod": "CM-10", "contract": "C-DATE-FAKEEVENT" },
1574
+ { "deprecated": "`StatusDot` / `IconTile` / `Spinner` / `SegmentedProgress` / `SuiteProgress` `tone`", "replacement": "`intent` (`pro` → `brand`, `muted` → `neutral`, `accent` → `info`, `destructive` → `danger`)", "codemod": "CM-06", "contract": "C-TONE" },
1575
+ { "deprecated": "`ProgressBar` / `ProgressRing` `variant` (`default`, `destructive`, …)", "replacement": "`intent` (`brand`, `danger`, …); value-driven auto colour written down explicitly", "codemod": "CM-19", "contract": "C-PROGRESS" },
1576
+ { "deprecated": "`Badge variant=\"default\"` / `\"secondary\"` / `\"destructive\"` / `\"success\"` / `\"warning\"` / `\"info\"` / `\"outline\"`", "replacement": "`variant` (`solid`, `soft`, `outline`) + `intent`", "codemod": "—", "contract": "C-BADGE" },
1577
+ { "deprecated": "`FormError`", "replacement": "`FieldError` inside a `Field`", "codemod": "—", "contract": "C-FORM-MSG" },
1578
+ { "deprecated": "`FormSuccess`", "replacement": "`FieldDescription` inside a `Field`, or a toast for a saved form", "codemod": "—", "contract": "C-FORM-MSG" },
1579
+ { "deprecated": "`FormSection`", "replacement": "`Fieldset` + `FieldsetLegend`", "codemod": "—", "contract": "—" },
1580
+ { "deprecated": "`PhoneInput`, `PhoneCountryInput` (+ `CountrySelect`, `CountryFlag`)", "replacement": "`PhoneField` (E.164 value, `Combobox` country picker)", "codemod": "—", "contract": "—" },
1581
+ { "deprecated": "`Sidebar gutterPx`", "replacement": "The sidebar's own geometry tokens", "codemod": "—", "contract": "—" },
1582
+ { "deprecated": "`CloseIcon`, `ArrowRightSmallIcon`", "replacement": "`XIcon`, `ArrowRightIcon` (same drawing)", "codemod": "—", "contract": "—" },
1583
+ { "deprecated": "Hidden `<input name>` mirrors added because a control posted nothing", "replacement": "Remove them: every control participates in the form through `FormBridge`", "codemod": "CM-14 (finder)", "contract": "C-HIDDEN-MIRRORS" },
1584
+ { "deprecated": "Selectors into a component's internal DOM", "replacement": "`className` / `classNames` and `data-slot` selectors (ADR-008)", "codemod": "CM-15 (finder)", "contract": "C-DOM-*" }
1585
+ ]
1586
+ }