@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
|
@@ -3,6 +3,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
4
4
|
import { X } from "lucide-react";
|
|
5
5
|
import { cn } from "../../lib/cn.js";
|
|
6
|
+
import { useOverlayContainer } from "../../lib/overlay-container.js";
|
|
7
|
+
import { DEV, warn } from "../../lib/warn.js";
|
|
6
8
|
const Dialog = DialogPrimitive.Root;
|
|
7
9
|
const DialogTrigger = DialogPrimitive.Trigger;
|
|
8
10
|
const DialogClose = DialogPrimitive.Close;
|
|
@@ -26,12 +28,25 @@ function DialogContent({
|
|
|
26
28
|
hideTitle = false,
|
|
27
29
|
...rest
|
|
28
30
|
}) {
|
|
29
|
-
|
|
31
|
+
const container = useOverlayContainer();
|
|
32
|
+
if (DEV && title === void 0) {
|
|
33
|
+
warn({
|
|
34
|
+
code: "DIALOG_TITLE_MISSING",
|
|
35
|
+
problem: 'DialogContent has no title, so its accessible name is the fallback string "Dialog". Every unnamed modal in the app announces identically, and the check that would have caught it passes.',
|
|
36
|
+
field: "title",
|
|
37
|
+
fix: "Give it a title that says what the dialog asks. Add hideTitle when the heading would be furniture on screen.",
|
|
38
|
+
component: "Dialog"
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { container: container ?? void 0, children: [
|
|
30
42
|
/* @__PURE__ */ jsx(
|
|
31
43
|
DialogPrimitive.Overlay,
|
|
32
44
|
{
|
|
33
45
|
"data-m22-animated": true,
|
|
34
|
-
className:
|
|
46
|
+
className: cn(
|
|
47
|
+
"inset-0 z-(--z-overlay) bg-(--scrim) data-[state=open]:animate-[m22-fade-in_var(--duration-fast)_var(--ease)]",
|
|
48
|
+
container ? "absolute" : "fixed"
|
|
49
|
+
)
|
|
35
50
|
}
|
|
36
51
|
),
|
|
37
52
|
/* @__PURE__ */ jsxs(
|
|
@@ -39,8 +54,11 @@ function DialogContent({
|
|
|
39
54
|
{
|
|
40
55
|
"data-m22-animated": true,
|
|
41
56
|
className: cn(
|
|
42
|
-
"fixed left-1/2 top-1/2 z-(--z-modal) max-h-[85vh] w-[min(92vw,32rem)] -translate-x-1/2 -translate-y-1/2 overflow-auto rounded-(--radius-lg) border border-(--panel-border) bg-(--panel-bg) p-6 panel-blur scroll-slim",
|
|
57
|
+
"fixed left-1/2 top-1/2 z-(--z-modal) max-h-[85vh] w-[min(92vw,32rem)] -translate-x-1/2 -translate-y-1/2 overflow-auto rounded-(--radius-lg) border border-(--panel-border) bg-(--panel-bg) p-6 shadow-(--panel-lift) panel-blur scroll-slim",
|
|
43
58
|
"data-[state=open]:animate-[m22-panel-in_var(--duration-base)_var(--ease)]",
|
|
59
|
+
// Against the container's box rather than the viewport's, and capped
|
|
60
|
+
// by it: 92vw inside a 400px frame is not a cap at all.
|
|
61
|
+
container && "absolute max-h-[calc(100%-2rem)] max-w-[calc(100%-2rem)]",
|
|
44
62
|
className
|
|
45
63
|
),
|
|
46
64
|
...rest,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Dialog/Dialog.tsx"],"sourcesContent":["'use client'\n\nimport * as DialogPrimitive from '@radix-ui/react-dialog'\nimport { X } from 'lucide-react'\nimport type { ComponentProps, ReactNode } from 'react'\nimport { cn } from '../../lib/cn'\n\n/** Radix Dialog root + trigger + close, re-exported as typed passthroughs. */\nexport const Dialog = DialogPrimitive.Root\nexport const DialogTrigger = DialogPrimitive.Trigger\nexport const DialogClose = DialogPrimitive.Close\n\n/** Title + description stack; renders nothing when both are omitted. */\nfunction DialogHeader({\n title,\n description,\n hidden,\n}: {\n title?: ReactNode\n description?: ReactNode\n hidden: boolean\n}) {\n if (title === undefined && description === undefined) return null\n return (\n <div className={cn('mb-4 flex flex-col gap-1 pe-8', hidden && 'sr-only')}>\n {title !== undefined && (\n <DialogPrimitive.Title className=\"m-0 font-heading text-[length:var(--fs-item)] font-normal text-(--ink)\">\n {title}\n </DialogPrimitive.Title>\n )}\n {description !== undefined && (\n <DialogPrimitive.Description className=\"m-0 text-sm leading-relaxed text-(--ink-3-aa)\">\n {description}\n </DialogPrimitive.Description>\n )}\n </div>\n )\n}\n\nexport interface DialogContentProps\n extends Omit<ComponentProps<typeof DialogPrimitive.Content>, 'title' | 'className'> {\n
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Dialog/Dialog.tsx"],"sourcesContent":["'use client'\n\nimport * as DialogPrimitive from '@radix-ui/react-dialog'\nimport { X } from 'lucide-react'\nimport type { ComponentProps, ReactNode } from 'react'\nimport { cn } from '../../lib/cn'\nimport { useOverlayContainer } from '../../lib/overlay-container'\nimport { DEV, warn } from '../../lib/warn'\n\n/** Radix Dialog root + trigger + close, re-exported as typed passthroughs. */\nexport const Dialog = DialogPrimitive.Root\nexport const DialogTrigger = DialogPrimitive.Trigger\nexport const DialogClose = DialogPrimitive.Close\n\n/** Title + description stack; renders nothing when both are omitted. */\nfunction DialogHeader({\n title,\n description,\n hidden,\n}: {\n title?: ReactNode\n description?: ReactNode\n hidden: boolean\n}) {\n if (title === undefined && description === undefined) return null\n return (\n <div className={cn('mb-4 flex flex-col gap-1 pe-8', hidden && 'sr-only')}>\n {title !== undefined && (\n <DialogPrimitive.Title className=\"m-0 font-heading text-[length:var(--fs-item)] font-normal text-(--ink)\">\n {title}\n </DialogPrimitive.Title>\n )}\n {description !== undefined && (\n <DialogPrimitive.Description className=\"m-0 text-sm leading-relaxed text-(--ink-3-aa)\">\n {description}\n </DialogPrimitive.Description>\n )}\n </div>\n )\n}\n\nexport interface DialogContentProps\n extends Omit<ComponentProps<typeof DialogPrimitive.Content>, 'title' | 'className'> {\n /**\n * Heading text.\n *\n * Pass one even when `hideTitle` is set. Radix requires a title, so omitting\n * it renders a hidden fallback reading the literal word \"Dialog\" — which\n * satisfies an automated accessibility check and announces every unnamed\n * modal in the application as the same thing. Development says so out loud.\n */\n title?: ReactNode\n /** Sub-heading under the title. */\n description?: ReactNode\n className?: string\n /** Show the top-right close control (default true). */\n showClose?: boolean\n /**\n * Keeps the title for assistive tech and hides it visually.\n *\n * For a surface whose purpose is obvious to anyone who can see it — a command\n * palette, a media lightbox — where a printed heading would be furniture. The\n * title itself is never optional: Radix requires one, and a modal with no\n * accessible name drops a screen reader into an unnamed region.\n */\n hideTitle?: boolean\n}\n\n/**\n * A modal surface: portal → scrim → centred panel.\n *\n * Radix owns the focus trap, the escape key, the scroll lock and the\n * `aria-modal` wiring — all of which a hand-rolled dialog gets subtly wrong,\n * usually by leaving focus behind in the page underneath.\n *\n * Radix requires a `Dialog.Title` whether or not one is shown, so a dialog\n * without a visible heading still renders a hidden one rather than shipping an\n * unnamed modal — and warns in development, because the fallback it renders is\n * the literal word \"Dialog\" and a placeholder that passes an accessibility\n * check is how the problem survives a review.\n *\n * Portals into the element an enclosing `OverlayContainer` names, and switches\n * from viewport positioning to container positioning when there is one. A\n * `fixed` panel covers the page whatever it is portalled into, so honouring\n * the container without that swap would have moved the markup and left the\n * picture unchanged.\n *\n * @example\n * <Dialog>\n * <DialogTrigger asChild><Button>Delete</Button></DialogTrigger>\n * <DialogContent title=\"Delete file\" description=\"This cannot be undone.\">\n * <DialogClose asChild><Button variant=\"secondary\">Cancel</Button></DialogClose>\n * </DialogContent>\n * </Dialog>\n */\nexport function DialogContent({\n title,\n description,\n children,\n className,\n showClose = true,\n hideTitle = false,\n ...rest\n}: DialogContentProps) {\n const container = useOverlayContainer()\n\n if (DEV && title === undefined) {\n warn({\n code: 'DIALOG_TITLE_MISSING',\n problem:\n 'DialogContent has no title, so its accessible name is the fallback string \"Dialog\". Every unnamed modal in the app announces identically, and the check that would have caught it passes.',\n field: 'title',\n fix: 'Give it a title that says what the dialog asks. Add hideTitle when the heading would be furniture on screen.',\n component: 'Dialog',\n })\n }\n\n return (\n <DialogPrimitive.Portal container={container ?? undefined}>\n <DialogPrimitive.Overlay\n data-m22-animated\n className={cn(\n 'inset-0 z-(--z-overlay) bg-(--scrim) data-[state=open]:animate-[m22-fade-in_var(--duration-fast)_var(--ease)]',\n container ? 'absolute' : 'fixed',\n )}\n />\n <DialogPrimitive.Content\n data-m22-animated\n className={cn(\n 'fixed left-1/2 top-1/2 z-(--z-modal) max-h-[85vh] w-[min(92vw,32rem)] -translate-x-1/2 -translate-y-1/2 overflow-auto rounded-(--radius-lg) border border-(--panel-border) bg-(--panel-bg) p-6 shadow-(--panel-lift) panel-blur scroll-slim',\n 'data-[state=open]:animate-[m22-panel-in_var(--duration-base)_var(--ease)]',\n // Against the container's box rather than the viewport's, and capped\n // by it: 92vw inside a 400px frame is not a cap at all.\n container && 'absolute max-h-[calc(100%-2rem)] max-w-[calc(100%-2rem)]',\n className,\n )}\n {...rest}\n >\n <DialogHeader title={title} description={description} hidden={hideTitle} />\n\n {title === undefined && (\n <DialogPrimitive.Title className=\"sr-only\">Dialog</DialogPrimitive.Title>\n )}\n\n {showClose && (\n <DialogPrimitive.Close\n aria-label=\"Close\"\n className=\"absolute end-3 top-3 grid size-9 place-items-center rounded-(--radius-pill) text-(--ink-3-aa) transition-colors duration-(--duration-fast) hover:bg-(--stone) hover:text-(--ink)\"\n >\n <X size={16} strokeWidth={1.5} aria-hidden />\n </DialogPrimitive.Close>\n )}\n\n {children}\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n )\n}\n\nexport default Dialog\n"],"mappings":";AA0BI,SAEI,KAFJ;AAxBJ,YAAY,qBAAqB;AACjC,SAAS,SAAS;AAElB,SAAS,UAAU;AACnB,SAAS,2BAA2B;AACpC,SAAS,KAAK,YAAY;AAGnB,MAAM,SAAS,gBAAgB;AAC/B,MAAM,gBAAgB,gBAAgB;AACtC,MAAM,cAAc,gBAAgB;AAG3C,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,MAAI,UAAU,UAAa,gBAAgB,OAAW,QAAO;AAC7D,SACE,qBAAC,SAAI,WAAW,GAAG,iCAAiC,UAAU,SAAS,GACpE;AAAA,cAAU,UACT,oBAAC,gBAAgB,OAAhB,EAAsB,WAAU,0EAC9B,iBACH;AAAA,IAED,gBAAgB,UACf,oBAAC,gBAAgB,aAAhB,EAA4B,WAAU,iDACpC,uBACH;AAAA,KAEJ;AAEJ;AAwDO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,GAAG;AACL,GAAuB;AACrB,QAAM,YAAY,oBAAoB;AAEtC,MAAI,OAAO,UAAU,QAAW;AAC9B,SAAK;AAAA,MACH,MAAM;AAAA,MACN,SACE;AAAA,MACF,OAAO;AAAA,MACP,KAAK;AAAA,MACL,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SACE,qBAAC,gBAAgB,QAAhB,EAAuB,WAAW,aAAa,QAC9C;AAAA;AAAA,MAAC,gBAAgB;AAAA,MAAhB;AAAA,QACC,qBAAiB;AAAA,QACjB,WAAW;AAAA,UACT;AAAA,UACA,YAAY,aAAa;AAAA,QAC3B;AAAA;AAAA,IACF;AAAA,IACA;AAAA,MAAC,gBAAgB;AAAA,MAAhB;AAAA,QACC,qBAAiB;AAAA,QACjB,WAAW;AAAA,UACT;AAAA,UACA;AAAA;AAAA;AAAA,UAGA,aAAa;AAAA,UACb;AAAA,QACF;AAAA,QACC,GAAG;AAAA,QAEJ;AAAA,8BAAC,gBAAa,OAAc,aAA0B,QAAQ,WAAW;AAAA,UAExE,UAAU,UACT,oBAAC,gBAAgB,OAAhB,EAAsB,WAAU,WAAU,oBAAM;AAAA,UAGlD,aACC;AAAA,YAAC,gBAAgB;AAAA,YAAhB;AAAA,cACC,cAAW;AAAA,cACX,WAAU;AAAA,cAEV,8BAAC,KAAE,MAAM,IAAI,aAAa,KAAK,eAAW,MAAC;AAAA;AAAA,UAC7C;AAAA,UAGD;AAAA;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;AAEA,IAAO,iBAAQ;","names":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ComponentProps } from 'react';
|
|
2
|
+
import { ComponentProps, ReactNode } from 'react';
|
|
3
3
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
4
4
|
import { LucideIcon } from 'lucide-react';
|
|
5
5
|
|
|
@@ -11,16 +11,17 @@ type DropdownMenuContentProps = ComponentProps<typeof DropdownMenuPrimitive.Cont
|
|
|
11
11
|
* A menu surface.
|
|
12
12
|
*
|
|
13
13
|
* A menu is a list of ACTIONS. If the items navigate somewhere, they belong in
|
|
14
|
-
* a nav; if they set a value, that is a `Select` or a `RadioGroup` —
|
|
15
|
-
*
|
|
16
|
-
* checked state a screen reader needs.
|
|
14
|
+
* a nav; if they set a value, that is a `Select` or a `RadioGroup` — this
|
|
15
|
+
* package ships no checkbox or radio menu item, and a plain item pretending to
|
|
16
|
+
* be a choice loses the checked state a screen reader needs.
|
|
17
17
|
*
|
|
18
18
|
* @example
|
|
19
19
|
* <DropdownMenu>
|
|
20
20
|
* <DropdownMenuTrigger asChild><Button variant="secondary">Menu</Button></DropdownMenuTrigger>
|
|
21
21
|
* <DropdownMenuContent>
|
|
22
|
-
* <
|
|
23
|
-
*
|
|
22
|
+
* <DropdownMenuGroup label="Account">
|
|
23
|
+
* <DropdownMenuItem icon={Settings}>Settings</DropdownMenuItem>
|
|
24
|
+
* </DropdownMenuGroup>
|
|
24
25
|
* <DropdownMenuSeparator />
|
|
25
26
|
* <DropdownMenuItem icon={LogOut}>Sign out</DropdownMenuItem>
|
|
26
27
|
* </DropdownMenuContent>
|
|
@@ -28,8 +29,16 @@ type DropdownMenuContentProps = ComponentProps<typeof DropdownMenuPrimitive.Cont
|
|
|
28
29
|
*/
|
|
29
30
|
declare function DropdownMenuContent({ className, sideOffset, children, ...rest }: DropdownMenuContentProps): react.JSX.Element;
|
|
30
31
|
interface DropdownMenuItemProps extends ComponentProps<typeof DropdownMenuPrimitive.Item> {
|
|
31
|
-
/**
|
|
32
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Optional leading icon, rendered before the label.
|
|
34
|
+
*
|
|
35
|
+
* Either spelling: `icon={Settings}` passes the component and this sizes it,
|
|
36
|
+
* `icon={<Settings size={16} />}` passes the element and this places it. The
|
|
37
|
+
* two used to mean opposite things one import apart — `CommandItem.icon` took
|
|
38
|
+
* the element while this took the component — and the wrong one did not fail
|
|
39
|
+
* a type check into anything actionable, it failed at render.
|
|
40
|
+
*/
|
|
41
|
+
icon?: LucideIcon | ReactNode;
|
|
33
42
|
/** Paints the row as destructive. Use for delete, revoke, disconnect. */
|
|
34
43
|
destructive?: boolean;
|
|
35
44
|
}
|
|
@@ -40,10 +49,39 @@ interface DropdownMenuItemProps extends ComponentProps<typeof DropdownMenuPrimit
|
|
|
40
49
|
* hover and keyboard focus — styling `:hover` alone leaves the keyboard user
|
|
41
50
|
* unable to see where they are.
|
|
42
51
|
*/
|
|
43
|
-
declare function DropdownMenuItem({ icon
|
|
52
|
+
declare function DropdownMenuItem({ icon, destructive, className, children, ...rest }: DropdownMenuItemProps): react.JSX.Element;
|
|
44
53
|
/** Hairline divider between menu groups. */
|
|
45
54
|
declare function DropdownMenuSeparator({ className, ...rest }: ComponentProps<typeof DropdownMenuPrimitive.Separator>): react.JSX.Element;
|
|
46
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* Mono eyebrow heading, on its own.
|
|
57
|
+
*
|
|
58
|
+
* Visual only: Radix renders it as a bare `<div>` with no role, so it segments
|
|
59
|
+
* the menu for a reader who can see it and for nobody else. Reach for
|
|
60
|
+
* `DropdownMenuGroup` when the eyebrow is a HEADING over rows; this is right
|
|
61
|
+
* for a line that heads nothing — the signed-in address at the top of an
|
|
62
|
+
* account menu.
|
|
63
|
+
*/
|
|
47
64
|
declare function DropdownMenuLabel({ className, ...rest }: ComponentProps<typeof DropdownMenuPrimitive.Label>): react.JSX.Element;
|
|
65
|
+
interface DropdownMenuGroupProps extends ComponentProps<typeof DropdownMenuPrimitive.Group> {
|
|
66
|
+
/** The eyebrow over the rows, and the group's accessible name. */
|
|
67
|
+
label?: ReactNode;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A named section of a menu.
|
|
71
|
+
*
|
|
72
|
+
* The eyebrow alone was a picture of a heading. Radix's `MenuLabel` carries no
|
|
73
|
+
* role and no `aria-labelledby` wiring, and `MenuGroup` — which does carry
|
|
74
|
+
* `role="group"` — was not re-exported by this package at all, so a sighted
|
|
75
|
+
* reader saw three labelled sections and a screen-reader user got one
|
|
76
|
+
* undifferentiated list. This renders the group, renders the label inside it,
|
|
77
|
+
* and points the one at the other, which is the whole of the fix and not
|
|
78
|
+
* something a caller should have to remember.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* <DropdownMenuGroup label="Account">
|
|
82
|
+
* <DropdownMenuItem icon={Settings}>Settings</DropdownMenuItem>
|
|
83
|
+
* </DropdownMenuGroup>
|
|
84
|
+
*/
|
|
85
|
+
declare function DropdownMenuGroup({ label, children, ...rest }: DropdownMenuGroupProps): react.JSX.Element;
|
|
48
86
|
|
|
49
|
-
export { DropdownMenu, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuItem, type DropdownMenuItemProps, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, DropdownMenu as default };
|
|
87
|
+
export { DropdownMenu, DropdownMenuContent, type DropdownMenuContentProps, DropdownMenuGroup, type DropdownMenuGroupProps, DropdownMenuItem, type DropdownMenuItemProps, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, DropdownMenu as default };
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
4
|
+
import { isValidElement, useId } from "react";
|
|
4
5
|
import { cn } from "../../lib/cn.js";
|
|
5
6
|
import { useOverlayContainer } from "../../lib/overlay-container.js";
|
|
7
|
+
function isIconComponent(icon) {
|
|
8
|
+
if (isValidElement(icon)) return false;
|
|
9
|
+
if (typeof icon === "function") return true;
|
|
10
|
+
if (typeof icon !== "object" || icon === null) return false;
|
|
11
|
+
return !Array.isArray(icon) && !(Symbol.iterator in icon) && !("then" in icon);
|
|
12
|
+
}
|
|
13
|
+
function iconNode(icon) {
|
|
14
|
+
if (icon === void 0 || icon === null || icon === false) return null;
|
|
15
|
+
if (!isIconComponent(icon)) {
|
|
16
|
+
return /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "grid size-4 shrink-0 place-items-center [&_svg]:size-4", children: icon });
|
|
17
|
+
}
|
|
18
|
+
const Icon = icon;
|
|
19
|
+
return /* @__PURE__ */ jsx(Icon, { size: 16, strokeWidth: 1.5, className: "shrink-0", "aria-hidden": true });
|
|
20
|
+
}
|
|
6
21
|
const DropdownMenu = DropdownMenuPrimitive.Root;
|
|
7
22
|
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
8
23
|
function DropdownMenuContent({
|
|
@@ -20,7 +35,7 @@ function DropdownMenuContent({
|
|
|
20
35
|
sideOffset,
|
|
21
36
|
"data-m22-animated": true,
|
|
22
37
|
className: cn(
|
|
23
|
-
"z-(--z-dropdown) min-w-44 rounded-(--radius-lg) border border-(--panel-border) bg-(--panel-bg) p-1.5 panel-blur",
|
|
38
|
+
"z-(--z-dropdown) min-w-44 rounded-(--radius-lg) border border-(--panel-border) bg-(--panel-bg) p-1.5 shadow-(--panel-lift) panel-blur",
|
|
24
39
|
"data-[state=open]:animate-[m22-pop-in_var(--duration-fast)_var(--ease-out-expo)] data-[state=closed]:animate-[m22-pop-out_var(--duration-fast)_var(--ease)] origin-(--radix-popper-transform-origin)",
|
|
25
40
|
className
|
|
26
41
|
),
|
|
@@ -30,7 +45,7 @@ function DropdownMenuContent({
|
|
|
30
45
|
) });
|
|
31
46
|
}
|
|
32
47
|
function DropdownMenuItem({
|
|
33
|
-
icon
|
|
48
|
+
icon,
|
|
34
49
|
destructive = false,
|
|
35
50
|
className,
|
|
36
51
|
children,
|
|
@@ -46,7 +61,7 @@ function DropdownMenuItem({
|
|
|
46
61
|
),
|
|
47
62
|
...rest,
|
|
48
63
|
children: [
|
|
49
|
-
|
|
64
|
+
iconNode(icon),
|
|
50
65
|
children
|
|
51
66
|
]
|
|
52
67
|
}
|
|
@@ -76,10 +91,25 @@ function DropdownMenuLabel({
|
|
|
76
91
|
}
|
|
77
92
|
);
|
|
78
93
|
}
|
|
94
|
+
function DropdownMenuGroup({ label, children, ...rest }) {
|
|
95
|
+
const id = useId();
|
|
96
|
+
return /* @__PURE__ */ jsxs(
|
|
97
|
+
DropdownMenuPrimitive.Group,
|
|
98
|
+
{
|
|
99
|
+
"aria-labelledby": label === void 0 ? void 0 : id,
|
|
100
|
+
...rest,
|
|
101
|
+
children: [
|
|
102
|
+
label !== void 0 && /* @__PURE__ */ jsx(DropdownMenuLabel, { id, children: label }),
|
|
103
|
+
children
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
}
|
|
79
108
|
var DropdownMenu_default = DropdownMenu;
|
|
80
109
|
export {
|
|
81
110
|
DropdownMenu,
|
|
82
111
|
DropdownMenuContent,
|
|
112
|
+
DropdownMenuGroup,
|
|
83
113
|
DropdownMenuItem,
|
|
84
114
|
DropdownMenuLabel,
|
|
85
115
|
DropdownMenuSeparator,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/DropdownMenu/DropdownMenu.tsx"],"sourcesContent":["'use client'\n\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport type { LucideIcon } from 'lucide-react'\nimport type
|
|
1
|
+
{"version":3,"sources":["../../../src/components/DropdownMenu/DropdownMenu.tsx"],"sourcesContent":["'use client'\n\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport type { LucideIcon } from 'lucide-react'\nimport { isValidElement, useId, type ComponentProps, type ReactNode } from 'react'\nimport { cn } from '../../lib/cn'\nimport { useOverlayContainer } from '../../lib/overlay-container'\n\n/**\n * True for a component type — `icon={Settings}` — rather than a rendered element.\n *\n * Everything a `ReactNode` can be is an element, a primitive, an array, another\n * iterable or a promise; a Lucide icon is none of those, it is a `forwardRef`\n * object. So both spellings are tellable apart at runtime, which is what lets\n * one prop take either — and it has to, because this prop meant the opposite\n * thing one import away and the wrong spelling failed at render, not at the\n * type.\n */\nfunction isIconComponent(icon: LucideIcon | ReactNode): icon is LucideIcon {\n if (isValidElement(icon)) return false\n if (typeof icon === 'function') return true\n if (typeof icon !== 'object' || icon === null) return false\n return !Array.isArray(icon) && !(Symbol.iterator in icon) && !('then' in icon)\n}\n\n/** The leading glyph, sized by this component when it was handed a component. */\nfunction iconNode(icon: LucideIcon | ReactNode): ReactNode {\n if (icon === undefined || icon === null || icon === false) return null\n if (!isIconComponent(icon)) {\n return (\n <span aria-hidden className=\"grid size-4 shrink-0 place-items-center [&_svg]:size-4\">\n {icon}\n </span>\n )\n }\n const Icon = icon\n return <Icon size={16} strokeWidth={1.5} className=\"shrink-0\" aria-hidden />\n}\n\n/** Radix DropdownMenu root + trigger, re-exported as typed passthroughs. */\nexport const DropdownMenu = DropdownMenuPrimitive.Root\nexport const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger\n\nexport type DropdownMenuContentProps = ComponentProps<typeof DropdownMenuPrimitive.Content>\n\n/**\n * A menu surface.\n *\n * A menu is a list of ACTIONS. If the items navigate somewhere, they belong in\n * a nav; if they set a value, that is a `Select` or a `RadioGroup` — this\n * package ships no checkbox or radio menu item, and a plain item pretending to\n * be a choice loses the checked state a screen reader needs.\n *\n * @example\n * <DropdownMenu>\n * <DropdownMenuTrigger asChild><Button variant=\"secondary\">Menu</Button></DropdownMenuTrigger>\n * <DropdownMenuContent>\n * <DropdownMenuGroup label=\"Account\">\n * <DropdownMenuItem icon={Settings}>Settings</DropdownMenuItem>\n * </DropdownMenuGroup>\n * <DropdownMenuSeparator />\n * <DropdownMenuItem icon={LogOut}>Sign out</DropdownMenuItem>\n * </DropdownMenuContent>\n * </DropdownMenu>\n */\nexport function DropdownMenuContent({\n className,\n sideOffset = 6,\n children,\n ...rest\n}: DropdownMenuContentProps) {\n const container = useOverlayContainer()\n\n return (\n <DropdownMenuPrimitive.Portal container={container ?? undefined}>\n <DropdownMenuPrimitive.Content\n collisionBoundary={container ?? undefined}\n collisionPadding={8}\n sideOffset={sideOffset}\n data-m22-animated\n className={cn(\n 'z-(--z-dropdown) min-w-44 rounded-(--radius-lg) border border-(--panel-border) bg-(--panel-bg) p-1.5 shadow-(--panel-lift) panel-blur',\n 'data-[state=open]:animate-[m22-pop-in_var(--duration-fast)_var(--ease-out-expo)] data-[state=closed]:animate-[m22-pop-out_var(--duration-fast)_var(--ease)] origin-(--radix-popper-transform-origin)',\n className,\n )}\n {...rest}\n >\n {children}\n </DropdownMenuPrimitive.Content>\n </DropdownMenuPrimitive.Portal>\n )\n}\n\nexport interface DropdownMenuItemProps extends ComponentProps<typeof DropdownMenuPrimitive.Item> {\n /**\n * Optional leading icon, rendered before the label.\n *\n * Either spelling: `icon={Settings}` passes the component and this sizes it,\n * `icon={<Settings size={16} />}` passes the element and this places it. The\n * two used to mean opposite things one import apart — `CommandItem.icon` took\n * the element while this took the component — and the wrong one did not fail\n * a type check into anything actionable, it failed at render.\n */\n icon?: LucideIcon | ReactNode\n /** Paints the row as destructive. Use for delete, revoke, disconnect. */\n destructive?: boolean\n}\n\n/**\n * A menu row.\n *\n * Highlight is driven by Radix's `data-highlighted`, which covers both pointer\n * hover and keyboard focus — styling `:hover` alone leaves the keyboard user\n * unable to see where they are.\n */\nexport function DropdownMenuItem({\n icon,\n destructive = false,\n className,\n children,\n ...rest\n}: DropdownMenuItemProps) {\n return (\n <DropdownMenuPrimitive.Item\n className={cn(\n 'flex cursor-pointer items-center gap-2.5 rounded-(--radius-row) px-2.5 py-2 text-sm outline-none transition-colors duration-(--duration-fast) data-[highlighted]:bg-(--stone) data-[disabled]:pointer-events-none data-[disabled]:opacity-(--disabled-opacity)',\n destructive ? 'text-(--danger)' : 'text-(--ink-2) data-[highlighted]:text-(--ink)',\n className,\n )}\n {...rest}\n >\n {iconNode(icon)}\n {children}\n </DropdownMenuPrimitive.Item>\n )\n}\n\n/** Hairline divider between menu groups. */\nexport function DropdownMenuSeparator({\n className,\n ...rest\n}: ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n className={cn('my-1 h-px bg-(--rule)', className)}\n {...rest}\n />\n )\n}\n\n/**\n * Mono eyebrow heading, on its own.\n *\n * Visual only: Radix renders it as a bare `<div>` with no role, so it segments\n * the menu for a reader who can see it and for nobody else. Reach for\n * `DropdownMenuGroup` when the eyebrow is a HEADING over rows; this is right\n * for a line that heads nothing — the signed-in address at the top of an\n * account menu.\n */\nexport function DropdownMenuLabel({\n className,\n ...rest\n}: ComponentProps<typeof DropdownMenuPrimitive.Label>) {\n return (\n <DropdownMenuPrimitive.Label\n className={cn('px-2.5 py-1.5 eyebrow text-(--ink-3-aa)', className)}\n {...rest}\n />\n )\n}\n\nexport interface DropdownMenuGroupProps\n extends ComponentProps<typeof DropdownMenuPrimitive.Group> {\n /** The eyebrow over the rows, and the group's accessible name. */\n label?: ReactNode\n}\n\n/**\n * A named section of a menu.\n *\n * The eyebrow alone was a picture of a heading. Radix's `MenuLabel` carries no\n * role and no `aria-labelledby` wiring, and `MenuGroup` — which does carry\n * `role=\"group\"` — was not re-exported by this package at all, so a sighted\n * reader saw three labelled sections and a screen-reader user got one\n * undifferentiated list. This renders the group, renders the label inside it,\n * and points the one at the other, which is the whole of the fix and not\n * something a caller should have to remember.\n *\n * @example\n * <DropdownMenuGroup label=\"Account\">\n * <DropdownMenuItem icon={Settings}>Settings</DropdownMenuItem>\n * </DropdownMenuGroup>\n */\nexport function DropdownMenuGroup({ label, children, ...rest }: DropdownMenuGroupProps) {\n const id = useId()\n\n return (\n <DropdownMenuPrimitive.Group\n aria-labelledby={label === undefined ? undefined : id}\n {...rest}\n >\n {label !== undefined && <DropdownMenuLabel id={id}>{label}</DropdownMenuLabel>}\n {children}\n </DropdownMenuPrimitive.Group>\n )\n}\n\nexport default DropdownMenu\n"],"mappings":";AA8BM,cA6FF,YA7FE;AA5BN,YAAY,2BAA2B;AAEvC,SAAS,gBAAgB,aAAkD;AAC3E,SAAS,UAAU;AACnB,SAAS,2BAA2B;AAYpC,SAAS,gBAAgB,MAAkD;AACzE,MAAI,eAAe,IAAI,EAAG,QAAO;AACjC,MAAI,OAAO,SAAS,WAAY,QAAO;AACvC,MAAI,OAAO,SAAS,YAAY,SAAS,KAAM,QAAO;AACtD,SAAO,CAAC,MAAM,QAAQ,IAAI,KAAK,EAAE,OAAO,YAAY,SAAS,EAAE,UAAU;AAC3E;AAGA,SAAS,SAAS,MAAyC;AACzD,MAAI,SAAS,UAAa,SAAS,QAAQ,SAAS,MAAO,QAAO;AAClE,MAAI,CAAC,gBAAgB,IAAI,GAAG;AAC1B,WACE,oBAAC,UAAK,eAAW,MAAC,WAAU,0DACzB,gBACH;AAAA,EAEJ;AACA,QAAM,OAAO;AACb,SAAO,oBAAC,QAAK,MAAM,IAAI,aAAa,KAAK,WAAU,YAAW,eAAW,MAAC;AAC5E;AAGO,MAAM,eAAe,sBAAsB;AAC3C,MAAM,sBAAsB,sBAAsB;AAwBlD,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA,GAAG;AACL,GAA6B;AAC3B,QAAM,YAAY,oBAAoB;AAEtC,SACE,oBAAC,sBAAsB,QAAtB,EAA6B,WAAW,aAAa,QACpD;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,mBAAmB,aAAa;AAAA,MAChC,kBAAkB;AAAA,MAClB;AAAA,MACA,qBAAiB;AAAA,MACjB,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH,GACF;AAEJ;AAwBO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA0B;AACxB,SACE;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,cAAc,oBAAoB;AAAA,QAClC;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA,iBAAS,IAAI;AAAA,QACb;AAAA;AAAA;AAAA,EACH;AAEJ;AAGO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA,GAAG;AACL,GAA2D;AACzD,SACE;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,WAAW,GAAG,yBAAyB,SAAS;AAAA,MAC/C,GAAG;AAAA;AAAA,EACN;AAEJ;AAWO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA,GAAG;AACL,GAAuD;AACrD,SACE;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,WAAW,GAAG,2CAA2C,SAAS;AAAA,MACjE,GAAG;AAAA;AAAA,EACN;AAEJ;AAwBO,SAAS,kBAAkB,EAAE,OAAO,UAAU,GAAG,KAAK,GAA2B;AACtF,QAAM,KAAK,MAAM;AAEjB,SACE;AAAA,IAAC,sBAAsB;AAAA,IAAtB;AAAA,MACC,mBAAiB,UAAU,SAAY,SAAY;AAAA,MAClD,GAAG;AAAA,MAEH;AAAA,kBAAU,UAAa,oBAAC,qBAAkB,IAAS,iBAAM;AAAA,QACzD;AAAA;AAAA;AAAA,EACH;AAEJ;AAEA,IAAO,uBAAQ;","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
3
|
import { LucideIcon } from 'lucide-react';
|
|
4
|
+
import { HeadingLevel } from '../Heading/Heading.js';
|
|
4
5
|
|
|
5
6
|
interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
6
7
|
/** Optional lucide icon, shown muted inside a quiet circle. */
|
|
@@ -9,6 +10,26 @@ interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>
|
|
|
9
10
|
description?: ReactNode;
|
|
10
11
|
/** The one thing to do next. An empty state without an action is a dead end. */
|
|
11
12
|
action?: ReactNode;
|
|
13
|
+
/**
|
|
14
|
+
* The heading level `title` opens, in the document the empty state lands in.
|
|
15
|
+
*
|
|
16
|
+
* Defaults to `2`, which is the placement this component is sized for: it
|
|
17
|
+
* stands in for a whole view inside a page that already has an `h1`, so the
|
|
18
|
+
* level below that one is the level that does not leave a hole in heading
|
|
19
|
+
* navigation. Under a section that already has its own `h2`, pass `3`.
|
|
20
|
+
*
|
|
21
|
+
* The default was `3` and fixed, which was wrong in the ordinary case and
|
|
22
|
+
* impossible to correct — the documentation could name the rule but a caller
|
|
23
|
+
* had no prop to follow it with. `2` is the common case rather than a
|
|
24
|
+
* compromise, and it is optional rather than required because the correct
|
|
25
|
+
* placement has one answer often enough that making every existing call site
|
|
26
|
+
* restate it would buy nothing.
|
|
27
|
+
*
|
|
28
|
+
* The size does not follow the level. `title` renders at `--fs-sub` at every
|
|
29
|
+
* level, because moving a state down the outline is a fact about the document
|
|
30
|
+
* and not a request for smaller type.
|
|
31
|
+
*/
|
|
32
|
+
level?: HeadingLevel;
|
|
12
33
|
}
|
|
13
34
|
/**
|
|
14
35
|
* A collection with nothing in it — yet.
|
|
@@ -25,7 +46,10 @@ interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'>
|
|
|
25
46
|
* description="Create your first project to get started."
|
|
26
47
|
* action={<Button>New project</Button>}
|
|
27
48
|
* />
|
|
49
|
+
* @example
|
|
50
|
+
* // Inside a section that already has its own heading.
|
|
51
|
+
* <EmptyState level={3} title="No invoices yet" />
|
|
28
52
|
*/
|
|
29
|
-
declare function EmptyState({ icon: Icon, title, description, action, className, ...rest }: EmptyStateProps): react.JSX.Element;
|
|
53
|
+
declare function EmptyState({ icon: Icon, title, description, action, level, className, ...rest }: EmptyStateProps): react.JSX.Element;
|
|
30
54
|
|
|
31
55
|
export { EmptyState, type EmptyStateProps, EmptyState as default };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Heading } from "../Heading/Heading.js";
|
|
2
3
|
import { cn } from "../../lib/cn.js";
|
|
3
4
|
function EmptyState({
|
|
4
5
|
icon: Icon,
|
|
5
6
|
title,
|
|
6
7
|
description,
|
|
7
8
|
action,
|
|
9
|
+
level = 2,
|
|
8
10
|
className,
|
|
9
11
|
...rest
|
|
10
12
|
}) {
|
|
@@ -15,7 +17,7 @@ function EmptyState({
|
|
|
15
17
|
...rest,
|
|
16
18
|
children: [
|
|
17
19
|
Icon && /* @__PURE__ */ jsx("span", { className: "mb-6 flex size-14 items-center justify-center rounded-(--radius-pill) bg-(--stone) text-(--ink-3-aa)", children: /* @__PURE__ */ jsx(Icon, { size: 24, strokeWidth: 1.5, "aria-hidden": true }) }),
|
|
18
|
-
/* @__PURE__ */ jsx(
|
|
20
|
+
/* @__PURE__ */ jsx(Heading, { level, size: "sub", children: title }),
|
|
19
21
|
description && /* @__PURE__ */ jsx("p", { className: "m-0 mt-2 max-w-sm text-sm leading-relaxed text-(--ink-3-aa)", children: description }),
|
|
20
22
|
action && /* @__PURE__ */ jsx("div", { className: "mt-8", children: action })
|
|
21
23
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/EmptyState/EmptyState.tsx"],"sourcesContent":["import type { LucideIcon } from 'lucide-react'\nimport type { HTMLAttributes, ReactNode } from 'react'\nimport { cn } from '../../lib/cn'\n\nexport interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Optional lucide icon, shown muted inside a quiet circle. */\n icon?: LucideIcon\n title: ReactNode\n description?: ReactNode\n /** The one thing to do next. An empty state without an action is a dead end. */\n action?: ReactNode\n}\n\n/**\n * A collection with nothing in it — yet.\n *\n * Distinct from `ErrorState`: nothing went wrong here, so the copy says what to\n * do rather than what failed. The two are different components because the\n * shared temptation — one component with a `variant` — produces error pages\n * that read like empty folders.\n *\n * @example\n * <EmptyState\n * icon={Inbox}\n * title=\"No projects yet\"\n * description=\"Create your first project to get started.\"\n * action={<Button>New project</Button>}\n * />\n */\nexport function EmptyState({\n icon: Icon,\n title,\n description,\n action,\n className,\n ...rest\n}: EmptyStateProps) {\n return (\n <div\n className={cn('flex flex-col items-center px-(--page-pad) py-20 text-center', className)}\n {...rest}\n >\n {Icon && (\n <span className=\"mb-6 flex size-14 items-center justify-center rounded-(--radius-pill) bg-(--stone) text-(--ink-3-aa)\">\n <Icon size={24} strokeWidth={1.5} aria-hidden />\n </span>\n )}\n <
|
|
1
|
+
{"version":3,"sources":["../../../src/components/EmptyState/EmptyState.tsx"],"sourcesContent":["import type { LucideIcon } from 'lucide-react'\nimport type { HTMLAttributes, ReactNode } from 'react'\nimport { Heading, type HeadingLevel } from '../Heading/Heading'\nimport { cn } from '../../lib/cn'\n\nexport interface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {\n /** Optional lucide icon, shown muted inside a quiet circle. */\n icon?: LucideIcon\n title: ReactNode\n description?: ReactNode\n /** The one thing to do next. An empty state without an action is a dead end. */\n action?: ReactNode\n /**\n * The heading level `title` opens, in the document the empty state lands in.\n *\n * Defaults to `2`, which is the placement this component is sized for: it\n * stands in for a whole view inside a page that already has an `h1`, so the\n * level below that one is the level that does not leave a hole in heading\n * navigation. Under a section that already has its own `h2`, pass `3`.\n *\n * The default was `3` and fixed, which was wrong in the ordinary case and\n * impossible to correct — the documentation could name the rule but a caller\n * had no prop to follow it with. `2` is the common case rather than a\n * compromise, and it is optional rather than required because the correct\n * placement has one answer often enough that making every existing call site\n * restate it would buy nothing.\n *\n * The size does not follow the level. `title` renders at `--fs-sub` at every\n * level, because moving a state down the outline is a fact about the document\n * and not a request for smaller type.\n */\n level?: HeadingLevel\n}\n\n/**\n * A collection with nothing in it — yet.\n *\n * Distinct from `ErrorState`: nothing went wrong here, so the copy says what to\n * do rather than what failed. The two are different components because the\n * shared temptation — one component with a `variant` — produces error pages\n * that read like empty folders.\n *\n * @example\n * <EmptyState\n * icon={Inbox}\n * title=\"No projects yet\"\n * description=\"Create your first project to get started.\"\n * action={<Button>New project</Button>}\n * />\n * @example\n * // Inside a section that already has its own heading.\n * <EmptyState level={3} title=\"No invoices yet\" />\n */\nexport function EmptyState({\n icon: Icon,\n title,\n description,\n action,\n level = 2,\n className,\n ...rest\n}: EmptyStateProps) {\n return (\n <div\n className={cn('flex flex-col items-center px-(--page-pad) py-20 text-center', className)}\n {...rest}\n >\n {Icon && (\n <span className=\"mb-6 flex size-14 items-center justify-center rounded-(--radius-pill) bg-(--stone) text-(--ink-3-aa)\">\n <Icon size={24} strokeWidth={1.5} aria-hidden />\n </span>\n )}\n <Heading level={level} size=\"sub\">\n {title}\n </Heading>\n {description && (\n <p className=\"m-0 mt-2 max-w-sm text-sm leading-relaxed text-(--ink-3-aa)\">{description}</p>\n )}\n {action && <div className=\"mt-8\">{action}</div>}\n </div>\n )\n}\n\nexport default EmptyState\n"],"mappings":"AA+DI,SAMM,KANN;AA7DJ,SAAS,eAAkC;AAC3C,SAAS,UAAU;AAkDZ,SAAS,WAAW;AAAA,EACzB,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,gEAAgE,SAAS;AAAA,MACtF,GAAG;AAAA,MAEH;AAAA,gBACC,oBAAC,UAAK,WAAU,wGACd,8BAAC,QAAK,MAAM,IAAI,aAAa,KAAK,eAAW,MAAC,GAChD;AAAA,QAEF,oBAAC,WAAQ,OAAc,MAAK,OACzB,iBACH;AAAA,QACC,eACC,oBAAC,OAAE,WAAU,+DAA+D,uBAAY;AAAA,QAEzF,UAAU,oBAAC,SAAI,WAAU,QAAQ,kBAAO;AAAA;AAAA;AAAA,EAC3C;AAEJ;AAEA,IAAO,qBAAQ;","names":[]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
|
+
import { HeadingLevel } from '../Heading/Heading.js';
|
|
3
4
|
|
|
4
5
|
interface ErrorStateProps extends HTMLAttributes<HTMLElement> {
|
|
5
6
|
/** The status, set large — "404", "500". Decorative; the heading carries the meaning. */
|
|
@@ -8,6 +9,23 @@ interface ErrorStateProps extends HTMLAttributes<HTMLElement> {
|
|
|
8
9
|
message: ReactNode;
|
|
9
10
|
/** The way back. Render it with {@link ERROR_ACTION_CLASS}. */
|
|
10
11
|
action: ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* The heading level `heading` opens, in the document the error state lands in.
|
|
14
|
+
*
|
|
15
|
+
* Defaults to `1`, and that is not a compromise: this component replaces the
|
|
16
|
+
* page rather than sitting inside one — its own ground, its own viewport, its
|
|
17
|
+
* own top clearance — so the page's single `h1` is the one it renders. Kept
|
|
18
|
+
* as the default, existing call sites render exactly the markup they did.
|
|
19
|
+
*
|
|
20
|
+
* The prop exists because the level was previously fixed, and the one piece
|
|
21
|
+
* of advice this component's documentation gives about headings — do not put
|
|
22
|
+
* it inside a shell that already has an `h1` — was advice a caller had no way
|
|
23
|
+
* to take. Now they do: inside a shell that owns the page heading, pass `2`.
|
|
24
|
+
*
|
|
25
|
+
* The size does not follow the level. `heading` renders at `--fs-heading` at
|
|
26
|
+
* every level; a failure demoted in the outline is the same failure.
|
|
27
|
+
*/
|
|
28
|
+
level?: HeadingLevel;
|
|
11
29
|
}
|
|
12
30
|
/**
|
|
13
31
|
* The recovery affordance's look, exported so every error page offers the same
|
|
@@ -28,7 +46,10 @@ declare const ERROR_ACTION_CLASS = "text-sm text-(--ink) underline decoration-(-
|
|
|
28
46
|
* message="The page you're looking for has moved, or never existed."
|
|
29
47
|
* action={<a href="/" className={ERROR_ACTION_CLASS}>Back home</a>}
|
|
30
48
|
* />
|
|
49
|
+
* @example
|
|
50
|
+
* // Inside a shell that already owns the page's h1.
|
|
51
|
+
* <ErrorState level={2} code="503" heading="Invoices could not be loaded" … />
|
|
31
52
|
*/
|
|
32
|
-
declare function ErrorState({ code, heading, message, action, className, ...rest }: ErrorStateProps): react.JSX.Element;
|
|
53
|
+
declare function ErrorState({ code, heading, message, action, level, className, ...rest }: ErrorStateProps): react.JSX.Element;
|
|
33
54
|
|
|
34
55
|
export { ERROR_ACTION_CLASS, ErrorState, type ErrorStateProps, ErrorState as default };
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Heading } from "../Heading/Heading.js";
|
|
2
3
|
import { cn } from "../../lib/cn.js";
|
|
3
4
|
const ERROR_ACTION_CLASS = "text-sm text-(--ink) underline decoration-(--rule-2) underline-offset-4 transition-colors duration-(--duration-fast) hover:decoration-(--ink)";
|
|
4
|
-
function ErrorState({
|
|
5
|
+
function ErrorState({
|
|
6
|
+
code,
|
|
7
|
+
heading,
|
|
8
|
+
message,
|
|
9
|
+
action,
|
|
10
|
+
level = 1,
|
|
11
|
+
className,
|
|
12
|
+
...rest
|
|
13
|
+
}) {
|
|
5
14
|
return /* @__PURE__ */ jsx(
|
|
6
15
|
"section",
|
|
7
16
|
{
|
|
@@ -12,11 +21,11 @@ function ErrorState({ code, heading, message, action, className, ...rest }) {
|
|
|
12
21
|
"p",
|
|
13
22
|
{
|
|
14
23
|
"aria-hidden": "true",
|
|
15
|
-
className: "m-0 font-heading text-[length:var(--fs-title)] leading-
|
|
24
|
+
className: "m-0 font-heading text-[length:var(--fs-title)] leading-tight text-(--ink)",
|
|
16
25
|
children: code
|
|
17
26
|
}
|
|
18
27
|
),
|
|
19
|
-
/* @__PURE__ */ jsx("
|
|
28
|
+
/* @__PURE__ */ jsx(Heading, { level, size: "heading", className: "mb-4 mt-6", children: heading }),
|
|
20
29
|
/* @__PURE__ */ jsx("p", { className: "mb-10 max-w-(--measure-record) text-base leading-relaxed text-(--ink-3-aa)", children: message }),
|
|
21
30
|
action
|
|
22
31
|
] })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ErrorState/ErrorState.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react'\nimport { cn } from '../../lib/cn'\n\nexport interface ErrorStateProps extends HTMLAttributes<HTMLElement> {\n /** The status, set large — \"404\", \"500\". Decorative; the heading carries the meaning. */\n code: ReactNode\n heading: ReactNode\n message: ReactNode\n /** The way back. Render it with {@link ERROR_ACTION_CLASS}. */\n action: ReactNode\n}\n\n/**\n * The recovery affordance's look, exported so every error page offers the same\n * one rather than each inventing a link style.\n */\nexport const ERROR_ACTION_CLASS =\n 'text-sm text-(--ink) underline decoration-(--rule-2) underline-offset-4 transition-colors duration-(--duration-fast) hover:decoration-(--ink)'\n\n/**\n * A page that could not be shown.\n *\n * The code is set at the top of the type ladder and marked `aria-hidden` — read\n * aloud, \"404\" before the sentence explaining it is noise, and the heading\n * immediately after says the same thing in words.\n *\n * @example\n * <ErrorState\n * code=\"404\"\n * heading=\"Page not found\"\n * message=\"The page you're looking for has moved, or never existed.\"\n * action={<a href=\"/\" className={ERROR_ACTION_CLASS}>Back home</a>}\n * />\n */\nexport function ErrorState({
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ErrorState/ErrorState.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react'\nimport { Heading, type HeadingLevel } from '../Heading/Heading'\nimport { cn } from '../../lib/cn'\n\nexport interface ErrorStateProps extends HTMLAttributes<HTMLElement> {\n /** The status, set large — \"404\", \"500\". Decorative; the heading carries the meaning. */\n code: ReactNode\n heading: ReactNode\n message: ReactNode\n /** The way back. Render it with {@link ERROR_ACTION_CLASS}. */\n action: ReactNode\n /**\n * The heading level `heading` opens, in the document the error state lands in.\n *\n * Defaults to `1`, and that is not a compromise: this component replaces the\n * page rather than sitting inside one — its own ground, its own viewport, its\n * own top clearance — so the page's single `h1` is the one it renders. Kept\n * as the default, existing call sites render exactly the markup they did.\n *\n * The prop exists because the level was previously fixed, and the one piece\n * of advice this component's documentation gives about headings — do not put\n * it inside a shell that already has an `h1` — was advice a caller had no way\n * to take. Now they do: inside a shell that owns the page heading, pass `2`.\n *\n * The size does not follow the level. `heading` renders at `--fs-heading` at\n * every level; a failure demoted in the outline is the same failure.\n */\n level?: HeadingLevel\n}\n\n/**\n * The recovery affordance's look, exported so every error page offers the same\n * one rather than each inventing a link style.\n */\nexport const ERROR_ACTION_CLASS =\n 'text-sm text-(--ink) underline decoration-(--rule-2) underline-offset-4 transition-colors duration-(--duration-fast) hover:decoration-(--ink)'\n\n/**\n * A page that could not be shown.\n *\n * The code is set at the top of the type ladder and marked `aria-hidden` — read\n * aloud, \"404\" before the sentence explaining it is noise, and the heading\n * immediately after says the same thing in words.\n *\n * @example\n * <ErrorState\n * code=\"404\"\n * heading=\"Page not found\"\n * message=\"The page you're looking for has moved, or never existed.\"\n * action={<a href=\"/\" className={ERROR_ACTION_CLASS}>Back home</a>}\n * />\n * @example\n * // Inside a shell that already owns the page's h1.\n * <ErrorState level={2} code=\"503\" heading=\"Invoices could not be loaded\" … />\n */\nexport function ErrorState({\n code,\n heading,\n message,\n action,\n level = 1,\n className,\n ...rest\n}: ErrorStateProps) {\n return (\n <section\n className={cn('flex min-h-svh flex-col justify-center bg-(--paper) pt-24', className)}\n {...rest}\n >\n <div className=\"mx-auto w-full max-w-(--w-page) px-(--page-pad)\">\n {/* `leading-tight`, not `leading-none`. At the title step this face\n draws about 62px of ink, and a line box of exactly the font size is\n 47 — so the figures overflowed their own box by seven pixels at the\n top and seven at the bottom, pressing up against the eyebrow above\n and eating half the gap to the heading below. The box that says\n nothing is spaced from is the box the ink is actually in. */}\n <p\n aria-hidden=\"true\"\n className=\"m-0 font-heading text-[length:var(--fs-title)] leading-tight text-(--ink)\"\n >\n {code}\n </p>\n <Heading level={level} size=\"heading\" className=\"mb-4 mt-6\">\n {heading}\n </Heading>\n <p className=\"mb-10 max-w-(--measure-record) text-base leading-relaxed text-(--ink-3-aa)\">\n {message}\n </p>\n {action}\n </div>\n </section>\n )\n}\n\nexport default ErrorState\n"],"mappings":"AAqEM,SAOE,KAPF;AApEN,SAAS,eAAkC;AAC3C,SAAS,UAAU;AAgCZ,MAAM,qBACX;AAoBK,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA,GAAG;AACL,GAAoB;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,6DAA6D,SAAS;AAAA,MACnF,GAAG;AAAA,MAEJ,+BAAC,SAAI,WAAU,mDAOb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAU;AAAA,YAET;AAAA;AAAA,QACH;AAAA,QACA,oBAAC,WAAQ,OAAc,MAAK,WAAU,WAAU,aAC7C,mBACH;AAAA,QACA,oBAAC,OAAE,WAAU,8EACV,mBACH;AAAA,QACC;AAAA,SACH;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,qBAAQ;","names":[]}
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { HTMLAttributes, ReactNode } from 'react';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Where the control sits relative to its label.
|
|
6
|
+
*
|
|
7
|
+
* `stacked` is the form row: label, control, message, down the page.
|
|
8
|
+
*
|
|
9
|
+
* `row` is the settings row: the label and its `description` in a column at the
|
|
10
|
+
* inline start, the control at the inline end, one rhythm down a settings
|
|
11
|
+
* screen. It is a layout, not a second component — the label wiring, the
|
|
12
|
+
* required marker and the message slot are the same three things either way,
|
|
13
|
+
* and a `SettingRow` beside this would be all three of them written twice.
|
|
14
|
+
*/
|
|
15
|
+
type FieldLayout = 'stacked' | 'row';
|
|
4
16
|
interface FieldProps extends HTMLAttributes<HTMLDivElement> {
|
|
5
17
|
/** Visible label text; renders a `--danger` asterisk when `required`. */
|
|
6
18
|
label?: ReactNode;
|
|
@@ -11,11 +23,23 @@ interface FieldProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
11
23
|
* — a form library referencing it by name, say.
|
|
12
24
|
*/
|
|
13
25
|
htmlFor?: string;
|
|
26
|
+
/**
|
|
27
|
+
* A second line under the LABEL, explaining what the setting does.
|
|
28
|
+
*
|
|
29
|
+
* Distinct from `hint`, which sits under the control and belongs to the input
|
|
30
|
+
* — "We never share it". This belongs to the thing being switched on, and it
|
|
31
|
+
* is what makes a settings row a settings row. Both reach the control through
|
|
32
|
+
* `aria-describedby`, so a row that has a description and an error announces
|
|
33
|
+
* both.
|
|
34
|
+
*/
|
|
35
|
+
description?: ReactNode;
|
|
14
36
|
/** Helper copy shown below the control when there is no `error`. */
|
|
15
37
|
hint?: ReactNode;
|
|
16
38
|
/** Validation message; takes precedence over `hint` when present. */
|
|
17
39
|
error?: ReactNode;
|
|
18
40
|
required?: boolean;
|
|
41
|
+
/** Where the control sits relative to its label. See {@link FieldLayout}. */
|
|
42
|
+
layout?: FieldLayout;
|
|
19
43
|
children: ReactNode;
|
|
20
44
|
}
|
|
21
45
|
/**
|
|
@@ -32,13 +56,56 @@ interface FieldProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
32
56
|
* reader. The id is now generated when it is not supplied.
|
|
33
57
|
*
|
|
34
58
|
* `hint` and `error` are one slot, not two stacked messages: when a field is
|
|
35
|
-
* wrong, the thing to read is what is wrong with it.
|
|
59
|
+
* wrong, the thing to read is what is wrong with it. `description` is a
|
|
60
|
+
* different slot again — it explains the SETTING, not the input, and it is what
|
|
61
|
+
* `layout="row"` puts under the label to make a settings row.
|
|
62
|
+
*
|
|
63
|
+
* **How the wiring reaches the control.** `cloneElement` puts the four
|
|
64
|
+
* attributes on the single child, and each control forwards them to whatever
|
|
65
|
+
* element carries the role — which is the child itself for `Input`, `Textarea`,
|
|
66
|
+
* `NativeSelect`, `Checkbox`, `Switch` and any host element written by hand, and
|
|
67
|
+
* a trigger, a group or a thumb further down for `Select`, `Combobox`,
|
|
68
|
+
* `DatePicker`, `Slider`, `RadioGroup` and `ToggleGroup`. The composites used to
|
|
69
|
+
* drop them on the floor, which drew a hint under a control that never announced
|
|
70
|
+
* it; a wrapper that appears to wire things up and does not is worse than one
|
|
71
|
+
* that never claimed to.
|
|
72
|
+
*
|
|
73
|
+
* The label's own id travels separately, through context, because a name is the
|
|
74
|
+
* one thing a prop cannot carry: a trigger whose text is its VALUE is named by
|
|
75
|
+
* the label AND by itself, so `<Field label="Region"><Select/></Field>`
|
|
76
|
+
* announces "Region, Australia" rather than either half.
|
|
77
|
+
*
|
|
78
|
+
* Three things stay out of reach, and each of them is the control's own markup
|
|
79
|
+
* rather than a gap in this wiring. A `<label for>` binds only to a labellable
|
|
80
|
+
* element, so the words do not click through to a `RadioGroup`, a `ToggleGroup`
|
|
81
|
+
* or a `Slider`: the first two are a `role="radiogroup"` named by pointing back
|
|
82
|
+
* at the label instead, exactly as a `<legend>` is, and the third carries
|
|
83
|
+
* `role="slider"` on a thumb below a roleless root. `required` reaches a control
|
|
84
|
+
* as `aria-required`, which `DatePicker`'s plain `<button>` trigger and a
|
|
85
|
+
* multiple-value `ToggleGroup`'s `role="toolbar"` have nowhere to put; there the
|
|
86
|
+
* asterisk is the only marker. And `aria-invalid` reaches `Slider`'s root rather
|
|
87
|
+
* than its thumb, so an errored slider is drawn wrong without being announced
|
|
88
|
+
* wrong.
|
|
89
|
+
*
|
|
90
|
+
* Each composite still takes its own `label` prop — that is what names it
|
|
91
|
+
* standing outside a field, and `Select`, `Combobox` and `DatePicker` warn when
|
|
92
|
+
* it is blank. It is no longer used INSTEAD of this one's.
|
|
93
|
+
*
|
|
94
|
+
* What no wiring can reach, the field says out loud in development rather than
|
|
95
|
+
* failing silently: `FIELD_CONTROL_NOT_LABELLABLE` when the child is a host
|
|
96
|
+
* element a label cannot bind to — the `<div>` wrapper that takes the id and
|
|
97
|
+
* leaves the control inside it with nothing — and `FIELD_CONTROL_NOT_WIRED`
|
|
98
|
+
* when there is no single element to wire at all.
|
|
36
99
|
*
|
|
37
100
|
* @example
|
|
38
101
|
* <Field label="Email" required hint="We never share it."><Input type="email" /></Field>
|
|
39
102
|
* @example
|
|
40
103
|
* <Field label="Name" error="Name is required."><Input /></Field>
|
|
104
|
+
* @example
|
|
105
|
+
* <Field layout="row" label="Email notifications" description="A digest every Monday.">
|
|
106
|
+
* <Switch defaultChecked />
|
|
107
|
+
* </Field>
|
|
41
108
|
*/
|
|
42
|
-
declare function Field({ label, htmlFor, hint, error, required, children, className, ...rest }: FieldProps): react.JSX.Element;
|
|
109
|
+
declare function Field({ label, htmlFor, description, hint, error, required, layout, children, className, ...rest }: FieldProps): react.JSX.Element;
|
|
43
110
|
|
|
44
|
-
export { Field, type FieldProps, Field as default };
|
|
111
|
+
export { Field, type FieldLayout, type FieldProps, Field as default };
|