@misoto22/design 0.3.1 → 0.6.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 (266) hide show
  1. package/README.md +124 -0
  2. package/bin/misoto22-design.mjs +205 -0
  3. package/dist/agent/Accordion.md +41 -0
  4. package/dist/agent/Alert.md +42 -0
  5. package/dist/agent/AppShell.md +40 -0
  6. package/dist/agent/AreaChart.md +68 -0
  7. package/dist/agent/Article.md +41 -0
  8. package/dist/agent/Avatar.md +32 -0
  9. package/dist/agent/Badge.md +40 -0
  10. package/dist/agent/BarChart.md +65 -0
  11. package/dist/agent/BarList.md +40 -0
  12. package/dist/agent/BigNumber.md +45 -0
  13. package/dist/agent/BoxPlot.md +58 -0
  14. package/dist/agent/Breadcrumb.md +32 -0
  15. package/dist/agent/BulletChart.md +48 -0
  16. package/dist/agent/Button.md +56 -0
  17. package/dist/agent/Calendar.md +42 -0
  18. package/dist/agent/Card.md +49 -0
  19. package/dist/agent/Checkbox.md +35 -0
  20. package/dist/agent/Collapsible.md +46 -0
  21. package/dist/agent/Combobox.md +50 -0
  22. package/dist/agent/Command.md +93 -0
  23. package/dist/agent/ComposedChart.md +57 -0
  24. package/dist/agent/ContextMenu.md +59 -0
  25. package/dist/agent/DatePicker.md +75 -0
  26. package/dist/agent/Diagram.md +46 -0
  27. package/dist/agent/Dialog.md +52 -0
  28. package/dist/agent/DropdownMenu.md +70 -0
  29. package/dist/agent/EmptyState.md +37 -0
  30. package/dist/agent/ErrorState.md +41 -0
  31. package/dist/agent/Facet.md +82 -0
  32. package/dist/agent/Field.md +37 -0
  33. package/dist/agent/FigureBand.md +37 -0
  34. package/dist/agent/FloatingIconButton.md +38 -0
  35. package/dist/agent/FunnelChart.md +52 -0
  36. package/dist/agent/Heatmap.md +53 -0
  37. package/dist/agent/Histogram.md +63 -0
  38. package/dist/agent/Input.md +30 -0
  39. package/dist/agent/Kbd.md +29 -0
  40. package/dist/agent/LineChart.md +60 -0
  41. package/dist/agent/LinkArrow.md +29 -0
  42. package/dist/agent/NativeSelect.md +40 -0
  43. package/dist/agent/NavItem.md +35 -0
  44. package/dist/agent/Pagination.md +43 -0
  45. package/dist/agent/PieChart.md +55 -0
  46. package/dist/agent/Popover.md +57 -0
  47. package/dist/agent/Progress.md +33 -0
  48. package/dist/agent/RadarChart.md +54 -0
  49. package/dist/agent/RadialChart.md +57 -0
  50. package/dist/agent/RadioGroup.md +44 -0
  51. package/dist/agent/SankeyChart.md +61 -0
  52. package/dist/agent/ScatterChart.md +54 -0
  53. package/dist/agent/ScrollArea.md +40 -0
  54. package/dist/agent/SearchableMenu.md +46 -0
  55. package/dist/agent/Select.md +75 -0
  56. package/dist/agent/Separator.md +35 -0
  57. package/dist/agent/Sheet.md +57 -0
  58. package/dist/agent/Skeleton.md +73 -0
  59. package/dist/agent/Slider.md +39 -0
  60. package/dist/agent/Sparkline.md +45 -0
  61. package/dist/agent/Spinner.md +39 -0
  62. package/dist/agent/StatusDot.md +36 -0
  63. package/dist/agent/StatusPill.md +28 -0
  64. package/dist/agent/Steps.md +44 -0
  65. package/dist/agent/Switch.md +29 -0
  66. package/dist/agent/Table.md +85 -0
  67. package/dist/agent/Tabs.md +48 -0
  68. package/dist/agent/Tag.md +35 -0
  69. package/dist/agent/Textarea.md +26 -0
  70. package/dist/agent/Toast.md +26 -0
  71. package/dist/agent/ToggleGroup.md +44 -0
  72. package/dist/agent/Tooltip.md +51 -0
  73. package/dist/agent/TreemapChart.md +52 -0
  74. package/dist/agent/WaterfallChart.md +62 -0
  75. package/dist/agent/catalog.json +1791 -0
  76. package/dist/agent/index.md +131 -0
  77. package/dist/article.css +393 -0
  78. package/dist/charts/AreaChart/AreaChart.d.ts +191 -0
  79. package/dist/charts/AreaChart/AreaChart.js +480 -0
  80. package/dist/charts/AreaChart/AreaChart.js.map +1 -0
  81. package/dist/charts/BarChart/BarChart.d.ts +179 -0
  82. package/dist/charts/BarChart/BarChart.js +591 -0
  83. package/dist/charts/BarChart/BarChart.js.map +1 -0
  84. package/dist/charts/BarList/BarList.d.ts +57 -0
  85. package/dist/charts/BarList/BarList.js +71 -0
  86. package/dist/charts/BarList/BarList.js.map +1 -0
  87. package/dist/charts/BigNumber/BigNumber.d.ts +56 -0
  88. package/dist/charts/BigNumber/BigNumber.js +31 -0
  89. package/dist/charts/BigNumber/BigNumber.js.map +1 -0
  90. package/dist/charts/BoxPlot/BoxPlot.d.ts +177 -0
  91. package/dist/charts/BoxPlot/BoxPlot.js +495 -0
  92. package/dist/charts/BoxPlot/BoxPlot.js.map +1 -0
  93. package/dist/charts/BulletChart/BulletChart.d.ts +100 -0
  94. package/dist/charts/BulletChart/BulletChart.js +162 -0
  95. package/dist/charts/BulletChart/BulletChart.js.map +1 -0
  96. package/dist/charts/ComposedChart/ComposedChart.d.ts +171 -0
  97. package/dist/charts/ComposedChart/ComposedChart.js +667 -0
  98. package/dist/charts/ComposedChart/ComposedChart.js.map +1 -0
  99. package/dist/charts/Facet/Facet.d.ts +240 -0
  100. package/dist/charts/Facet/Facet.js +133 -0
  101. package/dist/charts/Facet/Facet.js.map +1 -0
  102. package/dist/charts/Facet/panels.d.ts +187 -0
  103. package/dist/charts/Facet/panels.js +203 -0
  104. package/dist/charts/Facet/panels.js.map +1 -0
  105. package/dist/charts/FunnelChart/FunnelChart.d.ts +101 -0
  106. package/dist/charts/FunnelChart/FunnelChart.js +147 -0
  107. package/dist/charts/FunnelChart/FunnelChart.js.map +1 -0
  108. package/dist/charts/Heatmap/Heatmap.d.ts +78 -0
  109. package/dist/charts/Heatmap/Heatmap.js +108 -0
  110. package/dist/charts/Heatmap/Heatmap.js.map +1 -0
  111. package/dist/charts/Histogram/Histogram.d.ts +165 -0
  112. package/dist/charts/Histogram/Histogram.js +350 -0
  113. package/dist/charts/Histogram/Histogram.js.map +1 -0
  114. package/dist/charts/LineChart/LineChart.d.ts +167 -0
  115. package/dist/charts/LineChart/LineChart.js +486 -0
  116. package/dist/charts/LineChart/LineChart.js.map +1 -0
  117. package/dist/charts/PieChart/PieChart.d.ts +128 -0
  118. package/dist/charts/PieChart/PieChart.js +309 -0
  119. package/dist/charts/PieChart/PieChart.js.map +1 -0
  120. package/dist/charts/RadarChart/RadarChart.d.ts +123 -0
  121. package/dist/charts/RadarChart/RadarChart.js +299 -0
  122. package/dist/charts/RadarChart/RadarChart.js.map +1 -0
  123. package/dist/charts/RadialChart/RadialChart.d.ts +124 -0
  124. package/dist/charts/RadialChart/RadialChart.js +257 -0
  125. package/dist/charts/RadialChart/RadialChart.js.map +1 -0
  126. package/dist/charts/SankeyChart/SankeyChart.d.ts +137 -0
  127. package/dist/charts/SankeyChart/SankeyChart.js +501 -0
  128. package/dist/charts/SankeyChart/SankeyChart.js.map +1 -0
  129. package/dist/charts/ScatterChart/ScatterChart.d.ts +128 -0
  130. package/dist/charts/ScatterChart/ScatterChart.js +269 -0
  131. package/dist/charts/ScatterChart/ScatterChart.js.map +1 -0
  132. package/dist/charts/Sparkline/Sparkline.d.ts +53 -0
  133. package/dist/charts/Sparkline/Sparkline.js +93 -0
  134. package/dist/charts/Sparkline/Sparkline.js.map +1 -0
  135. package/dist/charts/TreemapChart/TreemapChart.d.ts +93 -0
  136. package/dist/charts/TreemapChart/TreemapChart.js +118 -0
  137. package/dist/charts/TreemapChart/TreemapChart.js.map +1 -0
  138. package/dist/charts/WaterfallChart/WaterfallChart.d.ts +164 -0
  139. package/dist/charts/WaterfallChart/WaterfallChart.js +319 -0
  140. package/dist/charts/WaterfallChart/WaterfallChart.js.map +1 -0
  141. package/dist/charts/index.d.ts +41 -0
  142. package/dist/charts/index.js +128 -0
  143. package/dist/charts/index.js.map +1 -0
  144. package/dist/charts/lib/annotations.d.ts +103 -0
  145. package/dist/charts/lib/annotations.js +99 -0
  146. package/dist/charts/lib/annotations.js.map +1 -0
  147. package/dist/charts/lib/axis.d.ts +18 -0
  148. package/dist/charts/lib/axis.js +21 -0
  149. package/dist/charts/lib/axis.js.map +1 -0
  150. package/dist/charts/lib/background.d.ts +33 -0
  151. package/dist/charts/lib/background.js +173 -0
  152. package/dist/charts/lib/background.js.map +1 -0
  153. package/dist/charts/lib/brush.d.ts +94 -0
  154. package/dist/charts/lib/brush.js +535 -0
  155. package/dist/charts/lib/brush.js.map +1 -0
  156. package/dist/charts/lib/chart.d.ts +94 -0
  157. package/dist/charts/lib/chart.js +134 -0
  158. package/dist/charts/lib/chart.js.map +1 -0
  159. package/dist/charts/lib/dot.d.ts +29 -0
  160. package/dist/charts/lib/dot.js +78 -0
  161. package/dist/charts/lib/dot.js.map +1 -0
  162. package/dist/charts/lib/empty.d.ts +31 -0
  163. package/dist/charts/lib/empty.js +13 -0
  164. package/dist/charts/lib/empty.js.map +1 -0
  165. package/dist/charts/lib/export.d.ts +103 -0
  166. package/dist/charts/lib/export.js +204 -0
  167. package/dist/charts/lib/export.js.map +1 -0
  168. package/dist/charts/lib/figure.d.ts +61 -0
  169. package/dist/charts/lib/figure.js +59 -0
  170. package/dist/charts/lib/figure.js.map +1 -0
  171. package/dist/charts/lib/format.d.ts +46 -0
  172. package/dist/charts/lib/format.js +56 -0
  173. package/dist/charts/lib/format.js.map +1 -0
  174. package/dist/charts/lib/legend.d.ts +45 -0
  175. package/dist/charts/lib/legend.js +117 -0
  176. package/dist/charts/lib/legend.js.map +1 -0
  177. package/dist/charts/lib/loading.d.ts +48 -0
  178. package/dist/charts/lib/loading.js +105 -0
  179. package/dist/charts/lib/loading.js.map +1 -0
  180. package/dist/charts/lib/paint.d.ts +154 -0
  181. package/dist/charts/lib/paint.js +551 -0
  182. package/dist/charts/lib/paint.js.map +1 -0
  183. package/dist/charts/lib/sonify-control.d.ts +163 -0
  184. package/dist/charts/lib/sonify-control.js +172 -0
  185. package/dist/charts/lib/sonify-control.js.map +1 -0
  186. package/dist/charts/lib/sonify.d.ts +248 -0
  187. package/dist/charts/lib/sonify.js +262 -0
  188. package/dist/charts/lib/sonify.js.map +1 -0
  189. package/dist/charts/lib/toolbar.d.ts +143 -0
  190. package/dist/charts/lib/toolbar.js +156 -0
  191. package/dist/charts/lib/toolbar.js.map +1 -0
  192. package/dist/charts/lib/tooltip.d.ts +59 -0
  193. package/dist/charts/lib/tooltip.js +135 -0
  194. package/dist/charts/lib/tooltip.js.map +1 -0
  195. package/dist/charts/lib/values.d.ts +56 -0
  196. package/dist/charts/lib/values.js +71 -0
  197. package/dist/charts/lib/values.js.map +1 -0
  198. package/dist/charts/lib/zoom.d.ts +139 -0
  199. package/dist/charts/lib/zoom.js +314 -0
  200. package/dist/charts/lib/zoom.js.map +1 -0
  201. package/dist/components/AppShell/AppShell.d.ts +15 -1
  202. package/dist/components/AppShell/AppShell.js +8 -4
  203. package/dist/components/AppShell/AppShell.js.map +1 -1
  204. package/dist/components/Article/Article.d.ts +51 -0
  205. package/dist/components/Article/Article.js +21 -0
  206. package/dist/components/Article/Article.js.map +1 -0
  207. package/dist/components/Button/Button.js +2 -2
  208. package/dist/components/Button/Button.js.map +1 -1
  209. package/dist/components/Calendar/Calendar.d.ts +1 -1
  210. package/dist/components/Calendar/Calendar.js +259 -24
  211. package/dist/components/Calendar/Calendar.js.map +1 -1
  212. package/dist/components/Checkbox/Checkbox.js +1 -1
  213. package/dist/components/Checkbox/Checkbox.js.map +1 -1
  214. package/dist/components/Collapsible/Collapsible.d.ts +15 -1
  215. package/dist/components/Collapsible/Collapsible.js +18 -0
  216. package/dist/components/Collapsible/Collapsible.js.map +1 -1
  217. package/dist/components/Combobox/Combobox.js +1 -1
  218. package/dist/components/Combobox/Combobox.js.map +1 -1
  219. package/dist/components/Command/Command.js +7 -7
  220. package/dist/components/Command/Command.js.map +1 -1
  221. package/dist/components/ContextMenu/ContextMenu.js +2 -2
  222. package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
  223. package/dist/components/Diagram/Diagram.d.ts +81 -0
  224. package/dist/components/Diagram/Diagram.js +139 -0
  225. package/dist/components/Diagram/Diagram.js.map +1 -0
  226. package/dist/components/Dialog/Dialog.js +1 -1
  227. package/dist/components/Dialog/Dialog.js.map +1 -1
  228. package/dist/components/DropdownMenu/DropdownMenu.js +2 -2
  229. package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
  230. package/dist/components/FigureBand/FigureBand.js +41 -30
  231. package/dist/components/FigureBand/FigureBand.js.map +1 -1
  232. package/dist/components/Popover/Popover.js +1 -1
  233. package/dist/components/Popover/Popover.js.map +1 -1
  234. package/dist/components/Select/Select.js +2 -2
  235. package/dist/components/Select/Select.js.map +1 -1
  236. package/dist/components/Sheet/Sheet.js +1 -1
  237. package/dist/components/Sheet/Sheet.js.map +1 -1
  238. package/dist/components/Slider/Slider.js +1 -1
  239. package/dist/components/Slider/Slider.js.map +1 -1
  240. package/dist/components/Steps/Steps.d.ts +65 -0
  241. package/dist/components/Steps/Steps.js +55 -0
  242. package/dist/components/Steps/Steps.js.map +1 -0
  243. package/dist/components/Switch/Switch.js +1 -1
  244. package/dist/components/Switch/Switch.js.map +1 -1
  245. package/dist/components/Tooltip/Tooltip.js +1 -1
  246. package/dist/components/Tooltip/Tooltip.js.map +1 -1
  247. package/dist/index.d.ts +4 -1
  248. package/dist/index.js +3 -0
  249. package/dist/index.js.map +1 -1
  250. package/dist/lib/useSelectionIndicator.js +14 -10
  251. package/dist/lib/useSelectionIndicator.js.map +1 -1
  252. package/dist/semantic.css +19 -0
  253. package/dist/styles.css +1 -1
  254. package/dist/themes.css +103 -7
  255. package/dist/tokens.css +193 -10
  256. package/dist/tokens.d.ts +25 -0
  257. package/dist/tokens.js +154 -8
  258. package/dist/tokens.json +154 -8
  259. package/package.json +45 -20
  260. package/skills/misoto22-design/SKILL.md +171 -0
  261. package/skills/misoto22-design/evals/claims.json +95 -0
  262. package/skills/misoto22-design/rules/a11y.md +115 -0
  263. package/skills/misoto22-design/rules/composition.md +108 -0
  264. package/skills/misoto22-design/rules/forms.md +128 -0
  265. package/skills/misoto22-design/rules/naming.md +155 -0
  266. package/skills/misoto22-design/rules/tokens.md +131 -0
@@ -0,0 +1,57 @@
1
+ # Popover
2
+
3
+ A panel anchored to a control, holding content you can interact with.
4
+
5
+ - Group: Overlays
6
+ - Import: `import { Popover } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/popover/
9
+ - Related: tooltip, dropdown-menu
10
+
11
+ ## When to reach for it
12
+
13
+ Anything with a link, a field or a button in it. A tooltip describes and cannot be entered — put a control inside one and it becomes unreachable.
14
+
15
+ ## Accessibility
16
+
17
+ - Inside a bounded frame — a device preview, an embedded console — wrap the subtree in `<OverlayContainer container={el}>`. The panel then renders into that element and collides with its edges instead of the viewport’s, and inherits the `dir` and `data-density` set there.
18
+ - label is required: a popover is a dialog, and an unnamed one announces nothing.
19
+ - Its contents Tab like the rest of the page, unlike a menu’s arrow-key list.
20
+
21
+ ## Keyboard
22
+
23
+ - Enter / Space — Opens it.
24
+ - Tab — Moves through its contents like the rest of the page.
25
+ - Escape — Closes it and returns focus to the trigger.
26
+
27
+ ## Popover
28
+
29
+ Radix Popover root, trigger, anchor and close, as typed passthroughs.
30
+
31
+ ## PopoverTrigger
32
+
33
+ ## PopoverAnchor
34
+
35
+ ## PopoverClose
36
+
37
+ ## PopoverContent
38
+
39
+ A panel anchored to a control, holding content the reader can interact with. The line against `Tooltip` is not visual, it is behavioural: a tooltip describes and cannot be entered; a popover holds things you tab to. Anything with a link, a field or a button in it is a popover, and putting that inside a tooltip makes it unreachable — the tooltip closes as soon as focus tries to move into it. Against `DropdownMenu`: a menu is a list of actions with menu semantics and arrow-key navigation. A popover is free-form, and its contents Tab like the rest of the page.
40
+
41
+ ### Props
42
+
43
+ - `label` (required) — `string`. Names the panel for assistive tech. Required — a popover is a dialog.
44
+ - `showClose` — `boolean` default `false`. Show the top-end close control.
45
+
46
+ Also accepts: `ComponentProps<typeof PopoverPrimitive.Content>`.
47
+
48
+ ## Examples
49
+
50
+ ```tsx
51
+ <Popover>
52
+ <PopoverTrigger asChild><Button variant="secondary">Filters</Button></PopoverTrigger>
53
+ <PopoverContent label="Filters">
54
+ <Field label="Status"><Select>…</Select></Field>
55
+ </PopoverContent>
56
+ </Popover>
57
+ ```
@@ -0,0 +1,33 @@
1
+ # Progress
2
+
3
+ A bar that fills, or sweeps when the end is unknown.
4
+
5
+ - Group: Feedback
6
+ - Import: `import { Progress } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/progress/
9
+ - Related: spinner
10
+
11
+ ## Accessibility
12
+
13
+ - Omitting value drops aria-valuenow, so a screen reader hears “indeterminate” rather than a number that is a guess.
14
+ - label is required — a bare bar announces nothing.
15
+
16
+ ## Progress
17
+
18
+ A bar that fills, or sweeps when the end is unknown. Flat: a track in `--stone`, a fill in `--ink`. The White Reset has no gradient and no glow, so the only thing carrying the reading is the boundary between the two.
19
+
20
+ ### Props
21
+
22
+ - `value` — `number | null` default `null`. 0–100. Omit (or pass `null`) when the duration is genuinely unknown — the bar then sweeps instead of filling, and Radix drops `aria-valuenow` so a screen reader is told "indeterminate" rather than a number that is a guess.
23
+ - `label` (required) — `string`. Names what is progressing. Required: a bare bar announces nothing.
24
+ - `showValue` — `boolean` default `false`. Prints the percentage above the bar. Only meaningful when `value` is set.
25
+
26
+ Also accepts: `Omit<ComponentProps<typeof ProgressPrimitive.Root>, 'value'>`.
27
+
28
+ ## Examples
29
+
30
+ ```tsx
31
+ <Progress value={62} label="Uploading photos" showValue />
32
+ <Progress label="Indexing" />
33
+ ```
@@ -0,0 +1,54 @@
1
+ # RadarChart
2
+
3
+ A profile across several named dimensions.
4
+
5
+ - Group: Charts
6
+ - Import: `import { RadarChart } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/radar-chart/
9
+ - Related: line-chart, pie-chart
10
+
11
+ ## When to reach for it
12
+
13
+ Recognising a silhouette. The area a radar encloses depends on the order its spokes happen to be in, so it is the wrong chart for comparing magnitudes.
14
+
15
+ ## Accessibility
16
+
17
+ - title is required; the rows are also rendered as a visually hidden table.
18
+ - Two or three series at most: filled polygons overlap, and judging areas through two layers of translucency is what a radar is worst at. Past that, variant="lines".
19
+
20
+ ## RadarChart
21
+
22
+ A profile across several named dimensions — the shape for "what is this thing strong and weak at". It reads a SHAPE, not a set of values: the area a radar encloses depends on the order the spokes happen to be in, so it is the wrong chart for comparing magnitudes and the right one for recognising a silhouette. Two or three series at most.
23
+
24
+ ### Props
25
+
26
+ - `config` (required) — `TConfig & ValidateKeys<TData, TConfig>`.
27
+ - `data` (required) — `TData[]`. The rows the chart draws. One entry per point, bar or category.
28
+ - `title` (required) — `string`. What the chart shows, in a sentence a reader could act on. Required, and announced to a screen reader even when it is not printed.
29
+ - `showTitle` — `boolean`. Prints the title above the plot instead of hiding it from sight.
30
+ - `description` — `ReactNode`. A line under the title — the unit, the window, the caveat.
31
+ - `children` (required) — `ReactNode`. The composed parts — axes, grid, tooltip, legend, and the marks themselves.
32
+ - `className` — `string`. Merged onto the figure, last, so a call site can size or space it.
33
+ - `chartProps` — `ComponentProps<typeof RechartsRadarChart>`. Escape hatch onto the raw Recharts chart element.
34
+ - `defaultSelectedDataKey` — `string | null` default `null`. The series lit on first render. Selection dims every other series.
35
+ - `onSelectionChange` — `(selectedDataKey: string | null) => void`. Fires when the selection changes, and with null when it is cleared.
36
+ - `isLoading` — `boolean` default `false`. Swaps the marks for an animated skeleton, keeping the measured height so the page does not jump when the data lands.
37
+ - `loadingPoints` — `number`. How many points the skeleton draws.
38
+ - `angleDataKey` — `keyof TData & string`. The row field naming each spoke. Used by the table view.
39
+ - `hideDataTable` — `boolean` default `false`. Drops the hidden table view. Only correct when the page prints the data itself.
40
+
41
+ ## Types
42
+
43
+ - `RadarVariant` = `'filled' | 'lines'`
44
+
45
+ ## Examples
46
+
47
+ ```tsx
48
+ <RadarChart title="Team skills" config={config} data={data} angleDataKey="skill">
49
+ <RadarChart.PolarGrid />
50
+ <RadarChart.PolarAngleAxis dataKey="skill" />
51
+ <RadarChart.Tooltip />
52
+ <RadarChart.Radar dataKey="current" />
53
+ </RadarChart>
54
+ ```
@@ -0,0 +1,57 @@
1
+ # RadialChart
2
+
3
+ Values on an arc — a gauge, or a few totals against one scale.
4
+
5
+ - Group: Charts
6
+ - Import: `import { RadialChart } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/radial-chart/
9
+ - Related: pie-chart, bar-chart
10
+
11
+ ## When to reach for it
12
+
13
+ A single value against a fixed total. Past about four bars a BarChart is the honest choice, because a radial bar’s radius is not its value.
14
+
15
+ ## Accessibility
16
+
17
+ - title is required; pass valueKey and the rows are also rendered as a visually hidden table.
18
+ - Set max or the scale comes from the data and the largest bar always fills the arc — which makes 62% and 98% look identical.
19
+ - showTrack draws the unfilled remainder, which is what makes a gauge readable at all.
20
+
21
+ ## RadialChart
22
+
23
+ Values on an arc — a gauge, or a small set of totals against one scale. The caveat worth knowing before reaching for it: a radial bar's LENGTH is its value, but its RADIUS is not, so an inner bar and an outer bar of the same value are drawn different lengths. That makes it a poor comparison and a good single-value gauge; past about four bars, a `<BarChart>` is the honest choice.
24
+
25
+ ### Props
26
+
27
+ - `config` (required) — `ChartConfig`. Bar names → their label and paint. Keys must match the `nameKey` values.
28
+ - `data` (required) — `TData[]`. The rows the chart draws. One entry per point, bar or category.
29
+ - `nameKey` (required) — `keyof TData & string`. The row field naming each bar.
30
+ - `title` (required) — `string`. What the chart shows, in a sentence a reader could act on. Required, and announced to a screen reader even when it is not printed.
31
+ - `showTitle` — `boolean`. Prints the title above the plot instead of hiding it from sight.
32
+ - `description` — `ReactNode`. A line under the title — the unit, the window, the caveat.
33
+ - `children` (required) — `ReactNode`. The composed parts — axes, grid, tooltip, legend, and the marks themselves.
34
+ - `className` — `string`. Merged onto the figure, last, so a call site can size or space it.
35
+ - `chartProps` — `ComponentProps<typeof RechartsRadialBarChart>`. Escape hatch onto the raw Recharts chart element.
36
+ - `variant` — `RadialVariant` default `'full'`. The arc shape — a full ring, or the half circle a gauge wants.
37
+ - `max` — `number`. What a full sweep is worth. Without it the scale comes from the data, so the largest bar always fills the arc — which is right for a comparison and wrong for a gauge. Set it (typically 100) whenever a single value has to read against a fixed total, or "62%" and "98%" will look identical.
38
+ - `innerRadius` — `number | string` default `'30%'`. Where the arc starts, from the centre.
39
+ - `outerRadius` — `number | string` default `'100%'`. Where the arc ends.
40
+ - `defaultSelectedBar` — `string | null` default `null`. The bar lit on first render.
41
+ - `onSelectionChange` — `(selection: { name: string; value: number } | null) => void`. Fires when the selection changes, and with null when it is cleared.
42
+ - `isLoading` — `boolean` default `false`. Swaps the marks for an animated skeleton, keeping the measured height so the page does not jump when the data lands.
43
+ - `valueKey` — `keyof TData & string`. The row field holding each bar's number. Used by the table view.
44
+ - `hideDataTable` — `boolean` default `false`. Drops the hidden table view. Only correct when the page prints the data itself.
45
+
46
+ ## Types
47
+
48
+ - `RadialVariant` = `'full' | 'semi'`
49
+
50
+ ## Examples
51
+
52
+ ```tsx
53
+ <RadialChart title="Storage used" config={config} data={data} nameKey="tier" max={100}>
54
+ <RadialChart.RadialBar dataKey="used" />
55
+ <RadialChart.Tooltip />
56
+ </RadialChart>
57
+ ```
@@ -0,0 +1,44 @@
1
+ # RadioGroup
2
+
3
+ A set of mutually exclusive choices.
4
+
5
+ - Group: Forms
6
+ - Import: `import { RadioGroup } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/radio-group/
9
+ - Related: checkbox, select
10
+
11
+ ## Accessibility
12
+
13
+ - One tab stop for the whole group; the arrow keys move between options, per the ARIA radiogroup pattern.
14
+ - The label is inside the <label>, so the whole row is the click target.
15
+
16
+ ## Keyboard
17
+
18
+ - Tab — Moves into the group, and out of it — the whole group is one stop.
19
+ - ↑ / ↓ / ← / → — Moves between options AND selects as it goes.
20
+
21
+ ## RadioGroup
22
+
23
+ A set of mutually exclusive choices. Radix owns the roving tabindex, so the whole group is ONE tab stop and the arrow keys move between options — which is what the ARIA radiogroup pattern requires and what a stack of hand-rolled `<input type="radio">` wrappers usually gets wrong.
24
+
25
+ Also accepts: `ComponentProps<typeof RadioGroupPrimitive.Root>`.
26
+
27
+ ## RadioGroupItem
28
+
29
+ One option, and its label, as a single click target. The `<label>` wraps both, so the whole row is clickable — a bare 18px circle is below every pointer-target guideline and is miserable on a phone. It is also what gives the control its accessible name: remove the wrapper and the radio has no name at all. Selection follows focus, which is the half of the pattern that makes a radiogroup usable from the keyboard: moving to an option chooses it, so nobody has to press an extra key to commit. That is implemented here rather than inherited, because the upstream primitive gates it on a flag cleared by `keyup` and loses the race against its own focus move — see ARROW_GRACE_MS. Re-selecting an already-selected option is a no-op, so this stays correct even where the upstream path does fire.
30
+
31
+ ### Props
32
+
33
+ - `children` (required) — `ReactNode`. The visible label. Rendered inside the `<label>` that wraps the control.
34
+
35
+ Also accepts: `Omit<ComponentProps<typeof RadioGroupPrimitive.Item>, 'children'>`.
36
+
37
+ ## Examples
38
+
39
+ ```tsx
40
+ <RadioGroup defaultValue="light" aria-label="Theme">
41
+ <RadioGroupItem value="light">Light</RadioGroupItem>
42
+ <RadioGroupItem value="dark">Dark</RadioGroupItem>
43
+ </RadioGroup>
44
+ ```
@@ -0,0 +1,61 @@
1
+ # SankeyChart
2
+
3
+ Where a quantity goes as it moves through stages.
4
+
5
+ - Group: Charts
6
+ - Import: `import { SankeyChart } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/sankey-chart/
9
+ - Related: bar-chart
10
+
11
+ ## When to reach for it
12
+
13
+ A funnel, a budget, an energy or traffic breakdown. The only chart here whose data is a graph rather than a table.
14
+
15
+ ## Accessibility
16
+
17
+ - title is required. The hidden table lists the FLOWS rather than the nodes — a table of node totals would lose every “from → to” the diagram exists to show.
18
+ - Four link variants: gradient reads as flow, source and target attribute a band to one end, solid gives up colour and lets the nodes carry identity.
19
+
20
+ ## SankeyChart
21
+
22
+ Where a quantity goes as it moves through stages — the shape for a funnel, a budget, an energy or traffic breakdown. The only chart here whose data is a GRAPH rather than a table, so it takes `{ nodes, links }` instead of rows, and the table view lists the flows rather than the nodes.
23
+
24
+ ### Props
25
+
26
+ - `data` (required) — `SankeyData`. The nodes and the links between them, in Recharts' own shape.
27
+ - `config` (required) — `ChartConfig`. Node names → their label and paint.
28
+ - `title` (required) — `string`. What the chart shows, in a sentence a reader could act on. Required, and announced to a screen reader even when it is not printed.
29
+ - `showTitle` — `boolean`. Prints the title above the plot instead of hiding it from sight.
30
+ - `description` — `ReactNode`. A line under the title — the unit, the window, the caveat.
31
+ - `children` (required) — `ReactNode`. The composed parts — axes, grid, tooltip, legend, and the marks themselves.
32
+ - `className` — `string`. Merged onto the figure, last, so a call site can size or space it.
33
+ - `sankeyProps` — `Omit<SankeyProps, 'data'>`. Escape hatch onto the raw Recharts Sankey element.
34
+ - `nodeWidth` — `number` default `10`. How wide each node rectangle is, in pixels.
35
+ - `nodePadding` — `number` default `10`. Vertical gap between nodes in the same column, in pixels.
36
+ - `linkCurvature` — `number` default `0.5`. 0 draws straight links, 1 the fullest curve.
37
+ - `iterations` — `number` default `32`. Layout passes. More is tidier and slower.
38
+ - `sort` — `boolean` default `true`. Lets the layout reorder nodes for the fewest crossings.
39
+ - `align` — `'left' | 'justify'` default `'justify'`. How nodes are placed along the flow axis.
40
+ - `verticalAlign` — `'justify' | 'top'` default `'justify'`. How nodes are distributed within a column.
41
+ - `defaultSelectedNode` — `string | null` default `null`. The node lit on first render. Selecting one dims every flow it does not touch.
42
+ - `onSelectionChange` — `(selection: { name: string; value: number } | null) => void`. Fires when the selection changes, and with null when it is cleared.
43
+ - `isLoading` — `boolean` default `false`. Swaps the marks for an animated skeleton, keeping the measured height so the page does not jump when the data lands.
44
+ - `hideDataTable` — `boolean` default `false`. Drops the hidden table view. Only correct when the page prints the data itself.
45
+
46
+ ## Types
47
+
48
+ - `SankeyLinkVariant` = `'gradient' | 'solid' | 'source' | 'target'`
49
+ - `SankeyLabelPosition` = `'inside' | 'outside'`
50
+
51
+ ## Examples
52
+
53
+ ```tsx
54
+ <SankeyChart title="Traffic by source and outcome" config={config} data={data}>
55
+ <SankeyChart.Node radius={2}>
56
+ <SankeyChart.NodeLabel position="outside" showValues />
57
+ </SankeyChart.Node>
58
+ <SankeyChart.Link variant="gradient" />
59
+ <SankeyChart.Tooltip />
60
+ </SankeyChart>
61
+ ```
@@ -0,0 +1,54 @@
1
+ # ScatterChart
2
+
3
+ Two measures against each other, one mark per observation.
4
+
5
+ - Group: Charts
6
+ - Import: `import { ScatterChart } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/scatter-chart/
9
+ - Related: line-chart, heatmap
10
+
11
+ ## When to reach for it
12
+
13
+ Correlation, clustering, outliers — the questions that do not survive being bucketed into a bar. The only chart here whose x axis is a number rather than a category.
14
+
15
+ ## Accessibility
16
+
17
+ - title is required. The table view is declared rather than inferred: scatter data lives on each series, so there is no single set of rows to read off the root.
18
+ - Shape does the work hue does elsewhere. Two overlapping clouds separate far better by circle-versus-cross than by two steps of grey — and shape survives overprinting, which a lightness step does not.
19
+ - A solid mark carries a surface-coloured ring, so two observations that land on top of each other stay countable.
20
+ - ZAxis maps its measure to a mark’s AREA, not its radius: doubling a radius quadruples the ink, which is the most common way a bubble chart lies.
21
+
22
+ ## ScatterChart
23
+
24
+ Two measures against each other, one mark per observation — the shape for "is there a relationship here". The only chart in the set whose x axis is a NUMBER rather than a category, which is the whole point: a scatter answers correlation, clustering and outliers, and none of those questions survive being bucketed into a bar. Past three series, shape stops separating them and the answer is small multiples — one chart per series, same axes — rather than a fourth mark.
25
+
26
+ ### Props
27
+
28
+ - `config` (required) — `ChartConfig`. Series keys → their label and paint. Declaration order is ramp order.
29
+ - `title` (required) — `string`. What the chart shows, in a sentence a reader could act on. Required, and announced to a screen reader even when it is not printed.
30
+ - `showTitle` — `boolean`. Prints the title above the plot instead of hiding it from sight.
31
+ - `description` — `ReactNode`. A line under the title — the unit, the window, the caveat.
32
+ - `children` (required) — `ReactNode`. The composed parts — axes, grid, tooltip, legend, and the marks themselves.
33
+ - `className` — `string`. Merged onto the figure, last, so a call site can size or space it.
34
+ - `chartProps` — `ComponentProps<typeof RechartsScatterChart>`. Escape hatch onto the raw Recharts chart element.
35
+ - `defaultSelectedDataKey` — `string | null` default `null`. The series lit on first render. Selection dims every other series.
36
+ - `onSelectionChange` — `(selectedDataKey: string | null) => void`. Fires when the selection changes, and with null when it is cleared.
37
+ - `table` — `ScatterTable | false`. The rows behind the hidden table view, with the fields to print. Scatter data lives on each `<Scatter>` rather than on the root, so unlike every other chart here the table cannot be inferred — it is declared.
38
+
39
+ ## Types
40
+
41
+ - `ScatterShape` = `'circle' | 'square' | 'triangle' | 'diamond' | 'cross' | 'ring'`
42
+ - `ScatterVariant` = `'solid' | 'outline' | 'gradient'`
43
+
44
+ ## Examples
45
+
46
+ ```tsx
47
+ <ScatterChart title="Load time against bundle size" config={config}>
48
+ <ScatterChart.Grid />
49
+ <ScatterChart.XAxis dataKey="kb" name="Bundle" unit=" kB" />
50
+ <ScatterChart.YAxis dataKey="ms" name="Load" unit=" ms" />
51
+ <ScatterChart.Tooltip />
52
+ <ScatterChart.Scatter dataKey="desktop" data={desktop} />
53
+ </ScatterChart>
54
+ ```
@@ -0,0 +1,40 @@
1
+ # ScrollArea
2
+
3
+ A box that scrolls, with a scrollbar that looks the same everywhere.
4
+
5
+ - Group: Surfaces
6
+ - Import: `import { ScrollArea } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/scroll-area/
9
+ - Related: table
10
+
11
+ ## When to reach for it
12
+
13
+ A bounded panel — a long option list, a log. For page-level or prose scroll the scroll-slim utility is lighter and needs no component.
14
+
15
+ ## Accessibility
16
+
17
+ - The viewport stays focusable. A scrollable region whose contents are not focusable has nothing to Tab to, so everything past the fold does not exist without a mouse.
18
+ - label is required, because an unnamed keyboard stop announces "group" and nothing else.
19
+
20
+ ## Keyboard
21
+
22
+ - Tab — Moves focus into the region, which is what makes it scrollable at all without a mouse.
23
+ - ↑ / ↓ / Page Up / Page Down — Scrolls it.
24
+
25
+ ## ScrollArea
26
+
27
+ A box that scrolls, with a scrollbar that looks the same on every platform. The reason to reach for this over `overflow-auto` is not the scrollbar — it is that Radix keeps the viewport focusable and the bar operable, which a bare overflow container does not. A scrollable region whose contents are not themselves focusable is unreachable by keyboard: there is nothing to Tab to, so everything past the fold does not exist without a mouse. For a page-level or prose scroll, the `scroll-slim` utility is lighter and needs no component. This is for a bounded panel: a long option list, a log, a sidebar that outgrows its column.
28
+
29
+ ### Props
30
+
31
+ - `label` (required) — `string`. Names the region. Required, and not decoration: a scroll container is a keyboard stop, and an unnamed stop announces "group" and nothing else.
32
+ - `orientation` — `'vertical' | 'horizontal' | 'both'` default `'vertical'`.
33
+
34
+ Also accepts: `ComponentProps<typeof ScrollAreaPrimitive.Root>`.
35
+
36
+ ## Examples
37
+
38
+ ```tsx
39
+ <ScrollArea label="Deploy log" className="h-48">…</ScrollArea>
40
+ ```
@@ -0,0 +1,46 @@
1
+ # SearchableMenu
2
+
3
+ A menu of actions you can type into.
4
+
5
+ - Group: Overlays
6
+ - Import: `import { SearchableMenu } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/searchable-menu/
9
+ - Related: dropdown-menu, command, combobox
10
+
11
+ ## When to reach for it
12
+
13
+ A DropdownMenu past about a dozen rows stops being scannable, and nesting submenus makes it worse. This is the same list with a filter over it. Not a Command palette: that is page-level and modal; this is anchored to a control.
14
+
15
+ ## Accessibility
16
+
17
+ - Inside a bounded frame — a device preview, an embedded console — wrap the subtree in `<OverlayContainer container={el}>`. The panel then renders into that element and collides with its edges instead of the viewport’s, and inherits the `dir` and `data-density` set there.
18
+ - The rows are options inside a listbox rather than menuitems, because filtering requires it — the highlight moves through aria-activedescendant while focus stays in the input, and a menu cannot do that.
19
+ - The trade is deliberate: a menu that cannot be filtered is worse for the reader than a listbox that runs actions.
20
+
21
+ ## Keyboard
22
+
23
+ - Enter / Space — Opens the menu.
24
+ - ↑ / ↓ — Moves the highlight while focus stays in the filter.
25
+ - Enter — Runs the highlighted action.
26
+ - Escape — Closes without running anything.
27
+
28
+ ## SearchableMenu
29
+
30
+ A menu of actions you can type into. The fourth corner of a square the system otherwise had three of, and the distinction is worth stating because reaching for the wrong one is easy: | | few options | many options | |---|---|---| | **sets a value** | `Select` | `Combobox` | | **runs an action** | `DropdownMenu` | `SearchableMenu` | A `DropdownMenu` past about a dozen rows stops being scannable, and the usual response — nesting submenus — makes it worse. This is the same list with a filter over it. Not the same thing as `Command`: that is a page-level palette, usually modal and usually bound to ⌘K. This is anchored to a control, like the menu it replaces. The rows are `option`s inside a listbox rather than `menuitem`s, because that is what the filtering pattern requires — the highlight moves through `aria-activedescendant` while focus stays in the input, and a menu cannot do that. The trade is deliberate: a menu that cannot be filtered is worse for the reader than a listbox that runs actions.
31
+
32
+ ### Props
33
+
34
+ - `actions` (required) — `MenuAction[]`.
35
+ - `children` (required) — `ReactNode`. The trigger's text.
36
+ - `label` (required) — `string`. Names the menu for assistive tech.
37
+ - `searchPlaceholder` — `string` default `'Filter…'`.
38
+ - `emptyMessage` — `string` default `'Nothing matches.'`.
39
+ - `align` — `'start' | 'center' | 'end'` default `'start'`.
40
+ - `className` — `string`.
41
+
42
+ ## Examples
43
+
44
+ ```tsx
45
+ <SearchableMenu label="Actions" actions={ACTIONS}>Actions</SearchableMenu>
46
+ ```
@@ -0,0 +1,75 @@
1
+ # Select
2
+
3
+ A choice from a list, styled the whole way down.
4
+
5
+ - Group: Forms
6
+ - Import: `import { Select } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/select/
9
+ - Related: combobox, native-select, field
10
+
11
+ ## When to reach for it
12
+
13
+ Up to roughly a dozen options. Past that a Combobox wins, because a list nobody can filter is slower to scan than one you can type into.
14
+
15
+ ## Accessibility
16
+
17
+ - Inside a bounded frame — a device preview, an embedded console — wrap the subtree in `<OverlayContainer container={el}>`. The panel then renders into that element and collides with its edges instead of the viewport’s, and inherits the `dir` and `data-density` set there.
18
+ - The option list is ours, so it does not change typeface, spacing and selection colour the moment it opens — which is what a native select does.
19
+ - The keyboard contract is the platform's: typeahead, arrows, Home and End, Escape to close without choosing.
20
+ - label is required. The trigger shows a value, and a value is not a name.
21
+
22
+ ## Keyboard
23
+
24
+ - Enter / Space / ↓ — Opens the list.
25
+ - ↑ / ↓ — Moves between options.
26
+ - a–z — Typeahead — jumps to the next option starting with that letter.
27
+ - Home / End — Jumps to the first or last option.
28
+ - Escape — Closes without choosing.
29
+
30
+ ## SelectRoot
31
+
32
+ Radix Select root, group and label, as typed passthroughs.
33
+
34
+ ## SelectGroup
35
+
36
+ ## Select
37
+
38
+ A choice from a list, styled the whole way down. The option list is ours — drawn from the same tokens as everything else, so it does not change typeface, spacing and selection colour the moment it opens. That is the whole reason this replaced the native control as the default: a design system whose most common form control stops being part of the system on click is not a design system, it is a stylesheet for closed states. The keyboard contract is Radix's, which means it is the platform's: typeahead works, the arrows move, Home and End reach the ends, and Escape closes without choosing. That was the one genuine argument for staying native, and it is answered. Past roughly a dozen options, reach for `Combobox` — a list nobody can filter is worse than one they can type into. Where the platform picker is genuinely better — a phone, or a form that must survive without JavaScript — reach for `NativeSelect`.
39
+
40
+ ### Props
41
+
42
+ - `contentClassName` — `string`. Classes for the option PANEL, not the trigger. `className` styles the trigger, which is the common case. This exists for the uncommon one: a select inside a bounded surface, where the default 18rem of list would cover the thing the reader is choosing for — a year picker over its own calendar, say.
43
+ - `label` (required) — `string`. Names the control. Required — the trigger shows a value, and a value is not a name.
44
+ - `placeholder` — `string` default `'Select…'`.
45
+ - `invalid` — `boolean`. Paints the resting border with `--danger` and reflects `aria-invalid`.
46
+ - `disabled` — `boolean`.
47
+ - `className` — `string`.
48
+ - `children` (required) — `ReactNode`. `SelectItem`s, optionally wrapped in `SelectGroup` with a `SelectLabel`.
49
+
50
+ Also accepts: `ComponentProps<typeof SelectPrimitive.Root>`.
51
+
52
+ ## SelectItem
53
+
54
+ One option. The tick marks the chosen one; the fill marks the highlighted one.
55
+
56
+ Also accepts: `ComponentProps<typeof SelectPrimitive.Item>`.
57
+
58
+ ## SelectLabel
59
+
60
+ Mono eyebrow heading for a group of options. Must sit inside a `SelectGroup` — Radix throws otherwise, because a heading with no group is a heading for nothing, and assistive tech would announce it as an option.
61
+
62
+ ## SelectSeparator
63
+
64
+ Hairline divider between groups.
65
+
66
+ ## Examples
67
+
68
+ ```tsx
69
+ <Field label="Region">
70
+ <Select label="Region" defaultValue="au">
71
+ <SelectItem value="au">Australia</SelectItem>
72
+ <SelectItem value="nz">New Zealand</SelectItem>
73
+ </Select>
74
+ </Field>
75
+ ```
@@ -0,0 +1,35 @@
1
+ # Separator
2
+
3
+ A rule, in the three weights a monochrome page needs.
4
+
5
+ - Group: Display
6
+ - Import: `import { Separator } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/separator/
9
+
10
+ ## When to reach for it
11
+
12
+ Hairline between rows, edge between blocks, hard under a masthead.
13
+
14
+ ## Accessibility
15
+
16
+ - role="none" by default. A rule that only groups things visually must not be announced.
17
+
18
+ ## Separator
19
+
20
+ A rule. In a monochrome system the rule does the work colour would otherwise do, so it has three weights rather than one: hairline between rows, edge between blocks, hard under a masthead. Picking by name keeps a page from drifting into five hand-tuned greys.
21
+
22
+ ### Props
23
+
24
+ - `orientation` — `'horizontal' | 'vertical'` default `'horizontal'`.
25
+ - `weight` — `'hairline' | 'edge' | 'hard'` default `'hairline'`. `hairline` divides rows inside one block; `edge` divides one block from the next.
26
+ - `decorative` — `boolean` default `true`. A rule that only groups things visually is decoration and must not be announced. Set `false` when the rule genuinely separates two sections a screen reader should hear as distinct.
27
+
28
+ Also accepts: `HTMLAttributes<HTMLDivElement>`.
29
+
30
+ ## Examples
31
+
32
+ ```tsx
33
+ <Separator weight="hard" />
34
+ <Separator orientation="vertical" className="h-4" />
35
+ ```
@@ -0,0 +1,57 @@
1
+ # Sheet
2
+
3
+ A panel docked to an edge of the viewport.
4
+
5
+ - Group: Overlays
6
+ - Import: `import { Sheet } from '@misoto22/design'`
7
+ - Version: 0.6.0
8
+ - Docs: https://ui.misoto22.com/components/sheet/
9
+ - Related: dialog, popover
10
+
11
+ ## When to reach for it
12
+
13
+ A modal that needs room — a filter panel, a detail view. It IS a Dialog, docked; the sides are named in reading order, so `end` is the right in English and the left in Arabic.
14
+
15
+ ## Accessibility
16
+
17
+ - Shares Dialog’s focus trap, Escape handling and scroll lock rather than reproducing them — a second focus trap is a second one to get wrong.
18
+ - The title is required, visible or not.
19
+
20
+ ## Keyboard
21
+
22
+ - Escape — Closes it, and focus returns to the trigger.
23
+ - Tab — Cycles inside the sheet.
24
+
25
+ ## Sheet
26
+
27
+ Radix Dialog root, trigger and close — a sheet IS a dialog, docked.
28
+
29
+ ## SheetTrigger
30
+
31
+ ## SheetClose
32
+
33
+ ## SheetContent
34
+
35
+ A panel docked to an edge of the viewport. It is a modal dialog — Radix's, so the focus trap, the escape key, the scroll lock and the `aria-modal` wiring are the same ones `Dialog` gets. The only differences are where it sits and which way it arrives, which is why this shares that implementation rather than reproducing it: a second focus trap is a second focus trap to get wrong. The title is required, visible or not. A modal with no accessible name drops a screen reader into an unnamed region with no way back out.
36
+
37
+ ### Props
38
+
39
+ - `side` — `SheetSide` default `'end'`. Which edge it is docked to. `end` by default.
40
+ - `title` (required) — `ReactNode`.
41
+ - `description` — `ReactNode`.
42
+ - `hideTitle` — `boolean` default `false`. Hide the title visually while keeping it for assistive tech.
43
+
44
+ Also accepts: `Omit<ComponentProps<typeof DialogPrimitive.Content>, 'title'>`.
45
+
46
+ ## Types
47
+
48
+ - `SheetSide` = `'start' | 'end' | 'top' | 'bottom'`
49
+
50
+ ## Examples
51
+
52
+ ```tsx
53
+ <Sheet>
54
+ <SheetTrigger asChild><Button variant="secondary">Filters</Button></SheetTrigger>
55
+ <SheetContent title="Filters" description="Narrow the list.">…</SheetContent>
56
+ </Sheet>
57
+ ```