@misoto22/design 0.8.0 → 0.9.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 (157) hide show
  1. package/dist/agent/Accordion.md +1 -1
  2. package/dist/agent/Alert.md +1 -1
  3. package/dist/agent/AppShell.md +1 -1
  4. package/dist/agent/ArchitectureFigure.md +1 -1
  5. package/dist/agent/AreaChart.md +1 -1
  6. package/dist/agent/Article.md +1 -1
  7. package/dist/agent/AspectRatio.md +1 -1
  8. package/dist/agent/Avatar.md +1 -1
  9. package/dist/agent/Badge.md +1 -1
  10. package/dist/agent/BarChart.md +1 -1
  11. package/dist/agent/BarList.md +1 -1
  12. package/dist/agent/BigNumber.md +1 -1
  13. package/dist/agent/BoxPlot.md +1 -1
  14. package/dist/agent/Breadcrumb.md +1 -1
  15. package/dist/agent/BulletChart.md +1 -1
  16. package/dist/agent/Button.md +1 -1
  17. package/dist/agent/Calendar.md +1 -1
  18. package/dist/agent/Card.md +1 -1
  19. package/dist/agent/Checkbox.md +1 -1
  20. package/dist/agent/Code.md +1 -1
  21. package/dist/agent/CodeBlock.md +1 -1
  22. package/dist/agent/Collapsible.md +1 -1
  23. package/dist/agent/ColorPicker.md +75 -0
  24. package/dist/agent/Combobox.md +1 -1
  25. package/dist/agent/Command.md +1 -1
  26. package/dist/agent/ComposedChart.md +1 -1
  27. package/dist/agent/ContextMenu.md +1 -1
  28. package/dist/agent/DataflowFigure.md +1 -1
  29. package/dist/agent/DatePicker.md +1 -1
  30. package/dist/agent/DescriptionList.md +1 -1
  31. package/dist/agent/Diagram.md +1 -1
  32. package/dist/agent/DiagramCanvas.md +1 -1
  33. package/dist/agent/DiagramExportMenu.md +1 -1
  34. package/dist/agent/DiagramInspector.md +1 -1
  35. package/dist/agent/DiagramLegend.md +1 -1
  36. package/dist/agent/DiagramMinimap.md +1 -1
  37. package/dist/agent/DiagramToolbar.md +1 -1
  38. package/dist/agent/Dialog.md +1 -1
  39. package/dist/agent/DropdownMenu.md +1 -1
  40. package/dist/agent/EmptyState.md +1 -1
  41. package/dist/agent/ErrorState.md +1 -1
  42. package/dist/agent/Facet.md +1 -1
  43. package/dist/agent/Field.md +1 -1
  44. package/dist/agent/FigureBand.md +1 -1
  45. package/dist/agent/FloatingIconButton.md +1 -1
  46. package/dist/agent/FunnelChart.md +1 -1
  47. package/dist/agent/Heading.md +1 -1
  48. package/dist/agent/Heatmap.md +1 -1
  49. package/dist/agent/Histogram.md +1 -1
  50. package/dist/agent/Input.md +1 -1
  51. package/dist/agent/Kbd.md +1 -1
  52. package/dist/agent/LifecycleFigure.md +1 -1
  53. package/dist/agent/LineChart.md +1 -1
  54. package/dist/agent/LinkArrow.md +1 -1
  55. package/dist/agent/Markdown.md +1 -1
  56. package/dist/agent/NativeSelect.md +1 -1
  57. package/dist/agent/NavItem.md +1 -1
  58. package/dist/agent/NumberField.md +72 -0
  59. package/dist/agent/Pagination.md +1 -1
  60. package/dist/agent/PieChart.md +1 -1
  61. package/dist/agent/Popover.md +1 -1
  62. package/dist/agent/Progress.md +1 -1
  63. package/dist/agent/RadarChart.md +1 -1
  64. package/dist/agent/RadialChart.md +1 -1
  65. package/dist/agent/RadioGroup.md +1 -1
  66. package/dist/agent/SankeyChart.md +1 -1
  67. package/dist/agent/ScatterChart.md +1 -1
  68. package/dist/agent/ScrollArea.md +1 -1
  69. package/dist/agent/SearchableMenu.md +1 -1
  70. package/dist/agent/Select.md +1 -1
  71. package/dist/agent/Separator.md +1 -1
  72. package/dist/agent/SequenceFigure.md +1 -1
  73. package/dist/agent/Sheet.md +1 -1
  74. package/dist/agent/Sidebar.md +193 -0
  75. package/dist/agent/Skeleton.md +1 -1
  76. package/dist/agent/Slider.md +7 -3
  77. package/dist/agent/Sparkline.md +1 -1
  78. package/dist/agent/Spinner.md +1 -1
  79. package/dist/agent/StatusDot.md +1 -1
  80. package/dist/agent/StatusPill.md +1 -1
  81. package/dist/agent/Steps.md +1 -1
  82. package/dist/agent/Switch.md +1 -1
  83. package/dist/agent/Table.md +3 -1
  84. package/dist/agent/Tabs.md +1 -1
  85. package/dist/agent/Tag.md +1 -1
  86. package/dist/agent/Text.md +1 -1
  87. package/dist/agent/Textarea.md +1 -1
  88. package/dist/agent/Timestamp.md +1 -1
  89. package/dist/agent/Toast.md +1 -1
  90. package/dist/agent/ToggleGroup.md +1 -1
  91. package/dist/agent/Toolbar.md +1 -1
  92. package/dist/agent/Tooltip.md +1 -1
  93. package/dist/agent/TreemapChart.md +1 -1
  94. package/dist/agent/WaterfallChart.md +1 -1
  95. package/dist/agent/WorkflowFigure.md +1 -1
  96. package/dist/agent/catalog.json +361 -2
  97. package/dist/agent/index.md +8 -5
  98. package/dist/charts/BulletChart/BulletChart.js +16 -2
  99. package/dist/charts/BulletChart/BulletChart.js.map +1 -1
  100. package/dist/charts/RadarChart/RadarChart.js +4 -2
  101. package/dist/charts/RadarChart/RadarChart.js.map +1 -1
  102. package/dist/components/ColorPicker/ColorPicker.d.ts +67 -0
  103. package/dist/components/ColorPicker/ColorPicker.js +334 -0
  104. package/dist/components/ColorPicker/ColorPicker.js.map +1 -0
  105. package/dist/components/Command/Command.js +1 -1
  106. package/dist/components/Command/Command.js.map +1 -1
  107. package/dist/components/ContextMenu/ContextMenu.js +1 -1
  108. package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
  109. package/dist/components/Dialog/Dialog.js +1 -1
  110. package/dist/components/Dialog/Dialog.js.map +1 -1
  111. package/dist/components/DropdownMenu/DropdownMenu.js +1 -1
  112. package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
  113. package/dist/components/ErrorState/ErrorState.js +1 -1
  114. package/dist/components/ErrorState/ErrorState.js.map +1 -1
  115. package/dist/components/NavItem/NavItem.js +1 -1
  116. package/dist/components/NavItem/NavItem.js.map +1 -1
  117. package/dist/components/NumberField/NumberField.d.ts +69 -0
  118. package/dist/components/NumberField/NumberField.js +162 -0
  119. package/dist/components/NumberField/NumberField.js.map +1 -0
  120. package/dist/components/Popover/Popover.js +1 -1
  121. package/dist/components/Popover/Popover.js.map +1 -1
  122. package/dist/components/Select/Select.js +1 -1
  123. package/dist/components/Select/Select.js.map +1 -1
  124. package/dist/components/Sheet/Sheet.js +1 -1
  125. package/dist/components/Sheet/Sheet.js.map +1 -1
  126. package/dist/components/Sidebar/Sidebar.d.ts +349 -0
  127. package/dist/components/Sidebar/Sidebar.js +455 -0
  128. package/dist/components/Sidebar/Sidebar.js.map +1 -0
  129. package/dist/components/Slider/Slider.d.ts +22 -1
  130. package/dist/components/Slider/Slider.js +72 -8
  131. package/dist/components/Slider/Slider.js.map +1 -1
  132. package/dist/components/Table/Table.d.ts +14 -0
  133. package/dist/components/Table/Table.js.map +1 -1
  134. package/dist/components/Tabs/Tabs.js +7 -1
  135. package/dist/components/Tabs/Tabs.js.map +1 -1
  136. package/dist/diagrams/lib/route.d.ts +22 -1
  137. package/dist/diagrams/lib/route.js +24 -1
  138. package/dist/diagrams/lib/route.js.map +1 -1
  139. package/dist/diagrams/lib/wires.js +9 -5
  140. package/dist/diagrams/lib/wires.js.map +1 -1
  141. package/dist/index.d.ts +3 -0
  142. package/dist/index.js +3 -0
  143. package/dist/index.js.map +1 -1
  144. package/dist/lib/color.d.ts +80 -0
  145. package/dist/lib/color.js +189 -0
  146. package/dist/lib/color.js.map +1 -0
  147. package/dist/lib/numeric.d.ts +35 -0
  148. package/dist/lib/numeric.js +29 -0
  149. package/dist/lib/numeric.js.map +1 -0
  150. package/dist/styles.css +1 -1
  151. package/dist/themes.css +8 -0
  152. package/dist/tokens.css +66 -3
  153. package/dist/tokens.d.ts +3 -0
  154. package/dist/tokens.js +17 -0
  155. package/dist/tokens.json +17 -0
  156. package/package.json +1 -1
  157. package/skills/misoto22-design/rules/forms.md +3 -1
@@ -4,7 +4,7 @@ The platform’s own picker, restyled where it can be.
4
4
 
5
5
  - Group: Forms
6
6
  - Import: `import { NativeSelect } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/native-select/
9
9
  - Related: select, field
10
10
 
@@ -4,7 +4,7 @@ A row in a sidebar.
4
4
 
5
5
  - Group: Navigation
6
6
  - Import: `import { NavItem } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/nav-item/
9
9
  - Related: app-shell
10
10
 
@@ -0,0 +1,72 @@
1
+ # NumberField
2
+
3
+ A number, typed or swept to.
4
+
5
+ - Group: Forms
6
+ - Import: `import { NumberField } from '@misoto22/design'`
7
+ - Version: 0.9.0
8
+ - Docs: https://ui.misoto22.com/components/number-field/
9
+ - Related: input, slider, field
10
+
11
+ ## When to reach for it
12
+
13
+ The number has a range and a sensible increment. A bare quantity is an Input with type="number"; a value judged by WHERE it sits on a track is a Slider.
14
+
15
+ ## Anatomy
16
+
17
+ - **Field** (required) — A native number input wearing CONTROL_BASE, so it is the same box as Input, Textarea and Select — same padding, same focus, same disabled opacity. The native spinner buttons are hidden: they are three different controls in three browsers and none of them is this system’s.
18
+ - **Scrub grip** — A horizontal-arrows glyph at the inline start, on unless scrub is false. Dragging it changes the value by one step every 4px, ten steps with Shift held, and it follows the reading direction — in an RTL page, more is to the left. Pointer only and aria-hidden, because the keyboard already has the arrow keys.
19
+ - **Unit** — unit, drawn inside the end of the box and announced through aria-describedby. The slot is a fixed 3rem, so a unit longer than about four characters runs under a long number.
20
+
21
+ ## Best practices
22
+
23
+ ### Do
24
+
25
+ - Reach for it when a value is TUNED rather than entered — a duration, a line height, an offset. The grip is the whole argument for this over an Input: a reader finds those by sweeping past the neighbouring values, not by typing candidates one at a time.
26
+ - Wrap it in a Field. The root is a div and the id lands on the input inside it, so the label binds and clicks through exactly as it does for an Input — but only if there is a Field to do it.
27
+ - Pass min, max and step. They are what the arrows step by, what one notch of a scrub is worth, and what the value is reconciled with when the field is left; without them the control is an Input with a grip on it.
28
+
29
+ ### Don’t
30
+
31
+ - Do not expect the range to hold mid-keystroke. Clamping happens on blur, not on every character, because a minimum of 10 otherwise makes 50 unreachable — the 5 is clamped up before the 0 arrives. onValueChange can report a number outside the range; the value that SETTLES is always inside it.
32
+ - Do not turn the grip off and expect a pointer to have another way through. There are no spinner buttons behind it — hiding those is the point — so scrub={false} leaves a mouse with typing and nothing else. Turn it off for a quantity that is chosen rather than swept to, and accept that trade knowingly.
33
+ - Do not put the unit in the box and nowhere else past about four characters. The slot is fixed, so “requests” runs under the number; a long unit belongs in the Field’s label, where it is read rather than clipped.
34
+
35
+ ## Accessibility
36
+
37
+ - It is a real <input type="number">, so the platform supplies the spinbutton role, the value, and the range it is announced against.
38
+ - unit reaches assistive tech through aria-describedby, so “300” is not announced as a number with no dimension.
39
+ - The grip is aria-hidden and not focusable: it commits nothing a keyboard cannot already reach, and announcing it would offer a reader a control that does nothing when they press it.
40
+ - invalid and aria-invalid are read together, so a form library setting either one paints the same border.
41
+
42
+ ## Keyboard
43
+
44
+ - ↑ / ↓ — Steps by one step, honouring min and max.
45
+ - Enter — Reconciles what has been typed with the range and the step.
46
+ - Escape — Abandons the edit and restores the last settled value.
47
+
48
+ ## NumberField
49
+
50
+ A number, typed or swept to. `Input` with `type="number"` is a box that happens to reject letters. This is the control for a number that has a RANGE and a sensible increment: the arrows step it, the grip sweeps it, and `min`, `max` and `step` are honoured on the way out rather than merely announced. Reach for `Slider` instead when the position along the range is the information — a volume, a confidence, anything a reader judges by where the thumb sits. Reach for this when the digits are. A slider that also has to be exact is a `Slider` with `editable`, not one of these beside it. **Clamping happens when the field is left, not while it is being typed.** A minimum of 10 would otherwise make 50 unreachable: the `5` is clamped up to 10 before the `0` arrives. So `onValueChange` can report a number outside the range mid-keystroke, and the value that settles is always inside it. The native spinner buttons are hidden — they are three different controls in three browsers, and none of them is this system's. The grip replaces them for a pointer; the arrow keys were always the keyboard's answer.
51
+
52
+ ### Props
53
+
54
+ - `value` — `number`.
55
+ - `defaultValue` — `number`.
56
+ - `onValueChange` — `(value: number) => void`. Fires with the parsed number. Raw `onChange` still fires with the event.
57
+ - `min` — `number` default `Number.NEGATIVE_INFINITY`.
58
+ - `max` — `number` default `Number.POSITIVE_INFINITY`.
59
+ - `step` — `number` default `1`. The increment for the arrows and for one notch of a scrub.
60
+ - `unit` — `string`. A unit drawn inside the end of the field — `%`, `px`, `ms`. The field reserves a fixed slot for it, so keep it to about four characters; a longer one runs under a long number. It is announced through `aria-describedby` as well as drawn, because a unit nobody hears turns "300" into a number with no dimension.
61
+ - `scrub` — `boolean` default `true`. A grip at the start of the field that changes the value as it is dragged. On by default, and the reason to reach for this over `<Input type="number">`: a value that is being TUNED — a duration, a weight, an offset — is found by sweeping through neighbouring values, not by typing candidates one at a time. Shift multiplies the travel by ten. Pointer only, and `aria-hidden` for that reason: the same journey on a keyboard is the arrow keys on the field itself, which the platform already provides. Turn it off where the number is a quantity rather than a setting — a line item's quantity is chosen, not swept to.
62
+ - `invalid` — `boolean`. Paints the resting border with `--danger` and reflects `aria-invalid`.
63
+ - `ref` — `Ref<HTMLInputElement>`.
64
+
65
+ Also accepts: `Omit<InputHTMLAttributes<HTMLInputElement>, 'value' | 'defaultValue' | 'min' | 'max' | 'step' | 'type'>`.
66
+
67
+ ## Examples
68
+
69
+ ```tsx
70
+ <Field label="Line height"><NumberField defaultValue={1.5} min={1} max={3} step={0.1} /></Field>
71
+ <Field label="Timeout"><NumberField defaultValue={30} min={0} max={600} unit="s" /></Field>
72
+ ```
@@ -4,7 +4,7 @@ Numbered pages, with the middle elided.
4
4
 
5
5
  - Group: Navigation
6
6
  - Import: `import { Pagination } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/pagination/
9
9
  - Related: breadcrumb
10
10
 
@@ -4,7 +4,7 @@ Parts of one whole.
4
4
 
5
5
  - Group: Charts
6
6
  - Import: `import { PieChart } from '@misoto22/design/charts'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/pie-chart/
9
9
  - Related: radial-chart, bar-chart
10
10
 
@@ -4,7 +4,7 @@ A panel anchored to a control, holding content you can interact with.
4
4
 
5
5
  - Group: Overlays
6
6
  - Import: `import { Popover } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/popover/
9
9
  - Related: tooltip, dropdown-menu
10
10
 
@@ -4,7 +4,7 @@ A bar that fills, or sweeps when the end is unknown.
4
4
 
5
5
  - Group: Feedback
6
6
  - Import: `import { Progress } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/progress/
9
9
  - Related: spinner
10
10
 
@@ -4,7 +4,7 @@ A profile across several named dimensions.
4
4
 
5
5
  - Group: Charts
6
6
  - Import: `import { RadarChart } from '@misoto22/design/charts'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/radar-chart/
9
9
  - Related: line-chart, pie-chart
10
10
 
@@ -4,7 +4,7 @@ Values on an arc — a gauge, or a few totals against one scale.
4
4
 
5
5
  - Group: Charts
6
6
  - Import: `import { RadialChart } from '@misoto22/design/charts'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/radial-chart/
9
9
  - Related: pie-chart, bar-chart
10
10
 
@@ -4,7 +4,7 @@ A set of mutually exclusive choices.
4
4
 
5
5
  - Group: Forms
6
6
  - Import: `import { RadioGroup } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/radio-group/
9
9
  - Related: checkbox, select
10
10
 
@@ -4,7 +4,7 @@ Where a quantity goes as it moves through stages.
4
4
 
5
5
  - Group: Charts
6
6
  - Import: `import { SankeyChart } from '@misoto22/design/charts'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/sankey-chart/
9
9
  - Related: bar-chart
10
10
 
@@ -4,7 +4,7 @@ Two measures against each other, one mark per observation.
4
4
 
5
5
  - Group: Charts
6
6
  - Import: `import { ScatterChart } from '@misoto22/design/charts'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/scatter-chart/
9
9
  - Related: line-chart, heatmap
10
10
 
@@ -4,7 +4,7 @@ A box that scrolls, with a scrollbar that looks the same everywhere.
4
4
 
5
5
  - Group: Surfaces
6
6
  - Import: `import { ScrollArea } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/scroll-area/
9
9
  - Related: table
10
10
 
@@ -4,7 +4,7 @@ A menu of actions you can type into.
4
4
 
5
5
  - Group: Overlays
6
6
  - Import: `import { SearchableMenu } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/searchable-menu/
9
9
  - Related: dropdown-menu, command, combobox
10
10
 
@@ -4,7 +4,7 @@ A choice from a list, styled the whole way down.
4
4
 
5
5
  - Group: Forms
6
6
  - Import: `import { Select } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/select/
9
9
  - Related: combobox, native-select, field
10
10
 
@@ -4,7 +4,7 @@ A rule, in the three weights a monochrome page needs — with words in it when t
4
4
 
5
5
  - Group: Display
6
6
  - Import: `import { Separator } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/separator/
9
9
 
10
10
  ## When to reach for it
@@ -4,7 +4,7 @@ A call chain over time: who asks whom, in what order, and what comes back.
4
4
 
5
5
  - Group: Diagrams
6
6
  - Import: `import { SequenceFigure } from '@misoto22/design/diagrams'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/sequence-figure/
9
9
  - Related: workflow-figure, architecture-figure
10
10
 
@@ -4,7 +4,7 @@ A panel docked to an edge of the viewport.
4
4
 
5
5
  - Group: Overlays
6
6
  - Import: `import { Sheet } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/sheet/
9
9
  - Related: dialog, popover
10
10
 
@@ -0,0 +1,193 @@
1
+ # Sidebar
2
+
3
+ A navigation rail down the side of an application.
4
+
5
+ - Group: Navigation
6
+ - Import: `import { Sidebar } from '@misoto22/design'`
7
+ - Version: 0.9.0
8
+ - Docs: https://ui.misoto22.com/components/sidebar/
9
+ - Related: nav-item, collapsible, app-shell
10
+
11
+ ## When to reach for it
12
+
13
+ A whole application’s navigation, in a column that stays. A list of links inside a page is NavItem on its own; a strip of panels is Tabs.
14
+
15
+ ## Anatomy
16
+
17
+ - **Provider** (required) — SidebarProvider. It holds whether the rail is open and binds the shortcut that changes it, and it sits ABOVE both the rail and the content beside it — the page has to reserve the rail’s width, and a state that lived inside the rail could only ever be read downwards. It also supplies the tooltip provider a collapsed rail needs, so the icon state works without the app being told to wrap itself in one.
18
+ - **Rail** (required) — Sidebar. A <nav>, not an <aside>: the element decides the landmark, and a rail of links announced as “complementary” is not the one a reader jumps to when they go looking for the navigation. Its width animates between --sidebar-w and --sidebar-w-icon while the column inside stays full width, so the rows do not reflow under the wipe.
19
+ - **Header** — SidebarHeader. The brand, the workspace, the switcher — and where SidebarTrigger belongs. A control that hides a thing lives on the thing; out in an application’s masthead it is one more anonymous icon with nothing connecting it to the column it operates.
20
+ - **Content** — SidebarContent. The scrolling middle, and the only part that scrolls.
21
+ - **Group** — SidebarGroup: a heading, an optional count, an optional action, and rows behind a hairline. The heading is the same size as its rows and outranks them by weight and one step of ink — smaller than what it contains, it reads as a footnote over a list rather than as a title over its own contents.
22
+ - **Row** — SidebarItem, which is NavItem plus the two things a rail adds: a trailing slot, and an answer for the state with no room for words. Collapsed, the label leaves the layout and becomes the row’s tooltip.
23
+ - **Branch** — SidebarBranch: a row that opens onto more rows, behind the same hairline a group draws and one indent further in. It is the line between a place and a heading — a workspace that contains projects is a place containing places, and it carries an icon and a state the way its children do, which a Group has neither of. Two levels is what the indent has room for; a third in a 16rem column is a horizontal scrollbar with an outline in it.
24
+ - **Footer** — SidebarFooter. The utilities a rail ends on, kept out of the index above it.
25
+ - **Page** — SidebarInset, the column beside the rail. It is `min-w-0` — the half every hand-written version forgets, and the reason one wide table inside pushes the page past the viewport and takes the rail’s width with it. Under variant="inset" it is also the panel: the rail becomes the ground, and this draws the bordered --paper surface sitting on it.
26
+ - **Drawer** — What the rail becomes under the provider’s breakpoint (768px by default): fixed against its own edge, over a scrim, and inert while closed. Nothing to render — the same <Sidebar> is both — but it is a different component to a reader, and the collapsible setting does not apply there.
27
+
28
+ ## Best practices
29
+
30
+ ### Do
31
+
32
+ - Give every row an icon if the rail collapses to icons. The icon is the whole of what a collapsed row shows, and SidebarItem keeps the label drawn on a row without one rather than leaving a blank line — which is a rail that is half collapsed.
33
+ - Choose collapsible by what the rows ARE. icon suits a fixed set a reader learns the shape of; offcanvas suits a long index nobody memorises, where a column of unrecognisable glyphs is worse than no column.
34
+ - Reach for SidebarBranch when the thing is a PLACE that contains places, and for SidebarGroup when it is a heading over a set. A group has no icon and no state because it is not somewhere you can be; a branch has both because it is.
35
+ - Put SidebarTrigger in the header. It is where the component expects it and where a reader looks for it, and it is the difference between a control that belongs to the rail and one that has wandered into the masthead.
36
+ - Wrap the page in SidebarInset rather than a hand-written flex column. It carries min-w-0, which is what stops one wide table inside the page from pushing the whole layout past the viewport, and it is the other half of variant="inset".
37
+ - Pass persist with a key when the rail is an application’s own. A reader who put the rail away did not mean “until the next page”. Only the docked state is kept: restoring an open drawer is a page that loads with its navigation over the top of itself.
38
+ - Give the provider a ground for variant="floating" and variant="inset" — bg-(--stone) on the element holding it. Both draw a --paper panel, and a panel on the same colour as the thing behind it is a border with nothing on either side of it.
39
+
40
+ ### Don’t
41
+
42
+ - Do not reach for it for navigation inside a page. This is an application landmark that owns a whole edge of the window; a set of links in a column is NavItem, and putting those in a rail gives a page two navigation landmarks competing for the same reader.
43
+ - Do not pass shortcut and then bind Cmd+B yourself. Two handlers on one chord toggle twice and land back where they started, which reads as a rail that ignores its own shortcut. Pass shortcut={null} where the app owns it.
44
+ - Do not nest a branch inside a branch. The indent is sized for two levels at this width, and a third takes the words with it — what a reader gets is an outline with a horizontal scrollbar under it.
45
+ - Do not control open without onOpenChange. The trigger and the shortcut then both do nothing, and the state that looks broken is the one the caller froze.
46
+ - Do not put a transform, filter or perspective on an element wrapping the provider. The drawer is fixed, and any of those makes that ancestor its containing block — so it opens inside the wrapper instead of against the edge of the window.
47
+ - Do not build the phone drawer yourself around this. It already is one under breakpoint, with the scrim, the inert closed state and the close-on-navigate; a second one outside gives the page two drawers and one of them has no scrim.
48
+
49
+ ## Accessibility
50
+
51
+ - label is required, and names the landmark. A page with two navigations in it announces two things called “navigation” unless each says which it is.
52
+ - The trigger’s name says what it will DO and aria-expanded reports what is true now, so it is never the permanently ambiguous “Toggle sidebar”.
53
+ - A collapsed row keeps its label as its accessible name, through a tooltip — an icon alone is a guess for a sighted reader and nothing at all for a screen reader.
54
+ - A collapsed group keeps its heading as the group’s name even though the words are not drawn.
55
+ - The current row carries aria-current="page", not only a darker ground.
56
+ - The closed drawer is inert, not merely translated off-screen. Off-screen it still holds focus and is still read aloud, so a shut drawer puts its whole index between the reader and the page they were on.
57
+ - The scrim is a button with a name, because tapping beside a drawer is how a drawer is closed — and a gesture that exists only for a pointer is one a keyboard cannot make.
58
+
59
+ ## Keyboard
60
+
61
+ - ⌘B / Ctrl B — Opens and closes the rail.
62
+ - Enter / Space — On a group heading, folds or unfolds it.
63
+ - Tab — Moves through the rows in the order they are drawn.
64
+
65
+ ## useSidebar
66
+
67
+ The rail's own state, for anything that has to answer to it. A page beside the rail needs it to reserve the right width; a control inside needs to know whether its label is being drawn. This one THROWS outside a provider, and the parts above do not, and the difference is who made the mistake. A part rendered on its own is somebody writing `<Sidebar>` to see what it looks like; a call to this hook is code asking for state that nothing is keeping, and returning a plausible default there is a layout that is wrong in one state and right in the other with nothing to say which.
68
+
69
+ ## SidebarProvider
70
+
71
+ Holds whether the rail is open, and binds the shortcut that changes it. Separate from `Sidebar` itself because the answer is needed on BOTH sides of the layout: the rail draws itself from it, and the content beside the rail reserves width from it. A state that lived inside the rail could only ever be read downwards.
72
+
73
+ ### Props
74
+
75
+ - `open` — `boolean`. Controlled open state. Leave off to let the provider own it.
76
+ - `defaultOpen` — `boolean` default `true`.
77
+ - `onOpenChange` — `(open: boolean) => void`.
78
+ - `collapsible` — `SidebarCollapsible` default `'icon'`. What closing does to the rail. See SidebarProps.collapsible.
79
+ - `shortcut` — `string | null` default `'b'`. The keyboard shortcut that toggles the rail, as a single letter. `b`, with the platform's own modifier, because that is what every editor and every application shell already uses for the same thing. Pass `null` to bind nothing — an app that already owns that chord should not have it taken twice, and a rail that cannot be closed does not need a shortcut for closing it.
80
+ - `side` — `SidebarSide` default `'start'`. Which edge the rail is on. Logical: `end` is the right in LTR, the left in RTL.
81
+ - `variant` — `SidebarVariant` default `'flush'`. How the rail meets the page. `flush` is a column with a hairline down its inner edge — the rail and the page are one surface divided by a line. `floating` lifts the rail off that surface as its own bordered panel with the page ground showing around it. `inset` is the same gesture the other way up: the rail sits on the page ground and `SidebarInset` draws the CONTENT as the panel. `floating` and `inset` both need a ground to sit on — put `bg-(--stone)` on the element holding the provider, or they are a panel on the same colour as the thing behind it.
82
+ - `breakpoint` — `SidebarBreakpoint | null` default `'md'`. The step below which the rail becomes a drawer over the page. A rail is a column when there is a column's worth of room and an overlay when there is not; below this the rail is `fixed`, covers the page from its own edge, and closes onto a scrim. `null` pins it as a column at every width, for a layout that is never narrow — an embedded console, a preview frame. Named, not a number: the switch is a media query in the stylesheet, and a class built from a runtime number is a class the compiler never emitted. It also puts the rail on the same four steps as the page around it.
83
+ - `persist` — `string | null` default `null`. A `localStorage` key under which the DOCKED state is remembered. A reader who put the rail away did not mean "until the next page". Only the docked state is kept: an open drawer is a thing a reader did to this screen, and restoring it on the next visit is a page that opens with its navigation over the top of itself. Read after mount, never during render — a value from storage in the first pass is a hydration mismatch, and the markup the server sent is the one the client has to agree with.
84
+ - `contained` — `boolean` default `false`. The drawer covers its nearest positioned ancestor rather than the window. For a rail inside a bounded frame — a device preview, an embedded console, an example on a documentation page. `fixed` resolves against the viewport wherever the markup sits, so without this the drawer inside a 400px preview opens across the whole page it is previewed on. Give the frame `relative`.
85
+ - `children` (required) — `ReactNode`.
86
+
87
+ ## Sidebar
88
+
89
+ A navigation rail down the side of an application. A `<nav>`, not an `<aside>`. The element decides the landmark, and a rail of links announced as "complementary" is not the one a screen reader user jumps to when they go looking for the navigation. Composed rather than configured: a rail is a header, a scrolling middle and a footer, and every product wants different things in all three. What this owns is the part that is the same everywhere — the width, the edge, the scroll behaviour, and what happens when it closes. **Closing has three shapes**, and `collapsible` on the provider picks one. `icon` keeps the rail and drops the labels, which is right when the rows are a fixed set a reader learns the shape of. `offcanvas` takes the whole rail away, which is right when the rows are a long index nobody memorises. `none` is a rail that does not close. The trigger belongs INSIDE the rail — `SidebarHeader` places it — rather than out in an application's masthead. A control that hides a thing should live on the thing: in the masthead it is one more anonymous icon in a row of them, and nothing connects it to the column it operates. **Under the provider's `breakpoint` it is a drawer**, not a column: `fixed` against its own edge, over a scrim, and `inert` while closed. Merely translating it off-screen is not closed — it keeps focus and it is still read aloud, so a shut drawer puts its whole index between the reader and the page they were on. The scrim is a real button, because tapping beside a drawer is how a drawer is closed and that gesture has to exist for a keyboard too. `fixed` resolves against the viewport unless an ancestor has a `transform`, `filter` or `perspective`, which makes that ancestor the containing block instead. Do not put one on an element wrapping the provider, or the drawer opens inside it.
90
+
91
+ ### Props
92
+
93
+ - `label` (required) — `string`. Names the landmark. Required: a page with two navigations in it announces two things called "navigation" unless each of them says which it is.
94
+ - `scrimLabel` — `string` default `'Close the navigation'`. What the scrim behind the open drawer announces. It is a button — tapping beside a drawer closes it, and that has to be a control a keyboard and a screen reader can reach, not a decorated `<div>`.
95
+ - `children` (required) — `ReactNode`.
96
+
97
+ Also accepts: `Omit<ComponentProps<'nav'>, 'children'>`.
98
+
99
+ ## SidebarInset
100
+
101
+ The page beside the rail. Every layout built on this component was writing the same `flex min-w-0 flex-1 flex-col` by hand, and `min-w-0` is the half everybody forgets: a flex child's floor is its content, so one wide table inside pushes the whole page past the viewport and takes the rail's width with it. It is also the other half of `variant="inset"`. There the rail is the ground and this is the panel — a bordered `--paper` surface with the ground showing around it — which is why the variant lives on the provider rather than on either piece: one setting, two components, and no way to set half of it. A `<div>`, not a `<main>`. What goes in here is usually a masthead AND the page under it, and only one of those is the main landmark.
102
+
103
+ ## SidebarHeader
104
+
105
+ The block at the top of the rail: a brand, a workspace, a switcher. It is also where `SidebarTrigger` belongs, and the layout assumes one: anything passed as `children` takes the space and the trigger sits at the inline end of the row.
106
+
107
+ ## SidebarContent
108
+
109
+ The scrolling middle. Everything that is a list of places goes here.
110
+
111
+ ## SidebarFooter
112
+
113
+ The block at the bottom: the utilities, the account, the thing a rail ends on. A separate landmark from the content above it because it is a separate kind of thing — a reader scanning the index does not want Trash and Help in it.
114
+
115
+ ## SidebarSeparator
116
+
117
+ A rule between blocks of rows, inset to the rail's own padding.
118
+
119
+ ## SidebarTrigger
120
+
121
+ The control that opens and closes the rail. Its accessible name changes with what it will DO, and `aria-expanded` reports what is true now — a button permanently called "Toggle sidebar" tells a screen reader user nothing about which way it will go.
122
+
123
+ ### Props
124
+
125
+ - `labels` — `{ open: string; close: string }` default `{ open: 'Open the sidebar', close: 'Close the sidebar' }`. What the button announces. Both states, because it says both things.
126
+
127
+ Also accepts: `ComponentProps<'button'>`.
128
+
129
+ ## SidebarGroup
130
+
131
+ A labelled block of rows, optionally foldable. The heading is the same SIZE as the rows beneath it and outranks them by weight and by ink. Both halves of that are corrections. Smaller, it inverted the hierarchy it exists to express — a group read as a footnote over a list rather than as a title over its own contents. In the MONO face, which is where it went next, ten of them stacked in a column read as a terminal listing: mono is this system's voice for code, metadata and figures, and a navigation heading is none of those. Rank belongs to weight and to a step up the ink ladder, which are the two signals that can outrank a row without changing what kind of thing it is. An open group draws a hairline down its rows. Fifty rows under seven headings have nothing in them saying which heading any given row belongs to — only the distance to the last one, which is gone the moment the list is scrolled. The whole block hides when the rail is collapsed to icons: a heading with no room for its own word is two or three letters and a number, and the rows are still there underneath as icons.
132
+
133
+ ### Props
134
+
135
+ - `label` (required) — `string`. The heading over the rows.
136
+ - `count` — `number`. How many rows are inside, printed on the far side of the heading.
137
+ - `badge` — `ReactNode`. A mark that belongs to the GROUP — "Beta", "3 new". Beside the label, not out at the end with the count: it qualifies the words, and a qualifier that has drifted to the other side of the row reads as a second, unrelated fact.
138
+ - `action` — `ReactNode`. A control on the heading row — a menu, an "add" button. Sits between the label and the count, and is NOT rendered inside the heading's own button: a control nested in a control is one the keyboard reaches by pressing the thing it is inside.
139
+ - `collapsible` — `boolean` default `true`. Whether the group folds at all. A group of two rows usually should not.
140
+ - `defaultOpen` — `boolean` default `true`.
141
+ - `children` (required) — `ReactNode`.
142
+ - `className` — `string`.
143
+
144
+ ## SidebarBranch
145
+
146
+ A row that opens onto more rows. The thing a rail is for and the thing a flat list of groups cannot do: a workspace with projects in it, a folder with documents in it, a service with its environments. `SidebarGroup` is a HEADING over a set — it is not itself a place, and it has no icon and no state. This is a place that contains places, so it is a row like any other and it carries the same icon, trailing slot and hover as its children. The children sit behind the same hairline a group draws, one indent further in, so nesting reads as depth rather than as two unrelated lists. Two levels is what the indent has room for at this width; a third is a tree, and a tree in a 16rem column is a horizontal scrollbar with an outline in it. Collapsed to icons the row becomes its icon and the children are not drawn — there is nowhere for an indent to go, and a nested icon under an unnested one is two glyphs with no visible relationship.
147
+
148
+ ### Props
149
+
150
+ - `label` (required) — `string`. The row's own words, and the name of the group it opens.
151
+ - `icon` — `LucideIcon`. Drawn at the start of the row, and the whole of the row when collapsed.
152
+ - `trailing` — `ReactNode`. A count or a state at the end of the row.
153
+ - `defaultOpen` — `boolean` default `false`.
154
+ - `open` — `boolean`.
155
+ - `onOpenChange` — `(open: boolean) => void`.
156
+ - `children` (required) — `ReactNode`.
157
+ - `className` — `string`.
158
+
159
+ ## SidebarItem
160
+
161
+ One row. `NavItem` with the two things a RAIL adds: a trailing slot, and an answer for the state where there is no room for words. Collapsed to icons the label is removed from the layout rather than hidden with CSS — a `sr-only` label still occupies the flex row's gap — and moves into a tooltip, because an icon on its own is a guess for everyone and unusable for a screen reader. A row with no `icon` keeps its label collapsed, since hiding it would leave a blank row: the icon is what makes the collapsed state legible, and a rail that collapses needs one on every row.
162
+
163
+ ### Props
164
+
165
+ - `trailing` — `ReactNode`. A count or a state on the far side of the row. Hidden with the label.
166
+
167
+ Also accepts: `NavItemProps`.
168
+
169
+ ## Types
170
+
171
+ - `SidebarCollapsible` = `'icon' | 'offcanvas' | 'none'`
172
+ - `SidebarSide` = `'start' | 'end'`
173
+ - `SidebarVariant` = `'flush' | 'inset' | 'floating'`
174
+ - `SidebarBreakpoint` = `'sm' | 'md' | 'lg' | 'xl'`
175
+
176
+ ## Examples
177
+
178
+ ```tsx
179
+ <SidebarProvider>
180
+ <Sidebar label="Documentation">
181
+ <SidebarHeader>Acme</SidebarHeader>
182
+ <SidebarContent>
183
+ <SidebarGroup label="Guide" count={2}>
184
+ <SidebarItem href="/start" icon={Home}>Getting started</SidebarItem>
185
+ </SidebarGroup>
186
+ </SidebarContent>
187
+ </Sidebar>
188
+ </SidebarProvider>
189
+ <SidebarBranch label="Acme HQ" icon={Building} defaultOpen>
190
+ <SidebarItem href="/hq" icon={Home}>Home</SidebarItem>
191
+ <SidebarItem href="/hq/tasks" icon={CheckSquare}>My tasks</SidebarItem>
192
+ </SidebarBranch>
193
+ ```
@@ -4,7 +4,7 @@ The shape of the page, before the page.
4
4
 
5
5
  - Group: Feedback
6
6
  - Import: `import { Skeleton } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/skeleton/
9
9
  - Related: spinner, empty-state
10
10
 
@@ -4,7 +4,7 @@ A value chosen along a range.
4
4
 
5
5
  - Group: Forms
6
6
  - Import: `import { Slider } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/slider/
9
9
  - Related: progress
10
10
 
@@ -14,6 +14,7 @@ A value chosen along a range.
14
14
  - **Range** — The --accent fill from the minimum to the thumb, or between the two thumbs of a range.
15
15
  - **Thumb** — One per entry in the value array — so the number of thumbs comes from the value, not from a prop, and a slider given neither value nor defaultValue falls back to the primitive’s own default of one thumb at the minimum. Each is a 16px circle with an invisible 44px hit area from a before pseudo-element.
16
16
  - **Value readout** — Only with showValue: a mono row above the track, the names on the start edge and the formatted values on the end, each joined by an en dash and in the thumbs’ own order — so a two-ended range reads “Minimum – Maximum” over “10 – 90”.
17
+ - **Editable readout** — What editable turns those figures into: one box per thumb, showing format’s output at rest and the bare number while it has focus, so a reader still sees “$1,200” and a typist is never asked to type a currency symbol back. Each is named separately from its thumb — two controls announcing “Quality” is one control announced twice.
17
18
 
18
19
  ## Best practices
19
20
 
@@ -21,11 +22,12 @@ A value chosen along a range.
21
22
 
22
23
  - Pass defaultValue or value whenever there is more than one end to it. The thumb count comes from that array, so a price filter left to the default is a single thumb sitting at the minimum.
23
24
  - Pass an array of two names for a two-thumb range: every thumb after the first falls back to names[0], so both ends of a price filter otherwise announce themselves as “Minimum”.
24
- - Put an Input beside it when the exact number matters. A slider cannot be typed into, and someone who needs 37 rather than roughly 40 is dragging a 16px thumb across a hundred steps to get it.
25
+ - Turn on editable when the exact number matters. A slider on its own cannot be typed into, and someone who needs 37 rather than roughly 40 is dragging a 16px thumb across a hundred steps to get it — the box in the readout is the way out, and it replaces the second Input this used to ask for.
25
26
 
26
27
  ### Don’t
27
28
 
28
29
  - format becomes each thumb’s aria-valuetext, which REPLACES the number rather than decorating it — so a formatter that rounds hard or drops the unit is what a screen reader gets instead of the value.
30
+ - editable typing is bounded by the NEIGHBOURING thumb as well as by min and max, and it has to be: 90 typed into the lower end of a range sitting at 70 would otherwise cross the two thumbs over. So a number can be accepted and then land somewhere else, and the box shows where it landed.
29
31
  - Do not disable a slider to make it read-only: the whole control dims and stops taking the pointer, and Radix drops the thumb out of the tab order, so the value becomes unreachable rather than uneditable.
30
32
  - Do not pass two names to a one-thumb slider: the heading prints one name per THUMB, so the second is drawn nowhere and announced nowhere.
31
33
  - A Field’s label above it does not name it and does not click through: the role is on the THUMB and the root is a <span>, so the label prop here is the only name a reader hears. The hint and the error do reach the thumb.
@@ -45,12 +47,13 @@ A value chosen along a range.
45
47
 
46
48
  ## Slider
47
49
 
48
- A value chosen along a range. Radix owns the keyboard contract — arrows step, Page keys jump, Home and End reach the ends — and the ARIA that reports the value. What is here is the look, and the labelling, which is the part a slider most often gets wrong: a thumb that announces "42" and nothing else leaves a screen reader user with a number and no idea what it measures. A 44px hit area sits invisibly around the 16px thumb, because a thumb sized for the design is well under any pointer-target guideline. Inside a `Field`, the hint, the error and the requirement land on the THUMB, which is the element carrying `role="slider"` — on the root they would sit on a `<span>` with no role and announce nothing. The NAME still comes from `label` here: a field's label above a slider points at that same roleless root, so it neither names the control nor clicks through to it.
50
+ A value chosen along a range. Radix owns the keyboard contract — arrows step, Page keys jump, Home and End reach the ends — and the ARIA that reports the value. What is here is the look, and the labelling, which is the part a slider most often gets wrong: a thumb that announces "42" and nothing else leaves a screen reader user with a number and no idea what it measures. A 44px hit area sits invisibly around the 16px thumb, because a thumb sized for the design is well under any pointer-target guideline. `editable` is the answer to the thing a slider cannot do. Reach for it whenever the exact figure is the point — a budget, a timeout, a price — and leave it off when the value is genuinely approximate, because a box invites precision the setting may not have. Inside a `Field`, the hint, the error and the requirement land on the THUMB, which is the element carrying `role="slider"` — on the root they would sit on a `<span>` with no role and announce nothing. The NAME still comes from `label` here: a field's label above a slider points at that same roleless root, so it neither names the control nor clicks through to it.
49
51
 
50
52
  ### Props
51
53
 
52
54
  - `label` (required) — `string | [string, string]`. Names the control. Required: a slider with no name announces only a number, and a number with no noun is not information. A range slider (two thumbs) needs one name per thumb — pass an array.
53
55
  - `showValue` — `boolean` default `false`. Prints the current value beside the label. A two-thumb range prints both names and both values, in the same order — the heading used to print the first name over a pair of numbers, which read as "Minimum" over "10 – 90".
56
+ - `editable` — `boolean` default `false`. Turns that readout into a box the number can be typed into, and implies `showValue`. A slider is a control for a NEIGHBOURHOOD; someone who needs 1,150 rather than roughly 1,200 is dragging a 16px thumb across a hundred steps to get it. This is the way out, in the place the value already is, rather than a second field beside the track that has to be kept in step by hand. The box shows `format`'s output at rest and the bare number while it has focus, so a reader still sees "$1,200" and a typist is never asked to type a currency symbol back.
54
57
  - `format` — `(value: number) => string`. Renders the value with a unit or a currency, e.g. `(n) => n + '%'`. Reaches assistive tech as well as the readout: it becomes each thumb's `aria-valuetext`, so a thumb showing "$1,200" announces that rather than the bare number. Left off, the platform announces the value itself.
55
58
 
56
59
  Also accepts: `ComponentProps<typeof SliderPrimitive.Root>`.
@@ -59,4 +62,5 @@ Also accepts: `ComponentProps<typeof SliderPrimitive.Root>`.
59
62
 
60
63
  ```tsx
61
64
  <Slider label="Quality" defaultValue={[80]} max={100} step={5} showValue format={(n) => `${n}%`} />
65
+ <Slider label="Monthly budget" defaultValue={[1200]} max={5000} step={50} editable format={(n) => `$${n}`} />
62
66
  ```
@@ -4,7 +4,7 @@ A run of numbers at the size of a word.
4
4
 
5
5
  - Group: Data
6
6
  - Import: `import { Sparkline } from '@misoto22/design/charts'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/sparkline/
9
9
  - Related: line-chart, table
10
10
 
@@ -4,7 +4,7 @@ The one “working” indicator — a ring, never a shimmer.
4
4
 
5
5
  - Group: Feedback
6
6
  - Import: `import { Spinner } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/spinner/
9
9
  - Related: skeleton, progress
10
10
 
@@ -4,7 +4,7 @@ The dot beside a status word.
4
4
 
5
5
  - Group: Display
6
6
  - Import: `import { StatusDot } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/status-dot/
9
9
  - Related: status-pill
10
10
 
@@ -4,7 +4,7 @@ A live state, named: a dot plus an uppercase mono label.
4
4
 
5
5
  - Group: Display
6
6
  - Import: `import { StatusPill } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/status-pill/
9
9
  - Related: status-dot, badge
10
10
 
@@ -4,7 +4,7 @@ A numbered sequence, as a rail — one thing after another, with a rule through
4
4
 
5
5
  - Group: Display
6
6
  - Import: `import { Steps } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/steps/
9
9
  - Related: diagram, article
10
10
 
@@ -4,7 +4,7 @@ A setting that takes effect immediately.
4
4
 
5
5
  - Group: Forms
6
6
  - Import: `import { Switch } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/switch/
9
9
  - Related: checkbox
10
10
 
@@ -4,7 +4,7 @@ A ruled data table — alignment, sorting and rules all per column.
4
4
 
5
5
  - Group: Data
6
6
  - Import: `import { Table } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/table/
9
9
  - Related: card, figure-band
10
10
 
@@ -85,6 +85,8 @@ Also accepts: `Omit<ThHTMLAttributes<HTMLTableCellElement>, 'align'>`.
85
85
 
86
86
  ## TD
87
87
 
88
+ A body cell. TOP-aligned, and that is a choice about which kind of table is the common one here: a cell holding a paragraph. Top is what lines the first lines of a row up with each other, and centring a two-word term against a four-line description puts the term in the middle of nothing. It is the wrong default for the other kind — a row of one-line values with a control in it. A 36px button next to 16px of text makes a 52px row, and every other cell then hangs at the top of it with twenty pixels of nothing underneath, which reads as a column that has slipped. Pass `className="align-middle"` on those rows; the data-table template does.
89
+
88
90
  ### Props
89
91
 
90
92
  - `align` — `TableAlign` default `'start'`. Which edge the cell's contents sit against. Match the column's header.
@@ -4,7 +4,7 @@ One strip, several panels.
4
4
 
5
5
  - Group: Navigation
6
6
  - Import: `import { Tabs } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/tabs/
9
9
  - Related: accordion
10
10
 
package/dist/agent/Tag.md CHANGED
@@ -4,7 +4,7 @@ A subject label — a topic, a technology, a filter facet — that filters with
4
4
 
5
5
  - Group: Display
6
6
  - Import: `import { Tag } from '@misoto22/design'`
7
- - Version: 0.8.0
7
+ - Version: 0.9.0
8
8
  - Docs: https://ui.misoto22.com/components/tag/
9
9
  - Related: badge, status-pill
10
10