@misoto22/design 0.7.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.
- package/AGENTS.md +87 -0
- package/CLAUDE.md +1 -0
- package/README.md +50 -5
- package/bin/misoto22-design.mjs +59 -13
- package/dist/agent/Accordion.md +24 -1
- package/dist/agent/Alert.md +23 -1
- package/dist/agent/AppShell.md +30 -2
- package/dist/agent/ArchitectureFigure.md +25 -2
- package/dist/agent/AreaChart.md +27 -2
- package/dist/agent/Article.md +26 -3
- package/dist/agent/AspectRatio.md +57 -0
- package/dist/agent/Avatar.md +25 -5
- package/dist/agent/Badge.md +22 -1
- package/dist/agent/BarChart.md +29 -2
- package/dist/agent/BarList.md +27 -1
- package/dist/agent/BigNumber.md +26 -2
- package/dist/agent/BoxPlot.md +24 -1
- package/dist/agent/Breadcrumb.md +24 -2
- package/dist/agent/BulletChart.md +23 -1
- package/dist/agent/Button.md +25 -1
- package/dist/agent/Calendar.md +37 -3
- package/dist/agent/Card.md +24 -2
- package/dist/agent/Checkbox.md +23 -2
- package/dist/agent/Code.md +50 -0
- package/dist/agent/CodeBlock.md +74 -0
- package/dist/agent/Collapsible.md +22 -1
- package/dist/agent/ColorPicker.md +75 -0
- package/dist/agent/Combobox.md +29 -3
- package/dist/agent/Command.md +25 -2
- package/dist/agent/ComposedChart.md +26 -2
- package/dist/agent/ContextMenu.md +37 -4
- package/dist/agent/DataflowFigure.md +22 -1
- package/dist/agent/DatePicker.md +34 -6
- package/dist/agent/DescriptionList.md +68 -0
- package/dist/agent/Diagram.md +27 -3
- package/dist/agent/DiagramCanvas.md +24 -1
- package/dist/agent/DiagramExportMenu.md +29 -3
- package/dist/agent/DiagramInspector.md +23 -1
- package/dist/agent/DiagramLegend.md +22 -1
- package/dist/agent/DiagramMinimap.md +24 -4
- package/dist/agent/DiagramToolbar.md +23 -1
- package/dist/agent/Dialog.md +26 -3
- package/dist/agent/DropdownMenu.md +45 -6
- package/dist/agent/EmptyState.md +26 -1
- package/dist/agent/ErrorState.md +27 -2
- package/dist/agent/Facet.md +25 -1
- package/dist/agent/Field.md +45 -4
- package/dist/agent/FigureBand.md +24 -1
- package/dist/agent/FloatingIconButton.md +23 -1
- package/dist/agent/FunnelChart.md +23 -1
- package/dist/agent/Heading.md +64 -0
- package/dist/agent/Heatmap.md +25 -1
- package/dist/agent/Histogram.md +26 -2
- package/dist/agent/Input.md +22 -1
- package/dist/agent/Kbd.md +19 -1
- package/dist/agent/LifecycleFigure.md +22 -1
- package/dist/agent/LineChart.md +26 -2
- package/dist/agent/LinkArrow.md +20 -1
- package/dist/agent/Markdown.md +68 -0
- package/dist/agent/NativeSelect.md +23 -2
- package/dist/agent/NavItem.md +21 -1
- package/dist/agent/NumberField.md +72 -0
- package/dist/agent/Pagination.md +28 -2
- package/dist/agent/PieChart.md +26 -2
- package/dist/agent/Popover.md +23 -1
- package/dist/agent/Progress.md +27 -3
- package/dist/agent/RadarChart.md +26 -2
- package/dist/agent/RadialChart.md +26 -3
- package/dist/agent/RadioGroup.md +23 -2
- package/dist/agent/SankeyChart.md +25 -2
- package/dist/agent/ScatterChart.md +27 -2
- package/dist/agent/ScrollArea.md +24 -3
- package/dist/agent/SearchableMenu.md +23 -1
- package/dist/agent/Select.md +29 -3
- package/dist/agent/Separator.md +28 -4
- package/dist/agent/SequenceFigure.md +23 -1
- package/dist/agent/Sheet.md +25 -2
- package/dist/agent/Sidebar.md +193 -0
- package/dist/agent/Skeleton.md +24 -2
- package/dist/agent/Slider.md +31 -4
- package/dist/agent/Sparkline.md +23 -1
- package/dist/agent/Spinner.md +24 -2
- package/dist/agent/StatusDot.md +20 -1
- package/dist/agent/StatusPill.md +28 -2
- package/dist/agent/Steps.md +24 -1
- package/dist/agent/Switch.md +21 -1
- package/dist/agent/Table.md +28 -3
- package/dist/agent/Tabs.md +24 -2
- package/dist/agent/Tag.md +40 -9
- package/dist/agent/Text.md +65 -0
- package/dist/agent/Textarea.md +20 -1
- package/dist/agent/Timestamp.md +64 -0
- package/dist/agent/Toast.md +26 -2
- package/dist/agent/ToggleGroup.md +24 -2
- package/dist/agent/Toolbar.md +71 -0
- package/dist/agent/Tooltip.md +23 -1
- package/dist/agent/TreemapChart.md +24 -1
- package/dist/agent/WaterfallChart.md +24 -1
- package/dist/agent/WorkflowFigure.md +24 -2
- package/dist/agent/catalog.json +5915 -699
- package/dist/agent/index.md +20 -8
- package/dist/article.css +16 -4
- package/dist/charts/AreaChart/AreaChart.d.ts +9 -2
- package/dist/charts/AreaChart/AreaChart.js +12 -13
- package/dist/charts/AreaChart/AreaChart.js.map +1 -1
- package/dist/charts/BarChart/BarChart.d.ts +14 -3
- package/dist/charts/BarChart/BarChart.js +20 -12
- package/dist/charts/BarChart/BarChart.js.map +1 -1
- package/dist/charts/BarList/BarList.d.ts +9 -1
- package/dist/charts/BarList/BarList.js +9 -1
- package/dist/charts/BarList/BarList.js.map +1 -1
- package/dist/charts/BigNumber/BigNumber.d.ts +19 -3
- package/dist/charts/BigNumber/BigNumber.js +25 -5
- package/dist/charts/BigNumber/BigNumber.js.map +1 -1
- package/dist/charts/BoxPlot/BoxPlot.js +4 -2
- package/dist/charts/BoxPlot/BoxPlot.js.map +1 -1
- package/dist/charts/BulletChart/BulletChart.js +44 -9
- package/dist/charts/BulletChart/BulletChart.js.map +1 -1
- package/dist/charts/ComposedChart/ComposedChart.d.ts +9 -2
- package/dist/charts/ComposedChart/ComposedChart.js +10 -10
- package/dist/charts/ComposedChart/ComposedChart.js.map +1 -1
- package/dist/charts/FunnelChart/FunnelChart.d.ts +7 -2
- package/dist/charts/FunnelChart/FunnelChart.js +6 -16
- package/dist/charts/FunnelChart/FunnelChart.js.map +1 -1
- package/dist/charts/Heatmap/Heatmap.d.ts +17 -3
- package/dist/charts/Heatmap/Heatmap.js +20 -11
- package/dist/charts/Heatmap/Heatmap.js.map +1 -1
- package/dist/charts/Histogram/Histogram.d.ts +24 -1
- package/dist/charts/Histogram/Histogram.js +43 -11
- package/dist/charts/Histogram/Histogram.js.map +1 -1
- package/dist/charts/LineChart/LineChart.d.ts +9 -2
- package/dist/charts/LineChart/LineChart.js +11 -12
- package/dist/charts/LineChart/LineChart.js.map +1 -1
- package/dist/charts/PieChart/PieChart.d.ts +15 -3
- package/dist/charts/PieChart/PieChart.js +14 -6
- package/dist/charts/PieChart/PieChart.js.map +1 -1
- package/dist/charts/RadarChart/RadarChart.d.ts +15 -3
- package/dist/charts/RadarChart/RadarChart.js +15 -11
- package/dist/charts/RadarChart/RadarChart.js.map +1 -1
- package/dist/charts/RadialChart/RadialChart.d.ts +22 -4
- package/dist/charts/RadialChart/RadialChart.js +28 -6
- package/dist/charts/RadialChart/RadialChart.js.map +1 -1
- package/dist/charts/SankeyChart/SankeyChart.d.ts +16 -4
- package/dist/charts/SankeyChart/SankeyChart.js +14 -6
- package/dist/charts/SankeyChart/SankeyChart.js.map +1 -1
- package/dist/charts/ScatterChart/ScatterChart.d.ts +24 -3
- package/dist/charts/ScatterChart/ScatterChart.js +21 -15
- package/dist/charts/ScatterChart/ScatterChart.js.map +1 -1
- package/dist/charts/Sparkline/Sparkline.js +5 -3
- package/dist/charts/Sparkline/Sparkline.js.map +1 -1
- package/dist/charts/TreemapChart/TreemapChart.d.ts +7 -2
- package/dist/charts/TreemapChart/TreemapChart.js +20 -11
- package/dist/charts/TreemapChart/TreemapChart.js.map +1 -1
- package/dist/charts/WaterfallChart/WaterfallChart.js +4 -2
- package/dist/charts/WaterfallChart/WaterfallChart.js.map +1 -1
- package/dist/charts/lib/export.d.ts +1 -0
- package/dist/charts/lib/figure.d.ts +21 -1
- package/dist/charts/lib/figure.js +5 -2
- package/dist/charts/lib/figure.js.map +1 -1
- package/dist/charts/lib/scale.d.ts +23 -0
- package/dist/charts/lib/scale.js +13 -0
- package/dist/charts/lib/scale.js.map +1 -0
- package/dist/charts/lib/selection.d.ts +20 -0
- package/dist/charts/lib/selection.js +18 -0
- package/dist/charts/lib/selection.js.map +1 -0
- package/dist/charts/lib/toolbar.d.ts +1 -0
- package/dist/components/Accordion/Accordion.js +8 -1
- package/dist/components/Accordion/Accordion.js.map +1 -1
- package/dist/components/AppShell/AppShell.d.ts +6 -0
- package/dist/components/AppShell/AppShell.js +34 -4
- package/dist/components/AppShell/AppShell.js.map +1 -1
- package/dist/components/Article/Article.d.ts +11 -4
- package/dist/components/Article/Article.js +13 -0
- package/dist/components/Article/Article.js.map +1 -1
- package/dist/components/AspectRatio/AspectRatio.d.ts +46 -0
- package/dist/components/AspectRatio/AspectRatio.js +33 -0
- package/dist/components/AspectRatio/AspectRatio.js.map +1 -0
- package/dist/components/Avatar/Avatar.d.ts +12 -3
- package/dist/components/Avatar/Avatar.js +6 -1
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Breadcrumb/Breadcrumb.d.ts +6 -0
- package/dist/components/Breadcrumb/Breadcrumb.js +15 -0
- package/dist/components/Breadcrumb/Breadcrumb.js.map +1 -1
- package/dist/components/Button/Button.js +14 -0
- package/dist/components/Button/Button.js.map +1 -1
- package/dist/components/Calendar/Calendar.d.ts +29 -3
- package/dist/components/Calendar/Calendar.js +60 -12
- package/dist/components/Calendar/Calendar.js.map +1 -1
- package/dist/components/Card/Card.d.ts +6 -0
- package/dist/components/Card/Card.js +1 -1
- package/dist/components/Card/Card.js.map +1 -1
- package/dist/components/Checkbox/Checkbox.d.ts +5 -2
- package/dist/components/Checkbox/Checkbox.js +12 -2
- package/dist/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/components/Code/Code.d.ts +30 -0
- package/dist/components/Code/Code.js +21 -0
- package/dist/components/Code/Code.js.map +1 -0
- package/dist/components/CodeBlock/CodeBlock.d.ts +141 -0
- package/dist/components/CodeBlock/CodeBlock.js +123 -0
- package/dist/components/CodeBlock/CodeBlock.js.map +1 -0
- package/dist/components/Collapsible/Collapsible.js +10 -2
- package/dist/components/Collapsible/Collapsible.js.map +1 -1
- package/dist/components/ColorPicker/ColorPicker.d.ts +67 -0
- package/dist/components/ColorPicker/ColorPicker.js +334 -0
- package/dist/components/ColorPicker/ColorPicker.js.map +1 -0
- package/dist/components/Combobox/Combobox.d.ts +15 -1
- package/dist/components/Combobox/Combobox.js +25 -5
- package/dist/components/Combobox/Combobox.js.map +1 -1
- package/dist/components/Command/Command.d.ts +4 -2
- package/dist/components/Command/Command.js +14 -2
- package/dist/components/Command/Command.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.d.ts +30 -5
- package/dist/components/ContextMenu/ContextMenu.js +33 -3
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.d.ts +36 -4
- package/dist/components/DatePicker/DatePicker.js +55 -12
- package/dist/components/DatePicker/DatePicker.js.map +1 -1
- package/dist/components/DescriptionList/DescriptionList.d.ts +73 -0
- package/dist/components/DescriptionList/DescriptionList.js +35 -0
- package/dist/components/DescriptionList/DescriptionList.js.map +1 -0
- package/dist/components/Diagram/Diagram.d.ts +8 -3
- package/dist/components/Diagram/Diagram.js +82 -10
- package/dist/components/Diagram/Diagram.js.map +1 -1
- package/dist/components/Dialog/Dialog.d.ts +18 -3
- package/dist/components/Dialog/Dialog.js +21 -3
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.d.ts +49 -11
- package/dist/components/DropdownMenu/DropdownMenu.js +33 -3
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -1
- package/dist/components/EmptyState/EmptyState.d.ts +25 -1
- package/dist/components/EmptyState/EmptyState.js +3 -1
- package/dist/components/EmptyState/EmptyState.js.map +1 -1
- package/dist/components/ErrorState/ErrorState.d.ts +22 -1
- package/dist/components/ErrorState/ErrorState.js +12 -3
- package/dist/components/ErrorState/ErrorState.js.map +1 -1
- package/dist/components/Field/Field.d.ts +70 -3
- package/dist/components/Field/Field.js +53 -12
- package/dist/components/Field/Field.js.map +1 -1
- package/dist/components/Field/field-control.d.ts +31 -0
- package/dist/components/Field/field-control.js +12 -0
- package/dist/components/Field/field-control.js.map +1 -0
- package/dist/components/FloatingIconButton/FloatingIconButton.js +2 -0
- package/dist/components/FloatingIconButton/FloatingIconButton.js.map +1 -1
- package/dist/components/Heading/Heading.d.ts +62 -0
- package/dist/components/Heading/Heading.js +44 -0
- package/dist/components/Heading/Heading.js.map +1 -0
- package/dist/components/Markdown/Markdown.d.ts +139 -0
- package/dist/components/Markdown/Markdown.js +135 -0
- package/dist/components/Markdown/Markdown.js.map +1 -0
- package/dist/components/Markdown/inline.d.ts +29 -0
- package/dist/components/Markdown/inline.js +74 -0
- package/dist/components/Markdown/inline.js.map +1 -0
- package/dist/components/Markdown/nodes.d.ts +65 -0
- package/dist/components/Markdown/nodes.js +1 -0
- package/dist/components/Markdown/nodes.js.map +1 -0
- package/dist/components/Markdown/parse.d.ts +24 -0
- package/dist/components/Markdown/parse.js +110 -0
- package/dist/components/Markdown/parse.js.map +1 -0
- package/dist/components/Markdown/slug.d.ts +15 -0
- package/dist/components/Markdown/slug.js +7 -0
- package/dist/components/Markdown/slug.js.map +1 -0
- package/dist/components/NativeSelect/NativeSelect.d.ts +6 -0
- package/dist/components/NativeSelect/NativeSelect.js +2 -3
- package/dist/components/NativeSelect/NativeSelect.js.map +1 -1
- package/dist/components/NavItem/NavItem.js +1 -1
- package/dist/components/NavItem/NavItem.js.map +1 -1
- package/dist/components/NumberField/NumberField.d.ts +69 -0
- package/dist/components/NumberField/NumberField.js +162 -0
- package/dist/components/NumberField/NumberField.js.map +1 -0
- package/dist/components/Pagination/Pagination.d.ts +24 -1
- package/dist/components/Pagination/Pagination.js +6 -3
- package/dist/components/Pagination/Pagination.js.map +1 -1
- package/dist/components/Popover/Popover.js +1 -1
- package/dist/components/Popover/Popover.js.map +1 -1
- package/dist/components/Progress/Progress.d.ts +17 -5
- package/dist/components/Progress/Progress.js +18 -6
- package/dist/components/Progress/Progress.js.map +1 -1
- package/dist/components/RadioGroup/RadioGroup.d.ts +6 -0
- package/dist/components/RadioGroup/RadioGroup.js +11 -1
- package/dist/components/RadioGroup/RadioGroup.js.map +1 -1
- package/dist/components/ScrollArea/ScrollArea.d.ts +15 -0
- package/dist/components/ScrollArea/ScrollArea.js +2 -2
- package/dist/components/ScrollArea/ScrollArea.js.map +1 -1
- package/dist/components/SearchableMenu/SearchableMenu.d.ts +11 -2
- package/dist/components/SearchableMenu/SearchableMenu.js +24 -2
- package/dist/components/SearchableMenu/SearchableMenu.js.map +1 -1
- package/dist/components/Select/Select.d.ts +18 -2
- package/dist/components/Select/Select.js +21 -4
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Separator/Separator.d.ts +21 -3
- package/dist/components/Separator/Separator.js +9 -1
- package/dist/components/Separator/Separator.js.map +1 -1
- package/dist/components/Sheet/Sheet.d.ts +3 -0
- package/dist/components/Sheet/Sheet.js +12 -3
- package/dist/components/Sheet/Sheet.js.map +1 -1
- package/dist/components/Sidebar/Sidebar.d.ts +349 -0
- package/dist/components/Sidebar/Sidebar.js +455 -0
- package/dist/components/Sidebar/Sidebar.js.map +1 -0
- package/dist/components/Skeleton/Skeleton.d.ts +8 -1
- package/dist/components/Skeleton/Skeleton.js +1 -1
- package/dist/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/components/Slider/Slider.d.ts +42 -3
- package/dist/components/Slider/Slider.js +121 -30
- package/dist/components/Slider/Slider.js.map +1 -1
- package/dist/components/Spinner/Spinner.d.ts +8 -0
- package/dist/components/Spinner/Spinner.js +3 -2
- package/dist/components/Spinner/Spinner.js.map +1 -1
- package/dist/components/StatusPill/StatusPill.d.ts +5 -0
- package/dist/components/StatusPill/StatusPill.js +6 -0
- package/dist/components/StatusPill/StatusPill.js.map +1 -1
- package/dist/components/Table/Table.d.ts +20 -0
- package/dist/components/Table/Table.js +3 -1
- package/dist/components/Table/Table.js.map +1 -1
- package/dist/components/Tabs/Tabs.js +7 -1
- package/dist/components/Tabs/Tabs.js.map +1 -1
- package/dist/components/Tag/Tag.d.ts +68 -9
- package/dist/components/Tag/Tag.js +50 -10
- package/dist/components/Tag/Tag.js.map +1 -1
- package/dist/components/Text/Text.d.ts +62 -0
- package/dist/components/Text/Text.js +30 -0
- package/dist/components/Text/Text.js.map +1 -0
- package/dist/components/Timestamp/Timestamp.d.ts +59 -0
- package/dist/components/Timestamp/Timestamp.js +56 -0
- package/dist/components/Timestamp/Timestamp.js.map +1 -0
- package/dist/components/Toast/Toast.d.ts +9 -1
- package/dist/components/Toast/Toast.js +27 -4
- package/dist/components/Toast/Toast.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.d.ts +6 -1
- package/dist/components/ToggleGroup/ToggleGroup.js +11 -1
- package/dist/components/ToggleGroup/ToggleGroup.js.map +1 -1
- package/dist/components/Toolbar/Toolbar.d.ts +55 -0
- package/dist/components/Toolbar/Toolbar.js +43 -0
- package/dist/components/Toolbar/Toolbar.js.map +1 -0
- package/dist/diagrams/ArchitectureFigure/ArchitectureFigure.d.ts +6 -0
- package/dist/diagrams/ArchitectureFigure/ArchitectureFigure.js +48 -8
- package/dist/diagrams/ArchitectureFigure/ArchitectureFigure.js.map +1 -1
- package/dist/diagrams/DataflowFigure/DataflowFigure.js +21 -2
- package/dist/diagrams/DataflowFigure/DataflowFigure.js.map +1 -1
- package/dist/diagrams/DiagramCanvas/DiagramCanvas.d.ts +14 -0
- package/dist/diagrams/DiagramCanvas/DiagramCanvas.js +14 -7
- package/dist/diagrams/DiagramCanvas/DiagramCanvas.js.map +1 -1
- package/dist/diagrams/DiagramExportMenu/DiagramExportMenu.d.ts +38 -4
- package/dist/diagrams/DiagramExportMenu/DiagramExportMenu.js +14 -16
- package/dist/diagrams/DiagramExportMenu/DiagramExportMenu.js.map +1 -1
- package/dist/diagrams/DiagramInspector/DiagramInspector.js +2 -2
- package/dist/diagrams/DiagramInspector/DiagramInspector.js.map +1 -1
- package/dist/diagrams/DiagramMinimap/DiagramMinimap.d.ts +23 -7
- package/dist/diagrams/DiagramMinimap/DiagramMinimap.js +45 -18
- package/dist/diagrams/DiagramMinimap/DiagramMinimap.js.map +1 -1
- package/dist/diagrams/LifecycleFigure/LifecycleFigure.js +44 -12
- package/dist/diagrams/LifecycleFigure/LifecycleFigure.js.map +1 -1
- package/dist/diagrams/SequenceFigure/SequenceFigure.js +35 -5
- package/dist/diagrams/SequenceFigure/SequenceFigure.js.map +1 -1
- package/dist/diagrams/WorkflowFigure/WorkflowFigure.d.ts +3 -1
- package/dist/diagrams/WorkflowFigure/WorkflowFigure.js +76 -28
- package/dist/diagrams/WorkflowFigure/WorkflowFigure.js.map +1 -1
- package/dist/diagrams/index.d.ts +1 -0
- package/dist/diagrams/index.js +10 -0
- package/dist/diagrams/index.js.map +1 -1
- package/dist/diagrams/lib/dev.d.ts +61 -0
- package/dist/diagrams/lib/dev.js +96 -0
- package/dist/diagrams/lib/dev.js.map +1 -0
- package/dist/diagrams/lib/frame.d.ts +48 -7
- package/dist/diagrams/lib/frame.js +17 -2
- package/dist/diagrams/lib/frame.js.map +1 -1
- package/dist/diagrams/lib/route.d.ts +22 -1
- package/dist/diagrams/lib/route.js +24 -1
- package/dist/diagrams/lib/route.js.map +1 -1
- package/dist/diagrams/lib/wires.js +9 -5
- package/dist/diagrams/lib/wires.js.map +1 -1
- package/dist/diagrams/spec.d.ts +64 -12
- package/dist/index.d.ts +19 -4
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/keyframes.css +57 -3
- package/dist/lib/color.d.ts +80 -0
- package/dist/lib/color.js +189 -0
- package/dist/lib/color.js.map +1 -0
- package/dist/lib/numeric.d.ts +35 -0
- package/dist/lib/numeric.js +29 -0
- package/dist/lib/numeric.js.map +1 -0
- package/dist/lib/overlay-container.d.ts +14 -4
- package/dist/lib/overlay-container.js.map +1 -1
- package/dist/lib/warn.d.ts +73 -0
- package/dist/lib/warn.js +38 -0
- package/dist/lib/warn.js.map +1 -0
- package/dist/semantic.css +17 -6
- package/dist/styles.css +1 -1
- package/dist/themes.css +8 -0
- package/dist/tokens.css +86 -5
- package/dist/tokens.d.ts +4 -1
- package/dist/tokens.js +56 -36
- package/dist/tokens.json +56 -36
- package/llms.txt +35 -0
- package/package.json +5 -2
- package/skills/misoto22-design/evals/evals.json +84 -0
- package/skills/misoto22-design/rules/a11y.md +55 -3
- package/skills/misoto22-design/rules/forms.md +8 -1
package/dist/agent/Sheet.md
CHANGED
|
@@ -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.
|
|
7
|
+
- Version: 0.9.0
|
|
8
8
|
- Docs: https://ui.misoto22.com/components/sheet/
|
|
9
9
|
- Related: dialog, popover
|
|
10
10
|
|
|
@@ -12,6 +12,29 @@ A panel docked to an edge of the viewport.
|
|
|
12
12
|
|
|
13
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
14
|
|
|
15
|
+
## Anatomy
|
|
16
|
+
|
|
17
|
+
- **Scrim** (required) — The same --scrim at --z-overlay that Dialog uses — the same component, in fact, so the page behind is inert and scroll-locked exactly as it is under a dialog.
|
|
18
|
+
- **Panel** (required) — The docked box. start and end are a min(24rem, 92vw) column at full height; top and bottom are a full-width band capped at 85vh. A flex column that scrolls itself.
|
|
19
|
+
- **Title** (required) — title, typed as required rather than optional — there is no unnamed-sheet path to fall into, only a hidden-title one via hideTitle.
|
|
20
|
+
- **Description** — description, under the title, sharing the wrapper that hideTitle hides.
|
|
21
|
+
- **Close** (required) — The X in the top-end corner. Unlike Dialog there is no showClose to turn it off, so every sheet has one whichever edge it is docked to.
|
|
22
|
+
|
|
23
|
+
## Best practices
|
|
24
|
+
|
|
25
|
+
### Do
|
|
26
|
+
|
|
27
|
+
- Reach for a Sheet over a Dialog when the content is a list or a form long enough to scroll: it gets the full height of the viewport rather than Dialog’s 32rem by 85vh box, and the reader keeps the page edge as an anchor.
|
|
28
|
+
- Use top or bottom when the content is wide and short — a filter bar, a date range. start and end are a 24rem column, and a table pushed into one wraps into a ribbon.
|
|
29
|
+
- Name the sides start and end rather than reaching for left and right: each edge has its own literal class string carrying its own rtl: variant, so end arrives from the right in English and the left in Arabic with no second code path.
|
|
30
|
+
- Wrap the cancelling control in SheetClose so the close runs through Radix — a sheet closed by your own state setter leaves focus inside a panel that is no longer on the page.
|
|
31
|
+
|
|
32
|
+
### Don’t
|
|
33
|
+
|
|
34
|
+
- Do not re-declare the travel in className. The panel carries data-m22-animated, which removes its transform outright under reduced motion; a second transform of your own only gets the universal floor, so it still arrives — a hundredth of a millisecond later, from wherever you put it.
|
|
35
|
+
- An OverlayContainer whose element is not positioned docks the sheet to the wrong box: naming a container switches the panel from fixed to absolute, so an unpositioned container sends it to the nearest positioned ancestor rather than to the frame.
|
|
36
|
+
- It is a modal dialog, so the page behind is scroll-locked and pointer-inert: this is not the home for a filter panel the reader is meant to work alongside. That is a Popover, or a column in the layout.
|
|
37
|
+
|
|
15
38
|
## Accessibility
|
|
16
39
|
|
|
17
40
|
- 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.
|
|
@@ -32,7 +55,7 @@ Radix Dialog root, trigger and close — a sheet IS a dialog, docked.
|
|
|
32
55
|
|
|
33
56
|
## SheetContent
|
|
34
57
|
|
|
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.
|
|
58
|
+
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. Portals into the element an enclosing `OverlayContainer` names, docking to that element's edge rather than the viewport's when there is one.
|
|
36
59
|
|
|
37
60
|
### Props
|
|
38
61
|
|
|
@@ -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
|
+
```
|
package/dist/agent/Skeleton.md
CHANGED
|
@@ -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.
|
|
7
|
+
- Version: 0.9.0
|
|
8
8
|
- Docs: https://ui.misoto22.com/components/skeleton/
|
|
9
9
|
- Related: spinner, empty-state
|
|
10
10
|
|
|
@@ -12,6 +12,28 @@ The shape of the page, before the page.
|
|
|
12
12
|
|
|
13
13
|
A wait the reader would otherwise think was a broken page. A shape that describes what is coming beats a dot that describes nothing.
|
|
14
14
|
|
|
15
|
+
## Anatomy
|
|
16
|
+
|
|
17
|
+
- **Frame** (required) — SkeletonPage: the div carrying role="status", aria-busy="true" and the single pulse. It is the only part that speaks and the only part that moves — the shapes inside it do neither.
|
|
18
|
+
- **Label** (required) — The sr-only sentence inside the frame, from the required label prop. Every shape is aria-hidden, so this one sentence is the entire loading state for a screen reader.
|
|
19
|
+
- **Fill** — Skeleton itself: a --stone rectangle one line tall — h-3 — and, being a div, already full width. Height is the one dimension the element does not have on its own, so that is the one the base supplies; anything in className replaces it.
|
|
20
|
+
- **Line, Block and Circle** — The three presets over that fill. SkeletonLine is a 12px pill and takes its width from the caller, SkeletonBlock only sets --radius-sm, and SkeletonCircle is a fixed 36px round.
|
|
21
|
+
- **Paragraph** — SkeletonText: three lines by default, the last at 62% so it ends mid-measure the way prose does rather than squaring off into a table.
|
|
22
|
+
|
|
23
|
+
## Best practices
|
|
24
|
+
|
|
25
|
+
### Do
|
|
26
|
+
|
|
27
|
+
- Wrap the shapes in SkeletonPage even when there is only one bar. The role, the aria-busy and the pulse all live on the frame, so parts used loose are aria-hidden, silent and completely still — a grey rectangle that never resolves.
|
|
28
|
+
- Give every Skeleton the height of the thing it stands in for. The base falls back to one line, so a block left unsized is no longer invisible — it is a 12px bar where a 160px plate is about to land, and the page jumps by the difference.
|
|
29
|
+
- Make whatever replaces the skeleton announce itself or take focus. aria-busy never flips to false here — the frame is unmounted, not updated — so the end of the wait is the disappearance of the only thing that was speaking.
|
|
30
|
+
|
|
31
|
+
### Don’t
|
|
32
|
+
|
|
33
|
+
- Do not add animate-pulse to a part. The frame already animates opacity and a second ramp on a child multiplies with it, so the part beats at a rate the shape around it does not. Reduced motion is not the reason it is wrong: the rule in keyframes.css is a universal floor on animation-duration and transition-duration, so a hand-written Tailwind animation is clamped along with everything else. data-m22-animated is a component asserting its motion is decorative, not the mechanism that does the cancelling.
|
|
34
|
+
- Do not nest one SkeletonPage inside another. Each is a role="status" region with its own sr-only sentence, so a page assembled from two skeleton sections announces two loading messages and marks two regions busy for a single wait.
|
|
35
|
+
- Do not carry a skeleton between screens unedited. SkeletonCircle is 36px and SkeletonLine is 12px tall whatever they stand in for, so a copied avatar mount and a copied heading are two guaranteed reflows the moment the real content lands.
|
|
36
|
+
|
|
15
37
|
## Accessibility
|
|
16
38
|
|
|
17
39
|
- One live region on the wrapper; every shape inside it is aria-hidden.
|
|
@@ -19,7 +41,7 @@ A wait the reader would otherwise think was a broken page. A shape that describe
|
|
|
19
41
|
|
|
20
42
|
## Skeleton
|
|
21
43
|
|
|
22
|
-
The fill every skeleton part is drawn from: `--stone`,
|
|
44
|
+
The fill every skeleton part is drawn from: `--stone`, at the height of one line until something says otherwise. Deliberately NOT a shimmer. A shimmer sweeps a highlight across the shape, which implies a light source; the White Reset has none, so the sweep reads as a bug rather than as loading. The whole page breathes together instead — see `SkeletonPage`, which owns the single pulse. `h-3` is a default rather than a design. A `<div>` is already full width, so height was the one dimension a caller could omit and get nothing for — a bare `<Skeleton />` was a zero-height box, which is not a small skeleton but an absent one. Twelve pixels is the height `SkeletonLine` already chose, and any class the caller passes replaces it.
|
|
23
45
|
|
|
24
46
|
Also accepts: `HTMLAttributes<HTMLDivElement>`.
|
|
25
47
|
|
package/dist/agent/Slider.md
CHANGED
|
@@ -4,14 +4,39 @@ A value chosen along a range.
|
|
|
4
4
|
|
|
5
5
|
- Group: Forms
|
|
6
6
|
- Import: `import { Slider } from '@misoto22/design'`
|
|
7
|
-
- Version: 0.
|
|
7
|
+
- Version: 0.9.0
|
|
8
8
|
- Docs: https://ui.misoto22.com/components/slider/
|
|
9
9
|
- Related: progress
|
|
10
10
|
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
- **Track** (required) — A 1px rule in --stone that thickens to 1.5 when the pointer is anywhere over the control, not only over the thumb.
|
|
14
|
+
- **Range** — The --accent fill from the minimum to the thumb, or between the two thumbs of a range.
|
|
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
|
+
- **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.
|
|
18
|
+
|
|
19
|
+
## Best practices
|
|
20
|
+
|
|
21
|
+
### Do
|
|
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.
|
|
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”.
|
|
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.
|
|
26
|
+
|
|
27
|
+
### Don’t
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
34
|
+
|
|
11
35
|
## Accessibility
|
|
12
36
|
|
|
13
37
|
- label is required. A thumb that announces "42" and nothing else leaves a screen reader user with a number and no idea what it measures.
|
|
14
38
|
- A 44px hit area sits invisibly around the 16px thumb.
|
|
39
|
+
- format is announced as aria-valuetext, so a thumb showing “$1,200” says that rather than 1200.
|
|
15
40
|
- Arrows step, Page keys jump, Home and End reach the ends.
|
|
16
41
|
|
|
17
42
|
## Keyboard
|
|
@@ -22,13 +47,14 @@ A value chosen along a range.
|
|
|
22
47
|
|
|
23
48
|
## Slider
|
|
24
49
|
|
|
25
|
-
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.
|
|
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.
|
|
26
51
|
|
|
27
52
|
### Props
|
|
28
53
|
|
|
29
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.
|
|
30
|
-
- `showValue` — `boolean` default `false`. Prints the current value beside the label.
|
|
31
|
-
- `
|
|
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.
|
|
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.
|
|
32
58
|
|
|
33
59
|
Also accepts: `ComponentProps<typeof SliderPrimitive.Root>`.
|
|
34
60
|
|
|
@@ -36,4 +62,5 @@ Also accepts: `ComponentProps<typeof SliderPrimitive.Root>`.
|
|
|
36
62
|
|
|
37
63
|
```tsx
|
|
38
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}`} />
|
|
39
66
|
```
|
package/dist/agent/Sparkline.md
CHANGED
|
@@ -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.
|
|
7
|
+
- Version: 0.9.0
|
|
8
8
|
- Docs: https://ui.misoto22.com/components/sparkline/
|
|
9
9
|
- Related: line-chart, table
|
|
10
10
|
|
|
@@ -12,6 +12,28 @@ A run of numbers at the size of a word.
|
|
|
12
12
|
|
|
13
13
|
In a table cell, beside a figure, at the end of a row. When the trend needs reading precisely it wants a LineChart and its own space.
|
|
14
14
|
|
|
15
|
+
## Anatomy
|
|
16
|
+
|
|
17
|
+
- **Inline row** (required) — An inline-flex span, full width with 8px of gap, so the run sits in a table cell or beside a figure without breaking the line it is on.
|
|
18
|
+
- **Plot** (required) — One svg role="img" over a 0–100 by 0–100 viewBox with preserveAspectRatio="none", so it stretches to whatever width the container gives it. height, 28px by default, is the only fixed dimension.
|
|
19
|
+
- **Mark** (required) — The path, its area fill, or the bars — variant picks one. The stroke is drawn with non-scaling-stroke, which is what keeps the line the same weight in a narrow cell and a wide one after the box has been stretched to fit.
|
|
20
|
+
- **Last point** — A 2px dot on the final reading, from showLast, on the line and area variants. The bars variant carries the end of the run in its own last bar and draws no dot.
|
|
21
|
+
- **Printed value** — value, in mono tabular figures after the plot. It is also what the accessible name says after the label, and it is the only figure this component ever prints.
|
|
22
|
+
- **Too-short state** — What renders in place of the whole plot when fewer than two finite numbers survive: the label and “not enough data”, as one line of mono meta text.
|
|
23
|
+
|
|
24
|
+
## Best practices
|
|
25
|
+
|
|
26
|
+
### Do
|
|
27
|
+
|
|
28
|
+
- Pass value whenever a figure matters. The plot has no axis and no scale, so it carries shape and nothing else, and value is both the one number printed and the reading appended to the accessible name. Left out, that name falls back to the last point through toLocaleString — the raw number, without the unit, the currency or the rounding the row beside it uses.
|
|
29
|
+
- Pin domain across any two that will be read against each other. Each run is normalised into the same fixed box from its OWN min and max, so the highest point always touches the top edge and the lowest always the floor: a series moving between 4 and 6 and a series moving between 400 and 900 draw the same silhouette, and the difference between them is drawn nowhere.
|
|
30
|
+
- Downsample a long run before handing it over. The x step is 100 divided by one less than the number of points, spread across whatever width the cell has, so four hundred readings in a 200px cell land half a pixel apart and the path fills in as a band.
|
|
31
|
+
- Read a flat line through the middle as “unchanged”, not as “at its floor”. A run whose min equals its max has a scale with no width, so no position on it is truer than another and every point sits at the centre — the same answer Heatmap and BulletChart give a zero span, and the one that keeps “unchanged” and “pinned at its worst” apart in a column of them.
|
|
32
|
+
|
|
33
|
+
### Don’t
|
|
34
|
+
|
|
35
|
+
- Do not assume something chart-shaped always renders. Non-finite entries are filtered out first, and anything left under two points returns a line of text instead of an SVG, so the new account’s row is a sentence where every other row in the column is a chart.
|
|
36
|
+
|
|
15
37
|
## Accessibility
|
|
16
38
|
|
|
17
39
|
- label is required and is the whole accessible name: a sparkline has no axes and no legend, so nothing else describes it.
|
package/dist/agent/Spinner.md
CHANGED
|
@@ -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.
|
|
7
|
+
- Version: 0.9.0
|
|
8
8
|
- Docs: https://ui.misoto22.com/components/spinner/
|
|
9
9
|
- Related: skeleton, progress
|
|
10
10
|
|
|
@@ -12,6 +12,27 @@ The one “working” indicator — a ring, never a shimmer.
|
|
|
12
12
|
|
|
13
13
|
A wait short enough that the shape of what is coming does not matter. Longer than that, use a Skeleton.
|
|
14
14
|
|
|
15
|
+
## Anatomy
|
|
16
|
+
|
|
17
|
+
- **Live region** (required) — The outer span, and the only part with a voice. It carries role="status" while there is a label; pass label={null} and it turns into an aria-hidden box with no role at all.
|
|
18
|
+
- **Ring** (required) — The inner span — 14px, 18px or 26px of border on a transparent box, and the only element size, tone and className reach.
|
|
19
|
+
- **Leading quarter** (required) — border-t, drawn in --ink at the default tone and in the inherited colour at current. It is the whole difference between a ring and a plain circle, which is why a still ring still reads as unfinished.
|
|
20
|
+
- **Screen-reader label** — An sr-only span holding label, present unless label is null. Announced once, when the spinner mounts, and never again.
|
|
21
|
+
|
|
22
|
+
## Best practices
|
|
23
|
+
|
|
24
|
+
### Do
|
|
25
|
+
|
|
26
|
+
- Pass tone="current" for a spinner on any filled ground: the default draws the leading quarter in --ink over a --rule-2 track, and inside a primary Button both of those are the ground it is sitting on.
|
|
27
|
+
- Announce the arrival somewhere else. The label is read once on mount and nothing is said on the way out, so a reader who heard “Loading projects” is never told the projects came.
|
|
28
|
+
- Reach for label={null} only inside a control that already names the operation — it hides the whole element from assistive tech rather than merely dropping the text, so a silenced spinner standing on its own is a wait nobody is told about.
|
|
29
|
+
|
|
30
|
+
### Don’t
|
|
31
|
+
|
|
32
|
+
- label defaults to the bare word “Loading”, so a Spinner written without the prop ships the exact announcement the prop exists to prevent — the default is a placeholder, not a value.
|
|
33
|
+
- className is merged onto the ring AFTER size and tone, so it beats both: <Spinner size="lg" className="size-4" /> is a 16px ring, and the prop whose whole job was naming the size is the one that lost.
|
|
34
|
+
- Nothing here sets aria-busy — Button does that for its own control — so a spinner laid over a panel leaves the panel announced as ready while its contents are stale and its buttons still take clicks.
|
|
35
|
+
|
|
15
36
|
## Accessibility
|
|
16
37
|
|
|
17
38
|
- label names the specific thing being waited on; three spinners all saying “Loading” tell a screen reader nothing.
|
|
@@ -20,12 +41,13 @@ A wait short enough that the shape of what is coming does not matter. Longer tha
|
|
|
20
41
|
|
|
21
42
|
## Spinner
|
|
22
43
|
|
|
23
|
-
The system's one "working" indicator. A ring, not a blurred glow and not a shimmer: the White Reset has no light source, so depth and softness are not available to it. The leading quarter is the only thing that distinguishes the ring from a plain circle, which is why the track stays a hairline — a spinner is a hint that time is passing, not a feature of the page. It spins under `motion-safe` only. A reader who has asked for less motion gets a static ring, which still reads as "not finished" because the leading quarter is darker than the track. For a wait long enough that the reader would otherwise wonder whether the page is broken, prefer `Skeleton` — a shape that describes what is coming beats a dot that describes nothing.
|
|
44
|
+
The system's one "working" indicator. A ring, not a blurred glow and not a shimmer: the White Reset has no light source, so depth and softness are not available to it. The leading quarter is the only thing that distinguishes the ring from a plain circle, which is why the track stays a hairline — a spinner is a hint that time is passing, not a feature of the page. It spins under `motion-safe` only. A reader who has asked for less motion gets a static ring, which still reads as "not finished" because the leading quarter is darker than the track. For a wait long enough that the reader would otherwise wonder whether the page is broken, prefer `Skeleton` — a shape that describes what is coming beats a dot that describes nothing. `className` reaches the RING, alongside `size` and `tone`, and overrides them: every utility a caller has for a spinner is about the ring, and merged onto the wrapper instead `className="size-8"` grew an invisible box around an unchanged 18px circle. Layout still works from there — the wrapper is `inline-flex` and takes the ring's margin box as its own.
|
|
24
45
|
|
|
25
46
|
### Props
|
|
26
47
|
|
|
27
48
|
- `size` — `'sm' | 'md' | 'lg'` default `'md'`. 14px / 18px / 26px. Match the size of the type it sits beside.
|
|
28
49
|
- `tone` — `'default' | 'current'` default `'default'`. `default` draws the ring against the page — a hairline track in the rule colour with the leading quarter in ink. `current` draws it in the inherited text colour, which is what a spinner inside a filled button needs: on an ink ground an ink ring is invisible.
|
|
50
|
+
- `className` — `string`. Merged onto the RING, after `size` and `tone`, so it overrides both.
|
|
29
51
|
- `label` — `string | null` default `'Loading'`. Announced to assistive tech. Pass the specific thing being waited on ("Loading projects"), not the generic word — a screen reader user hearing "Loading" three times cannot tell which three things. Pass `null` for a spinner that sits inside a control which already names the operation (a button whose own label changes to "Saving…"), so the two are not read out twice.
|
|
30
52
|
|
|
31
53
|
Also accepts: `HTMLAttributes<HTMLSpanElement>`.
|
package/dist/agent/StatusDot.md
CHANGED
|
@@ -4,10 +4,29 @@ The dot beside a status word.
|
|
|
4
4
|
|
|
5
5
|
- Group: Display
|
|
6
6
|
- Import: `import { StatusDot } from '@misoto22/design'`
|
|
7
|
-
- Version: 0.
|
|
7
|
+
- Version: 0.9.0
|
|
8
8
|
- Docs: https://ui.misoto22.com/components/status-dot/
|
|
9
9
|
- Related: status-pill
|
|
10
10
|
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
- **Box** (required) — The aria-hidden <span> the whole thing lives in — 8px square at md, 7px at sm, inline-grid and shrink-0 so it stays circular in a flex row however long the label beside it runs.
|
|
14
|
+
- **Dot** (required) — An absolutely-positioned filled circle in --ok, --warn, --danger or --ink-3-aa. It is the only part of this component tone touches.
|
|
15
|
+
- **Halo** — A second ring of the same colour on the m22-halo keyframes, present only while pulse is true. A separate element rather than a box-shadow, because a shadow in this system is never blurred.
|
|
16
|
+
|
|
17
|
+
## Best practices
|
|
18
|
+
|
|
19
|
+
### Do
|
|
20
|
+
|
|
21
|
+
- Set pulse={false} for anything settled. It defaults to true, so a dot for a build that finished or a status that will not change today carries a halo announcing that something is happening right now.
|
|
22
|
+
- Reach for StatusPill the moment you find yourself writing the dot and its label together — that pairing assembled per call site is how one site ended up with three dot sizes and two pulse timings for the same state.
|
|
23
|
+
- Let it sit directly in the flex row beside its label: shrink-0 is what keeps it round, and a dot wrapped in a div that can shrink comes out an ellipse as soon as the label runs long.
|
|
24
|
+
|
|
25
|
+
### Don’t
|
|
26
|
+
|
|
27
|
+
- An aria-label on the dot buys nothing — aria-hidden is still set, and a hidden element has no name to give. A call site with no visible label is a state no screen reader ever reports.
|
|
28
|
+
- sm and md are 7px and 8px, one pixel apart. That is an optical adjustment for sitting beside smaller type, not a size scale, and nothing in a layout should be built on the difference.
|
|
29
|
+
|
|
11
30
|
## Accessibility
|
|
12
31
|
|
|
13
32
|
- aria-hidden without exception: it repeats a state the adjacent label already names.
|
package/dist/agent/StatusPill.md
CHANGED
|
@@ -4,13 +4,39 @@ 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.
|
|
7
|
+
- Version: 0.9.0
|
|
8
8
|
- Docs: https://ui.misoto22.com/components/status-pill/
|
|
9
9
|
- Related: status-dot, badge
|
|
10
10
|
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
- **Pill** (required) — The outlined <span>: --radius-pill, a --rule-2 hairline, --paper ground, and deliberately uneven padding — 10px before the dot, 12px after the label — so the pair sits optically centred rather than mathematically.
|
|
14
|
+
- **Dot** (required) — A StatusDot handed tone and pulse. It is aria-hidden, so it is not where the tone reaches a reader who cannot see it.
|
|
15
|
+
- **Label** (required) — children in the eyebrow idiom — 11px uppercase mono, tracking pulled back from 0.2em to 0.12em because a pill is a shorter run than a section kicker.
|
|
16
|
+
- **Severity** — A visually-hidden “Warning” or “Error” at the warning and danger tones, so those two reach a reader through something other than a colour on a hidden dot. success and neutral add nothing: they are the absence of alarm, which is what a reader already assumes.
|
|
17
|
+
|
|
18
|
+
## Best practices
|
|
19
|
+
|
|
20
|
+
### Do
|
|
21
|
+
|
|
22
|
+
- Put the state in the words anyway. The severity word reaches a screen reader and nothing else — the pill’s own text is --ink-2 at every tone, so on a monochrome screen “Degraded” in a warning pill and in a neutral one are still the same pill.
|
|
23
|
+
- Set pulse={false} once the state has settled — the default halo means “right now”, and an archived or shipped pill pulsing forever tells the reader something is live when nothing is.
|
|
24
|
+
- Take the whole pill rather than composing a dot and a span at the call site: that assembly is how the same “available for work” chip came out at three dot sizes and two pulse timings on one site.
|
|
25
|
+
|
|
26
|
+
### Don’t
|
|
27
|
+
|
|
28
|
+
- It is not a live region. The pill is a plain <span>, so a state flipping from Available to Degraded while the reader is on the page changes silently — if the change is the news, the call site owns the role="status" around it.
|
|
29
|
+
- One per view, not one per row. The label is an uppercase eyebrow at 0.12em tracking — the loudest small type the system has — and a column of them down a table is Badge’s job, which is why Badge carries the same status tones in plain 12px mono.
|
|
30
|
+
|
|
31
|
+
## Accessibility
|
|
32
|
+
|
|
33
|
+
- The warning and danger tones are doubled by a visually-hidden severity word, because the dot that carries the colour is aria-hidden and has no name to give.
|
|
34
|
+
- success and neutral are silent on purpose: announcing “OK” before every settled pill is noise charged to the two tones worth interrupting for.
|
|
35
|
+
- Not a live region. A state that flips while the reader is on the page changes silently unless the call site owns a role="status" around it.
|
|
36
|
+
|
|
11
37
|
## StatusPill
|
|
12
38
|
|
|
13
|
-
A live state, named: a dot plus an uppercase mono label in an outlined pill. One component rather than a dot and a pill assembled per call site, which is how the same "available for work" chip ended up with three different dot sizes and two different pulse timings on one site.
|
|
39
|
+
A live state, named: a dot plus an uppercase mono label in an outlined pill. One component rather than a dot and a pill assembled per call site, which is how the same "available for work" chip ended up with three different dot sizes and two different pulse timings on one site. A warning or danger tone is doubled by a visually-hidden severity word, so the tone survives the dot being hidden. It does not survive monochrome: the pill's own text is `--ink-2` at every tone, and the state itself still belongs in the words the call site writes.
|
|
14
40
|
|
|
15
41
|
### Props
|
|
16
42
|
|
package/dist/agent/Steps.md
CHANGED
|
@@ -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.
|
|
7
|
+
- Version: 0.9.0
|
|
8
8
|
- Docs: https://ui.misoto22.com/components/steps/
|
|
9
9
|
- Related: diagram, article
|
|
10
10
|
|
|
@@ -12,6 +12,29 @@ A numbered sequence, as a rail — one thing after another, with a rule through
|
|
|
12
12
|
|
|
13
13
|
A pipeline, a migration, a recipe: an order with no branches. The moment something forks or points at something else it is a Diagram, and drawing a fork as a list hides it.
|
|
14
14
|
|
|
15
|
+
## Anatomy
|
|
16
|
+
|
|
17
|
+
- **Rail** (required) — The <ol>, carrying --step-size — one number that three rules read: the marker’s own box, where the connector starts, and where it is centred.
|
|
18
|
+
- **Marker** (required) — A 2rem circle per step, aria-hidden: the position number, or a blank hairline node when marker is "rule". Filled with --accent for the current one.
|
|
19
|
+
- **Connector** — A hairline drawn on every item but the last, placed absolutely from the foot of that marker to the foot of its row — so it spans the gap rather than running behind the markers, and no tail hangs off the end of the sequence.
|
|
20
|
+
- **Title** (required) — step.title, at 15px in the interface face. The step’s name — a noun, not a description of what happens in it.
|
|
21
|
+
- **Note** — step.note, a mono line under the title: what the step is made of, what it costs, what it uses.
|
|
22
|
+
|
|
23
|
+
## Best practices
|
|
24
|
+
|
|
25
|
+
### Do
|
|
26
|
+
|
|
27
|
+
- Use marker="rule" for a sequence of states. “Queued, running, done” is an order rather than an instruction list, and a digit in front of each one tells the reader they are steps to perform.
|
|
28
|
+
- Mark at most one step current: it is the one thing the rail states rather than draws, and two filled markers put the process in two places at once.
|
|
29
|
+
- Pass label when no heading names the sequence — it is the list’s only name, so without it the rail is announced as five items belonging to nothing.
|
|
30
|
+
- Retune the rail through --step-size on the list rather than by restyling the marker: the marker box, the connector’s start and its centring all read that one number, and moving one of the three leaves the line beginning in mid-air.
|
|
31
|
+
|
|
32
|
+
### Don’t
|
|
33
|
+
|
|
34
|
+
- A fork drawn here is a fork the reader never sees. The connector runs from each step to the next one in the array and to nothing else, so two branches flatten into four consecutive steps and the choice between them leaves the figure entirely.
|
|
35
|
+
- steps={[]} renders null rather than an empty rail, so a list filtered down to nothing leaves a heading standing over a gap unless the call site checks the length itself.
|
|
36
|
+
- Nothing here is clickable and the props spread onto the <ol>, so an onClick meant for a step lands on the whole list. A sequence the reader is meant to move through is a Breadcrumb or a Tabs.
|
|
37
|
+
|
|
15
38
|
## Accessibility
|
|
16
39
|
|
|
17
40
|
- An <ol>, because the order IS the content — a stack of divs says nothing about sequence.
|
package/dist/agent/Switch.md
CHANGED
|
@@ -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.
|
|
7
|
+
- Version: 0.9.0
|
|
8
8
|
- Docs: https://ui.misoto22.com/components/switch/
|
|
9
9
|
- Related: checkbox
|
|
10
10
|
|
|
@@ -12,6 +12,26 @@ A setting that takes effect immediately.
|
|
|
12
12
|
|
|
13
13
|
Inside a form with a Save button, a switch is a lie about when the change happened. Use a Checkbox.
|
|
14
14
|
|
|
15
|
+
## Anatomy
|
|
16
|
+
|
|
17
|
+
- **Track** (required) — A 36×20 <button role="switch"> on a pill radius, filled --stone when off and --accent when on. Filled rather than outlined, so it still reads as a control on a white page.
|
|
18
|
+
- **Thumb** (required) — A 14px paper circle with a hairline, not a white disc on a shadow — this system has no shadows. It stretches to 20px while pressed and rounds out as it lands; motion-reduce drops that entirely.
|
|
19
|
+
- **Label** — Not rendered here either. The Radix root IS a <button>, though, which a <label for> does bind to — so unlike Select or RadioGroup, a Field’s label above a Switch really does click through to it.
|
|
20
|
+
|
|
21
|
+
## Best practices
|
|
22
|
+
|
|
23
|
+
### Do
|
|
24
|
+
|
|
25
|
+
- Handle the failure at the control. The flip has already claimed the change happened, so an onCheckedChange whose request fails must put the thumb back and say why, or the page is showing a setting the server does not have.
|
|
26
|
+
- Name it for the state, not the action: the accessible name is read together with “on” or “off”, so “Email notifications, on” is a sentence and “Turn on email notifications, on” is two contradictory ones.
|
|
27
|
+
- Keep the flip instant to the eye even when the write is not — an optimistic thumb with a quiet undo beats a spinner on a control whose whole claim is that it already took effect.
|
|
28
|
+
|
|
29
|
+
### Don’t
|
|
30
|
+
|
|
31
|
+
- A switch has two states and no third. “Inherit from the workspace” cannot be a switch, because the only way to draw it is unchecked, which announces “off” — that is a RadioGroup or a Select.
|
|
32
|
+
- There is no readOnly: disabled is the only lock, and it takes the control out of the tab order, so a keyboard reader tabbing the form passes the setting without ever hearing its value.
|
|
33
|
+
- Do not add transition-all from a call site. It replaces transition-[transform,width] wholesale, which puts the track’s colour on the thumb’s longer duration and turns a flip into a fade.
|
|
34
|
+
|
|
15
35
|
## Keyboard
|
|
16
36
|
|
|
17
37
|
- Space / Enter — Toggles it, and the change applies immediately.
|