division-ds 0.2.0 → 0.3.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.
Files changed (95) hide show
  1. package/AGENTS.md +11 -5
  2. package/division-ds-0.3.0.tgz +0 -0
  3. package/package.json +1 -1
  4. package/public/docs/components/accordion.md +2 -0
  5. package/public/docs/components/ai-label.md +2 -0
  6. package/public/docs/components/alert-dialog.md +2 -0
  7. package/public/docs/components/alert.md +2 -0
  8. package/public/docs/components/approval-request.md +2 -0
  9. package/public/docs/components/auth-form.md +2 -0
  10. package/public/docs/components/avatar-group.md +2 -0
  11. package/public/docs/components/avatar.md +2 -0
  12. package/public/docs/components/badge.md +2 -0
  13. package/public/docs/components/breadcrumbs.md +2 -0
  14. package/public/docs/components/button.md +2 -0
  15. package/public/docs/components/card.md +2 -0
  16. package/public/docs/components/carousel.md +2 -0
  17. package/public/docs/components/cart.md +2 -0
  18. package/public/docs/components/chart-panel.md +2 -0
  19. package/public/docs/components/chat-message.md +3 -0
  20. package/public/docs/components/chat-thread.md +2 -0
  21. package/public/docs/components/checkbox.md +2 -0
  22. package/public/docs/components/checkout-form.md +2 -0
  23. package/public/docs/components/command-palette.md +6 -1
  24. package/public/docs/components/data-table.md +2 -0
  25. package/public/docs/components/date-picker.md +166 -0
  26. package/public/docs/components/date-presets.md +111 -0
  27. package/public/docs/components/date-range-picker.md +135 -0
  28. package/public/docs/components/description-list.md +2 -0
  29. package/public/docs/components/dialog.md +2 -0
  30. package/public/docs/components/divider.md +2 -0
  31. package/public/docs/components/dropdown-menu.md +2 -0
  32. package/public/docs/components/empty-state.md +2 -0
  33. package/public/docs/components/footer.md +2 -0
  34. package/public/docs/components/form-field.md +4 -1
  35. package/public/docs/components/icon-button.md +2 -0
  36. package/public/docs/components/input.md +2 -0
  37. package/public/docs/components/kanban-board.md +2 -0
  38. package/public/docs/components/kbd.md +2 -0
  39. package/public/docs/components/link.md +2 -0
  40. package/public/docs/components/list-item.md +3 -0
  41. package/public/docs/components/loading-animation.md +2 -0
  42. package/public/docs/components/multi-select.md +2 -0
  43. package/public/docs/components/navbar.md +2 -0
  44. package/public/docs/components/newsletter-form.md +2 -0
  45. package/public/docs/components/page-header.md +2 -0
  46. package/public/docs/components/pagination.md +2 -0
  47. package/public/docs/components/product-card.md +3 -0
  48. package/public/docs/components/progress.md +3 -1
  49. package/public/docs/components/prompt-input.md +2 -0
  50. package/public/docs/components/quantity-stepper.md +2 -0
  51. package/public/docs/components/radio.md +38 -1
  52. package/public/docs/components/rating.md +2 -0
  53. package/public/docs/components/score-ring.md +2 -0
  54. package/public/docs/components/search.md +2 -0
  55. package/public/docs/components/section-heading.md +2 -0
  56. package/public/docs/components/segmented-control.md +2 -0
  57. package/public/docs/components/select.md +3 -1
  58. package/public/docs/components/sheet.md +2 -0
  59. package/public/docs/components/sidebar.md +2 -0
  60. package/public/docs/components/skeleton.md +2 -0
  61. package/public/docs/components/slider.md +3 -1
  62. package/public/docs/components/sparkline.md +2 -0
  63. package/public/docs/components/spinner.md +4 -2
  64. package/public/docs/components/stat.md +2 -0
  65. package/public/docs/components/status-tracker.md +2 -0
  66. package/public/docs/components/stepper.md +2 -0
  67. package/public/docs/components/switch.md +4 -2
  68. package/public/docs/components/tabs.md +2 -0
  69. package/public/docs/components/tag.md +2 -0
  70. package/public/docs/components/textarea.md +2 -0
  71. package/public/docs/components/time-field.md +127 -0
  72. package/public/docs/components/timeline.md +2 -0
  73. package/public/docs/components/toast.md +2 -0
  74. package/public/docs/components/tool-call.md +2 -0
  75. package/public/docs/components/tooltip.md +2 -0
  76. package/public/manifest/components.json +947 -72
  77. package/public/manifest/tokens.json +36 -5
  78. package/scripts/division-ds.mjs +5 -5
  79. package/scripts/lib/agent-docs.mjs +49 -6
  80. package/scripts/lib/ai-copy.mjs +15 -1
  81. package/scripts/lib/check-text.mjs +13 -0
  82. package/scripts/lib/mcp-server.mjs +2 -1
  83. package/scripts/lib/mcp-tools.mjs +25 -12
  84. package/scripts/lib/props-validator.mjs +2 -1
  85. package/scripts/lib/search-score.mjs +24 -0
  86. package/scripts/lib/token-discipline.mjs +10 -3
  87. package/skills/division-ds/SKILL.md +2 -2
  88. package/skills/division-ds/commands/add.md +1 -1
  89. package/skills/division-ds/commands/build.md +1 -1
  90. package/skills/division-ds/commands/fix.md +1 -1
  91. package/skills/division-ds/commands/review.md +2 -2
  92. package/skills/division-ds/topics/ai.md +2 -1
  93. package/skills/division-ds/topics/forms.md +3 -0
  94. package/skills/division-ds/topics/layout.md +3 -1
  95. package/division-ds-0.2.0.tgz +0 -0
@@ -0,0 +1,135 @@
1
+ # DateRangePicker
2
+
3
+ > A start and an end date in one field, an add-on to DatePicker. Type both, or open two months side by side: the first day you pick is the start, the band follows you to the second, which sets the end and closes the calendar. Put DatePresets in `aside` for one-click periods like Last 7 days. Installs DatePicker with it.
4
+
5
+ - **Best for:** A booking, a report window, a leave request.
6
+ - **Not for:** One day: DatePicker.
7
+ - Molecule. Source: `src/components/molecules/date-range-picker/DateRangePicker.tsx`
8
+ - Rendered docs page: `/components/date-range-picker`
9
+
10
+ ## Import
11
+
12
+ ```tsx
13
+ import { DateRangePicker, EMPTY_RANGE, useDateRangePicker } from 'src/components/molecules/date-range-picker/DateRangePicker'
14
+ ```
15
+
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
18
+ ## Props
19
+
20
+ | Prop | Type | Default | Description |
21
+ |---|---|---|---|
22
+ | `label` | `string` | | Required. Names the field. Inside a FormField, FormField sets it. |
23
+ | `value` | `{ start: string; end: string }` | | Controlled range. Each end is 'YYYY-MM-DD' or ''. |
24
+ | `defaultValue` | `{ start: string; end: string }` | `{ start: '', end: '' }` | Starting range when the picker holds it itself. |
25
+ | `onValueChange` | `(range: DateRange) => void` | | Fires when either end changes. Days picked in the calendar always arrive in order. |
26
+ | `min` | `string` | | Earliest date, 'YYYY-MM-DD'. |
27
+ | `max` | `string` | | Latest date, 'YYYY-MM-DD'. |
28
+ | `isDateDisabled` | `(date: string) => boolean` | | Days that cannot be picked. |
29
+ | `locale` | `string` | | Segment order, names and first day of the week. Defaults to the browser's. |
30
+ | `weekStartsOn` | `number` | | 0 Sunday to 6 Saturday. Defaults to the locale's. |
31
+ | `aside` | `ReactNode` | | Beside the months, in the popover. DatePresets reads and sets the range by itself here. |
32
+ | `partLabels` | `[string, string]` | `['Start date', 'End date']` | The names of the two dates. |
33
+ | `disabled` | `boolean` | `false` | Disables both dates and the button. |
34
+ | `invalid` | `boolean` | | Marks the field invalid. FormField sets it. |
35
+ | `required` | `boolean` | | Marks both dates required. FormField sets it. |
36
+ | `name` | `string` | | Submits name-start and name-end with a form. |
37
+ | `id` | `string` | | The field's id. FormField sets it. |
38
+ | `aria-describedby` | `string` | | The ids of the help and error text. FormField sets it. |
39
+ | `className` | `string` | | Combined with the field's classes. |
40
+ | `ref` | `Ref<HTMLDivElement>` | | The field's group element. |
41
+ | `useDateRangePicker()` | `() => { value: DateRange; select: (range: DateRange) => void } \| null` | | Inside the popover: the range, and a way to set it and close. For your own aside content. |
42
+
43
+ ## Types and helpers
44
+
45
+ Exported beside the component, from the same file. Import a type with `import type { ... }`.
46
+
47
+ ```ts
48
+ /** A start and an end, each 'YYYY-MM-DD' or '' while not chosen. */
49
+ export type DateRange = { start: IsoDate | ''; end: IsoDate | '' }
50
+ ```
51
+
52
+ ```ts
53
+ export const EMPTY_RANGE: DateRange = { start: '', end: '' }
54
+ ```
55
+
56
+ ```ts
57
+ /** The open picker's range, and a way to set it and close. DatePresets reads it, so a preset in
58
+ * `aside` needs no wiring. null outside a DateRangePicker. */
59
+ export const useDateRangePicker = () => useContext(Context)
60
+ ```
61
+
62
+ ## Examples
63
+
64
+ Each is compiled and rendered on the docs page. Imports are omitted; see above.
65
+
66
+ ### Default
67
+
68
+ ```tsx
69
+ <div className="w-full max-w-sm">
70
+ <DateRangePicker label="Stay" />
71
+ </div>
72
+ ```
73
+
74
+ ### With DatePresets beside the months
75
+
76
+ ```tsx
77
+ <div className="w-full max-w-sm">
78
+ <FormField label="Report period" help="Pick a preset, or two days.">
79
+ <DateRangePicker label="Report period" aside={<DatePresets />} />
80
+ </FormField>
81
+ </div>
82
+ ```
83
+
84
+ ### Controlled: the page holds the range
85
+
86
+ ```tsx
87
+ function Controlled() {
88
+ const [range, setRange] = useState<DateRange>({ start: '2026-11-09', end: '2026-11-13' })
89
+ return (
90
+ <div className="flex w-full max-w-sm flex-col gap-2">
91
+ <DateRangePicker label="Leave" value={range} onValueChange={setRange} />
92
+ <span className="font-mono text-xs text-[var(--color-text-secondary)]">
93
+ start: {range.start || '—'}, end: {range.end || '—'}
94
+ </span>
95
+ </div>
96
+ )
97
+ }
98
+
99
+ <Controlled />
100
+ ```
101
+
102
+ ### Limits: November and December only
103
+
104
+ ```tsx
105
+ <div className="w-full max-w-sm">
106
+ <DateRangePicker label="Rental" min="2026-11-01" max="2026-12-30" defaultValue={{ start: '2026-11-20', end: '2026-11-23' }} />
107
+ </div>
108
+ ```
109
+
110
+ ## Keyboard
111
+
112
+ | Keys | Result |
113
+ |---|---|
114
+ | `0–9` `↑` `↓` | Types or steps the focused segment of either date. |
115
+ | `←` `→` | In the field: the next segment, across both dates. In the calendar: the day before or after, moving the band. |
116
+ | `Page Up` `Page Down` | A month earlier or later. With Shift, a year. |
117
+ | `Enter` `Space` | Picks the start, then the end, which closes the calendar. |
118
+ | `Esc` | Closes the calendar. A start picked without an end stays as the start. |
119
+
120
+ ## Do
121
+
122
+ - Add DatePresets in aside when people mostly want the usual periods.
123
+ - Validate the length yourself if a range has a limit (a 30-day report), and say so in help text.
124
+
125
+ ## Don't
126
+
127
+ - Don't use two separate DatePickers for a start and an end: nobody sees the band.
128
+ - Don't reorder a typed range for the user; the field marks it invalid so they can see what they typed.
129
+
130
+ ## Anatomy
131
+
132
+ - **Field**: A group named by the label, holding two segmented dates (Start date, End date) and the calendar button. A typed end before the start marks it invalid.
133
+ - **Calendar**: Two months, stacked on narrow screens. The ends are solid accent squares, the days between a light accent band.
134
+ - **Hint**: "Pick the first day." or "Pick the last day.", under the months, announced when it changes.
135
+ - **Aside**: An optional column beside the months, for DatePresets.
@@ -13,6 +13,8 @@
13
13
  import { DescriptionList } from 'src/components/molecules/description-list/DescriptionList'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Dialog, DialogClose, DialogContent, DialogFooter, DialogTrigger } from 'src/components/organisms/dialog/Dialog'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Divider } from 'src/components/atoms/divider/Divider'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from 'src/components/molecules/dropdown-menu/DropdownMenu'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { EmptyState } from 'src/components/molecules/empty-state/EmptyState'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Footer } from 'src/components/organisms/footer/Footer'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -4,6 +4,7 @@
4
4
 
5
5
  - **Best for:** The label, help and error for an Input, Textarea, Select, MultiSelect or QuantityStepper.
6
6
  - **Not for:** Search or RatingInput, which name themselves. Switch, Checkbox and Radio take an id and a label with htmlFor instead.
7
+ - **Also on this page:** `ErrorSummary`
7
8
  - Molecule. Source: `src/components/molecules/form-field/FormField.tsx`
8
9
  - Rendered docs page: `/components/form-field`
9
10
 
@@ -14,6 +15,8 @@ import { FormField } from 'src/components/molecules/form-field/FormField'
14
15
  import { ErrorSummary } from 'src/components/molecules/form-field/ErrorSummary'
15
16
  ```
16
17
 
18
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
19
+
17
20
  ## Props
18
21
 
19
22
  | Prop | Type | Default | Description |
@@ -22,7 +25,7 @@ import { ErrorSummary } from 'src/components/molecules/form-field/ErrorSummary'
22
25
  | `help` | `string` | | Instruction text, read out before any error. |
23
26
  | `error` | `string` | | Sets invalid on the control and adds the error line. |
24
27
  | `required` | `boolean` | `false` | Adds the asterisk (hidden from screen readers) and the built-in required attribute on the control. That attribute is what assistive technology actually announces. |
25
- | `children` | `ReactElement` | | Exactly one control: Input, Textarea, Select or QuantityStepper. A label set on a Select or QuantityStepper child is replaced by the FormField label. |
28
+ | `children` | `ReactElement` | | Exactly one control: Input, Textarea, Select or QuantityStepper. A label set on a Select or QuantityStepper child is replaced by the FormField label. An id you give the control is kept (point an ErrorSummary entry at it); without one, FormField makes one up. |
26
29
  | `className` | `string` | | Extra CSS classes, merged with the outer element's own. When two Tailwind classes clash, the later one wins. |
27
30
  | `ref` | `Ref<HTMLDivElement>` | | Passed through to the outer element. |
28
31
  | `errors (ErrorSummary)` | `{ fieldId: string; message: string }[]` | | What stopped the form from submitting, in the order of the fields. Each entry links to its field and moves focus there. An empty list shows nothing. |
@@ -13,6 +13,8 @@
13
13
  import { IconButton } from 'src/components/atoms/icon-button/IconButton'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Input, inputVariants } from 'src/components/atoms/input/Input'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Requires
17
19
 
18
20
  - A <FormField> around it. On its own the control has no label. FormField adds the label, the help text and the error, and connects their ids.
@@ -13,6 +13,8 @@
13
13
  import { KanbanBoard, applyKanbanMove, groupKanbanItems, kanbanDragOver, kanbanDrop, kanbanMessages, kanbanPosition } from 'src/components/organisms/kanban-board/KanbanBoard'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Requires
17
19
 
18
20
  - A parent that holds items in state and applies each onMove (applyKanbanMove does the update).
@@ -13,6 +13,8 @@
13
13
  import { Kbd } from 'src/components/atoms/kbd/Kbd'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Link, linkVariants } from 'src/components/atoms/link/Link'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -4,6 +4,7 @@
4
4
 
5
5
  - **Best for:** A row people scan in a List: media, a title, meta and one or two actions.
6
6
  - **Not for:** Data in a table that people compare across columns: use DataTable.
7
+ - **Also on this page:** `List`
7
8
  - Molecule. Source: `src/components/molecules/list-item/ListItem.tsx`
8
9
  - Rendered docs page: `/components/list-item`
9
10
 
@@ -13,6 +14,8 @@
13
14
  import { List, ListItem } from 'src/components/molecules/list-item/ListItem'
14
15
  ```
15
16
 
17
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
18
+
16
19
  ## Requires
17
20
 
18
21
  - A <List> around the rows (a ul with role="list"), or as="div" on a row that stands alone.
@@ -13,6 +13,8 @@
13
13
  import { LoadingAnimation } from 'src/components/atoms/loading-animation/LoadingAnimation'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { MultiSelect } from 'src/components/molecules/multi-select/MultiSelect'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Requires
17
19
 
18
20
  - A <FormField> around it. FormField supplies the visible label, the help and the error, and replaces the label prop with its own.
@@ -13,6 +13,8 @@
13
13
  import { Navbar } from 'src/components/organisms/navbar/Navbar'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { NewsletterForm } from 'src/components/organisms/newsletter-form/NewsletterForm'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { PageHeader } from 'src/components/molecules/page-header/PageHeader'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Pagination, paginationRange } from 'src/components/molecules/pagination/Pagination'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -4,6 +4,7 @@
4
4
 
5
5
  - **Best for:** One product in a shop grid, where the whole card opens it and Add to cart sits on it.
6
6
  - **Not for:** A general content panel: use Card.
7
+ - **Also on this page:** `ProductGrid`
7
8
  - Organism. Source: `src/components/organisms/product-card/ProductCard.tsx`
8
9
  - Rendered docs page: `/components/product-card`
9
10
 
@@ -13,6 +14,8 @@
13
14
  import { ProductCard, ProductGrid } from 'src/components/organisms/product-card/ProductCard'
14
15
  ```
15
16
 
17
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
18
+
16
19
  ## Props
17
20
 
18
21
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Progress } from 'src/components/atoms/progress/Progress'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -21,7 +23,7 @@ import { Progress } from 'src/components/atoms/progress/Progress'
21
23
  | `value` | `number \| null` | | null means indeterminate. The value is clamped to [0, max], so an out-of-range value shows as complete instead of overflowing the track. |
22
24
  | `max` | `number` | `100` | The value at which the bar is complete. |
23
25
  | `showValue` | `boolean` | `false` | Shows the percentage (or "In progress") as a readout. |
24
- | `tone` | `'signal' \| 'ok' \| 'warning' \| 'hostile'` | `'signal'` | The fill colour. signal paints accent.signal.fill to match Slider. On the track in light theme that’s a 2.15:1 contrast ratio, below the 3:1 a bar needs when it’s the only sign of progress. So set showValue there. |
26
+ | `tone` | `'signal' \| 'ok' \| 'warning' \| 'hostile'` | `'signal'` | The fill colour. signal paints accent.signal.indicator to match Slider. On the track in light theme that’s a 2.15:1 contrast ratio, below the 3:1 a bar needs when it’s the only sign of progress. So set showValue there. |
25
27
  | `className` | `string` | | Merged with the outer wrapper’s classes. Later Tailwind utilities (Tailwind is the CSS framework the system is styled with) win. |
26
28
  | `ref` | `Ref<HTMLDivElement>` | | Passed through to the Radix Progress root, which is the bar itself. Radix is the library of accessible building blocks this component sits on. |
27
29
  | `...rest` | `Omit<HTMLAttributes<HTMLDivElement>, 'children'>` | | Every native div prop except children, spread onto the outer wrapper, so a molecule can attach a data-testid there. children is typed away because this component draws its own label row and track, and a children prop would be thrown away without any warning. |
@@ -13,6 +13,8 @@
13
13
  import { PromptInput } from 'src/components/molecules/prompt-input/PromptInput'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Requires
17
19
 
18
20
  - A parent that keeps the draft in state and clears it in onSubmit.
@@ -13,6 +13,8 @@
13
13
  import { QuantityStepper, clampQuantity, gridMax } from 'src/components/molecules/quantity-stepper/QuantityStepper'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Radio, RadioGroup } from 'src/components/atoms/radio/Radio'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -123,7 +125,7 @@ const SPEEDS = ['standard', 'priority', 'overnight'] as const
123
125
 
124
126
  ## Do
125
127
 
126
- - Name the group with aria-label or a FormField legend.
128
+ - Name the group: in a form, a fieldset legend that the RadioGroup points at with aria-labelledby; elsewhere, aria-label.
127
129
  - Offer a default when one option really is the norm.
128
130
  - Keep the set short. Past about seven options, use a Select.
129
131
 
@@ -133,6 +135,41 @@ const SPEEDS = ['standard', 'priority', 'overnight'] as const
133
135
  - Don't put a radio outside a RadioGroup. Both the roving focus and the value come from the group.
134
136
  - Don't make choosing an option perform the action. Put a button after the group.
135
137
 
138
+ ## Common mistakes
139
+
140
+ Wrong:
141
+
142
+ ```tsx
143
+ <FormField label="Difficulty" error={error}>
144
+ <RadioGroup>
145
+ <Radio value="easy" />
146
+ </RadioGroup>
147
+ </FormField>
148
+ ```
149
+
150
+ Right:
151
+
152
+ ```tsx
153
+ <fieldset aria-describedby={error ? 'difficulty-error' : undefined}>
154
+ <legend id="difficulty-label" className="font-mono text-[11px] font-semibold uppercase tracking-[0.12em] text-[var(--color-text-primary)]">
155
+ Difficulty
156
+ </legend>
157
+ <RadioGroup aria-labelledby="difficulty-label" aria-required="true" value={value} onValueChange={setValue} className="mt-2">
158
+ {['easy', 'moderate', 'hard'].map(option => (
159
+ <div key={option} className="flex items-center gap-2">
160
+ <Radio id={`difficulty-${option}`} value={option} invalid={Boolean(error)} />
161
+ <label htmlFor={`difficulty-${option}`} className="font-body text-sm">{option}</label>
162
+ </div>
163
+ ))}
164
+ </RadioGroup>
165
+ {error ? (
166
+ <p id="difficulty-error" className="mt-1.5 font-body text-sm text-[var(--color-accent-hostile-text)]">{error}</p>
167
+ ) : null}
168
+ </fieldset>
169
+ ```
170
+
171
+ FormField clones one control and gives it an id and a label; a group of radios has neither. The fieldset and legend name the group, the label styles match FormField, and the error is linked through aria-describedby. Give ErrorSummary the id of the first Radio so its link lands in the group.
172
+
136
173
  ## Anatomy
137
174
 
138
175
  - **RadioGroup**: Has role=radiogroup, which tells assistive tech (screen readers and similar tools) this is a set of radios. It handles roving focus, where only one option is reachable by Tab and the arrows move between the rest, and it owns the value.
@@ -13,6 +13,8 @@
13
13
  import { Rating, RatingInput } from 'src/components/molecules/rating/Rating'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { ScoreRing, scoreBand } from 'src/components/atoms/score-ring/ScoreRing'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Search } from 'src/components/molecules/search/Search'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { SectionHeading } from 'src/components/molecules/section-heading/SectionHeading'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { SegmentedControl } from 'src/components/molecules/segmented-control/SegmentedControl'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Select } from 'src/components/atoms/select/Select'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Requires
17
19
 
18
20
  - A <FormField> around it. On its own the control has no label. FormField supplies the label, the help text and the error, and connects their ids so assistive tech (screen readers and similar tools) reads them together.
@@ -216,7 +218,7 @@ const TERRAIN_OPTIONS = [
216
218
  - **Trigger**: Uses exactly the same frame and styling as Input, so a select and a text field line up in a form.
217
219
  - **Value**: Shows the placeholder until something’s chosen.
218
220
  - **Content**: Portalled and positioned by Radix, the library of accessible building blocks this sits on. It slides down out of the trigger as it opens (M7; Radix’s Select closes at once, with no exit animation). It’s the one atom that carries the corner crosshair, because it’s a surface framing other content, and that’s what the crosshair marks. It’s also the shape that can’t be cut, since clip-path would clip the crosshair’s arms and the last row’s selection fill along with them.
219
- - **Item**: Highlighted rows use signal.fill with signal.ink. That’s the fill-selection grammar, the system’s rule for how a selection looks.
221
+ - **Item**: Highlighted rows use accent.signal.indicator with accent.signal.indicator-ink. That’s the fill-selection grammar, the system’s rule for how a selection looks.
220
222
  - **ItemIndicator**: A tick on the selected row, so selection isn’t shown by the highlight alone.
221
223
  - **Item icon**: Optional. Sits before the label and is aria-hidden, an ARIA (Accessible Rich Internet Applications) attribute that hides it from assistive tech. It follows the row colour, so it turns ink on the highlight. It isn’t shown in the trigger.
222
224
  - **Group label**: Used with groups: a mono (monospaced font) heading over its rows that names the group for screen readers. It can’t be selected. A hairline separates the groups.
@@ -13,6 +13,8 @@
13
13
  import { Sheet, SheetClose, SheetContent, SheetTrigger } from 'src/components/organisms/sheet/Sheet'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Sidebar } from 'src/components/organisms/sidebar/Sidebar'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Skeleton, SkeletonGroup } from 'src/components/atoms/skeleton/Skeleton'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Slider } from 'src/components/atoms/slider/Slider'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -108,5 +110,5 @@ function SingleValueLive() {
108
110
 
109
111
  - **Label and readout**: An 11px (pixel) mono label, in a monospaced font, and a 24px Oxanium readout with tabular figures, digits that all take the same width. Unlike Progress, there are no dimmed leading zeros. min and max belong to the caller and formatValue can return anything, so a fixed digit width would be one the value doesn’t actually have.
110
112
  - **Track**: 4px tall, sunken, no border.
111
- - **Range**: The filled span, in signal.fill.
113
+ - **Range**: The filled span, in accent.signal.indicator.
112
114
  - **Thumb**: A 20px square inside a 24px hit area, the region that responds to a click or tap. There’s one per value.
@@ -13,6 +13,8 @@
13
13
  import { Sparkline } from 'src/components/atoms/sparkline/Sparkline'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -13,6 +13,8 @@
13
13
  import { Spinner, spinnerVariants } from 'src/components/atoms/spinner/Spinner'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |
@@ -32,7 +34,7 @@ Exported beside the component, from the same file. Import a type with `import ty
32
34
  export const spinnerVariants = cva(
33
35
  // The arc takes `currentColor`, so a caller can recolour it with one text utility: Button does
34
36
  // exactly that, so the arc matches whatever ink the button label is set in.
35
- 'inline-block shrink-0 text-[var(--color-accent-signal-fill)]',
37
+ 'inline-block shrink-0 text-[var(--color-accent-signal-indicator)]',
36
38
  {
37
39
  variants: {
38
40
  size: { sm: 'w-3.5 h-3.5', md: 'w-5 h-5', lg: 'w-6 h-6' },
@@ -91,6 +93,6 @@ Not focusable. No keyboard behaviour of its own.
91
93
  ## Anatomy
92
94
 
93
95
  - **span**: The root. It gets role="status" only when it's labelled.
94
- - **Ring (ring)**: An SVG (Scalable Vector Graphics) track at 20% of currentColor, which is the surrounding text colour, plus an arc in currentColor. That's accent.signal.fill by default.
96
+ - **Ring (ring)**: An SVG (Scalable Vector Graphics) track at 20% of currentColor, which is the surrounding text colour, plus an arc in currentColor. That's accent.signal.indicator by default.
95
97
  - **Blocks (conveyor)**: Three block glyphs, from full to half shade, running over a ten-cell track in border.control.
96
98
  - **sr-only label**: The text a screen reader announces. sr-only means it's hidden on screen but still read aloud. It's only there when label is passed.
@@ -13,6 +13,8 @@
13
13
  import { Stat } from 'src/components/molecules/stat/Stat'
14
14
  ```
15
15
 
16
+ Paths are from the Division DS repository root. Installed with shadcn they start `src/division-ds/` instead of `src/` (`src/division-ds/components/...`); import them relative to your file.
17
+
16
18
  ## Props
17
19
 
18
20
  | Prop | Type | Default | Description |