@misoto22/design 0.7.0 → 0.8.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/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/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/Skeleton.md +24 -2
- package/dist/agent/Slider.md +27 -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 +26 -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 +5602 -745
- package/dist/agent/index.md +13 -4
- 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 +28 -7
- 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 +11 -9
- 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/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 +13 -1
- package/dist/components/Command/Command.js.map +1 -1
- package/dist/components/ContextMenu/ContextMenu.d.ts +30 -5
- package/dist/components/ContextMenu/ContextMenu.js +32 -2
- 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 +20 -2
- package/dist/components/Dialog/Dialog.js.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.d.ts +49 -11
- package/dist/components/DropdownMenu/DropdownMenu.js +32 -2
- 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 +11 -2
- 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/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/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 +20 -3
- 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 +11 -2
- package/dist/components/Sheet/Sheet.js.map +1 -1
- 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 +21 -3
- package/dist/components/Slider/Slider.js +54 -27
- 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 +6 -0
- package/dist/components/Table/Table.js +3 -1
- package/dist/components/Table/Table.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/wires.js.map +1 -1
- package/dist/diagrams/spec.d.ts +64 -12
- package/dist/index.d.ts +16 -4
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/keyframes.css +57 -3
- 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/tokens.css +20 -2
- package/dist/tokens.d.ts +1 -1
- package/dist/tokens.js +39 -36
- package/dist/tokens.json +39 -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 +5 -0
package/dist/agent/index.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# @misoto22/design 0.
|
|
1
|
+
# @misoto22/design 0.8.0
|
|
2
2
|
|
|
3
3
|
> Monochrome design system: portable CSS tokens and accessible React 19
|
|
4
4
|
> primitives. Components ship compiled — import them, do not copy them.
|
|
@@ -38,7 +38,7 @@ re-pointed in a stylesheet.
|
|
|
38
38
|
|
|
39
39
|
### Forms
|
|
40
40
|
|
|
41
|
-
- **Field** — A labelled form row: label, control, and the one message below it.
|
|
41
|
+
- **Field** — A labelled form row: label, control, and the one message below it — and, in row layout, the settings row.
|
|
42
42
|
- **Input** — A single line of text entry.
|
|
43
43
|
- **Textarea** — Multi-line text entry, resizable vertically only.
|
|
44
44
|
- **Select** — A choice from a list, styled the whole way down.
|
|
@@ -84,16 +84,22 @@ re-pointed in a stylesheet.
|
|
|
84
84
|
### Display
|
|
85
85
|
|
|
86
86
|
- **Badge** — A count or a state, set in mono so it reads as metadata.
|
|
87
|
-
- **Tag** — A subject label — a topic, a technology, a filter facet.
|
|
87
|
+
- **Tag** — A subject label — a topic, a technology, a filter facet — that filters with onClick and is dismissed with onRemove.
|
|
88
88
|
- **Kbd** — A key on a keyboard, set as one.
|
|
89
89
|
- **Avatar** — A person, as a circle, with initials until the image lands.
|
|
90
90
|
- **StatusDot** — The dot beside a status word.
|
|
91
91
|
- **Steps** — A numbered sequence, as a rail — one thing after another, with a rule through them.
|
|
92
92
|
- **StatusPill** — A live state, named: a dot plus an uppercase mono label.
|
|
93
93
|
- **LinkArrow** — The mark on a link that leaves the page.
|
|
94
|
-
- **Separator** — A rule, in the three weights a monochrome page needs.
|
|
94
|
+
- **Separator** — A rule, in the three weights a monochrome page needs — with words in it when the break has something to say.
|
|
95
95
|
- **Diagram** — A flow or architecture figure, drawn out of the system’s own parts.
|
|
96
96
|
- **FigureBand** — A row of counted facts, divided by hairlines and nothing else.
|
|
97
|
+
- **Text** — The system’s paragraph, on the second rung of the ink ladder.
|
|
98
|
+
- **Heading** — A heading whose element and whose size are two decisions.
|
|
99
|
+
- **Code** — A function name or a flag, inside a sentence.
|
|
100
|
+
- **CodeBlock** — A multi-line snippet, on a plate, with a way to take it away.
|
|
101
|
+
- **Markdown** — A Markdown string, rendered as this system’s components.
|
|
102
|
+
- **Timestamp** — A date or a time, rendered the one way the system renders them.
|
|
97
103
|
|
|
98
104
|
### Surfaces
|
|
99
105
|
|
|
@@ -102,6 +108,9 @@ re-pointed in a stylesheet.
|
|
|
102
108
|
- **AppShell** — Two columns on a desktop, a drawer on a phone.
|
|
103
109
|
- **Calendar** — A month, as a grid of days.
|
|
104
110
|
- **ScrollArea** — A box that scrolls, with a scrollbar that looks the same everywhere.
|
|
111
|
+
- **DescriptionList** — One record’s fields, as a real <dl> rather than a grid of divs.
|
|
112
|
+
- **Toolbar** — The bar of actions at the edge of a working surface.
|
|
113
|
+
- **AspectRatio** — A box that keeps its shape whatever is inside it.
|
|
105
114
|
|
|
106
115
|
### Data
|
|
107
116
|
|
package/dist/article.css
CHANGED
|
@@ -7,10 +7,22 @@
|
|
|
7
7
|
has to be the element names themselves.
|
|
8
8
|
|
|
9
9
|
Scoped to `[data-m22-article]`, which the `Article` component writes. Nothing
|
|
10
|
-
here leaks: a page that does not opt in is untouched
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
here leaks: a page that does not opt in is untouched.
|
|
11
|
+
|
|
12
|
+
Inside one, these rules BEAT a component's utilities, and that is the
|
|
13
|
+
mechanism the composition rests on rather than an accident. `styles/index.css`
|
|
14
|
+
imports this file unlayered while Tailwind's utilities sit in
|
|
15
|
+
`@layer utilities`, and an unlayered rule wins over a layered one whatever
|
|
16
|
+
either one's specificity is. So a `Markdown` paragraph — a `Text` carrying
|
|
17
|
+
`m-0` — gives its margin up to the rhythm below, which is the only reason
|
|
18
|
+
markdown dropped into an article reads as an article. The low specificity
|
|
19
|
+
here is for ordering these rules against EACH OTHER (see the `:is()` note
|
|
20
|
+
further down), not for losing to a utility.
|
|
21
|
+
|
|
22
|
+
A component that has to keep a property inside an article therefore cannot
|
|
23
|
+
do it with a class: it needs an inline style, or a tag this file does not
|
|
24
|
+
reach for — which is why `Diagram` draws its caption as a `<div>` rather than
|
|
25
|
+
as a `<figcaption>`.
|
|
14
26
|
|
|
15
27
|
It reads only tokens. Re-point the palette or move the radius factor and the
|
|
16
28
|
article moves with everything else, which is the whole reason this is here
|
|
@@ -82,8 +82,15 @@ interface AreaChartProps<TData extends Record<string, unknown>, TConfig extends
|
|
|
82
82
|
animationType?: ChartRevealType;
|
|
83
83
|
/** How several marks combine: side by side, stacked, or normalised to 100%. */
|
|
84
84
|
stackType?: AreaStackType;
|
|
85
|
-
/** The series lit on first render
|
|
85
|
+
/** The series lit on first render, when the chart keeps its own selection. */
|
|
86
86
|
defaultSelectedDataKey?: string | null;
|
|
87
|
+
/**
|
|
88
|
+
* The selected series, driven from outside.
|
|
89
|
+
*
|
|
90
|
+
* Give this and the chart follows it; leave it undefined and the chart keeps
|
|
91
|
+
* its own, starting from `defaultSelectedDataKey`.
|
|
92
|
+
*/
|
|
93
|
+
selectedDataKey?: string | null;
|
|
87
94
|
/** Fires when the selection changes, and with null when it is cleared. */
|
|
88
95
|
onSelectionChange?: (selectedDataKey: string | null) => void;
|
|
89
96
|
/**
|
|
@@ -133,7 +140,7 @@ interface AreaChartProps<TData extends Record<string, unknown>, TConfig extends
|
|
|
133
140
|
* <AreaChart.Area dataKey="desktop" variant="gradient" />
|
|
134
141
|
* </AreaChart>
|
|
135
142
|
*/
|
|
136
|
-
declare function AreaChart<TData extends Record<string, unknown>, TConfig extends Record<string, ChartConfig[string]>>({ config, data, title, showTitle, description, children, className, chartProps, curveType, animationType, stackType, defaultSelectedDataKey, onSelectionChange, isLoading, loadingPoints, xDataKey, hideDataTable, empty, }: AreaChartProps<TData, TConfig>): react.JSX.Element;
|
|
143
|
+
declare function AreaChart<TData extends Record<string, unknown>, TConfig extends Record<string, ChartConfig[string]>>({ config, data, title, showTitle, description, children, className, chartProps, curveType, animationType, stackType, defaultSelectedDataKey, selectedDataKey: controlledDataKey, onSelectionChange, isLoading, loadingPoints, xDataKey, hideDataTable, empty, }: AreaChartProps<TData, TConfig>): react.JSX.Element;
|
|
137
144
|
declare namespace AreaChart {
|
|
138
145
|
var Area: ({ dataKey, variant, strokeVariant, strokeWidth, curveType, animationType, connectNulls, isClickable, children, areaProps, }: AreaProps) => react.JSX.Element | null;
|
|
139
146
|
var Dot: FC<DotProps>;
|
|
@@ -4,11 +4,9 @@ import {
|
|
|
4
4
|
Children,
|
|
5
5
|
createContext,
|
|
6
6
|
isValidElement,
|
|
7
|
-
useCallback,
|
|
8
7
|
useContext,
|
|
9
8
|
useId,
|
|
10
|
-
useMemo
|
|
11
|
-
useState
|
|
9
|
+
useMemo
|
|
12
10
|
} from "react";
|
|
13
11
|
import {
|
|
14
12
|
Area as RechartsArea,
|
|
@@ -20,7 +18,8 @@ import {
|
|
|
20
18
|
import { useReducedMotion } from "motion/react";
|
|
21
19
|
import { ChartContainer, percentTick } from "../lib/chart.js";
|
|
22
20
|
import { ChartFigure } from "../lib/figure.js";
|
|
23
|
-
import {
|
|
21
|
+
import { useChartSelection } from "../lib/selection.js";
|
|
22
|
+
import {} from "../lib/empty.js";
|
|
24
23
|
import { axisLabel } from "../lib/axis.js";
|
|
25
24
|
import { defaultTick } from "../lib/format.js";
|
|
26
25
|
import { Annotation, ReferenceBand, ReferenceLine } from "../lib/annotations.js";
|
|
@@ -78,6 +77,7 @@ function AreaChart({
|
|
|
78
77
|
animationType = "forward",
|
|
79
78
|
stackType = "default",
|
|
80
79
|
defaultSelectedDataKey = null,
|
|
80
|
+
selectedDataKey: controlledDataKey,
|
|
81
81
|
onSelectionChange,
|
|
82
82
|
isLoading = false,
|
|
83
83
|
loadingPoints,
|
|
@@ -86,7 +86,6 @@ function AreaChart({
|
|
|
86
86
|
empty
|
|
87
87
|
}) {
|
|
88
88
|
const chartId = useId().replace(/:/g, "");
|
|
89
|
-
const [selectedDataKey, setSelectedDataKey] = useState(defaultSelectedDataKey);
|
|
90
89
|
const { rows: loadingData, onShimmerExit } = useLoadingRows(isLoading, loadingPoints);
|
|
91
90
|
const zoom = useChartZoom({ data, xDataKey });
|
|
92
91
|
const { brushSlot, toolbarSlot, sonifySlot, chartChildren } = useMemo(() => {
|
|
@@ -118,12 +117,10 @@ function AreaChart({
|
|
|
118
117
|
config,
|
|
119
118
|
xDataKey
|
|
120
119
|
);
|
|
121
|
-
const selectDataKey =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
},
|
|
126
|
-
[onSelectionChange]
|
|
120
|
+
const [selectedDataKey, selectDataKey] = useChartSelection(
|
|
121
|
+
controlledDataKey,
|
|
122
|
+
defaultSelectedDataKey,
|
|
123
|
+
onSelectionChange
|
|
127
124
|
);
|
|
128
125
|
const context = useMemo(
|
|
129
126
|
() => ({
|
|
@@ -157,9 +154,11 @@ function AreaChart({
|
|
|
157
154
|
description,
|
|
158
155
|
className,
|
|
159
156
|
table: hideDataTable ? false : { rows: data, rowKey: xDataKey, columns },
|
|
157
|
+
isEmpty,
|
|
158
|
+
empty,
|
|
160
159
|
children: [
|
|
161
160
|
sonifySlot && /* @__PURE__ */ jsx(ChartSonifyButton, { ...sonifySlot, title, series: sonifySeries }),
|
|
162
|
-
|
|
161
|
+
/* @__PURE__ */ jsx(
|
|
163
162
|
ChartControls,
|
|
164
163
|
{
|
|
165
164
|
toolbar: showToolbar ? toolbarSlot : null,
|
|
@@ -375,7 +374,7 @@ function YAxis({
|
|
|
375
374
|
tickMargin,
|
|
376
375
|
minTickGap,
|
|
377
376
|
width,
|
|
378
|
-
tickFormatter: isExpanded ? percentTick :
|
|
377
|
+
tickFormatter: tickFormatter ?? (isExpanded ? percentTick : defaultTick),
|
|
379
378
|
...rest,
|
|
380
379
|
children: axisLabel(label, "y")
|
|
381
380
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/charts/AreaChart/AreaChart.tsx"],"sourcesContent":["'use client'\n\nimport {\n Children,\n createContext,\n isValidElement,\n useCallback,\n useContext,\n useId,\n useMemo,\n useState,\n type ComponentProps,\n type FC,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport {\n Area as RechartsArea,\n AreaChart as RechartsAreaChart,\n CartesianGrid,\n XAxis as RechartsXAxis,\n YAxis as RechartsYAxis,\n} from 'recharts'\nimport { useReducedMotion } from 'motion/react'\nimport { ChartContainer, percentTick, type ChartConfig } from '../lib/chart'\nimport { ChartFigure } from '../lib/figure'\nimport { ChartEmpty, type ChartEmptyProps } from '../lib/empty'\nimport { axisLabel } from '../lib/axis'\nimport { defaultTick } from '../lib/format'\nimport { Annotation, ReferenceBand, ReferenceLine } from '../lib/annotations'\nimport { Values, findSlot, resolveValues, type ValuesProps } from '../lib/values'\nimport {\n ChartSonifyButton,\n Sonify,\n useChartSonifySeries,\n type SonifyProps,\n} from '../lib/sonify-control'\n\n/**\n * The axis props, with `label` narrowed to a string.\n *\n * Recharts' own `label` accepts a render function and a config object, neither\n * of which a call site should be reaching for to name an axis — and both of\n * which would let a consumer opt out of the system's own axis type styling\n * without noticing.\n */\nexport type ChartXAxisProps = Omit<ComponentProps<typeof RechartsXAxis>, 'label'> & {\n /** What this axis measures. Say the unit here or in the series label, once. */\n label?: string\n}\n\nexport type ChartYAxisProps = Omit<ComponentProps<typeof RechartsYAxis>, 'label'> & {\n /** What this axis measures. Say the unit here or in the series label, once. */\n label?: string\n}\n\nimport { ChartBackground, type ChartBackgroundVariant } from '../lib/background'\nimport { ChartDot, type ChartDotVariant } from '../lib/dot'\nimport {\n ChartLegend,\n ChartLegendContent,\n type ChartLegendAlign,\n type ChartLegendVariant,\n} from '../lib/legend'\nimport {\n ChartTooltip,\n ChartTooltipContent,\n type ChartTooltipRoundness,\n type ChartTooltipVariant,\n} from '../lib/tooltip'\nimport { Brush, ChartBrush, type BrushProps, type ChartBrushRange } from '../lib/brush'\nimport { ChartControls, Toolbar, type ToolbarProps } from '../lib/toolbar'\nimport { useChartZoom } from '../lib/zoom'\nimport { LoadingIndicator, LoadingShimmer, LOADING_KEY, useLoadingRows } from '../lib/loading'\nimport {\n AnimatedDashedStroke,\n AreaDottedFill,\n AreaGradientFill,\n AreaGradientReverseFill,\n AreaHatchedFill,\n AreaLinesFill,\n AreaSolidFill,\n RevealMask,\n SeriesGradient,\n UnselectedFill,\n type ChartRevealType,\n} from '../lib/paint'\n\n/** The series stroke, in pixels. Thin by default — law 1 is a thin mark. */\nconst STROKE_WIDTH = 0.8\n\n/** Every stacked area shares one id, which is what makes them stack. */\nconst STACK_ID = 'm22-area-stack'\n\n/**\n * Room around the plot, so the first and last tick labels are not sliced by the\n * container's edge. Recharts' own default is 5px on every side, which is not\n * enough for a label centred on the axis's first point.\n */\nconst CHART_MARGIN = { top: 8, right: 12, bottom: 0, left: 12 }\n\n/** How an area's curve is interpolated between points. */\nexport type ChartCurveType = ComponentProps<typeof RechartsArea>['type']\n\n/**\n * How an area meets the plot.\n *\n * In the monochrome default this is the PRIMARY way two series are told apart\n * — the ramp is the second encoding — so a chart with more than one area\n * should vary this before it varies anything else.\n */\nexport type AreaVariant = 'gradient' | 'gradient-reverse' | 'solid' | 'dotted' | 'lines' | 'hatched'\n\n/** How the line on top of an area is drawn. */\nexport type AreaStrokeVariant = 'solid' | 'dashed' | 'animated-dashed'\n\n/** How several areas combine: side by side, stacked, or normalised to 100%. */\nexport type AreaStackType = 'default' | 'stacked' | 'expanded'\n\ninterface AreaChartContextValue {\n config: ChartConfig\n /** The rows on screen, so a mark can label its own extremes. */\n rows: Record<string, unknown>[]\n curveType: ChartCurveType\n animationType: ChartRevealType\n isStacked: boolean\n isExpanded: boolean\n isLoading: boolean\n selectedDataKey: string | null\n selectDataKey: (dataKey: string | null) => void\n}\n\nconst AreaChartContext = createContext<AreaChartContextValue | null>(null)\n\nfunction useAreaChart(): AreaChartContextValue {\n const context = useContext(AreaChartContext)\n if (!context) throw new Error('An area chart part must be rendered inside <AreaChart>')\n return context\n}\n\n/** Fails the build when a config names a series the rows do not have. */\ntype ValidateKeys<TData, TConfig> = {\n [K in keyof TConfig]: K extends keyof TData ? ChartConfig[string] : never\n}\n\nexport interface AreaChartProps<\n TData extends Record<string, unknown>,\n TConfig extends Record<string, ChartConfig[string]>,\n> {\n /** Series keys → their label and paint. Declaration order is ramp order. */\n config: TConfig & ValidateKeys<TData, TConfig>\n /** The rows the chart draws. One entry per point, bar or category. */\n data: TData[]\n /**\n * What the chart shows, in a sentence a reader could act on. Required, and\n * announced to a screen reader even when it is not printed.\n */\n title: string\n /** Prints the title above the plot instead of hiding it from sight. */\n showTitle?: boolean\n /** A line under the title — the unit, the window, the caveat. */\n description?: ReactNode\n /**\n * The composed parts — axes, grid, tooltip, legend, and the marks\n * themselves.\n */\n children: ReactNode\n /** Merged onto the figure, last, so a call site can size or space it. */\n className?: string\n /** Escape hatch onto the raw Recharts chart element. */\n chartProps?: ComponentProps<typeof RechartsAreaChart>\n /** The curve every `<AreaChart.Area>` inherits. */\n curveType?: ChartCurveType\n /** The intro wipe every `<AreaChart.Area>` inherits. */\n animationType?: ChartRevealType\n /** How several marks combine: side by side, stacked, or normalised to 100%. */\n stackType?: AreaStackType\n /** The series lit on first render. Selection dims every other series. */\n defaultSelectedDataKey?: string | null\n /** Fires when the selection changes, and with null when it is cleared. */\n onSelectionChange?: (selectedDataKey: string | null) => void\n /**\n * Swaps the marks for an animated skeleton, keeping the measured height so\n * the page does not jump when the data lands.\n */\n isLoading?: boolean\n /** How many points the skeleton draws. */\n loadingPoints?: number\n /**\n * The row field on the category axis. Needed by the brush and by the table\n * view.\n */\n xDataKey?: keyof TData & string\n /**\n * Drops the hidden table view. Only correct when the page prints the data\n * itself.\n */\n hideDataTable?: boolean\n /**\n * What the chart shows when it has nothing to draw.\n *\n * Rendered instead of the plot whenever `data` is empty and the chart is not\n * loading — the state a real dashboard reaches within a week, and the one an\n * empty pair of axes is indistinguishable from a failed load. `false` keeps\n * the axes, for a chart whose emptiness is itself the reading.\n */\n empty?: ChartEmptyProps | false\n}\n\n/**\n * A filled series over a category axis — the shape for a magnitude that is\n * continuous, where the area under the line means something.\n *\n * Composed rather than configured: axes, grid, tooltip, legend and the areas\n * themselves are children, so a chart renders exactly the parts it asked for\n * and nothing is switched on by a prop nobody can see.\n *\n * Reach for `<LineChart>` instead when the reader is comparing several series\n * against each other rather than reading one total, and for `<BarChart>` when\n * the categories are discrete.\n *\n * @example\n * <AreaChart title=\"Visitors per month\" config={config} data={data} xDataKey=\"month\">\n * <AreaChart.Grid />\n * <AreaChart.XAxis dataKey=\"month\" />\n * <AreaChart.Tooltip />\n * <AreaChart.Area dataKey=\"desktop\" variant=\"gradient\" />\n * </AreaChart>\n */\nexport function AreaChart<\n TData extends Record<string, unknown>,\n TConfig extends Record<string, ChartConfig[string]>,\n>({\n config,\n data,\n title,\n showTitle,\n description,\n children,\n className,\n chartProps,\n curveType = 'linear',\n animationType = 'forward',\n stackType = 'default',\n defaultSelectedDataKey = null,\n onSelectionChange,\n isLoading = false,\n loadingPoints,\n xDataKey,\n hideDataTable = false,\n empty,\n}: AreaChartProps<TData, TConfig>) {\n const chartId = useId().replace(/:/g, '')\n const [selectedDataKey, setSelectedDataKey] = useState<string | null>(defaultSelectedDataKey)\n const { rows: loadingData, onShimmerExit } = useLoadingRows(isLoading, loadingPoints)\n // One window, two views of it: the brush strip below the plot and the\n // toolbar above it both read and write this. See `useChartZoom` for why they\n // are not two separate windows.\n const zoom = useChartZoom({ data, xDataKey })\n\n // The brush, the toolbar and the sonify control are declared as children but\n // never rendered into the Recharts tree — they live in the figure, outside\n // the SVG.\n const { brushSlot, toolbarSlot, sonifySlot, chartChildren } = useMemo(() => {\n const parts = Children.toArray(children)\n const element = parts.find((child) => isValidElement(child) && child.type === Brush)\n const props = (isValidElement(element) ? element.props : {}) as BrushProps\n return {\n brushSlot: { present: isValidElement(element), ...props },\n toolbarSlot: findSlot<ToolbarProps>(parts, Toolbar),\n sonifySlot: findSlot<SonifyProps>(parts, Sonify),\n chartChildren: parts.filter(\n (child) =>\n !(\n isValidElement(child) &&\n (child.type === Brush || child.type === Toolbar || child.type === Sonify)\n ),\n ),\n }\n }, [children])\n\n const columns = useMemo(\n () => Object.entries(config).map(([key, series]) => ({ key, label: series.label })),\n [config],\n )\n\n const isExpanded = stackType === 'expanded'\n const isStacked = stackType === 'stacked' || isExpanded\n const showBrush = brushSlot.present && !isLoading\n const showToolbar = toolbarSlot !== null && !isLoading\n // `empty === false` keeps the axes, for a chart whose emptiness is the\n // reading — a monitoring panel that should show a flat, silent range rather\n // than a message.\n const isEmpty = !isLoading && empty !== false && data.length === 0\n const displayData =\n isLoading ? loadingData : showBrush || showToolbar ? zoom.visibleData : data\n\n // The rows on screen, so a brushed range sounds like what it looks like. A\n // skeleton or an empty chart yields no finite value, which is what leaves the\n // control disabled rather than playing silence.\n const sonifySeries = useChartSonifySeries(\n sonifySlot,\n displayData as Record<string, unknown>[],\n config,\n xDataKey,\n )\n\n const selectDataKey = useCallback(\n (next: string | null) => {\n setSelectedDataKey(next)\n onSelectionChange?.(next)\n },\n [onSelectionChange],\n )\n\n const context = useMemo<AreaChartContextValue>(\n () => ({\n config,\n rows: displayData as Record<string, unknown>[],\n curveType,\n animationType,\n isStacked,\n isExpanded,\n isLoading,\n selectedDataKey,\n selectDataKey,\n }),\n [\n animationType,\n config,\n curveType,\n displayData,\n isExpanded,\n isLoading,\n isStacked,\n selectDataKey,\n selectedDataKey,\n ],\n )\n\n return (\n <AreaChartContext.Provider value={context}>\n <ChartFigure\n title={title}\n showTitle={showTitle}\n description={description}\n className={className}\n table={\n hideDataTable\n ? false\n : { rows: data, rowKey: xDataKey, columns }\n }\n >\n {sonifySlot && (\n <ChartSonifyButton {...sonifySlot} title={title} series={sonifySeries} />\n )}\n {isEmpty ? (\n <ChartEmpty {...(empty || {})} />\n ) : (\n <ChartControls\n toolbar={showToolbar ? toolbarSlot : null}\n zoom={zoom}\n title={title}\n rows={data}\n columns={columns}\n rowKey={xDataKey}\n >\n <ChartContainer\n config={config}\n footer={\n showBrush && (\n <ChartBrush\n data={data}\n config={config}\n xDataKey={xDataKey}\n variant=\"area\"\n curveType={curveType}\n height={brushSlot.height}\n formatLabel={brushSlot.formatLabel}\n stacked={isStacked}\n className=\"mt-1\"\n {...zoom.brushProps}\n onChange={(range: ChartBrushRange) => {\n zoom.brushProps.onChange(range)\n brushSlot.onChange?.(range)\n }}\n />\n )\n }\n >\n <RechartsAreaChart\n id={chartId}\n accessibilityLayer\n margin={CHART_MARGIN}\n stackOffset={isExpanded ? 'expand' : undefined}\n data={displayData}\n {...chartProps}\n >\n {chartChildren}\n {isLoading && (\n <LoadingArea chartId={chartId} curveType={curveType} onShimmerExit={onShimmerExit} />\n )}\n </RechartsAreaChart>\n </ChartContainer>\n </ChartControls>\n )}\n <LoadingIndicator isLoading={isLoading} />\n </ChartFigure>\n </AreaChartContext.Provider>\n )\n}\n\nexport interface AreaProps {\n /** The series to draw. Must exist on both the rows and the config. */\n dataKey: string\n variant?: AreaVariant\n strokeVariant?: AreaStrokeVariant\n strokeWidth?: number\n curveType?: ChartCurveType\n animationType?: ChartRevealType\n connectNulls?: boolean\n /** Lets a click on this area select it, dimming the rest. */\n isClickable?: boolean\n /** `<AreaChart.Dot>`, `<AreaChart.ActiveDot>` and `<AreaChart.Values>`. */\n children?: ReactNode\n areaProps?: ComponentProps<typeof RechartsArea>\n}\n\n/**\n * One filled series.\n *\n * Every area scopes its own gradients and patterns under a unique id, so any\n * number of them — each with its own variant, stroke and clickability — can\n * share a chart without one overwriting another's definitions.\n */\nfunction Area({\n dataKey,\n variant = 'gradient',\n strokeVariant = 'dashed',\n strokeWidth = STROKE_WIDTH,\n curveType,\n animationType,\n connectNulls = false,\n isClickable = false,\n children,\n areaProps,\n}: AreaProps) {\n const {\n config,\n curveType: defaultCurve,\n animationType: defaultAnimation,\n isStacked,\n isExpanded,\n isLoading,\n rows,\n selectedDataKey,\n selectDataKey,\n } = useAreaChart()\n const id = useId().replace(/:/g, '')\n const reduceMotion = useReducedMotion()\n\n if (isLoading) return null\n\n const reveal: ChartRevealType = reduceMotion ? 'none' : (animationType ?? defaultAnimation)\n const maskId = reveal === 'none' ? undefined : `${id}-reveal-mask`\n\n const isSelected = selectedDataKey === dataKey\n const hasSelection = selectedDataKey !== null\n const dimmed = hasSelection && !isSelected\n // The variant's own mask carries the fill strength now (`--chart-fill`), so\n // a base multiplier here would darken paper and erase ink a second time.\n // What is left is the SELECTION dim, which is a multiplier by definition.\n const opacity = dimmed\n ? { fill: 0.25, stroke: 0.3, dot: 0.3 }\n : { fill: 1, stroke: 1, dot: 1 }\n\n const { dot, activeDot } = resolveDots(children, id, dataKey, opacity.dot, maskId)\n const labels = resolveValues(\n findSlot<ValuesProps>(children, Values),\n rows.map((row) => Number(row[dataKey])).filter(Number.isFinite),\n )\n\n // An animated dash is a SMIL loop, which `keyframes.css` cannot reach — so it\n // is gated here rather than in CSS. It is also dropped while another series\n // is selected: a crawling dash on a dimmed line reads as the live one.\n const animateDash = strokeVariant === 'animated-dashed' && !hasSelection && !reduceMotion\n const isDashed = strokeVariant !== 'solid'\n\n return (\n <>\n <RechartsArea\n type={curveType ?? defaultCurve}\n dataKey={dataKey}\n connectNulls={connectNulls}\n fillOpacity={opacity.fill}\n strokeOpacity={opacity.stroke}\n fill={`url(#${id}-${dimmed ? 'unselected' : variant}-${dataKey})`}\n stroke={`url(#${id}-colors-${dataKey})`}\n stackId={isStacked ? STACK_ID : undefined}\n dot={dot}\n activeDot={activeDot}\n strokeWidth={strokeWidth}\n strokeDasharray={isDashed ? '3 3' : undefined}\n // Recharts' own area animation draws the fill and the dots on separate\n // clocks, so the markers arrive before the line reaches them. The mask\n // below wipes fill, stroke and dots in together instead.\n isAnimationActive={false}\n style={{\n ...(maskId ? { mask: `url(#${maskId})` } : {}),\n ...(isClickable ? { cursor: 'pointer' } : {}),\n }}\n onClick={() => {\n if (!isClickable) return\n selectDataKey(isSelected ? null : dataKey)\n }}\n {...areaProps}\n >\n {animateDash && <AnimatedDashedStroke />}\n {labels}\n </RechartsArea>\n <defs>\n {reveal !== 'none' && <RevealMask id={id} type={reveal} />}\n <SeriesGradient\n id={id}\n dataKey={dataKey}\n config={config}\n gradientUnits={isExpanded ? 'userSpaceOnUse' : 'objectBoundingBox'}\n />\n {variant === 'gradient' && <AreaGradientFill id={id} dataKey={dataKey} />}\n {variant === 'gradient-reverse' && <AreaGradientReverseFill id={id} dataKey={dataKey} />}\n {variant === 'solid' && <AreaSolidFill id={id} dataKey={dataKey} />}\n {variant === 'dotted' && <AreaDottedFill id={id} dataKey={dataKey} />}\n {variant === 'lines' && <AreaLinesFill id={id} dataKey={dataKey} />}\n {variant === 'hatched' && <AreaHatchedFill id={id} dataKey={dataKey} />}\n {dimmed && <UnselectedFill id={id} dataKey={dataKey} />}\n </defs>\n </>\n )\n}\n\nexport interface DotProps {\n variant?: ChartDotVariant\n}\n\n/**\n * The resting point marker for the area it is composed inside. A slot: it\n * renders nothing, and the parent reads its variant.\n */\nconst Dot: FC<DotProps> = () => null\n\n/** The marker under the pointer. Same slot shape as `<Dot>`. */\nconst ActiveDot: FC<DotProps> = () => null\n\n/** Lifts `<Dot>` and `<ActiveDot>` out of an area's children. */\nfunction resolveDots(\n children: ReactNode,\n id: string,\n dataKey: string,\n dotOpacity: number,\n maskId: string | undefined,\n) {\n let dot: ComponentProps<typeof RechartsArea>['dot'] = false\n let activeDot: ComponentProps<typeof RechartsArea>['activeDot'] = false\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return\n const { variant } = (child as ReactElement<DotProps>).props\n\n if (child.type === Dot) {\n // The resting dot shares the intro wipe so it appears with its own line.\n dot = (\n <ChartDot\n variant={variant}\n dataKey={dataKey}\n chartId={id}\n fillOpacity={dotOpacity}\n maskId={maskId}\n />\n )\n }\n if (child.type === ActiveDot) {\n // The active dot is never masked: it only exists on hover, long after\n // the intro has finished, and a stale mask would hide it entirely.\n activeDot = (\n <ChartDot variant={variant} dataKey={dataKey} chartId={id} fillOpacity={dotOpacity} />\n )\n }\n })\n\n return { dot, activeDot }\n}\n\n/** The category axis. Flat by default; every Recharts prop passes through. */\nfunction XAxis({\n tickLine = false,\n axisLine = false,\n tickMargin = 8,\n minTickGap = 8,\n label,\n ...rest\n}: ChartXAxisProps) {\n const { isLoading } = useAreaChart()\n if (isLoading) return null\n return (\n <RechartsXAxis\n tickLine={tickLine}\n axisLine={axisLine}\n tickMargin={tickMargin}\n minTickGap={minTickGap}\n {...rest}\n >\n {axisLabel(label, 'x')}\n </RechartsXAxis>\n )\n}\n\n/** The value axis. Formats as a percentage on its own when the stack is expanded. */\nfunction YAxis({\n tickLine = false,\n axisLine = false,\n tickMargin = 8,\n minTickGap = 8,\n width = 'auto',\n tickFormatter,\n label,\n ...rest\n}: ChartYAxisProps) {\n const { isLoading, isExpanded } = useAreaChart()\n if (isLoading) return null\n return (\n <RechartsYAxis\n tickLine={tickLine}\n axisLine={axisLine}\n tickMargin={tickMargin}\n minTickGap={minTickGap}\n width={width}\n tickFormatter={isExpanded ? percentTick : (tickFormatter ?? defaultTick)}\n {...rest}\n >\n {axisLabel(label, 'y')}\n </RechartsYAxis>\n )\n}\n\n/** Horizontal dashed rules. Vertical ones are off — they rarely earn their ink. */\nfunction Grid({\n vertical = false,\n strokeDasharray = '3 3',\n ...rest\n}: ComponentProps<typeof CartesianGrid>) {\n return <CartesianGrid vertical={vertical} strokeDasharray={strokeDasharray} {...rest} />\n}\n\nexport interface ChartTooltipSlotProps {\n variant?: ChartTooltipVariant\n roundness?: ChartTooltipRoundness\n /** Shows the tooltip at this row before anything is hovered. */\n defaultIndex?: number\n /** The crosshair that follows the pointer along the axis. */\n cursor?: boolean\n}\n\n/** The hover panel. Dims with the plot when a series is selected. */\nfunction Tooltip({ variant, roundness, defaultIndex, cursor = true }: ChartTooltipSlotProps) {\n const { isLoading, selectedDataKey } = useAreaChart()\n if (isLoading) return null\n\n return (\n <ChartTooltip\n defaultIndex={defaultIndex}\n cursor={cursor ? { strokeDasharray: '3 3', strokeWidth: STROKE_WIDTH } : false}\n content={\n <ChartTooltipContent selected={selectedDataKey} roundness={roundness} variant={variant} />\n }\n />\n )\n}\n\nexport interface ChartLegendSlotProps {\n variant?: ChartLegendVariant\n align?: ChartLegendAlign\n verticalAlign?: 'top' | 'middle' | 'bottom'\n /** Makes each entry a button that selects its series. */\n isClickable?: boolean\n}\n\n/**\n * The key. Required above one series: with the monochrome ramp two areas differ\n * by a step of grey and a texture, and neither names itself.\n */\nfunction Legend({\n variant,\n align = 'right',\n verticalAlign = 'top',\n isClickable = false,\n}: ChartLegendSlotProps) {\n const { selectedDataKey, selectDataKey } = useAreaChart()\n\n return (\n <ChartLegend\n verticalAlign={verticalAlign}\n align={align}\n content={\n <ChartLegendContent\n selected={selectedDataKey}\n onSelectChange={selectDataKey}\n isClickable={isClickable}\n variant={variant}\n />\n }\n />\n )\n}\n\n/** The decorative plate behind the plot. */\nfunction Background({ variant }: { variant: ChartBackgroundVariant }) {\n const { isLoading } = useAreaChart()\n if (isLoading) return null\n return <ChartBackground variant={variant} />\n}\n\n/** The skeleton drawn in place of the real areas while data is in flight. */\nfunction LoadingArea({\n chartId,\n curveType,\n onShimmerExit,\n}: {\n chartId: string\n curveType: ChartCurveType\n onShimmerExit: () => void\n}) {\n return (\n <>\n <RechartsArea\n type={curveType}\n dataKey={LOADING_KEY}\n fillOpacity={0.05}\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeOpacity={0.5}\n isAnimationActive={false}\n legendType=\"none\"\n tooltipType=\"none\"\n activeDot={false}\n dot={false}\n className=\"text-(--ink)\"\n style={{ mask: `url(#${chartId}-loading-mask)` }}\n />\n <defs>\n <LoadingShimmer id={chartId} onShimmerExit={onShimmerExit} />\n </defs>\n </>\n )\n}\n\n// Every part hangs off the root, so one import brings the whole vocabulary and\n// no two charts collide over a name like `Tooltip`.\nAreaChart.Area = Area\nAreaChart.Dot = Dot\nAreaChart.ActiveDot = ActiveDot\nAreaChart.XAxis = XAxis\nAreaChart.YAxis = YAxis\nAreaChart.Grid = Grid\nAreaChart.Tooltip = Tooltip\nAreaChart.Legend = Legend\nAreaChart.Background = Background\nAreaChart.ReferenceLine = ReferenceLine\nAreaChart.ReferenceBand = ReferenceBand\nAreaChart.Annotation = Annotation\nAreaChart.Values = Values\nAreaChart.Brush = Brush\nAreaChart.Toolbar = Toolbar\nAreaChart.Sonify = Sonify\n\nexport default AreaChart\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/charts/AreaChart/AreaChart.tsx"],"sourcesContent":["'use client'\n\nimport {\n Children,\n createContext,\n isValidElement,\n useContext,\n useId,\n useMemo,\n type ComponentProps,\n type FC,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport {\n Area as RechartsArea,\n AreaChart as RechartsAreaChart,\n CartesianGrid,\n XAxis as RechartsXAxis,\n YAxis as RechartsYAxis,\n} from 'recharts'\nimport { useReducedMotion } from 'motion/react'\nimport { ChartContainer, percentTick, type ChartConfig } from '../lib/chart'\nimport { ChartFigure } from '../lib/figure'\nimport { useChartSelection } from '../lib/selection'\nimport { type ChartEmptyProps } from '../lib/empty'\nimport { axisLabel } from '../lib/axis'\nimport { defaultTick } from '../lib/format'\nimport { Annotation, ReferenceBand, ReferenceLine } from '../lib/annotations'\nimport { Values, findSlot, resolveValues, type ValuesProps } from '../lib/values'\nimport {\n ChartSonifyButton,\n Sonify,\n useChartSonifySeries,\n type SonifyProps,\n} from '../lib/sonify-control'\n\n/**\n * The axis props, with `label` narrowed to a string.\n *\n * Recharts' own `label` accepts a render function and a config object, neither\n * of which a call site should be reaching for to name an axis — and both of\n * which would let a consumer opt out of the system's own axis type styling\n * without noticing.\n */\nexport type ChartXAxisProps = Omit<ComponentProps<typeof RechartsXAxis>, 'label'> & {\n /** What this axis measures. Say the unit here or in the series label, once. */\n label?: string\n}\n\nexport type ChartYAxisProps = Omit<ComponentProps<typeof RechartsYAxis>, 'label'> & {\n /** What this axis measures. Say the unit here or in the series label, once. */\n label?: string\n}\n\nimport { ChartBackground, type ChartBackgroundVariant } from '../lib/background'\nimport { ChartDot, type ChartDotVariant } from '../lib/dot'\nimport {\n ChartLegend,\n ChartLegendContent,\n type ChartLegendAlign,\n type ChartLegendVariant,\n} from '../lib/legend'\nimport {\n ChartTooltip,\n ChartTooltipContent,\n type ChartTooltipRoundness,\n type ChartTooltipVariant,\n} from '../lib/tooltip'\nimport { Brush, ChartBrush, type BrushProps, type ChartBrushRange } from '../lib/brush'\nimport { ChartControls, Toolbar, type ToolbarProps } from '../lib/toolbar'\nimport { useChartZoom } from '../lib/zoom'\nimport { LoadingIndicator, LoadingShimmer, LOADING_KEY, useLoadingRows } from '../lib/loading'\nimport {\n AnimatedDashedStroke,\n AreaDottedFill,\n AreaGradientFill,\n AreaGradientReverseFill,\n AreaHatchedFill,\n AreaLinesFill,\n AreaSolidFill,\n RevealMask,\n SeriesGradient,\n UnselectedFill,\n type ChartRevealType,\n} from '../lib/paint'\n\n/** The series stroke, in pixels. Thin by default — law 1 is a thin mark. */\nconst STROKE_WIDTH = 0.8\n\n/** Every stacked area shares one id, which is what makes them stack. */\nconst STACK_ID = 'm22-area-stack'\n\n/**\n * Room around the plot, so the first and last tick labels are not sliced by the\n * container's edge. Recharts' own default is 5px on every side, which is not\n * enough for a label centred on the axis's first point.\n */\nconst CHART_MARGIN = { top: 8, right: 12, bottom: 0, left: 12 }\n\n/** How an area's curve is interpolated between points. */\nexport type ChartCurveType = ComponentProps<typeof RechartsArea>['type']\n\n/**\n * How an area meets the plot.\n *\n * In the monochrome default this is the PRIMARY way two series are told apart\n * — the ramp is the second encoding — so a chart with more than one area\n * should vary this before it varies anything else.\n */\nexport type AreaVariant = 'gradient' | 'gradient-reverse' | 'solid' | 'dotted' | 'lines' | 'hatched'\n\n/** How the line on top of an area is drawn. */\nexport type AreaStrokeVariant = 'solid' | 'dashed' | 'animated-dashed'\n\n/** How several areas combine: side by side, stacked, or normalised to 100%. */\nexport type AreaStackType = 'default' | 'stacked' | 'expanded'\n\ninterface AreaChartContextValue {\n config: ChartConfig\n /** The rows on screen, so a mark can label its own extremes. */\n rows: Record<string, unknown>[]\n curveType: ChartCurveType\n animationType: ChartRevealType\n isStacked: boolean\n isExpanded: boolean\n isLoading: boolean\n selectedDataKey: string | null\n selectDataKey: (dataKey: string | null) => void\n}\n\nconst AreaChartContext = createContext<AreaChartContextValue | null>(null)\n\nfunction useAreaChart(): AreaChartContextValue {\n const context = useContext(AreaChartContext)\n if (!context) throw new Error('An area chart part must be rendered inside <AreaChart>')\n return context\n}\n\n/** Fails the build when a config names a series the rows do not have. */\ntype ValidateKeys<TData, TConfig> = {\n [K in keyof TConfig]: K extends keyof TData ? ChartConfig[string] : never\n}\n\nexport interface AreaChartProps<\n TData extends Record<string, unknown>,\n TConfig extends Record<string, ChartConfig[string]>,\n> {\n /** Series keys → their label and paint. Declaration order is ramp order. */\n config: TConfig & ValidateKeys<TData, TConfig>\n /** The rows the chart draws. One entry per point, bar or category. */\n data: TData[]\n /**\n * What the chart shows, in a sentence a reader could act on. Required, and\n * announced to a screen reader even when it is not printed.\n */\n title: string\n /** Prints the title above the plot instead of hiding it from sight. */\n showTitle?: boolean\n /** A line under the title — the unit, the window, the caveat. */\n description?: ReactNode\n /**\n * The composed parts — axes, grid, tooltip, legend, and the marks\n * themselves.\n */\n children: ReactNode\n /** Merged onto the figure, last, so a call site can size or space it. */\n className?: string\n /** Escape hatch onto the raw Recharts chart element. */\n chartProps?: ComponentProps<typeof RechartsAreaChart>\n /** The curve every `<AreaChart.Area>` inherits. */\n curveType?: ChartCurveType\n /** The intro wipe every `<AreaChart.Area>` inherits. */\n animationType?: ChartRevealType\n /** How several marks combine: side by side, stacked, or normalised to 100%. */\n stackType?: AreaStackType\n /** The series lit on first render, when the chart keeps its own selection. */\n defaultSelectedDataKey?: string | null\n /**\n * The selected series, driven from outside.\n *\n * Give this and the chart follows it; leave it undefined and the chart keeps\n * its own, starting from `defaultSelectedDataKey`.\n */\n selectedDataKey?: string | null\n /** Fires when the selection changes, and with null when it is cleared. */\n onSelectionChange?: (selectedDataKey: string | null) => void\n /**\n * Swaps the marks for an animated skeleton, keeping the measured height so\n * the page does not jump when the data lands.\n */\n isLoading?: boolean\n /** How many points the skeleton draws. */\n loadingPoints?: number\n /**\n * The row field on the category axis. Needed by the brush and by the table\n * view.\n */\n xDataKey?: keyof TData & string\n /**\n * Drops the hidden table view. Only correct when the page prints the data\n * itself.\n */\n hideDataTable?: boolean\n /**\n * What the chart shows when it has nothing to draw.\n *\n * Rendered instead of the plot whenever `data` is empty and the chart is not\n * loading — the state a real dashboard reaches within a week, and the one an\n * empty pair of axes is indistinguishable from a failed load. `false` keeps\n * the axes, for a chart whose emptiness is itself the reading.\n */\n empty?: ChartEmptyProps | false\n}\n\n/**\n * A filled series over a category axis — the shape for a magnitude that is\n * continuous, where the area under the line means something.\n *\n * Composed rather than configured: axes, grid, tooltip, legend and the areas\n * themselves are children, so a chart renders exactly the parts it asked for\n * and nothing is switched on by a prop nobody can see.\n *\n * Reach for `<LineChart>` instead when the reader is comparing several series\n * against each other rather than reading one total, and for `<BarChart>` when\n * the categories are discrete.\n *\n * @example\n * <AreaChart title=\"Visitors per month\" config={config} data={data} xDataKey=\"month\">\n * <AreaChart.Grid />\n * <AreaChart.XAxis dataKey=\"month\" />\n * <AreaChart.Tooltip />\n * <AreaChart.Area dataKey=\"desktop\" variant=\"gradient\" />\n * </AreaChart>\n */\nexport function AreaChart<\n TData extends Record<string, unknown>,\n TConfig extends Record<string, ChartConfig[string]>,\n>({\n config,\n data,\n title,\n showTitle,\n description,\n children,\n className,\n chartProps,\n curveType = 'linear',\n animationType = 'forward',\n stackType = 'default',\n defaultSelectedDataKey = null,\n selectedDataKey: controlledDataKey,\n onSelectionChange,\n isLoading = false,\n loadingPoints,\n xDataKey,\n hideDataTable = false,\n empty,\n}: AreaChartProps<TData, TConfig>) {\n const chartId = useId().replace(/:/g, '')\n const { rows: loadingData, onShimmerExit } = useLoadingRows(isLoading, loadingPoints)\n // One window, two views of it: the brush strip below the plot and the\n // toolbar above it both read and write this. See `useChartZoom` for why they\n // are not two separate windows.\n const zoom = useChartZoom({ data, xDataKey })\n\n // The brush, the toolbar and the sonify control are declared as children but\n // never rendered into the Recharts tree — they live in the figure, outside\n // the SVG.\n const { brushSlot, toolbarSlot, sonifySlot, chartChildren } = useMemo(() => {\n const parts = Children.toArray(children)\n const element = parts.find((child) => isValidElement(child) && child.type === Brush)\n const props = (isValidElement(element) ? element.props : {}) as BrushProps\n return {\n brushSlot: { present: isValidElement(element), ...props },\n toolbarSlot: findSlot<ToolbarProps>(parts, Toolbar),\n sonifySlot: findSlot<SonifyProps>(parts, Sonify),\n chartChildren: parts.filter(\n (child) =>\n !(\n isValidElement(child) &&\n (child.type === Brush || child.type === Toolbar || child.type === Sonify)\n ),\n ),\n }\n }, [children])\n\n const columns = useMemo(\n () => Object.entries(config).map(([key, series]) => ({ key, label: series.label })),\n [config],\n )\n\n const isExpanded = stackType === 'expanded'\n const isStacked = stackType === 'stacked' || isExpanded\n const showBrush = brushSlot.present && !isLoading\n const showToolbar = toolbarSlot !== null && !isLoading\n // `empty === false` keeps the axes, for a chart whose emptiness is the\n // reading — a monitoring panel that should show a flat, silent range rather\n // than a message.\n const isEmpty = !isLoading && empty !== false && data.length === 0\n const displayData =\n isLoading ? loadingData : showBrush || showToolbar ? zoom.visibleData : data\n\n // The rows on screen, so a brushed range sounds like what it looks like. A\n // skeleton or an empty chart yields no finite value, which is what leaves the\n // control disabled rather than playing silence.\n const sonifySeries = useChartSonifySeries(\n sonifySlot,\n displayData as Record<string, unknown>[],\n config,\n xDataKey,\n )\n\n const [selectedDataKey, selectDataKey] = useChartSelection(\n controlledDataKey,\n defaultSelectedDataKey,\n onSelectionChange,\n )\n\n const context = useMemo<AreaChartContextValue>(\n () => ({\n config,\n rows: displayData as Record<string, unknown>[],\n curveType,\n animationType,\n isStacked,\n isExpanded,\n isLoading,\n selectedDataKey,\n selectDataKey,\n }),\n [\n animationType,\n config,\n curveType,\n displayData,\n isExpanded,\n isLoading,\n isStacked,\n selectDataKey,\n selectedDataKey,\n ],\n )\n\n return (\n <AreaChartContext.Provider value={context}>\n <ChartFigure\n title={title}\n showTitle={showTitle}\n description={description}\n className={className}\n table={\n hideDataTable\n ? false\n : { rows: data, rowKey: xDataKey, columns }\n }\n isEmpty={isEmpty}\n empty={empty}\n >\n {sonifySlot && (\n <ChartSonifyButton {...sonifySlot} title={title} series={sonifySeries} />\n )}\n <ChartControls\n toolbar={showToolbar ? toolbarSlot : null}\n zoom={zoom}\n title={title}\n rows={data}\n columns={columns}\n rowKey={xDataKey}\n >\n <ChartContainer\n config={config}\n footer={\n showBrush && (\n <ChartBrush\n data={data}\n config={config}\n xDataKey={xDataKey}\n variant=\"area\"\n curveType={curveType}\n height={brushSlot.height}\n formatLabel={brushSlot.formatLabel}\n stacked={isStacked}\n className=\"mt-1\"\n {...zoom.brushProps}\n onChange={(range: ChartBrushRange) => {\n zoom.brushProps.onChange(range)\n brushSlot.onChange?.(range)\n }}\n />\n )\n }\n >\n <RechartsAreaChart\n id={chartId}\n accessibilityLayer\n margin={CHART_MARGIN}\n stackOffset={isExpanded ? 'expand' : undefined}\n data={displayData}\n {...chartProps}\n >\n {chartChildren}\n {isLoading && (\n <LoadingArea chartId={chartId} curveType={curveType} onShimmerExit={onShimmerExit} />\n )}\n </RechartsAreaChart>\n </ChartContainer>\n </ChartControls>\n <LoadingIndicator isLoading={isLoading} />\n </ChartFigure>\n </AreaChartContext.Provider>\n )\n}\n\nexport interface AreaProps {\n /** The series to draw. Must exist on both the rows and the config. */\n dataKey: string\n variant?: AreaVariant\n strokeVariant?: AreaStrokeVariant\n strokeWidth?: number\n curveType?: ChartCurveType\n animationType?: ChartRevealType\n connectNulls?: boolean\n /** Lets a click on this area select it, dimming the rest. */\n isClickable?: boolean\n /** `<AreaChart.Dot>`, `<AreaChart.ActiveDot>` and `<AreaChart.Values>`. */\n children?: ReactNode\n areaProps?: ComponentProps<typeof RechartsArea>\n}\n\n/**\n * One filled series.\n *\n * Every area scopes its own gradients and patterns under a unique id, so any\n * number of them — each with its own variant, stroke and clickability — can\n * share a chart without one overwriting another's definitions.\n */\nfunction Area({\n dataKey,\n variant = 'gradient',\n strokeVariant = 'dashed',\n strokeWidth = STROKE_WIDTH,\n curveType,\n animationType,\n connectNulls = false,\n isClickable = false,\n children,\n areaProps,\n}: AreaProps) {\n const {\n config,\n curveType: defaultCurve,\n animationType: defaultAnimation,\n isStacked,\n isExpanded,\n isLoading,\n rows,\n selectedDataKey,\n selectDataKey,\n } = useAreaChart()\n const id = useId().replace(/:/g, '')\n const reduceMotion = useReducedMotion()\n\n if (isLoading) return null\n\n const reveal: ChartRevealType = reduceMotion ? 'none' : (animationType ?? defaultAnimation)\n const maskId = reveal === 'none' ? undefined : `${id}-reveal-mask`\n\n const isSelected = selectedDataKey === dataKey\n const hasSelection = selectedDataKey !== null\n const dimmed = hasSelection && !isSelected\n // The variant's own mask carries the fill strength now (`--chart-fill`), so\n // a base multiplier here would darken paper and erase ink a second time.\n // What is left is the SELECTION dim, which is a multiplier by definition.\n const opacity = dimmed\n ? { fill: 0.25, stroke: 0.3, dot: 0.3 }\n : { fill: 1, stroke: 1, dot: 1 }\n\n const { dot, activeDot } = resolveDots(children, id, dataKey, opacity.dot, maskId)\n const labels = resolveValues(\n findSlot<ValuesProps>(children, Values),\n rows.map((row) => Number(row[dataKey])).filter(Number.isFinite),\n )\n\n // An animated dash is a SMIL loop, which `keyframes.css` cannot reach — so it\n // is gated here rather than in CSS. It is also dropped while another series\n // is selected: a crawling dash on a dimmed line reads as the live one.\n const animateDash = strokeVariant === 'animated-dashed' && !hasSelection && !reduceMotion\n const isDashed = strokeVariant !== 'solid'\n\n return (\n <>\n <RechartsArea\n type={curveType ?? defaultCurve}\n dataKey={dataKey}\n connectNulls={connectNulls}\n fillOpacity={opacity.fill}\n strokeOpacity={opacity.stroke}\n fill={`url(#${id}-${dimmed ? 'unselected' : variant}-${dataKey})`}\n stroke={`url(#${id}-colors-${dataKey})`}\n stackId={isStacked ? STACK_ID : undefined}\n dot={dot}\n activeDot={activeDot}\n strokeWidth={strokeWidth}\n strokeDasharray={isDashed ? '3 3' : undefined}\n // Recharts' own area animation draws the fill and the dots on separate\n // clocks, so the markers arrive before the line reaches them. The mask\n // below wipes fill, stroke and dots in together instead.\n isAnimationActive={false}\n style={{\n ...(maskId ? { mask: `url(#${maskId})` } : {}),\n ...(isClickable ? { cursor: 'pointer' } : {}),\n }}\n onClick={() => {\n if (!isClickable) return\n selectDataKey(isSelected ? null : dataKey)\n }}\n {...areaProps}\n >\n {animateDash && <AnimatedDashedStroke />}\n {labels}\n </RechartsArea>\n <defs>\n {reveal !== 'none' && <RevealMask id={id} type={reveal} />}\n <SeriesGradient\n id={id}\n dataKey={dataKey}\n config={config}\n gradientUnits={isExpanded ? 'userSpaceOnUse' : 'objectBoundingBox'}\n />\n {variant === 'gradient' && <AreaGradientFill id={id} dataKey={dataKey} />}\n {variant === 'gradient-reverse' && <AreaGradientReverseFill id={id} dataKey={dataKey} />}\n {variant === 'solid' && <AreaSolidFill id={id} dataKey={dataKey} />}\n {variant === 'dotted' && <AreaDottedFill id={id} dataKey={dataKey} />}\n {variant === 'lines' && <AreaLinesFill id={id} dataKey={dataKey} />}\n {variant === 'hatched' && <AreaHatchedFill id={id} dataKey={dataKey} />}\n {dimmed && <UnselectedFill id={id} dataKey={dataKey} />}\n </defs>\n </>\n )\n}\n\nexport interface DotProps {\n variant?: ChartDotVariant\n}\n\n/**\n * The resting point marker for the area it is composed inside. A slot: it\n * renders nothing, and the parent reads its variant.\n */\nconst Dot: FC<DotProps> = () => null\n\n/** The marker under the pointer. Same slot shape as `<Dot>`. */\nconst ActiveDot: FC<DotProps> = () => null\n\n/** Lifts `<Dot>` and `<ActiveDot>` out of an area's children. */\nfunction resolveDots(\n children: ReactNode,\n id: string,\n dataKey: string,\n dotOpacity: number,\n maskId: string | undefined,\n) {\n let dot: ComponentProps<typeof RechartsArea>['dot'] = false\n let activeDot: ComponentProps<typeof RechartsArea>['activeDot'] = false\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return\n const { variant } = (child as ReactElement<DotProps>).props\n\n if (child.type === Dot) {\n // The resting dot shares the intro wipe so it appears with its own line.\n dot = (\n <ChartDot\n variant={variant}\n dataKey={dataKey}\n chartId={id}\n fillOpacity={dotOpacity}\n maskId={maskId}\n />\n )\n }\n if (child.type === ActiveDot) {\n // The active dot is never masked: it only exists on hover, long after\n // the intro has finished, and a stale mask would hide it entirely.\n activeDot = (\n <ChartDot variant={variant} dataKey={dataKey} chartId={id} fillOpacity={dotOpacity} />\n )\n }\n })\n\n return { dot, activeDot }\n}\n\n/** The category axis. Flat by default; every Recharts prop passes through. */\nfunction XAxis({\n tickLine = false,\n axisLine = false,\n tickMargin = 8,\n minTickGap = 8,\n label,\n ...rest\n}: ChartXAxisProps) {\n const { isLoading } = useAreaChart()\n if (isLoading) return null\n return (\n <RechartsXAxis\n tickLine={tickLine}\n axisLine={axisLine}\n tickMargin={tickMargin}\n minTickGap={minTickGap}\n {...rest}\n >\n {axisLabel(label, 'x')}\n </RechartsXAxis>\n )\n}\n\n/**\n * The value axis. Formats as a percentage on its own when the stack is\n * expanded, and steps aside for a `tickFormatter` of your own.\n */\nfunction YAxis({\n tickLine = false,\n axisLine = false,\n tickMargin = 8,\n minTickGap = 8,\n width = 'auto',\n tickFormatter,\n label,\n ...rest\n}: ChartYAxisProps) {\n const { isLoading, isExpanded } = useAreaChart()\n if (isLoading) return null\n return (\n <RechartsYAxis\n tickLine={tickLine}\n axisLine={axisLine}\n tickMargin={tickMargin}\n minTickGap={minTickGap}\n width={width}\n // A caller's formatter wins over the expanded stack's own, rather than\n // being dropped by it: an axis that silently ignores what it was handed\n // is indistinguishable from one that was handed a typo.\n tickFormatter={tickFormatter ?? (isExpanded ? percentTick : defaultTick)}\n {...rest}\n >\n {axisLabel(label, 'y')}\n </RechartsYAxis>\n )\n}\n\n/** Horizontal dashed rules. Vertical ones are off — they rarely earn their ink. */\nfunction Grid({\n vertical = false,\n strokeDasharray = '3 3',\n ...rest\n}: ComponentProps<typeof CartesianGrid>) {\n return <CartesianGrid vertical={vertical} strokeDasharray={strokeDasharray} {...rest} />\n}\n\nexport interface ChartTooltipSlotProps {\n variant?: ChartTooltipVariant\n roundness?: ChartTooltipRoundness\n /** Shows the tooltip at this row before anything is hovered. */\n defaultIndex?: number\n /** The crosshair that follows the pointer along the axis. */\n cursor?: boolean\n}\n\n/** The hover panel. Dims with the plot when a series is selected. */\nfunction Tooltip({ variant, roundness, defaultIndex, cursor = true }: ChartTooltipSlotProps) {\n const { isLoading, selectedDataKey } = useAreaChart()\n if (isLoading) return null\n\n return (\n <ChartTooltip\n defaultIndex={defaultIndex}\n cursor={cursor ? { strokeDasharray: '3 3', strokeWidth: STROKE_WIDTH } : false}\n content={\n <ChartTooltipContent selected={selectedDataKey} roundness={roundness} variant={variant} />\n }\n />\n )\n}\n\nexport interface ChartLegendSlotProps {\n variant?: ChartLegendVariant\n align?: ChartLegendAlign\n verticalAlign?: 'top' | 'middle' | 'bottom'\n /** Makes each entry a button that selects its series. */\n isClickable?: boolean\n}\n\n/**\n * The key. Required above one series: with the monochrome ramp two areas differ\n * by a step of grey and a texture, and neither names itself.\n */\nfunction Legend({\n variant,\n align = 'right',\n verticalAlign = 'top',\n isClickable = false,\n}: ChartLegendSlotProps) {\n const { selectedDataKey, selectDataKey } = useAreaChart()\n\n return (\n <ChartLegend\n verticalAlign={verticalAlign}\n align={align}\n content={\n <ChartLegendContent\n selected={selectedDataKey}\n onSelectChange={selectDataKey}\n isClickable={isClickable}\n variant={variant}\n />\n }\n />\n )\n}\n\n/** The decorative plate behind the plot. */\nfunction Background({ variant }: { variant: ChartBackgroundVariant }) {\n const { isLoading } = useAreaChart()\n if (isLoading) return null\n return <ChartBackground variant={variant} />\n}\n\n/** The skeleton drawn in place of the real areas while data is in flight. */\nfunction LoadingArea({\n chartId,\n curveType,\n onShimmerExit,\n}: {\n chartId: string\n curveType: ChartCurveType\n onShimmerExit: () => void\n}) {\n return (\n <>\n <RechartsArea\n type={curveType}\n dataKey={LOADING_KEY}\n fillOpacity={0.05}\n fill=\"currentColor\"\n stroke=\"currentColor\"\n strokeOpacity={0.5}\n isAnimationActive={false}\n legendType=\"none\"\n tooltipType=\"none\"\n activeDot={false}\n dot={false}\n className=\"text-(--ink)\"\n style={{ mask: `url(#${chartId}-loading-mask)` }}\n />\n <defs>\n <LoadingShimmer id={chartId} onShimmerExit={onShimmerExit} />\n </defs>\n </>\n )\n}\n\n// Every part hangs off the root, so one import brings the whole vocabulary and\n// no two charts collide over a name like `Tooltip`.\nAreaChart.Area = Area\nAreaChart.Dot = Dot\nAreaChart.ActiveDot = ActiveDot\nAreaChart.XAxis = XAxis\nAreaChart.YAxis = YAxis\nAreaChart.Grid = Grid\nAreaChart.Tooltip = Tooltip\nAreaChart.Legend = Legend\nAreaChart.Background = Background\nAreaChart.ReferenceLine = ReferenceLine\nAreaChart.ReferenceBand = ReferenceBand\nAreaChart.Annotation = Annotation\nAreaChart.Values = Values\nAreaChart.Brush = Brush\nAreaChart.Toolbar = Toolbar\nAreaChart.Sonify = Sonify\n\nexport default AreaChart\n"],"mappings":"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","names":[]}
|
|
@@ -89,8 +89,15 @@ interface BarChartProps<TData extends Record<string, unknown>, TConfig extends R
|
|
|
89
89
|
barGap?: number;
|
|
90
90
|
/** Gap between categories. */
|
|
91
91
|
barCategoryGap?: number;
|
|
92
|
-
/** The series lit on first render
|
|
92
|
+
/** The series lit on first render, when the chart keeps its own selection. */
|
|
93
93
|
defaultSelectedDataKey?: string | null;
|
|
94
|
+
/**
|
|
95
|
+
* The selected series, driven from outside.
|
|
96
|
+
*
|
|
97
|
+
* Give this and the chart follows it; leave it undefined and the chart keeps
|
|
98
|
+
* its own, starting from `defaultSelectedDataKey`.
|
|
99
|
+
*/
|
|
100
|
+
selectedDataKey?: string | null;
|
|
94
101
|
/** Fires when the selection changes, and with null when it is cleared. */
|
|
95
102
|
onSelectionChange?: (selectedDataKey: string | null) => void;
|
|
96
103
|
/**
|
|
@@ -134,7 +141,7 @@ interface BarChartProps<TData extends Record<string, unknown>, TConfig extends R
|
|
|
134
141
|
* <BarChart.Bar dataKey="desktop" variant="duotone" />
|
|
135
142
|
* </BarChart>
|
|
136
143
|
*/
|
|
137
|
-
declare function BarChart<TData extends Record<string, unknown>, TConfig extends Record<string, ChartConfig[string]>>({ config, data, title, showTitle, description, children, className, chartProps, stackType, orientation, barRadius, animationType, barGap, barCategoryGap, defaultSelectedDataKey, onSelectionChange, isLoading, loadingBars, xDataKey, hideDataTable, empty, }: BarChartProps<TData, TConfig>): react.JSX.Element;
|
|
144
|
+
declare function BarChart<TData extends Record<string, unknown>, TConfig extends Record<string, ChartConfig[string]>>({ config, data, title, showTitle, description, children, className, chartProps, stackType, orientation, barRadius, animationType, barGap, barCategoryGap, defaultSelectedDataKey, selectedDataKey: controlledDataKey, onSelectionChange, isLoading, loadingBars, xDataKey, hideDataTable, empty, }: BarChartProps<TData, TConfig>): react.JSX.Element;
|
|
138
145
|
declare namespace BarChart {
|
|
139
146
|
var Bar: ({ dataKey, variant, radius, animationType, isClickable, enableHoverHighlight, glowing, buffer, children, barProps, }: BarProps) => react.JSX.Element | null;
|
|
140
147
|
var XAxis: ({ tickLine, axisLine, tickMargin, minTickGap, type, label, ...rest }: ChartXAxisProps) => react.JSX.Element | null;
|
|
@@ -165,10 +172,14 @@ interface BarProps {
|
|
|
165
172
|
/** A halo behind the bars — for the one series that is the point of the figure. */
|
|
166
173
|
glowing?: boolean;
|
|
167
174
|
/**
|
|
168
|
-
* Draws the
|
|
175
|
+
* Draws the last row of `data` as an open hatch rather than a solid bar.
|
|
169
176
|
*
|
|
170
177
|
* The idiom for a period still in progress: the bar is the same height as any
|
|
171
178
|
* other but is visibly not the same kind of fact.
|
|
179
|
+
*
|
|
180
|
+
* Tied to the last ROW, not to the last bar on screen. Brush or zoom into the
|
|
181
|
+
* middle of the range and no bar is hatched, because none of the periods in
|
|
182
|
+
* the window is still being counted.
|
|
172
183
|
*/
|
|
173
184
|
buffer?: boolean;
|
|
174
185
|
/** `<BarChart.Values>`. */
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
Children,
|
|
5
5
|
createContext,
|
|
6
6
|
isValidElement,
|
|
7
|
-
useCallback,
|
|
8
7
|
useContext,
|
|
9
8
|
useId,
|
|
10
9
|
useMemo,
|
|
@@ -21,7 +20,8 @@ import {
|
|
|
21
20
|
import { motion, useReducedMotion } from "motion/react";
|
|
22
21
|
import { ChartContainer } from "../lib/chart.js";
|
|
23
22
|
import { ChartFigure } from "../lib/figure.js";
|
|
24
|
-
import {
|
|
23
|
+
import { useChartSelection } from "../lib/selection.js";
|
|
24
|
+
import {} from "../lib/empty.js";
|
|
25
25
|
import { axisLabel } from "../lib/axis.js";
|
|
26
26
|
import { defaultTick } from "../lib/format.js";
|
|
27
27
|
import { Annotation, ReferenceBand, ReferenceLine } from "../lib/annotations.js";
|
|
@@ -53,6 +53,8 @@ const GROW_DURATION = 0.5;
|
|
|
53
53
|
const GROW_STAGGER = 0.05;
|
|
54
54
|
const STACK_ID = "m22-bar-stack";
|
|
55
55
|
const CHART_MARGIN = { top: 8, right: 12, bottom: 0, left: 12 };
|
|
56
|
+
const FOOT_GAP = 3;
|
|
57
|
+
const MIN_BAR_LENGTH = 1;
|
|
56
58
|
const BarChartContext = createContext(null);
|
|
57
59
|
function useBarChart() {
|
|
58
60
|
const context = useContext(BarChartContext);
|
|
@@ -75,6 +77,7 @@ function BarChart({
|
|
|
75
77
|
barGap,
|
|
76
78
|
barCategoryGap,
|
|
77
79
|
defaultSelectedDataKey = null,
|
|
80
|
+
selectedDataKey: controlledDataKey,
|
|
78
81
|
onSelectionChange,
|
|
79
82
|
isLoading = false,
|
|
80
83
|
loadingBars,
|
|
@@ -84,7 +87,6 @@ function BarChart({
|
|
|
84
87
|
}) {
|
|
85
88
|
const chartId = useId().replace(/:/g, "");
|
|
86
89
|
const [introStartedAt] = useState(() => Date.now());
|
|
87
|
-
const [selectedDataKey, setSelectedDataKey] = useState(defaultSelectedDataKey);
|
|
88
90
|
const [isPointerInChart, setIsPointerInChart] = useState(false);
|
|
89
91
|
const { rows: loadingData, onShimmerExit } = useLoadingRows(isLoading, loadingBars ?? 12);
|
|
90
92
|
const zoom = useChartZoom({ data, xDataKey });
|
|
@@ -111,18 +113,17 @@ function BarChart({
|
|
|
111
113
|
const showToolbar = toolbarSlot !== null && !isLoading;
|
|
112
114
|
const isEmpty = !isLoading && empty !== false && data.length === 0;
|
|
113
115
|
const displayData = showBrush || showToolbar ? zoom.visibleData : data;
|
|
116
|
+
const bufferIndex = data.length > 0 && displayData[displayData.length - 1] === data[data.length - 1] ? displayData.length - 1 : -1;
|
|
114
117
|
const sonifySeries = useChartSonifySeries(
|
|
115
118
|
sonifySlot,
|
|
116
119
|
isLoading ? loadingData : displayData,
|
|
117
120
|
config,
|
|
118
121
|
xDataKey
|
|
119
122
|
);
|
|
120
|
-
const selectDataKey =
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
},
|
|
125
|
-
[onSelectionChange]
|
|
123
|
+
const [selectedDataKey, selectDataKey] = useChartSelection(
|
|
124
|
+
controlledDataKey,
|
|
125
|
+
defaultSelectedDataKey,
|
|
126
|
+
onSelectionChange
|
|
126
127
|
);
|
|
127
128
|
const context = useMemo(
|
|
128
129
|
() => ({
|
|
@@ -135,6 +136,7 @@ function BarChart({
|
|
|
135
136
|
animationType,
|
|
136
137
|
introStartedAt,
|
|
137
138
|
dataLength: displayData.length,
|
|
139
|
+
bufferIndex,
|
|
138
140
|
selectedDataKey,
|
|
139
141
|
selectDataKey,
|
|
140
142
|
isPointerInChart
|
|
@@ -142,6 +144,7 @@ function BarChart({
|
|
|
142
144
|
[
|
|
143
145
|
animationType,
|
|
144
146
|
barRadius,
|
|
147
|
+
bufferIndex,
|
|
145
148
|
config,
|
|
146
149
|
displayData,
|
|
147
150
|
introStartedAt,
|
|
@@ -161,9 +164,11 @@ function BarChart({
|
|
|
161
164
|
description,
|
|
162
165
|
className,
|
|
163
166
|
table: hideDataTable ? false : { rows: data, rowKey: xDataKey, columns },
|
|
167
|
+
isEmpty,
|
|
168
|
+
empty,
|
|
164
169
|
children: [
|
|
165
170
|
sonifySlot && /* @__PURE__ */ jsx(ChartSonifyButton, { ...sonifySlot, title, series: sonifySeries }),
|
|
166
|
-
|
|
171
|
+
/* @__PURE__ */ jsx(
|
|
167
172
|
ChartControls,
|
|
168
173
|
{
|
|
169
174
|
toolbar: showToolbar ? toolbarSlot : null,
|
|
@@ -246,6 +251,7 @@ function Bar({
|
|
|
246
251
|
animationType: defaultAnimation,
|
|
247
252
|
introStartedAt,
|
|
248
253
|
dataLength,
|
|
254
|
+
bufferIndex,
|
|
249
255
|
selectedDataKey,
|
|
250
256
|
selectDataKey,
|
|
251
257
|
isPointerInChart
|
|
@@ -270,6 +276,7 @@ function Bar({
|
|
|
270
276
|
introStartedAt,
|
|
271
277
|
selectedDataKey,
|
|
272
278
|
dataLength,
|
|
279
|
+
bufferIndex,
|
|
273
280
|
onSelect: () => {
|
|
274
281
|
if (!isClickable) return;
|
|
275
282
|
selectDataKey(isSelected ? null : dataKey);
|
|
@@ -327,10 +334,11 @@ function BarShape(props) {
|
|
|
327
334
|
selectedDataKey,
|
|
328
335
|
isActive,
|
|
329
336
|
dataLength,
|
|
337
|
+
bufferIndex,
|
|
330
338
|
onSelect
|
|
331
339
|
} = props;
|
|
332
340
|
const index = typeof props.index === "number" ? props.index : -1;
|
|
333
|
-
const isBufferBar = buffer &&
|
|
341
|
+
const isBufferBar = buffer && index >= 0 && index === bufferIndex;
|
|
334
342
|
const isStripped = variant === "stripped";
|
|
335
343
|
const grow = growAnimation(animationType, index, dataLength, isHorizontal, introStartedAt);
|
|
336
344
|
const fill = isBufferBar ? `url(#${id}-buffer-${dataKey})` : variantFill(variant, id, dataKey);
|
|
@@ -350,7 +358,7 @@ function BarShape(props) {
|
|
|
350
358
|
x,
|
|
351
359
|
y,
|
|
352
360
|
width,
|
|
353
|
-
height: Math.max(
|
|
361
|
+
height: height <= 0 ? 0 : Math.max(MIN_BAR_LENGTH, height - FOOT_GAP),
|
|
354
362
|
opacity,
|
|
355
363
|
radius,
|
|
356
364
|
fill,
|