@hirobius/design-system 0.20.0 → 0.21.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.
- package/AGENTS.md +123 -0
- package/CONSUMING.md +4 -2
- package/DESIGN.md +28 -17
- package/NOTICE.md +1 -1
- package/README.md +37 -5
- package/dist/chunks/empty-state-DNoThgfV.js +1227 -0
- package/dist/chunks/form-By82qZcC.js +66 -0
- package/dist/fonts/geist-mono-400.woff2 +0 -0
- package/dist/fonts/satoshi-400.woff2 +0 -0
- package/dist/fonts/satoshi-500.woff2 +0 -0
- package/dist/fonts/satoshi-700.woff2 +0 -0
- package/dist/fonts.css +53 -0
- package/dist/form.js +1 -1
- package/dist/hirobius-ui.js +876 -877
- package/dist/manifest.js +1 -1
- package/dist/patterns.js +189 -170
- package/dist/styles.css +2 -2
- package/dist/tokens.css +1 -1
- package/dist/tokens.js +136 -57
- package/dist/types/src/app/components/alert-dialog.d.ts +5 -0
- package/dist/types/src/app/components/asset-img.d.ts +1 -0
- package/dist/types/src/app/components/avatar-group.d.ts +1 -0
- package/dist/types/src/app/components/badge.d.ts +1 -1
- package/dist/types/src/app/components/blockquote.d.ts +1 -0
- package/dist/types/src/app/components/button.d.ts +2 -0
- package/dist/types/src/app/components/card.d.ts +3 -2
- package/dist/types/src/app/components/data-table-section.d.ts +1 -0
- package/dist/types/src/app/components/destructive-section.d.ts +1 -0
- package/dist/types/src/app/components/dialog.d.ts +1 -0
- package/dist/types/src/app/components/error-pattern.d.ts +6 -1
- package/dist/types/src/app/components/form-actions.d.ts +1 -0
- package/dist/types/src/app/components/form-control.d.ts +10 -0
- package/dist/types/src/app/components/grid.d.ts +5 -0
- package/dist/types/src/app/components/icon.d.ts +1 -0
- package/dist/types/src/app/components/kbd.d.ts +1 -0
- package/dist/types/src/app/components/metadata-list.d.ts +1 -0
- package/dist/types/src/app/components/metric-tiles.d.ts +1 -0
- package/dist/types/src/app/components/progress.d.ts +1 -1
- package/dist/types/src/app/components/skeleton.d.ts +1 -1
- package/dist/types/src/app/components/stat.d.ts +4 -3
- package/dist/types/src/app/components/status-tile.d.ts +3 -2
- package/dist/types/src/app/components/table.d.ts +5 -0
- package/dist/types/src/app/components/text.d.ts +53 -6
- package/dist/types/src/app/components/timestamp.d.ts +1 -0
- package/dist/types/src/app/data/manifest-types.d.ts +4 -0
- package/dist/types/src/app/design-system/generated-token-refs.d.ts +37 -28
- package/dist/types/src/app/design-system/generated-token-values.d.ts +3 -0
- package/dist/types/src/app/design-system/tokens.d.ts +117 -15
- package/dist/types/src/index.d.ts +43 -40
- package/dist/variables.css +41 -33
- package/docs/CONSUMING.md +63 -39
- package/hirobius.tokens.json +77 -73
- package/llms.txt +158 -50
- package/mcp/catalog.mjs +366 -0
- package/mcp/guide.mjs +315 -0
- package/mcp/hds-mcp.mjs +49 -0
- package/mcp/server.mjs +94 -0
- package/package.json +35 -9
- package/public/hds-manifest.json +348 -254
- package/public/llms/components.txt +4 -3
- package/public/llms/layout.txt +1 -1
- package/public/llms-full.txt +190 -70
- package/public/llms.txt +158 -50
- package/scripts/eslint-plugin-hds/index.d.mts +29 -0
- package/scripts/eslint-plugin-hds/index.mjs +55 -0
- package/scripts/eslint-plugin-hds/package.json +30 -0
- package/scripts/eslint-plugin-hds/rules/no-raw-controls.mjs +47 -0
- package/scripts/eslint-plugin-hds/rules/no-raw-hex.mjs +70 -0
- package/scripts/eslint-plugin-hds/rules/no-raw-px-spacing.mjs +125 -0
- package/scripts/eslint-plugin-hds/rules/prefer-hds-layout-primitive.mjs +54 -0
- package/scripts/eslint-plugin-hds/rules/sx-token-first.mjs +111 -0
- package/scripts/eslint-plugin-hds/rules/utils.mjs +66 -0
- package/src/app/data/component-api.json +114 -53
- package/dist/chunks/empty-state-BBqhCx0S.js +0 -1217
- package/dist/chunks/form-COP3vK9_.js +0 -66
- package/dist/types/src/app/components/status-dot.d.ts +0 -39
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-10-
|
|
2
|
+
"generatedAt": "2026-10-07T18:55:36.429Z",
|
|
3
3
|
"source": "react-docgen-typescript@2.4.0",
|
|
4
4
|
"components": {
|
|
5
5
|
"Alert": {
|
|
6
6
|
"filePath": "src/app/components/alert.tsx",
|
|
7
7
|
"description": "Alert - compact feedback surface with contextual severity.",
|
|
8
|
+
"core": true,
|
|
8
9
|
"usage": {
|
|
9
10
|
"when": "Show a persistent inline message with a severity, next to the content it concerns.",
|
|
10
11
|
"whenNot": "A brief confirmation that should disappear on its own, or a status label.",
|
|
@@ -47,8 +48,23 @@
|
|
|
47
48
|
"AlertDialog": {
|
|
48
49
|
"filePath": "src/app/components/alert-dialog.tsx",
|
|
49
50
|
"description": "AlertDialog root + parts. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.",
|
|
51
|
+
"usage": {
|
|
52
|
+
"when": "Confirm a destructive or irreversible action (delete, archive, remove) before it runs, with Cancel and Action buttons.",
|
|
53
|
+
"whenNot": "A modal that collects input or shows content, or a confirmation after the action is done.",
|
|
54
|
+
"useInstead": [
|
|
55
|
+
{
|
|
56
|
+
"component": "Dialog",
|
|
57
|
+
"reason": "a modal with a form or other content"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"component": "ToastProvider",
|
|
61
|
+
"reason": "a brief confirmation after the action"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
50
65
|
"category": "Overlays",
|
|
51
66
|
"hidden": false,
|
|
67
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2035-24",
|
|
52
68
|
"props": [
|
|
53
69
|
{
|
|
54
70
|
"name": "children",
|
|
@@ -81,6 +97,7 @@
|
|
|
81
97
|
"description": "AssetImg - responsive asset frame with fallback placeholder handling. Contexts: default, lightbox, and detail.",
|
|
82
98
|
"category": "Display",
|
|
83
99
|
"hidden": false,
|
|
100
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2041-67",
|
|
84
101
|
"props": [
|
|
85
102
|
{
|
|
86
103
|
"name": "alt",
|
|
@@ -201,6 +218,7 @@
|
|
|
201
218
|
"Avatar": {
|
|
202
219
|
"filePath": "src/app/components/avatar.tsx",
|
|
203
220
|
"description": "Circular avatar. Renders the image when available, else initials from `alt`.",
|
|
221
|
+
"core": true,
|
|
204
222
|
"usage": {
|
|
205
223
|
"when": "Show a person or entity as an image with an initials fallback.",
|
|
206
224
|
"whenNot": "A generic pictogram, or a status marker.",
|
|
@@ -250,6 +268,7 @@
|
|
|
250
268
|
"description": "Renders up to `max` overlapping avatars followed by a `+N` overflow chip.",
|
|
251
269
|
"category": "Display",
|
|
252
270
|
"hidden": false,
|
|
271
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2030-63",
|
|
253
272
|
"props": [
|
|
254
273
|
{
|
|
255
274
|
"name": "children",
|
|
@@ -274,6 +293,7 @@
|
|
|
274
293
|
"Badge": {
|
|
275
294
|
"filePath": "src/app/components/badge.tsx",
|
|
276
295
|
"description": "Compact metadata/status chip. Tone is the only styling input.",
|
|
296
|
+
"core": true,
|
|
277
297
|
"usage": {
|
|
278
298
|
"when": "Label a status, state or count with a compact neutral or semantic chip, or a dot.",
|
|
279
299
|
"whenNot": "A chip people can toggle, or a message that needs a sentence.",
|
|
@@ -310,7 +330,7 @@
|
|
|
310
330
|
"name": "label",
|
|
311
331
|
"type": "string",
|
|
312
332
|
"required": false,
|
|
313
|
-
"description": "Names
|
|
333
|
+
"description": "Names a `dot` badge: role=\"img\" with this aria-label. Without it the dot is aria-hidden. A text badge ignores it: put the text in `children`."
|
|
314
334
|
},
|
|
315
335
|
{
|
|
316
336
|
"name": "size",
|
|
@@ -331,6 +351,7 @@
|
|
|
331
351
|
"description": "A quoted passage; pass `cite` for the source URL and `attribution` for a byline.",
|
|
332
352
|
"category": "Typography",
|
|
333
353
|
"hidden": false,
|
|
354
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2024-18",
|
|
334
355
|
"props": [
|
|
335
356
|
{
|
|
336
357
|
"name": "attribution",
|
|
@@ -349,6 +370,7 @@
|
|
|
349
370
|
"Box": {
|
|
350
371
|
"filePath": "src/app/components/box.tsx",
|
|
351
372
|
"description": "Box — polymorphic layout primitive with a token-first `sx` engine. `sx` is a deliberate SUBSET of MUI's sx — not all of CSS-in-JS is a feature: - Spacing shorthands (m/p/gap family) take the t-shirt scale ('xs'|'sm'|'md'|'lg'|'xl' → `--semantic-space-scale-*`, hds#206) through the resolver Stack's `gap` shares. Numbers still resolve as a count of 4px units (`p: 4` is 16px), and the deprecated 'tight'|'normal'|'inset'|'spacious' still read `--semantic-space-layout-*`, fixed px that compact density does not remap. HDS source may not use raw integers (check-spacing-vocabulary). - `color`/`bgcolor`/`borderColor`/`fill`/`stroke` resolve dotted token keys ('content.primary', 'surface.raised', 'border.subtle', 'accent', 'accent.hover', 'feedback.success', …) to the matching semantic CSS var. - Responsive `{ xs, sm, md, lg, xl }` objects compile to `min-width` media queries off the HDS breakpoint scale. - `&`-prefixed keys ('&:hover', '& > *', '&[data-state=open]') nest a selector, composable with responsive values. - Everything else passes through as a plain camelCase→kebab-case CSS declaration (numbers get `px` unless in the unitless allowlist). See `box-sx.ts` for the pure resolver + hashing/injection engine.",
|
|
373
|
+
"core": true,
|
|
352
374
|
"usage": {
|
|
353
375
|
"when": "Build one-off layout that no named layout primitive covers, using token keys through `sx`.",
|
|
354
376
|
"whenNot": "Ordinary vertical or horizontal spacing, columns, or page-width constraint.",
|
|
@@ -395,6 +417,7 @@
|
|
|
395
417
|
"Breadcrumb": {
|
|
396
418
|
"filePath": "src/app/components/breadcrumb.tsx",
|
|
397
419
|
"description": "Breadcrumb trail. Links route through the HDS router seam (plain anchors with no router, client-side nav when a router adapter is provided). The final item is marked aria-current=\"page\".",
|
|
420
|
+
"core": true,
|
|
398
421
|
"usage": {
|
|
399
422
|
"when": "Show where the current page sits in a hierarchy and link back up it.",
|
|
400
423
|
"whenNot": "Switching between sibling views, or stepping through pages of results.",
|
|
@@ -431,6 +454,7 @@
|
|
|
431
454
|
"Button": {
|
|
432
455
|
"filePath": "src/app/components/button.tsx",
|
|
433
456
|
"description": "Triggers an action when activated.",
|
|
457
|
+
"core": true,
|
|
434
458
|
"usage": {
|
|
435
459
|
"when": "Trigger an action (submit, save, open a dialog) with a text label and optional icons; for an icon-only control pass iconOnly with iconLeft and label; for an on/off toggle pass pressed.",
|
|
436
460
|
"whenNot": "Navigating to another page, where a link is the correct element.",
|
|
@@ -524,7 +548,7 @@
|
|
|
524
548
|
"name": "variant",
|
|
525
549
|
"type": "\"primary\" | \"secondary\" | \"tertiary\" | null",
|
|
526
550
|
"required": false,
|
|
527
|
-
"description": ""
|
|
551
|
+
"description": "Visual treatment: `primary`, `secondary` or `tertiary`. Defaults to `secondary` (an outline), so pass `primary` for the main action."
|
|
528
552
|
}
|
|
529
553
|
]
|
|
530
554
|
},
|
|
@@ -554,6 +578,7 @@
|
|
|
554
578
|
"Card": {
|
|
555
579
|
"filePath": "src/app/components/card.tsx",
|
|
556
580
|
"description": "Tagged per-export, not on the file block: this module exports eight components and a file-level @figma would hand all eight this one node.",
|
|
581
|
+
"core": true,
|
|
557
582
|
"usage": {
|
|
558
583
|
"when": "Group related content on a raised surface with header, body, footer and metric slots, or as one selectable option.",
|
|
559
584
|
"whenNot": "A bare padded background with no slot anatomy, or a single headline figure.",
|
|
@@ -644,28 +669,28 @@
|
|
|
644
669
|
},
|
|
645
670
|
"CardBody": {
|
|
646
671
|
"filePath": "src/app/components/card.tsx",
|
|
647
|
-
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label
|
|
672
|
+
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
|
|
648
673
|
"category": "Display",
|
|
649
674
|
"hidden": false,
|
|
650
675
|
"props": []
|
|
651
676
|
},
|
|
652
677
|
"CardDescription": {
|
|
653
678
|
"filePath": "src/app/components/card.tsx",
|
|
654
|
-
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label
|
|
679
|
+
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
|
|
655
680
|
"category": "Display",
|
|
656
681
|
"hidden": false,
|
|
657
682
|
"props": []
|
|
658
683
|
},
|
|
659
684
|
"CardFooter": {
|
|
660
685
|
"filePath": "src/app/components/card.tsx",
|
|
661
|
-
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label
|
|
686
|
+
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
|
|
662
687
|
"category": "Display",
|
|
663
688
|
"hidden": false,
|
|
664
689
|
"props": []
|
|
665
690
|
},
|
|
666
691
|
"CardHeader": {
|
|
667
692
|
"filePath": "src/app/components/card.tsx",
|
|
668
|
-
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label
|
|
693
|
+
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
|
|
669
694
|
"category": "Display",
|
|
670
695
|
"hidden": false,
|
|
671
696
|
"props": [
|
|
@@ -679,10 +704,16 @@
|
|
|
679
704
|
},
|
|
680
705
|
"CardMetric": {
|
|
681
706
|
"filePath": "src/app/components/card.tsx",
|
|
682
|
-
"description": "Card.Metric — one
|
|
707
|
+
"description": "Card.Metric — one label, a large value and an optional sub-line inside a Card.",
|
|
683
708
|
"usage": {
|
|
684
709
|
"when": "Show one headline figure (a KPI, a count, a total) with its label inside a Card.",
|
|
685
|
-
"whenNot": "A metric outside a Card, or several figures that share one label."
|
|
710
|
+
"whenNot": "A metric outside a Card, or several figures that share one label.",
|
|
711
|
+
"useInstead": [
|
|
712
|
+
{
|
|
713
|
+
"component": "MetricTiles",
|
|
714
|
+
"reason": "a row of headline numbers with no enclosing Card"
|
|
715
|
+
}
|
|
716
|
+
]
|
|
686
717
|
},
|
|
687
718
|
"category": "Display",
|
|
688
719
|
"hidden": false,
|
|
@@ -716,7 +747,7 @@
|
|
|
716
747
|
},
|
|
717
748
|
"CardProgress": {
|
|
718
749
|
"filePath": "src/app/components/card.tsx",
|
|
719
|
-
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label
|
|
750
|
+
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
|
|
720
751
|
"category": "Display",
|
|
721
752
|
"hidden": false,
|
|
722
753
|
"props": [
|
|
@@ -750,7 +781,7 @@
|
|
|
750
781
|
},
|
|
751
782
|
"CardTitle": {
|
|
752
783
|
"filePath": "src/app/components/card.tsx",
|
|
753
|
-
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label
|
|
784
|
+
"description": "Card — surface container with slot anatomy (12d-card-anatomy). Slot anatomy (DESIGN.md §\"Card Anatomy\"). Status, progress, and metadata are layout-bearing — they live in slots, never inline next to prose. <Card variant=\"accent\"> <Card.Header metadata={<Badge tone=\"warning\">in-progress</Badge>}> <Card.Title>Discovery phase</Card.Title> <Card.Description>Stakeholder interviews and audit prep.</Card.Description> </Card.Header> <Card.Progress value={42} max={100} label=\"5 / 12 tasks\" /> <Card.Metric label=\"Retainer\" value=\"$3,500\" sub=\"Active\" /> <Card.Body>…</Card.Body> <Card.Footer>…</Card.Footer> </Card> Slot reservations: - Header: title (h3) + optional description (caption) + optional metadata zone (right-aligned, holds <Badge> / <Tag> for status, never raw spans). - Progress: full-width 4px bar in a reserved 16px vertical rail. Owns its spacing — never crowds adjacent prose. - Metric: single label + big value (title) + optional sub-line. Reserved vertical block. Use multiple side-by-side via flex/grid container. - Body: prose, lists, structured content. NO inline status, progress, or thin colored bars. Group sections via separate <Card.Body> blocks. - Footer: actions, secondary metadata, timestamps. `variant`: 'default' (borderless) | 'accent' (2px accent border) — the structural axis, for highlighted entries like \"recommended package\". `tone`: neutral | danger | success | warning | info — the fixed feedback axis (#60 variant contract), for status-driven cards where the border IS the signal. `variant`/`tone` together replace hand-rolled `pkgHighlight`-style overrides. Legacy props (padding / gap / noPadding / as / style) are retained. Existing callers that pass raw children continue to work; new callers should prefer compound parts + `padding=\"none\"`. Depth comes from semantic.color.border.default (role.border) at rest; elevation tokens are not bound by default — pass `className=\"shadow-...\"` for a hover/floating treatment on interactive cards.",
|
|
754
785
|
"category": "Display",
|
|
755
786
|
"hidden": false,
|
|
756
787
|
"props": []
|
|
@@ -758,6 +789,7 @@
|
|
|
758
789
|
"Checkbox": {
|
|
759
790
|
"filePath": "src/app/components/checkbox.tsx",
|
|
760
791
|
"description": "Checkbox — custom-drawn checkbox with check / indeterminate glyph.",
|
|
792
|
+
"core": true,
|
|
761
793
|
"usage": {
|
|
762
794
|
"when": "Let people tick one or more independent options, or a parent choice that is partly selected.",
|
|
763
795
|
"whenNot": "An immediate on/off setting, or a choice of exactly one option from a set.",
|
|
@@ -867,6 +899,7 @@
|
|
|
867
899
|
"Combobox": {
|
|
868
900
|
"filePath": "src/app/components/combobox.tsx",
|
|
869
901
|
"description": "Combobox — searchable single- or multi-select (Popover + filtered listbox). A select-with-search built on the HDS Popover. The trigger shows the current selection (with `multiple`, a count and a removable chip per value); opening reveals a search field that filters the option list. Full keyboard support (↑/↓ to move, Enter to choose, Esc/outside-click to close) and listbox/option ARIA. Controlled via `value` + `onChange`. <Combobox options={[{ value: 'us', label: 'United States' }, …]} value={country} onChange={setCountry} placeholder=\"Select a country\" />",
|
|
902
|
+
"core": true,
|
|
870
903
|
"usage": {
|
|
871
904
|
"when": "Pick one value, or several with `multiple`, from a long list of options, with a search field that filters as you type.",
|
|
872
905
|
"whenNot": "A short list that needs no search, or an action list.",
|
|
@@ -998,6 +1031,7 @@
|
|
|
998
1031
|
"Container": {
|
|
999
1032
|
"filePath": "src/app/components/container.tsx",
|
|
1000
1033
|
"description": "Container — semantic width-constrained layout. Centers content horizontally and applies semantic max-width constraints. - maxWidth options: 'content' (760px prose) | 'max' (1200px full layout) - No arbitrary pixel values allowed Usage: <Container maxWidth=\"max\"> <div>...</div> </Container>",
|
|
1034
|
+
"core": true,
|
|
1001
1035
|
"usage": {
|
|
1002
1036
|
"when": "Constrain a page region to the content or maximum width and centre it.",
|
|
1003
1037
|
"whenNot": "Spacing between siblings, columns, or a surface with padding.",
|
|
@@ -1059,6 +1093,7 @@
|
|
|
1059
1093
|
"description": "Section heading and toolbar over a `Table`. Row actions are consumer nodes in a trailing column, the table scrolls horizontally on narrow widths without a `minWidth` from the caller, and zero rows shows an `EmptyState`.",
|
|
1060
1094
|
"category": "Display",
|
|
1061
1095
|
"hidden": false,
|
|
1096
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2075-268",
|
|
1062
1097
|
"props": [
|
|
1063
1098
|
{
|
|
1064
1099
|
"name": "actionsLabel",
|
|
@@ -1118,6 +1153,7 @@
|
|
|
1118
1153
|
"description": "Titled danger zone: a title, an explanation, and one danger `Button` that opens an `AlertDialog`. Pressing the button never runs the action; only the dialog's confirm does. Place it last on the screen, below the form.",
|
|
1119
1154
|
"category": "Actions",
|
|
1120
1155
|
"hidden": false,
|
|
1156
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2076-3",
|
|
1121
1157
|
"props": [
|
|
1122
1158
|
{
|
|
1123
1159
|
"name": "actionLabel",
|
|
@@ -1174,6 +1210,7 @@
|
|
|
1174
1210
|
"Dialog": {
|
|
1175
1211
|
"filePath": "src/app/components/dialog.tsx",
|
|
1176
1212
|
"description": "Tagged per-export, not on the file block: this module exports ten components and a file-level @figma would hand all ten this one node.",
|
|
1213
|
+
"core": true,
|
|
1177
1214
|
"usage": {
|
|
1178
1215
|
"when": "Interrupt the page with a modal that needs a decision or focused input before people continue.",
|
|
1179
1216
|
"whenNot": "A preview on hover, a message that needs no reply, or content that can stay inline.",
|
|
@@ -1189,6 +1226,10 @@
|
|
|
1189
1226
|
{
|
|
1190
1227
|
"component": "ToastProvider",
|
|
1191
1228
|
"reason": "a brief confirmation"
|
|
1229
|
+
},
|
|
1230
|
+
{
|
|
1231
|
+
"component": "AlertDialog",
|
|
1232
|
+
"reason": "confirming a destructive or irreversible action"
|
|
1192
1233
|
}
|
|
1193
1234
|
]
|
|
1194
1235
|
},
|
|
@@ -1468,6 +1509,7 @@
|
|
|
1468
1509
|
"Disclosure": {
|
|
1469
1510
|
"filePath": "src/app/components/disclosure.tsx",
|
|
1470
1511
|
"description": "Disclosure - compact disclosure surface for optional explanatory content.",
|
|
1512
|
+
"core": true,
|
|
1471
1513
|
"usage": {
|
|
1472
1514
|
"when": "Hide optional explanatory content behind a heading that people can expand.",
|
|
1473
1515
|
"whenNot": "Content people must see, or switching between panels.",
|
|
@@ -1550,6 +1592,7 @@
|
|
|
1550
1592
|
"Divider": {
|
|
1551
1593
|
"filePath": "src/app/components/divider.tsx",
|
|
1552
1594
|
"description": "Divider — semantic separator between content regions.",
|
|
1595
|
+
"core": true,
|
|
1553
1596
|
"usage": {
|
|
1554
1597
|
"when": "Separate two regions of content with a thin semantic rule.",
|
|
1555
1598
|
"whenNot": "Spacing alone would do, or the separation needs a container.",
|
|
@@ -1598,6 +1641,7 @@
|
|
|
1598
1641
|
"EmptyState": {
|
|
1599
1642
|
"filePath": "src/app/components/empty-state.tsx",
|
|
1600
1643
|
"description": "EmptyState — consistent no-data placeholder for lists, grids, and sections.",
|
|
1644
|
+
"core": true,
|
|
1601
1645
|
"usage": {
|
|
1602
1646
|
"when": "Say that a list, grid or section has no data yet, with a title and an optional description.",
|
|
1603
1647
|
"whenNot": "Content that is still loading, or a full-page error.",
|
|
@@ -1640,6 +1684,7 @@
|
|
|
1640
1684
|
"Field": {
|
|
1641
1685
|
"filePath": "src/app/components/field.tsx",
|
|
1642
1686
|
"description": "Caption label paired with a value — used in metadata grids and read-only forms.",
|
|
1687
|
+
"core": true,
|
|
1643
1688
|
"usage": {
|
|
1644
1689
|
"when": "Show a labelled read-only value, such as a name and its value in a detail view.",
|
|
1645
1690
|
"whenNot": "Editable input, or a single headline figure.",
|
|
@@ -1703,6 +1748,7 @@
|
|
|
1703
1748
|
"description": "Form footer with one fixed order: destructive (far left, if any), then secondary, then primary last and right-most. Gap is the tight layout token.",
|
|
1704
1749
|
"category": "Actions",
|
|
1705
1750
|
"hidden": false,
|
|
1751
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2075-87",
|
|
1706
1752
|
"props": [
|
|
1707
1753
|
{
|
|
1708
1754
|
"name": "destructive",
|
|
@@ -1836,6 +1882,7 @@
|
|
|
1836
1882
|
"Grid": {
|
|
1837
1883
|
"filePath": "src/app/components/grid.tsx",
|
|
1838
1884
|
"description": "Grid — responsive grid composition primitive. Enforces semantic gap and column values. No arbitrary CSS grid. - layout='fixed': responsive base (collapses via CSS at tablet/mobile). `columns` sets desktop count (default 12). Tablet/mobile clamp to min(8, cols) and min(4, cols) respectively. - layout='auto-fit': responsive card wrapping via auto-fit. - layout='auto-fill': tile wrapping at `minItemWidth` (TileGrid's recipe; 0.20.0 removed TileGrid). - subgrid=true: sets gridTemplateColumns:'subgrid' for nested alignment. Usage (default responsive 12-col): <Grid> <Grid.Item colSpan={6}>…</Grid.Item> <Grid.Item colSpan={6}>…</Grid.Item> </Grid> Usage (responsive auto-fit): <Grid layout=\"auto-fit\"> <Card /> <Card /> </Grid>",
|
|
1885
|
+
"core": true,
|
|
1839
1886
|
"usage": {
|
|
1840
1887
|
"when": "Lay out content in responsive columns with token-governed gaps, or align nested content with subgrid.",
|
|
1841
1888
|
"whenNot": "A single row or column, or styling a surface.",
|
|
@@ -1854,6 +1901,13 @@
|
|
|
1854
1901
|
"category": "Layout",
|
|
1855
1902
|
"hidden": false,
|
|
1856
1903
|
"props": [
|
|
1904
|
+
{
|
|
1905
|
+
"name": "align",
|
|
1906
|
+
"type": "\"center\" | \"end\" | \"start\" | \"stretch\"",
|
|
1907
|
+
"default": "start",
|
|
1908
|
+
"required": false,
|
|
1909
|
+
"description": "Cross-axis alignment of items in a row. Defaults to 'start': items hug their own height. Pass 'stretch' where a row of tiles must share one height."
|
|
1910
|
+
},
|
|
1857
1911
|
{
|
|
1858
1912
|
"name": "as",
|
|
1859
1913
|
"type": "ElementType<any, keyof IntrinsicElements>",
|
|
@@ -1918,6 +1972,7 @@
|
|
|
1918
1972
|
"HdsRouterProvider": {
|
|
1919
1973
|
"filePath": "src/app/context/RouterContext.tsx",
|
|
1920
1974
|
"description": "Provide a router adapter to all HDS components below. Wrap your app root once.",
|
|
1975
|
+
"core": true,
|
|
1921
1976
|
"usage": {
|
|
1922
1977
|
"when": "Wrap the app root once so HDS links and navigation use your client router; with no provider they stay plain anchors."
|
|
1923
1978
|
},
|
|
@@ -1941,6 +1996,7 @@
|
|
|
1941
1996
|
"HdsThemeProvider": {
|
|
1942
1997
|
"filePath": "src/app/context/hds-theme.tsx",
|
|
1943
1998
|
"description": "Renders a `data-hds` scope wrapper that carries the four theming dials as root attributes + CSS vars, and exposes them to `useHdsTheme()`.",
|
|
1999
|
+
"core": true,
|
|
1944
2000
|
"usage": {
|
|
1945
2001
|
"when": "Wrap an app or region once to set theme, density and other root attributes for everything inside it.",
|
|
1946
2002
|
"whenNot": "Styling a single component, or per-component overrides.",
|
|
@@ -2014,6 +2070,7 @@
|
|
|
2014
2070
|
"Icon": {
|
|
2015
2071
|
"filePath": "src/app/components/icon.tsx",
|
|
2016
2072
|
"description": "Icon — semantic icon wrapper for Lucide icons.",
|
|
2073
|
+
"core": true,
|
|
2017
2074
|
"usage": {
|
|
2018
2075
|
"when": "Draw a Lucide glyph at a size and colour from the design tokens.",
|
|
2019
2076
|
"whenNot": "A control someone can activate, or a picture that carries content.",
|
|
@@ -2030,6 +2087,7 @@
|
|
|
2030
2087
|
},
|
|
2031
2088
|
"category": "Display",
|
|
2032
2089
|
"hidden": false,
|
|
2090
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=27-2",
|
|
2033
2091
|
"props": [
|
|
2034
2092
|
{
|
|
2035
2093
|
"name": "aria-hidden",
|
|
@@ -2121,6 +2179,7 @@
|
|
|
2121
2179
|
"InlineLink": {
|
|
2122
2180
|
"filePath": "src/app/components/inline-link.tsx",
|
|
2123
2181
|
"description": "InlineLink ” inline navigation and external-link primitive for body copy.",
|
|
2182
|
+
"core": true,
|
|
2124
2183
|
"usage": {
|
|
2125
2184
|
"when": "Link to a route or external URL from inside body copy.",
|
|
2126
2185
|
"whenNot": "An action that changes something, or a control that needs button styling.",
|
|
@@ -2163,6 +2222,7 @@
|
|
|
2163
2222
|
"Input": {
|
|
2164
2223
|
"filePath": "src/app/components/input.tsx",
|
|
2165
2224
|
"description": "Input — text field primitive with label, helper, and error slots.",
|
|
2225
|
+
"core": true,
|
|
2166
2226
|
"usage": {
|
|
2167
2227
|
"when": "Collect a single line of text, a number, an email, a password, a date or a time, with label, helper and error slots.",
|
|
2168
2228
|
"whenNot": "Multi-line text, or choosing from a fixed list of options.",
|
|
@@ -2284,6 +2344,7 @@
|
|
|
2284
2344
|
"Kbd": {
|
|
2285
2345
|
"filePath": "src/app/components/kbd.tsx",
|
|
2286
2346
|
"description": "Renders a keyboard key or shortcut token, e.g. `<Kbd>⌘K</Kbd>`.",
|
|
2347
|
+
"core": true,
|
|
2287
2348
|
"usage": {
|
|
2288
2349
|
"when": "Show a keyboard key or shortcut hint inline, as a native kbd element.",
|
|
2289
2350
|
"whenNot": "Code samples, or a control that runs the shortcut.",
|
|
@@ -2296,6 +2357,7 @@
|
|
|
2296
2357
|
},
|
|
2297
2358
|
"category": "Display",
|
|
2298
2359
|
"hidden": false,
|
|
2360
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2026-9",
|
|
2299
2361
|
"props": [
|
|
2300
2362
|
{
|
|
2301
2363
|
"name": "size",
|
|
@@ -2310,6 +2372,7 @@
|
|
|
2310
2372
|
"description": "Renders object metadata as a semantic `<dl>` of term/description pairs.",
|
|
2311
2373
|
"category": "Display",
|
|
2312
2374
|
"hidden": false,
|
|
2375
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2041-47",
|
|
2313
2376
|
"props": [
|
|
2314
2377
|
{
|
|
2315
2378
|
"name": "footer",
|
|
@@ -2344,6 +2407,7 @@
|
|
|
2344
2407
|
"description": "One metric tile: eyebrow label, `heading2` value, caption sub line, on a raised surface at one fixed min-height. Wraps `Card.Metric` (the sibling with the eyebrow / h2 / caption scale) and adds the surface and the fixed height, so a tile needs no enclosing `Card`.",
|
|
2345
2408
|
"category": "Display",
|
|
2346
2409
|
"hidden": false,
|
|
2410
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2075-114",
|
|
2347
2411
|
"props": [
|
|
2348
2412
|
{
|
|
2349
2413
|
"name": "label",
|
|
@@ -2468,6 +2532,7 @@
|
|
|
2468
2532
|
"Pagination": {
|
|
2469
2533
|
"filePath": "src/app/components/pagination.tsx",
|
|
2470
2534
|
"description": "Paged navigation with first/last anchors, sibling pages, and ellipses.",
|
|
2535
|
+
"core": true,
|
|
2471
2536
|
"usage": {
|
|
2472
2537
|
"when": "Move between pages of a long result set, with truncated page numbers.",
|
|
2473
2538
|
"whenNot": "A hierarchy trail, or a short list that fits on one page.",
|
|
@@ -2560,6 +2625,7 @@
|
|
|
2560
2625
|
"Progress": {
|
|
2561
2626
|
"filePath": "src/app/components/progress.tsx",
|
|
2562
2627
|
"description": "Linear bar or circular ring. Determinate when `value` is a number, else indeterminate.",
|
|
2628
|
+
"core": true,
|
|
2563
2629
|
"usage": {
|
|
2564
2630
|
"when": "Show how far a task has got, as a bar or ring that is determinate or indeterminate.",
|
|
2565
2631
|
"whenNot": "A wait of unknown length with no bar, or content that is still loading.",
|
|
@@ -2624,6 +2690,7 @@
|
|
|
2624
2690
|
"Radio": {
|
|
2625
2691
|
"filePath": "src/app/components/radio.tsx",
|
|
2626
2692
|
"description": "Radio — radio button with animated selection indicator.",
|
|
2693
|
+
"core": true,
|
|
2627
2694
|
"usage": {
|
|
2628
2695
|
"when": "Choose exactly one option from a small set that should stay visible together.",
|
|
2629
2696
|
"whenNot": "Independent yes/no options, or a long list of options.",
|
|
@@ -2710,6 +2777,7 @@
|
|
|
2710
2777
|
"SegmentedControl": {
|
|
2711
2778
|
"filePath": "src/app/components/segmented-control.tsx",
|
|
2712
2779
|
"description": "SegmentedControl \" segmented selection input for compact mutually-exclusive choices. The active×hover×pressed×disabled×secondary state matrix is expressed through `cva` compound variants keyed by `active` / `interaction` (the live-or-frozen-demo hover/pressed/rest sub-state) / `variant` / `disabled`, each resolving to the same `--semantic-*` custom properties the pre-Tailwind inline styles referenced — same tokens, same pixels, just Tailwind classes instead of a `style` object. Per ADR-015 this control keeps its own hover/focus tracking (per-segment `string | null` cardinality) rather than the shared `useInteractionState` single-element machine; only the class composition changed, not the state machine feeding it.",
|
|
2780
|
+
"core": true,
|
|
2713
2781
|
"usage": {
|
|
2714
2782
|
"when": "Switch between two to five mutually exclusive views or modes in a compact row.",
|
|
2715
2783
|
"whenNot": "A form choice that submits with the form, or more than five options.",
|
|
@@ -2800,6 +2868,7 @@
|
|
|
2800
2868
|
"Select": {
|
|
2801
2869
|
"filePath": "src/app/components/select.tsx",
|
|
2802
2870
|
"description": "Select — dropdown selector built on Radix Select (ADR-001 Radix convention). Radix owns the listbox a11y contract: managed focus + active-descendant, typeahead, full keyboard (Home/End/PageUp-Down/wrap), Popper collision/flip positioning, and dismissal. The HDS surface is styled with the token-backed Tailwind idiom used by tabs.tsx / command-palette.tsx; `ref` targets the trigger button.",
|
|
2871
|
+
"core": true,
|
|
2803
2872
|
"usage": {
|
|
2804
2873
|
"when": "Choose one value from a short list of options in a form field.",
|
|
2805
2874
|
"whenNot": "Firing actions, or choosing from a list long enough to need search.",
|
|
@@ -2970,6 +3039,7 @@
|
|
|
2970
3039
|
"Skeleton": {
|
|
2971
3040
|
"filePath": "src/app/components/skeleton.tsx",
|
|
2972
3041
|
"description": "Decorative loading placeholder. Marked aria-hidden — announce the loading state on the surrounding region (e.g. aria-busy) rather than per skeleton.",
|
|
3042
|
+
"core": true,
|
|
2973
3043
|
"usage": {
|
|
2974
3044
|
"when": "Reserve the shape of content that is still loading, so the layout does not jump.",
|
|
2975
3045
|
"whenNot": "A task with measurable progress, or a wait with no layout to reserve.",
|
|
@@ -2992,7 +3062,7 @@
|
|
|
2992
3062
|
"name": "height",
|
|
2993
3063
|
"type": "string | number",
|
|
2994
3064
|
"required": false,
|
|
2995
|
-
"description": "Explicit height (number → px, or any CSS length). For `text`, defaults to 1em."
|
|
3065
|
+
"description": "Explicit height (number → px, or any CSS length). For `text`, defaults to 1em; for `rectangular`, 5rem."
|
|
2996
3066
|
},
|
|
2997
3067
|
{
|
|
2998
3068
|
"name": "variant",
|
|
@@ -3012,6 +3082,7 @@
|
|
|
3012
3082
|
"Slider": {
|
|
3013
3083
|
"filePath": "src/app/components/slider.tsx",
|
|
3014
3084
|
"description": "Slider — range slider with label and value display.",
|
|
3085
|
+
"core": true,
|
|
3015
3086
|
"usage": {
|
|
3016
3087
|
"when": "Pick a number within a known range by dragging, when the exact value matters less than the position.",
|
|
3017
3088
|
"whenNot": "A precise number the person must type or read exactly.",
|
|
@@ -3068,6 +3139,7 @@
|
|
|
3068
3139
|
"Spinner": {
|
|
3069
3140
|
"filePath": "src/app/components/spinner.tsx",
|
|
3070
3141
|
"description": "Indeterminate spinner. Inherits the surrounding text color via currentColor.",
|
|
3142
|
+
"core": true,
|
|
3071
3143
|
"usage": {
|
|
3072
3144
|
"when": "Show that something is loading when the wait is short or has no measurable end.",
|
|
3073
3145
|
"whenNot": "A task with measurable progress, or a region whose layout is known.",
|
|
@@ -3104,6 +3176,7 @@
|
|
|
3104
3176
|
"Stack": {
|
|
3105
3177
|
"filePath": "src/app/components/stack.tsx",
|
|
3106
3178
|
"description": "Stack — one-dimensional layout primitive.",
|
|
3179
|
+
"core": true,
|
|
3107
3180
|
"usage": {
|
|
3108
3181
|
"when": "Space a row or column of content with token gaps and simple flex alignment.",
|
|
3109
3182
|
"whenNot": "Multi-column layout, or giving content a background or padding.",
|
|
@@ -3183,11 +3256,15 @@
|
|
|
3183
3256
|
},
|
|
3184
3257
|
"Stat": {
|
|
3185
3258
|
"filePath": "src/app/components/stat.tsx",
|
|
3186
|
-
"description": "Headline metric — large value,
|
|
3259
|
+
"description": "Headline metric — large value, caption label, optional sub-line.",
|
|
3187
3260
|
"usage": {
|
|
3188
|
-
"when": "Show one
|
|
3189
|
-
"whenNot": "A figure inside a Card, or a status with a trailing badge.",
|
|
3261
|
+
"when": "Show one headline figure inline, inside prose or a dense list, with its label and an optional sub-line.",
|
|
3262
|
+
"whenNot": "A row of headline numbers on a screen, a figure inside a Card, or a status with a trailing badge.",
|
|
3190
3263
|
"useInstead": [
|
|
3264
|
+
{
|
|
3265
|
+
"component": "MetricTiles",
|
|
3266
|
+
"reason": "a row of headline numbers (one MetricTile per number)"
|
|
3267
|
+
},
|
|
3191
3268
|
{
|
|
3192
3269
|
"component": "Card.Metric",
|
|
3193
3270
|
"reason": "a figure inside a Card (hds#254 folds Stat into the Card slot)"
|
|
@@ -3228,40 +3305,6 @@
|
|
|
3228
3305
|
}
|
|
3229
3306
|
]
|
|
3230
3307
|
},
|
|
3231
|
-
"StatusDot": {
|
|
3232
|
-
"filePath": "src/app/components/status-dot.tsx",
|
|
3233
|
-
"description": "A small solid dot conveying a semantic status via `tone`.",
|
|
3234
|
-
"usage": {
|
|
3235
|
-
"useInstead": [
|
|
3236
|
-
{
|
|
3237
|
-
"component": "Badge",
|
|
3238
|
-
"reason": "with `dot`"
|
|
3239
|
-
}
|
|
3240
|
-
]
|
|
3241
|
-
},
|
|
3242
|
-
"category": "Feedback",
|
|
3243
|
-
"hidden": false,
|
|
3244
|
-
"props": [
|
|
3245
|
-
{
|
|
3246
|
-
"name": "label",
|
|
3247
|
-
"type": "string",
|
|
3248
|
-
"required": false,
|
|
3249
|
-
"description": "Accessible name for the status. When provided the dot is exposed as a `role=\"status\"` with this label; when omitted the dot is decorative (`aria-hidden`) and a sibling should carry the meaning."
|
|
3250
|
-
},
|
|
3251
|
-
{
|
|
3252
|
-
"name": "size",
|
|
3253
|
-
"type": "\"sm\" | \"md\" | \"lg\" | null",
|
|
3254
|
-
"required": false,
|
|
3255
|
-
"description": ""
|
|
3256
|
-
},
|
|
3257
|
-
{
|
|
3258
|
-
"name": "tone",
|
|
3259
|
-
"type": "\"success\" | \"danger\" | \"warning\" | \"info\" | \"neutral\" | \"inProgress\" | null",
|
|
3260
|
-
"required": false,
|
|
3261
|
-
"description": ""
|
|
3262
|
-
}
|
|
3263
|
-
]
|
|
3264
|
-
},
|
|
3265
3308
|
"StatusListItem": {
|
|
3266
3309
|
"filePath": "src/app/components/status-list-item.tsx",
|
|
3267
3310
|
"description": "Status dot + title row with optional muted notes and trailing slot (e.g. badge).",
|
|
@@ -3300,11 +3343,15 @@
|
|
|
3300
3343
|
"description": "Block-layout sibling of StatusListItem. Renders a raised surface tile with title, optional muted notes, and a trailing slot for a badge or affordance. Status colour belongs in the trailing slot, never as a left rule on the tile — every tile should look the same so feedback signals stay reserved for genuinely interrupting states.",
|
|
3301
3344
|
"usage": {
|
|
3302
3345
|
"when": "Show a titled status block with optional notes and a trailing badge or affordance.",
|
|
3303
|
-
"whenNot": "A
|
|
3346
|
+
"whenNot": "A headline number (never a value), or a row inside a list.",
|
|
3304
3347
|
"useInstead": [
|
|
3348
|
+
{
|
|
3349
|
+
"component": "MetricTiles",
|
|
3350
|
+
"reason": "a row of headline numbers"
|
|
3351
|
+
},
|
|
3305
3352
|
{
|
|
3306
3353
|
"component": "Card.Metric",
|
|
3307
|
-
"reason": "a headline figure (hds#254 folds StatusTile into the Card slot)"
|
|
3354
|
+
"reason": "a headline figure inside a Card (hds#254 folds StatusTile into the Card slot)"
|
|
3308
3355
|
},
|
|
3309
3356
|
{
|
|
3310
3357
|
"component": "StatusListItem",
|
|
@@ -3346,6 +3393,7 @@
|
|
|
3346
3393
|
"Surface": {
|
|
3347
3394
|
"filePath": "src/app/components/surface.tsx",
|
|
3348
3395
|
"description": "Surface — governed inset surface primitive. Enforces the \"Surface Inset\" rule: backgrounds MUST have internal padding. - Default padding: px24 (cards) | px16 (items) - Default border: none (elevation model — use shadow for lift) - Radius: `rounded-lg` (role radius + 4px), the one container radius shared with Card - shadow prop: applies a two-layer elevation shadow for card lift Usage: <Surface>Card content</Surface> <Surface padding=\"item\">Compact item</Surface> <Surface shadow>Lifted card with elevation shadow.</Surface>",
|
|
3396
|
+
"core": true,
|
|
3349
3397
|
"usage": {
|
|
3350
3398
|
"when": "Wrap content in a padded, background-bearing inset surface with no header or footer anatomy.",
|
|
3351
3399
|
"whenNot": "Page layout, section spacing, width constraints, or content that needs slots.",
|
|
@@ -3475,6 +3523,7 @@
|
|
|
3475
3523
|
"Table": {
|
|
3476
3524
|
"filePath": "src/app/components/table.tsx",
|
|
3477
3525
|
"description": "Table - structured data table primitive for documentation and compact UI matrices.",
|
|
3526
|
+
"core": true,
|
|
3478
3527
|
"usage": {
|
|
3479
3528
|
"when": "Show rows of structured data in aligned columns, with optional sorting.",
|
|
3480
3529
|
"whenNot": "A single record, a short list of links, or content that reflows as cards.",
|
|
@@ -3526,9 +3575,9 @@
|
|
|
3526
3575
|
{
|
|
3527
3576
|
"name": "flush",
|
|
3528
3577
|
"type": "boolean",
|
|
3529
|
-
"default": "
|
|
3578
|
+
"default": "true",
|
|
3530
3579
|
"required": false,
|
|
3531
|
-
"description": ""
|
|
3580
|
+
"description": "Drop the scroll region's own inset. On by default: every cell already carries the surface inset, so a padded region doubled it (48px at the edges, hds#522). Pass `flush={false}` to restore the extra region padding."
|
|
3532
3581
|
},
|
|
3533
3582
|
{
|
|
3534
3583
|
"name": "labelledBy",
|
|
@@ -3598,6 +3647,7 @@
|
|
|
3598
3647
|
"Tabs": {
|
|
3599
3648
|
"filePath": "src/app/components/tabs.tsx",
|
|
3600
3649
|
"description": "The tab set itself. Tagged here rather than in the file block because TabsList and TabsContent share this module and have no Figma node of their own — a file-level @figma would silently claim this node for all four.",
|
|
3650
|
+
"core": true,
|
|
3601
3651
|
"usage": {
|
|
3602
3652
|
"when": "Switch between panels of related content in the same place, one visible at a time.",
|
|
3603
3653
|
"whenNot": "A compact mode switch with no panels, or content that must all be visible.",
|
|
@@ -3729,6 +3779,7 @@
|
|
|
3729
3779
|
"Tag": {
|
|
3730
3780
|
"filePath": "src/app/components/tag.tsx",
|
|
3731
3781
|
"description": "Tag — interactive filter and category chip. The outer <button> carries the accessible 44px hit target directly via the size token while the inner pill keeps the visible surface compact. Colors (background, border-color, color) live in the pill's cva variants, painted through `group-hover`/`group-active` so the pill reacts to interaction on the shared outer button (converted off the former .hds-tag-btn/.hds-tag-pill theme.css rules for #60 — same behavior, now token-driven Tailwind classes). The `active` prop (aria-pressed selected state) is not one of the variant contract's four axes — it's expressed as the pill's `selected` cva variant, carrying the same rest → hover → pressed → focus-visible state matrix the contract expects, just keyed by selection instead of tone/size/density.",
|
|
3782
|
+
"core": true,
|
|
3732
3783
|
"usage": {
|
|
3733
3784
|
"when": "Show an interactive filter or category chip that people can toggle.",
|
|
3734
3785
|
"whenNot": "A read-only status or count label.",
|
|
@@ -3761,6 +3812,7 @@
|
|
|
3761
3812
|
"Text": {
|
|
3762
3813
|
"filePath": "src/app/components/text.tsx",
|
|
3763
3814
|
"description": "Text — polymorphic typography primitive spanning the full HDS type ramp.",
|
|
3815
|
+
"core": true,
|
|
3764
3816
|
"usage": {
|
|
3765
3817
|
"when": "Set any text on the type ramp, with the element chosen by `as`.",
|
|
3766
3818
|
"whenNot": "Navigation links, or a keyboard hint.",
|
|
@@ -3777,6 +3829,7 @@
|
|
|
3777
3829
|
},
|
|
3778
3830
|
"category": "Typography",
|
|
3779
3831
|
"hidden": false,
|
|
3832
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2022-31",
|
|
3780
3833
|
"props": [
|
|
3781
3834
|
{
|
|
3782
3835
|
"name": "as",
|
|
@@ -3814,6 +3867,7 @@
|
|
|
3814
3867
|
"Textarea": {
|
|
3815
3868
|
"filePath": "src/app/components/textarea.tsx",
|
|
3816
3869
|
"description": "Textarea — multi-line text field primitive with label, helper, and error slots. Mirrors Input's shell + token skin as a native `<textarea>`. Figma parity: the four states Default / Focus / Error / Disabled map to the focus-ring, `error`, and `disabled` treatments below.",
|
|
3870
|
+
"core": true,
|
|
3817
3871
|
"usage": {
|
|
3818
3872
|
"when": "Collect multi-line free text such as a message, note or description.",
|
|
3819
3873
|
"whenNot": "A single line of text, or choosing from a list.",
|
|
@@ -3884,6 +3938,7 @@
|
|
|
3884
3938
|
"description": "Presents a date/time with a machine-readable `dateTime` for accessibility.",
|
|
3885
3939
|
"category": "Display",
|
|
3886
3940
|
"hidden": false,
|
|
3941
|
+
"figmaUrl": "https://www.figma.com/design/2VgBbVpKiDnu0aftJEVyBQ/HDS-Tokens-Components-Copy?node-id=2031-11",
|
|
3887
3942
|
"props": [
|
|
3888
3943
|
{
|
|
3889
3944
|
"name": "date",
|
|
@@ -3915,6 +3970,7 @@
|
|
|
3915
3970
|
"ToastProvider": {
|
|
3916
3971
|
"filePath": "src/app/components/toast.tsx",
|
|
3917
3972
|
"description": "Provider + viewport for the toast system. Wrap the app root once.",
|
|
3973
|
+
"core": true,
|
|
3918
3974
|
"usage": {
|
|
3919
3975
|
"when": "Confirm an action with a brief message that appears and dismisses itself, through useToast.",
|
|
3920
3976
|
"whenNot": "A message people must act on or that must stay next to its content.",
|
|
@@ -3958,6 +4014,7 @@
|
|
|
3958
4014
|
"Toggle": {
|
|
3959
4015
|
"filePath": "src/app/components/toggle.tsx",
|
|
3960
4016
|
"description": "Toggle — boolean on/off toggle with animated thumb.",
|
|
4017
|
+
"core": true,
|
|
3961
4018
|
"usage": {
|
|
3962
4019
|
"when": "Switch one setting on or off, with the effect applying immediately.",
|
|
3963
4020
|
"whenNot": "A choice that only takes effect after submitting a form, or picking from several options.",
|
|
@@ -3999,6 +4056,7 @@
|
|
|
3999
4056
|
"VisuallyHidden": {
|
|
4000
4057
|
"filePath": "src/app/components/visually-hidden.tsx",
|
|
4001
4058
|
"description": "Renders its children off-screen (Tailwind `sr-only`) so they are announced by screen readers without occupying visual space — e.g. a text label for an icon-only control.",
|
|
4059
|
+
"core": true,
|
|
4002
4060
|
"usage": {
|
|
4003
4061
|
"when": "Give assistive technology a label or description that sighted people do not need to see.",
|
|
4004
4062
|
"whenNot": "Text everyone should read, or hiding an element from assistive technology too.",
|
|
@@ -4024,6 +4082,7 @@
|
|
|
4024
4082
|
"Menu": {
|
|
4025
4083
|
"filePath": "src/app/components/menu.tsx",
|
|
4026
4084
|
"description": "Menu root + parts. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.",
|
|
4085
|
+
"core": true,
|
|
4027
4086
|
"category": "Overlays",
|
|
4028
4087
|
"usage": {
|
|
4029
4088
|
"when": "Offer a list of actions from a trigger, closed until opened.",
|
|
@@ -4119,6 +4178,7 @@
|
|
|
4119
4178
|
"Popover": {
|
|
4120
4179
|
"filePath": "src/app/components/popover.tsx",
|
|
4121
4180
|
"description": "Popover root + parts. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.",
|
|
4181
|
+
"core": true,
|
|
4122
4182
|
"category": "Overlays",
|
|
4123
4183
|
"usage": {
|
|
4124
4184
|
"when": "Anchor interactive content, such as a short form, a filter set or a picker, to a trigger people click to open.",
|
|
@@ -4190,6 +4250,7 @@
|
|
|
4190
4250
|
"Tooltip": {
|
|
4191
4251
|
"filePath": "src/app/components/hds-tooltip.tsx",
|
|
4192
4252
|
"description": "Tooltip root. Bakes in the Radix Provider so a single `<Tooltip>` is self-contained — no app-level provider required. Controlled via `open`/`onOpenChange`, or uncontrolled with `defaultOpen`.",
|
|
4253
|
+
"core": true,
|
|
4193
4254
|
"category": "Overlays",
|
|
4194
4255
|
"usage": {
|
|
4195
4256
|
"when": "Name an icon-only control, or add a short hint that appears on hover and keyboard focus.",
|