@misoto22/folio 0.0.0 → 0.16.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 +88 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +21 -0
- package/README.md +208 -2
- package/bin/folio-design.mjs +277 -0
- package/bin/migrate-legacy.mjs +81 -0
- package/dist/agent/Accordion.md +65 -0
- package/dist/agent/Actions.md +49 -0
- package/dist/agent/Alert.md +65 -0
- package/dist/agent/AppShell.md +69 -0
- package/dist/agent/ArchitectureFigure.md +72 -0
- package/dist/agent/AreaChart.md +94 -0
- package/dist/agent/Article.md +65 -0
- package/dist/agent/AspectRatio.md +58 -0
- package/dist/agent/Avatar.md +53 -0
- package/dist/agent/Badge.md +62 -0
- package/dist/agent/BarChart.md +93 -0
- package/dist/agent/BarList.md +67 -0
- package/dist/agent/BigNumber.md +70 -0
- package/dist/agent/BoxPlot.md +82 -0
- package/dist/agent/Breadcrumb.md +55 -0
- package/dist/agent/BulletChart.md +71 -0
- package/dist/agent/Button.md +81 -0
- package/dist/agent/Calendar.md +77 -0
- package/dist/agent/CalendarHeatmap.md +75 -0
- package/dist/agent/Card.md +72 -0
- package/dist/agent/Checkbox.md +57 -0
- package/dist/agent/Code.md +51 -0
- package/dist/agent/CodeBlock.md +77 -0
- package/dist/agent/Collapsible.md +68 -0
- package/dist/agent/Collection.md +169 -0
- package/dist/agent/ColorPicker.md +76 -0
- package/dist/agent/Combobox.md +77 -0
- package/dist/agent/Command.md +122 -0
- package/dist/agent/ComposedChart.md +82 -0
- package/dist/agent/Contact.md +90 -0
- package/dist/agent/Content.md +70 -0
- package/dist/agent/ContextMenu.md +93 -0
- package/dist/agent/Conversation.md +247 -0
- package/dist/agent/DataflowFigure.md +49 -0
- package/dist/agent/DatePicker.md +104 -0
- package/dist/agent/DescriptionList.md +69 -0
- package/dist/agent/Diagram.md +71 -0
- package/dist/agent/DiagramCanvas.md +71 -0
- package/dist/agent/DiagramExportMenu.md +65 -0
- package/dist/agent/DiagramInspector.md +73 -0
- package/dist/agent/DiagramLegend.md +56 -0
- package/dist/agent/DiagramMinimap.md +69 -0
- package/dist/agent/DiagramToolbar.md +70 -0
- package/dist/agent/Dialog.md +76 -0
- package/dist/agent/DropdownMenu.md +110 -0
- package/dist/agent/EmptyState.md +63 -0
- package/dist/agent/ErrorState.md +67 -0
- package/dist/agent/Evidence.md +165 -0
- package/dist/agent/Facet.md +107 -0
- package/dist/agent/Field.md +79 -0
- package/dist/agent/FigureBand.md +49 -0
- package/dist/agent/FloatingIconButton.md +61 -0
- package/dist/agent/FunnelChart.md +75 -0
- package/dist/agent/Heading.md +65 -0
- package/dist/agent/Heatmap.md +78 -0
- package/dist/agent/Histogram.md +88 -0
- package/dist/agent/Input.md +52 -0
- package/dist/agent/Kbd.md +48 -0
- package/dist/agent/LifecycleFigure.md +50 -0
- package/dist/agent/LineChart.md +85 -0
- package/dist/agent/LinkArrow.md +49 -0
- package/dist/agent/Markdown.md +69 -0
- package/dist/agent/Media.md +261 -0
- package/dist/agent/Metric.md +70 -0
- package/dist/agent/Metrics.md +114 -0
- package/dist/agent/Music.md +86 -0
- package/dist/agent/NativeSelect.md +62 -0
- package/dist/agent/NavItem.md +56 -0
- package/dist/agent/NumberField.md +73 -0
- package/dist/agent/PageHeader.md +69 -0
- package/dist/agent/Pagination.md +70 -0
- package/dist/agent/PieChart.md +80 -0
- package/dist/agent/Popover.md +80 -0
- package/dist/agent/Portfolio.md +93 -0
- package/dist/agent/PortfolioIndex.md +34 -0
- package/dist/agent/Progress.md +58 -0
- package/dist/agent/RadarChart.md +79 -0
- package/dist/agent/RadialChart.md +81 -0
- package/dist/agent/RadioGroup.md +66 -0
- package/dist/agent/Reading.md +233 -0
- package/dist/agent/Recovery.md +72 -0
- package/dist/agent/SankeyChart.md +85 -0
- package/dist/agent/ScatterChart.md +80 -0
- package/dist/agent/ScrollArea.md +62 -0
- package/dist/agent/SearchPalette.md +51 -0
- package/dist/agent/SearchableMenu.md +69 -0
- package/dist/agent/Select.md +102 -0
- package/dist/agent/Separator.md +60 -0
- package/dist/agent/SequenceFigure.md +51 -0
- package/dist/agent/Sheet.md +82 -0
- package/dist/agent/Sidebar.md +194 -0
- package/dist/agent/SiteNavigation.md +62 -0
- package/dist/agent/SiteShell.md +67 -0
- package/dist/agent/Skeleton.md +96 -0
- package/dist/agent/Slider.md +67 -0
- package/dist/agent/Sparkline.md +68 -0
- package/dist/agent/Spinner.md +62 -0
- package/dist/agent/StatusDot.md +56 -0
- package/dist/agent/StatusPill.md +55 -0
- package/dist/agent/Steps.md +68 -0
- package/dist/agent/Switch.md +50 -0
- package/dist/agent/Table.md +111 -0
- package/dist/agent/Tabs.md +71 -0
- package/dist/agent/Tag.md +67 -0
- package/dist/agent/Text.md +66 -0
- package/dist/agent/Textarea.md +46 -0
- package/dist/agent/Timeline.md +114 -0
- package/dist/agent/Timestamp.md +65 -0
- package/dist/agent/Toast.md +51 -0
- package/dist/agent/ToggleGroup.md +67 -0
- package/dist/agent/Toolbar.md +72 -0
- package/dist/agent/Tooltip.md +74 -0
- package/dist/agent/TreemapChart.md +76 -0
- package/dist/agent/WaterfallChart.md +86 -0
- package/dist/agent/WorkflowFigure.md +51 -0
- package/dist/agent/catalog.json +8006 -0
- package/dist/agent/index.md +182 -0
- package/dist/article.css +407 -0
- package/dist/charts/AreaChart/AreaChart.d.ts +198 -0
- package/dist/charts/AreaChart/AreaChart.js +479 -0
- package/dist/charts/AreaChart/AreaChart.js.map +1 -0
- package/dist/charts/BarChart/BarChart.d.ts +190 -0
- package/dist/charts/BarChart/BarChart.js +599 -0
- package/dist/charts/BarChart/BarChart.js.map +1 -0
- package/dist/charts/BarList/BarList.d.ts +65 -0
- package/dist/charts/BarList/BarList.js +79 -0
- package/dist/charts/BarList/BarList.js.map +1 -0
- package/dist/charts/BigNumber/BigNumber.d.ts +72 -0
- package/dist/charts/BigNumber/BigNumber.js +51 -0
- package/dist/charts/BigNumber/BigNumber.js.map +1 -0
- package/dist/charts/BoxPlot/BoxPlot.d.ts +177 -0
- package/dist/charts/BoxPlot/BoxPlot.js +497 -0
- package/dist/charts/BoxPlot/BoxPlot.js.map +1 -0
- package/dist/charts/BulletChart/BulletChart.d.ts +100 -0
- package/dist/charts/BulletChart/BulletChart.js +197 -0
- package/dist/charts/BulletChart/BulletChart.js.map +1 -0
- package/dist/charts/CalendarHeatmap/CalendarHeatmap.d.ts +106 -0
- package/dist/charts/CalendarHeatmap/CalendarHeatmap.js +103 -0
- package/dist/charts/CalendarHeatmap/CalendarHeatmap.js.map +1 -0
- package/dist/charts/ComposedChart/ComposedChart.d.ts +178 -0
- package/dist/charts/ComposedChart/ComposedChart.js +667 -0
- package/dist/charts/ComposedChart/ComposedChart.js.map +1 -0
- package/dist/charts/Facet/Facet.d.ts +240 -0
- package/dist/charts/Facet/Facet.js +133 -0
- package/dist/charts/Facet/Facet.js.map +1 -0
- package/dist/charts/Facet/panels.d.ts +187 -0
- package/dist/charts/Facet/panels.js +203 -0
- package/dist/charts/Facet/panels.js.map +1 -0
- package/dist/charts/FunnelChart/FunnelChart.d.ts +106 -0
- package/dist/charts/FunnelChart/FunnelChart.js +137 -0
- package/dist/charts/FunnelChart/FunnelChart.js.map +1 -0
- package/dist/charts/Heatmap/Heatmap.d.ts +101 -0
- package/dist/charts/Heatmap/Heatmap.js +125 -0
- package/dist/charts/Heatmap/Heatmap.js.map +1 -0
- package/dist/charts/Histogram/Histogram.d.ts +188 -0
- package/dist/charts/Histogram/Histogram.js +382 -0
- package/dist/charts/Histogram/Histogram.js.map +1 -0
- package/dist/charts/LineChart/LineChart.d.ts +174 -0
- package/dist/charts/LineChart/LineChart.js +485 -0
- package/dist/charts/LineChart/LineChart.js.map +1 -0
- package/dist/charts/PieChart/PieChart.d.ts +140 -0
- package/dist/charts/PieChart/PieChart.js +317 -0
- package/dist/charts/PieChart/PieChart.js.map +1 -0
- package/dist/charts/RadarChart/RadarChart.d.ts +135 -0
- package/dist/charts/RadarChart/RadarChart.js +303 -0
- package/dist/charts/RadarChart/RadarChart.js.map +1 -0
- package/dist/charts/RadialChart/RadialChart.d.ts +142 -0
- package/dist/charts/RadialChart/RadialChart.js +279 -0
- package/dist/charts/RadialChart/RadialChart.js.map +1 -0
- package/dist/charts/SankeyChart/SankeyChart.d.ts +149 -0
- package/dist/charts/SankeyChart/SankeyChart.js +509 -0
- package/dist/charts/SankeyChart/SankeyChart.js.map +1 -0
- package/dist/charts/ScatterChart/ScatterChart.d.ts +149 -0
- package/dist/charts/ScatterChart/ScatterChart.js +275 -0
- package/dist/charts/ScatterChart/ScatterChart.js.map +1 -0
- package/dist/charts/Sparkline/Sparkline.d.ts +53 -0
- package/dist/charts/Sparkline/Sparkline.js +95 -0
- package/dist/charts/Sparkline/Sparkline.js.map +1 -0
- package/dist/charts/TreemapChart/TreemapChart.d.ts +98 -0
- package/dist/charts/TreemapChart/TreemapChart.js +127 -0
- package/dist/charts/TreemapChart/TreemapChart.js.map +1 -0
- package/dist/charts/WaterfallChart/WaterfallChart.d.ts +164 -0
- package/dist/charts/WaterfallChart/WaterfallChart.js +321 -0
- package/dist/charts/WaterfallChart/WaterfallChart.js.map +1 -0
- package/dist/charts/index.d.ts +43 -0
- package/dist/charts/index.js +130 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/charts/lib/annotations.d.ts +103 -0
- package/dist/charts/lib/annotations.js +99 -0
- package/dist/charts/lib/annotations.js.map +1 -0
- package/dist/charts/lib/axis.d.ts +18 -0
- package/dist/charts/lib/axis.js +21 -0
- package/dist/charts/lib/axis.js.map +1 -0
- package/dist/charts/lib/background.d.ts +33 -0
- package/dist/charts/lib/background.js +173 -0
- package/dist/charts/lib/background.js.map +1 -0
- package/dist/charts/lib/brush.d.ts +94 -0
- package/dist/charts/lib/brush.js +535 -0
- package/dist/charts/lib/brush.js.map +1 -0
- package/dist/charts/lib/chart.d.ts +94 -0
- package/dist/charts/lib/chart.js +149 -0
- package/dist/charts/lib/chart.js.map +1 -0
- package/dist/charts/lib/dot.d.ts +29 -0
- package/dist/charts/lib/dot.js +78 -0
- package/dist/charts/lib/dot.js.map +1 -0
- package/dist/charts/lib/empty.d.ts +31 -0
- package/dist/charts/lib/empty.js +24 -0
- package/dist/charts/lib/empty.js.map +1 -0
- package/dist/charts/lib/export.d.ts +94 -0
- package/dist/charts/lib/export.js +62 -0
- package/dist/charts/lib/export.js.map +1 -0
- package/dist/charts/lib/figure.d.ts +81 -0
- package/dist/charts/lib/figure.js +62 -0
- package/dist/charts/lib/figure.js.map +1 -0
- package/dist/charts/lib/format.d.ts +46 -0
- package/dist/charts/lib/format.js +56 -0
- package/dist/charts/lib/format.js.map +1 -0
- package/dist/charts/lib/legend.d.ts +45 -0
- package/dist/charts/lib/legend.js +117 -0
- package/dist/charts/lib/legend.js.map +1 -0
- package/dist/charts/lib/loading.d.ts +48 -0
- package/dist/charts/lib/loading.js +105 -0
- package/dist/charts/lib/loading.js.map +1 -0
- package/dist/charts/lib/paint.d.ts +154 -0
- package/dist/charts/lib/paint.js +551 -0
- package/dist/charts/lib/paint.js.map +1 -0
- 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/sonify-control.d.ts +163 -0
- package/dist/charts/lib/sonify-control.js +172 -0
- package/dist/charts/lib/sonify-control.js.map +1 -0
- package/dist/charts/lib/sonify.d.ts +248 -0
- package/dist/charts/lib/sonify.js +262 -0
- package/dist/charts/lib/sonify.js.map +1 -0
- package/dist/charts/lib/toolbar.d.ts +144 -0
- package/dist/charts/lib/toolbar.js +156 -0
- package/dist/charts/lib/toolbar.js.map +1 -0
- package/dist/charts/lib/tooltip.d.ts +59 -0
- package/dist/charts/lib/tooltip.js +135 -0
- package/dist/charts/lib/tooltip.js.map +1 -0
- package/dist/charts/lib/values.d.ts +56 -0
- package/dist/charts/lib/values.js +71 -0
- package/dist/charts/lib/values.js.map +1 -0
- package/dist/charts/lib/zoom.d.ts +139 -0
- package/dist/charts/lib/zoom.js +314 -0
- package/dist/charts/lib/zoom.js.map +1 -0
- package/dist/components/Accordion/Accordion.d.ts +34 -0
- package/dist/components/Accordion/Accordion.js +43 -0
- package/dist/components/Accordion/Accordion.js.map +1 -0
- package/dist/components/Alert/Alert.d.ts +32 -0
- package/dist/components/Alert/Alert.js +49 -0
- package/dist/components/Alert/Alert.js.map +1 -0
- package/dist/components/AppShell/AppShell.d.ts +58 -0
- package/dist/components/AppShell/AppShell.js +126 -0
- package/dist/components/AppShell/AppShell.js.map +1 -0
- package/dist/components/Article/Article.d.ts +58 -0
- package/dist/components/Article/Article.js +34 -0
- package/dist/components/Article/Article.js.map +1 -0
- 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 +38 -0
- package/dist/components/Avatar/Avatar.js +44 -0
- package/dist/components/Avatar/Avatar.js.map +1 -0
- package/dist/components/Badge/Badge.d.ts +30 -0
- package/dist/components/Badge/Badge.js +29 -0
- package/dist/components/Badge/Badge.js.map +1 -0
- package/dist/components/Breadcrumb/Breadcrumb.d.ts +37 -0
- package/dist/components/Breadcrumb/Breadcrumb.js +46 -0
- package/dist/components/Breadcrumb/Breadcrumb.js.map +1 -0
- package/dist/components/Button/Button.d.ts +70 -0
- package/dist/components/Button/Button.js +95 -0
- package/dist/components/Button/Button.js.map +1 -0
- package/dist/components/Calendar/Calendar.d.ts +54 -0
- package/dist/components/Calendar/Calendar.js +369 -0
- package/dist/components/Calendar/Calendar.js.map +1 -0
- package/dist/components/Card/Card.d.ts +55 -0
- package/dist/components/Card/Card.js +64 -0
- package/dist/components/Card/Card.js.map +1 -0
- package/dist/components/Checkbox/Checkbox.d.ts +26 -0
- package/dist/components/Checkbox/Checkbox.js +34 -0
- package/dist/components/Checkbox/Checkbox.js.map +1 -0
- 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 +145 -0
- package/dist/components/CodeBlock/CodeBlock.js +114 -0
- package/dist/components/CodeBlock/CodeBlock.js.map +1 -0
- package/dist/components/Collapsible/Collapsible.d.ts +45 -0
- package/dist/components/Collapsible/Collapsible.js +60 -0
- package/dist/components/Collapsible/Collapsible.js.map +1 -0
- 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 +77 -0
- package/dist/components/Combobox/Combobox.js +170 -0
- package/dist/components/Combobox/Combobox.js.map +1 -0
- package/dist/components/Command/Command.d.ts +125 -0
- package/dist/components/Command/Command.js +204 -0
- package/dist/components/Command/Command.js.map +1 -0
- package/dist/components/ContextMenu/ContextMenu.d.ts +63 -0
- package/dist/components/ContextMenu/ContextMenu.js +109 -0
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -0
- package/dist/components/DatePicker/DatePicker.d.ts +130 -0
- package/dist/components/DatePicker/DatePicker.js +257 -0
- package/dist/components/DatePicker/DatePicker.js.map +1 -0
- 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 +86 -0
- package/dist/components/Diagram/Diagram.js +211 -0
- package/dist/components/Diagram/Diagram.js.map +1 -0
- package/dist/components/Dialog/Dialog.d.ts +63 -0
- package/dist/components/Dialog/Dialog.js +90 -0
- package/dist/components/Dialog/Dialog.js.map +1 -0
- package/dist/components/DropdownMenu/DropdownMenu.d.ts +87 -0
- package/dist/components/DropdownMenu/DropdownMenu.js +120 -0
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -0
- package/dist/components/EmptyState/EmptyState.d.ts +55 -0
- package/dist/components/EmptyState/EmptyState.js +32 -0
- package/dist/components/EmptyState/EmptyState.js.map +1 -0
- package/dist/components/ErrorState/ErrorState.d.ts +55 -0
- package/dist/components/ErrorState/ErrorState.js +41 -0
- package/dist/components/ErrorState/ErrorState.js.map +1 -0
- package/dist/components/Field/Field.d.ts +111 -0
- package/dist/components/Field/Field.js +95 -0
- package/dist/components/Field/Field.js.map +1 -0
- 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/FigureBand/FigureBand.d.ts +31 -0
- package/dist/components/FigureBand/FigureBand.js +51 -0
- package/dist/components/FigureBand/FigureBand.js.map +1 -0
- package/dist/components/FloatingIconButton/FloatingIconButton.d.ts +29 -0
- package/dist/components/FloatingIconButton/FloatingIconButton.js +34 -0
- package/dist/components/FloatingIconButton/FloatingIconButton.js.map +1 -0
- 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/Input/Input.d.ts +22 -0
- package/dist/components/Input/Input.js +21 -0
- package/dist/components/Input/Input.js.map +1 -0
- package/dist/components/Kbd/Kbd.d.ts +27 -0
- package/dist/components/Kbd/Kbd.js +21 -0
- package/dist/components/Kbd/Kbd.js.map +1 -0
- package/dist/components/LinkArrow/LinkArrow.d.ts +24 -0
- package/dist/components/LinkArrow/LinkArrow.js +24 -0
- package/dist/components/LinkArrow/LinkArrow.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/Metric/Metric.d.ts +61 -0
- package/dist/components/Metric/Metric.js +51 -0
- package/dist/components/Metric/Metric.js.map +1 -0
- package/dist/components/NativeSelect/NativeSelect.d.ts +33 -0
- package/dist/components/NativeSelect/NativeSelect.js +44 -0
- package/dist/components/NativeSelect/NativeSelect.js.map +1 -0
- package/dist/components/NavItem/NavItem.d.ts +39 -0
- package/dist/components/NavItem/NavItem.js +31 -0
- package/dist/components/NavItem/NavItem.js.map +1 -0
- 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/PageHeader/PageHeader.d.ts +92 -0
- package/dist/components/PageHeader/PageHeader.js +37 -0
- package/dist/components/PageHeader/PageHeader.js.map +1 -0
- package/dist/components/Pagination/Pagination.d.ts +67 -0
- package/dist/components/Pagination/Pagination.js +112 -0
- package/dist/components/Pagination/Pagination.js.map +1 -0
- package/dist/components/Popover/Popover.d.ts +39 -0
- package/dist/components/Popover/Popover.js +57 -0
- package/dist/components/Popover/Popover.js.map +1 -0
- package/dist/components/Progress/Progress.d.ts +43 -0
- package/dist/components/Progress/Progress.js +57 -0
- package/dist/components/Progress/Progress.js.map +1 -0
- package/dist/components/RadioGroup/RadioGroup.d.ts +49 -0
- package/dist/components/RadioGroup/RadioGroup.js +53 -0
- package/dist/components/RadioGroup/RadioGroup.js.map +1 -0
- package/dist/components/ScrollArea/ScrollArea.d.ts +46 -0
- package/dist/components/ScrollArea/ScrollArea.js +54 -0
- package/dist/components/ScrollArea/ScrollArea.js.map +1 -0
- package/dist/components/SearchableMenu/SearchableMenu.d.ts +68 -0
- package/dist/components/SearchableMenu/SearchableMenu.js +101 -0
- package/dist/components/SearchableMenu/SearchableMenu.js.map +1 -0
- package/dist/components/Select/Select.d.ts +87 -0
- package/dist/components/Select/Select.js +130 -0
- package/dist/components/Select/Select.js.map +1 -0
- package/dist/components/Separator/Separator.d.ts +48 -0
- package/dist/components/Separator/Separator.js +43 -0
- package/dist/components/Separator/Separator.js.map +1 -0
- package/dist/components/Sheet/Sheet.d.ts +43 -0
- package/dist/components/Sheet/Sheet.js +79 -0
- package/dist/components/Sheet/Sheet.js.map +1 -0
- package/dist/components/Sidebar/Sidebar.d.ts +357 -0
- package/dist/components/Sidebar/Sidebar.js +447 -0
- package/dist/components/Sidebar/Sidebar.js.map +1 -0
- package/dist/components/Skeleton/Skeleton.d.ts +70 -0
- package/dist/components/Skeleton/Skeleton.js +44 -0
- package/dist/components/Skeleton/Skeleton.js.map +1 -0
- package/dist/components/Slider/Slider.d.ts +74 -0
- package/dist/components/Slider/Slider.js +143 -0
- package/dist/components/Slider/Slider.js.map +1 -0
- package/dist/components/Spinner/Spinner.d.ts +58 -0
- package/dist/components/Spinner/Spinner.js +49 -0
- package/dist/components/Spinner/Spinner.js.map +1 -0
- package/dist/components/StatusDot/StatusDot.d.ts +29 -0
- package/dist/components/StatusDot/StatusDot.js +44 -0
- package/dist/components/StatusDot/StatusDot.js.map +1 -0
- package/dist/components/StatusPill/StatusPill.d.ts +30 -0
- package/dist/components/StatusPill/StatusPill.js +37 -0
- package/dist/components/StatusPill/StatusPill.js.map +1 -0
- package/dist/components/Steps/Steps.d.ts +65 -0
- package/dist/components/Steps/Steps.js +25 -0
- package/dist/components/Steps/Steps.js.map +1 -0
- package/dist/components/Switch/Switch.d.ts +23 -0
- package/dist/components/Switch/Switch.js +23 -0
- package/dist/components/Switch/Switch.js.map +1 -0
- package/dist/components/Table/Table.d.ts +116 -0
- package/dist/components/Table/Table.js +137 -0
- package/dist/components/Table/Table.js.map +1 -0
- package/dist/components/Tabs/Tabs.d.ts +37 -0
- package/dist/components/Tabs/Tabs.js +205 -0
- package/dist/components/Tabs/Tabs.js.map +1 -0
- package/dist/components/Tag/Tag.d.ts +87 -0
- package/dist/components/Tag/Tag.js +62 -0
- package/dist/components/Tag/Tag.js.map +1 -0
- 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/Textarea/Textarea.d.ts +20 -0
- package/dist/components/Textarea/Textarea.js +32 -0
- package/dist/components/Textarea/Textarea.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 +32 -0
- package/dist/components/Toast/Toast.js +64 -0
- package/dist/components/Toast/Toast.js.map +1 -0
- package/dist/components/ToggleGroup/ToggleGroup.d.ts +46 -0
- package/dist/components/ToggleGroup/ToggleGroup.js +88 -0
- package/dist/components/ToggleGroup/ToggleGroup.js.map +1 -0
- 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/components/Tooltip/Tooltip.d.ts +43 -0
- package/dist/components/Tooltip/Tooltip.js +40 -0
- package/dist/components/Tooltip/Tooltip.js.map +1 -0
- package/dist/diagrams/ArchitectureFigure/ArchitectureFigure.d.ts +55 -0
- package/dist/diagrams/ArchitectureFigure/ArchitectureFigure.js +175 -0
- package/dist/diagrams/ArchitectureFigure/ArchitectureFigure.js.map +1 -0
- package/dist/diagrams/DataflowFigure/DataflowFigure.d.ts +28 -0
- package/dist/diagrams/DataflowFigure/DataflowFigure.js +148 -0
- package/dist/diagrams/DataflowFigure/DataflowFigure.js.map +1 -0
- package/dist/diagrams/DiagramCanvas/DiagramCanvas.d.ts +78 -0
- package/dist/diagrams/DiagramCanvas/DiagramCanvas.js +229 -0
- package/dist/diagrams/DiagramCanvas/DiagramCanvas.js.map +1 -0
- package/dist/diagrams/DiagramExportMenu/DiagramExportMenu.d.ts +106 -0
- package/dist/diagrams/DiagramExportMenu/DiagramExportMenu.js +123 -0
- package/dist/diagrams/DiagramExportMenu/DiagramExportMenu.js.map +1 -0
- package/dist/diagrams/DiagramInspector/DiagramInspector.d.ts +70 -0
- package/dist/diagrams/DiagramInspector/DiagramInspector.js +94 -0
- package/dist/diagrams/DiagramInspector/DiagramInspector.js.map +1 -0
- package/dist/diagrams/DiagramLegend/DiagramLegend.d.ts +42 -0
- package/dist/diagrams/DiagramLegend/DiagramLegend.js +35 -0
- package/dist/diagrams/DiagramLegend/DiagramLegend.js.map +1 -0
- package/dist/diagrams/DiagramMinimap/DiagramMinimap.d.ts +77 -0
- package/dist/diagrams/DiagramMinimap/DiagramMinimap.js +106 -0
- package/dist/diagrams/DiagramMinimap/DiagramMinimap.js.map +1 -0
- package/dist/diagrams/DiagramToolbar/DiagramToolbar.d.ts +48 -0
- package/dist/diagrams/DiagramToolbar/DiagramToolbar.js +53 -0
- package/dist/diagrams/DiagramToolbar/DiagramToolbar.js.map +1 -0
- package/dist/diagrams/LifecycleFigure/LifecycleFigure.d.ts +31 -0
- package/dist/diagrams/LifecycleFigure/LifecycleFigure.js +234 -0
- package/dist/diagrams/LifecycleFigure/LifecycleFigure.js.map +1 -0
- package/dist/diagrams/SequenceFigure/SequenceFigure.d.ts +38 -0
- package/dist/diagrams/SequenceFigure/SequenceFigure.js +261 -0
- package/dist/diagrams/SequenceFigure/SequenceFigure.js.map +1 -0
- package/dist/diagrams/WorkflowFigure/WorkflowFigure.d.ts +36 -0
- package/dist/diagrams/WorkflowFigure/WorkflowFigure.js +259 -0
- package/dist/diagrams/WorkflowFigure/WorkflowFigure.js.map +1 -0
- package/dist/diagrams/index.d.ts +17 -0
- package/dist/diagrams/index.js +29 -0
- package/dist/diagrams/index.js.map +1 -0
- 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 +138 -0
- package/dist/diagrams/lib/frame.js +131 -0
- package/dist/diagrams/lib/frame.js.map +1 -0
- package/dist/diagrams/lib/geometry.d.ts +114 -0
- package/dist/diagrams/lib/geometry.js +113 -0
- package/dist/diagrams/lib/geometry.js.map +1 -0
- package/dist/diagrams/lib/legend.d.ts +32 -0
- package/dist/diagrams/lib/legend.js +84 -0
- package/dist/diagrams/lib/legend.js.map +1 -0
- package/dist/diagrams/lib/marks.d.ts +207 -0
- package/dist/diagrams/lib/marks.js +480 -0
- package/dist/diagrams/lib/marks.js.map +1 -0
- package/dist/diagrams/lib/route.d.ts +106 -0
- package/dist/diagrams/lib/route.js +201 -0
- package/dist/diagrams/lib/route.js.map +1 -0
- package/dist/diagrams/lib/wires.d.ts +59 -0
- package/dist/diagrams/lib/wires.js +94 -0
- package/dist/diagrams/lib/wires.js.map +1 -0
- package/dist/diagrams/spec.d.ts +405 -0
- package/dist/diagrams/spec.js +1 -0
- package/dist/diagrams/spec.js.map +1 -0
- package/dist/fonts/hanken-grotesk-300.woff2 +0 -0
- package/dist/fonts/hanken-grotesk-400.woff2 +0 -0
- package/dist/fonts/hanken-grotesk-500.woff2 +0 -0
- package/dist/fonts/hanken-grotesk-600.woff2 +0 -0
- package/dist/fonts/hanken-grotesk-700.woff2 +0 -0
- package/dist/fonts/ibm-plex-mono-400.woff2 +0 -0
- package/dist/fonts/ibm-plex-mono-500.woff2 +0 -0
- package/dist/fonts/ibm-plex-mono-600.woff2 +0 -0
- package/dist/fonts/newsreader-300.woff2 +0 -0
- package/dist/fonts/newsreader-400.woff2 +0 -0
- package/dist/fonts/newsreader-500.woff2 +0 -0
- package/dist/fonts/newsreader-600.woff2 +0 -0
- package/dist/fonts.css +96 -0
- package/dist/index.d.ts +97 -0
- package/dist/index.js +80 -0
- package/dist/index.js.map +1 -0
- package/dist/keyframes.css +300 -0
- package/dist/lib/cn.d.ts +21 -0
- package/dist/lib/cn.js +9 -0
- package/dist/lib/cn.js.map +1 -0
- 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/control.d.ts +32 -0
- package/dist/lib/control.js +14 -0
- package/dist/lib/control.js.map +1 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.js +11 -0
- package/dist/lib/index.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 +48 -0
- package/dist/lib/overlay-container.js +15 -0
- package/dist/lib/overlay-container.js.map +1 -0
- package/dist/lib/slot-content.d.ts +8 -0
- package/dist/lib/slot-content.js +17 -0
- package/dist/lib/slot-content.js.map +1 -0
- package/dist/lib/step-rail.d.ts +45 -0
- package/dist/lib/step-rail.js +47 -0
- package/dist/lib/step-rail.js.map +1 -0
- package/dist/lib/svg-export.d.ts +138 -0
- package/dist/lib/svg-export.js +198 -0
- package/dist/lib/svg-export.js.map +1 -0
- package/dist/lib/useClipboardCopy.d.ts +30 -0
- package/dist/lib/useClipboardCopy.js +37 -0
- package/dist/lib/useClipboardCopy.js.map +1 -0
- package/dist/lib/useSelectionIndicator.d.ts +29 -0
- package/dist/lib/useSelectionIndicator.js +49 -0
- package/dist/lib/useSelectionIndicator.js.map +1 -0
- 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 +193 -0
- package/dist/styles.css +98 -0
- package/dist/themes.css +514 -0
- package/dist/tokens/brand.d.ts +47 -0
- package/dist/tokens/brand.js +38 -0
- package/dist/tokens/brand.js.map +1 -0
- package/dist/tokens.css +652 -0
- package/dist/tokens.d.ts +198 -0
- package/dist/tokens.js +1020 -0
- package/dist/tokens.json +1019 -0
- package/dist/website/Actions/Actions.d.ts +34 -0
- package/dist/website/Actions/Actions.js +29 -0
- package/dist/website/Actions/Actions.js.map +1 -0
- package/dist/website/Collection/Collection.d.ts +128 -0
- package/dist/website/Collection/Collection.js +162 -0
- package/dist/website/Collection/Collection.js.map +1 -0
- package/dist/website/Contact/Contact.d.ts +87 -0
- package/dist/website/Contact/Contact.js +94 -0
- package/dist/website/Contact/Contact.js.map +1 -0
- package/dist/website/Content/CodePanel.d.ts +27 -0
- package/dist/website/Content/CodePanel.js +30 -0
- package/dist/website/Content/CodePanel.js.map +1 -0
- package/dist/website/Content/Content.d.ts +29 -0
- package/dist/website/Content/Content.js +38 -0
- package/dist/website/Content/Content.js.map +1 -0
- package/dist/website/Conversation/Conversation.d.ts +193 -0
- package/dist/website/Conversation/Conversation.js +252 -0
- package/dist/website/Conversation/Conversation.js.map +1 -0
- package/dist/website/Evidence/Evidence.d.ts +116 -0
- package/dist/website/Evidence/Evidence.js +142 -0
- package/dist/website/Evidence/Evidence.js.map +1 -0
- package/dist/website/Media/Media.d.ts +173 -0
- package/dist/website/Media/Media.js +225 -0
- package/dist/website/Media/Media.js.map +1 -0
- package/dist/website/Media/MediaLightbox.d.ts +18 -0
- package/dist/website/Media/MediaLightbox.js +38 -0
- package/dist/website/Media/MediaLightbox.js.map +1 -0
- package/dist/website/Metrics/Metrics.d.ts +74 -0
- package/dist/website/Metrics/Metrics.js +96 -0
- package/dist/website/Metrics/Metrics.js.map +1 -0
- package/dist/website/Music/Music.d.ts +60 -0
- package/dist/website/Music/Music.js +80 -0
- package/dist/website/Music/Music.js.map +1 -0
- package/dist/website/Portfolio/FrameLayout.d.ts +9 -0
- package/dist/website/Portfolio/FrameLayout.js +42 -0
- package/dist/website/Portfolio/FrameLayout.js.map +1 -0
- package/dist/website/Portfolio/Portfolio.d.ts +49 -0
- package/dist/website/Portfolio/Portfolio.js +66 -0
- package/dist/website/Portfolio/Portfolio.js.map +1 -0
- package/dist/website/Portfolio/QuestionCard.d.ts +22 -0
- package/dist/website/Portfolio/QuestionCard.js +33 -0
- package/dist/website/Portfolio/QuestionCard.js.map +1 -0
- package/dist/website/PortfolioIndex/PortfolioIndex.d.ts +21 -0
- package/dist/website/PortfolioIndex/PortfolioIndex.js +31 -0
- package/dist/website/PortfolioIndex/PortfolioIndex.js.map +1 -0
- package/dist/website/Reading/Reading.d.ts +203 -0
- package/dist/website/Reading/Reading.js +357 -0
- package/dist/website/Reading/Reading.js.map +1 -0
- package/dist/website/Recovery/Recovery.d.ts +39 -0
- package/dist/website/Recovery/Recovery.js +96 -0
- package/dist/website/Recovery/Recovery.js.map +1 -0
- package/dist/website/SearchPalette/SearchPalette.d.ts +59 -0
- package/dist/website/SearchPalette/SearchPalette.js +120 -0
- package/dist/website/SearchPalette/SearchPalette.js.map +1 -0
- package/dist/website/SiteNavigation/SiteNavigation.d.ts +46 -0
- package/dist/website/SiteNavigation/SiteNavigation.js +101 -0
- package/dist/website/SiteNavigation/SiteNavigation.js.map +1 -0
- package/dist/website/SiteShell/SiteShell.d.ts +45 -0
- package/dist/website/SiteShell/SiteShell.js +46 -0
- package/dist/website/SiteShell/SiteShell.js.map +1 -0
- package/dist/website/Timeline/Timeline.d.ts +80 -0
- package/dist/website/Timeline/Timeline.js +99 -0
- package/dist/website/Timeline/Timeline.js.map +1 -0
- package/dist/website/index.d.ts +27 -0
- package/dist/website/index.js +21 -0
- package/dist/website/index.js.map +1 -0
- package/dist/website-actions.css +6 -0
- package/dist/website-base.css +46 -0
- package/dist/website-collection.css +89 -0
- package/dist/website-contact.css +29 -0
- package/dist/website-content.css +17 -0
- package/dist/website-controls.css +91 -0
- package/dist/website-conversation.css +115 -0
- package/dist/website-evidence.css +56 -0
- package/dist/website-media.css +227 -0
- package/dist/website-metrics.css +15 -0
- package/dist/website-music.css +27 -0
- package/dist/website-portfolio.css +94 -0
- package/dist/website-reading.css +159 -0
- package/dist/website-recovery.css +28 -0
- package/dist/website-search.css +26 -0
- package/dist/website-shell.css +89 -0
- package/dist/website-timeline.css +43 -0
- package/dist/website.css +25 -0
- package/llms.txt +35 -0
- package/package.json +163 -5
- package/skills/folio-design/SKILL.md +228 -0
- package/skills/folio-design/evals/claims.json +95 -0
- package/skills/folio-design/evals/evals.json +84 -0
- package/skills/folio-design/rules/a11y.md +167 -0
- package/skills/folio-design/rules/composition.md +108 -0
- package/skills/folio-design/rules/forms.md +135 -0
- package/skills/folio-design/rules/naming.md +155 -0
- package/skills/folio-design/rules/tokens.md +133 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ChartFigure } from "../lib/figure.js";
|
|
3
|
+
import {} from "../lib/empty.js";
|
|
4
|
+
import { defaultTick } from "../lib/format.js";
|
|
5
|
+
import { clampedFraction } from "../lib/scale.js";
|
|
6
|
+
const BAND_WEIGHT = { heaviest: 1, lightest: 0.3 };
|
|
7
|
+
const BAR_SHARE = 0.34;
|
|
8
|
+
function position(value, [low, high]) {
|
|
9
|
+
return clampedFraction(value, low, high);
|
|
10
|
+
}
|
|
11
|
+
function overflows(value, [low, high]) {
|
|
12
|
+
return value !== void 0 && Number.isFinite(value) && (value > high || value < low);
|
|
13
|
+
}
|
|
14
|
+
function pct(share) {
|
|
15
|
+
return `${Number((share * 100).toFixed(4))}%`;
|
|
16
|
+
}
|
|
17
|
+
function bands(ranges, [low, high], formatValue) {
|
|
18
|
+
const set = [...new Set(ranges.filter(Number.isFinite))].sort((a, b) => a - b);
|
|
19
|
+
const bounds = set.filter((bound) => bound > low && bound < high);
|
|
20
|
+
const edges = [low, ...bounds, high];
|
|
21
|
+
const count = edges.length - 1;
|
|
22
|
+
const { heaviest, lightest } = BAND_WEIGHT;
|
|
23
|
+
const list = Array.from({ length: count }, (_, index) => ({
|
|
24
|
+
from: edges[index],
|
|
25
|
+
to: edges[index + 1],
|
|
26
|
+
// Heaviest at the low end, lightening as the scale rises — so the measure
|
|
27
|
+
// bar, which is solid, stands out most where performance is best.
|
|
28
|
+
weight: count === 1 ? lightest : heaviest - index / (count - 1) * (heaviest - lightest)
|
|
29
|
+
}));
|
|
30
|
+
return { list, label: set.map(formatValue).join(", ") };
|
|
31
|
+
}
|
|
32
|
+
function resolve(data, domain, ranges, formatValue) {
|
|
33
|
+
return data.map((measure) => {
|
|
34
|
+
const own = measure.ranges ?? ranges ?? [];
|
|
35
|
+
const high = Math.max(measure.value, measure.target ?? Number.NEGATIVE_INFINITY, ...own);
|
|
36
|
+
const scale = measure.domain ?? domain ?? [Math.min(0, measure.value), high || 1];
|
|
37
|
+
const built = bands(own, scale, formatValue);
|
|
38
|
+
return { ...measure, domain: scale, bands: built.list, rangeLabel: built.label };
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function BulletChart({
|
|
42
|
+
title,
|
|
43
|
+
showTitle,
|
|
44
|
+
description,
|
|
45
|
+
data,
|
|
46
|
+
ranges,
|
|
47
|
+
domain,
|
|
48
|
+
formatValue = defaultTick,
|
|
49
|
+
showScale = false,
|
|
50
|
+
className,
|
|
51
|
+
hideDataTable = false,
|
|
52
|
+
empty
|
|
53
|
+
}) {
|
|
54
|
+
const measures = resolve(data, domain, ranges, formatValue);
|
|
55
|
+
return /* @__PURE__ */ jsx(
|
|
56
|
+
ChartFigure,
|
|
57
|
+
{
|
|
58
|
+
title,
|
|
59
|
+
showTitle,
|
|
60
|
+
description,
|
|
61
|
+
className,
|
|
62
|
+
table: hideDataTable ? false : {
|
|
63
|
+
rows: measures,
|
|
64
|
+
rowKey: "name",
|
|
65
|
+
columns: [
|
|
66
|
+
{ key: "value", label: "Value" },
|
|
67
|
+
{ key: "target", label: "Target" },
|
|
68
|
+
{ key: "rangeLabel", label: "Range bounds" }
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
isEmpty: measures.length === 0,
|
|
72
|
+
empty,
|
|
73
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex w-full flex-col gap-4", children: measures.map((measure) => /* @__PURE__ */ jsx(
|
|
74
|
+
BulletRow,
|
|
75
|
+
{
|
|
76
|
+
measure,
|
|
77
|
+
formatValue,
|
|
78
|
+
showScale
|
|
79
|
+
},
|
|
80
|
+
measure.name
|
|
81
|
+
)) })
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
function BulletRow({
|
|
86
|
+
measure,
|
|
87
|
+
formatValue,
|
|
88
|
+
showScale
|
|
89
|
+
}) {
|
|
90
|
+
const scale = measure.domain;
|
|
91
|
+
const barShare = position(measure.value, scale);
|
|
92
|
+
const targetShare = measure.target === void 0 ? null : position(measure.target, scale);
|
|
93
|
+
const runsOver = overflows(measure.value, scale) || overflows(measure.target, scale);
|
|
94
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-1.5", children: [
|
|
95
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-3", children: [
|
|
96
|
+
/* @__PURE__ */ jsxs("span", { className: "truncate text-sm text-(--ink)", children: [
|
|
97
|
+
measure.name,
|
|
98
|
+
measure.detail && /* @__PURE__ */ jsx("span", { className: "ms-2 mono-meta text-(--ink-3-aa)", children: measure.detail })
|
|
99
|
+
] }),
|
|
100
|
+
/* @__PURE__ */ jsxs("span", { className: "shrink-0 font-mono text-xs tabular-nums text-(--ink)", children: [
|
|
101
|
+
formatValue(measure.value),
|
|
102
|
+
measure.target !== void 0 && /* @__PURE__ */ jsxs("span", { className: "text-(--ink-3-aa)", children: [
|
|
103
|
+
" / ",
|
|
104
|
+
formatValue(measure.target)
|
|
105
|
+
] })
|
|
106
|
+
] })
|
|
107
|
+
] }),
|
|
108
|
+
/* @__PURE__ */ jsxs(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
"aria-hidden": true,
|
|
112
|
+
"data-slot": "bullet-track",
|
|
113
|
+
className: "relative h-6 w-full overflow-hidden rounded-(--radius-sm)",
|
|
114
|
+
children: [
|
|
115
|
+
measure.bands.map((band) => /* @__PURE__ */ jsx(
|
|
116
|
+
"span",
|
|
117
|
+
{
|
|
118
|
+
"data-slot": "bullet-band",
|
|
119
|
+
className: "absolute inset-y-0 block",
|
|
120
|
+
style: {
|
|
121
|
+
insetInlineStart: pct(position(band.from, scale)),
|
|
122
|
+
inlineSize: pct(position(band.to, scale) - position(band.from, scale)),
|
|
123
|
+
// The one translucent-mark pair in the token layer, because it is
|
|
124
|
+
// the only one that holds a different number on each ground.
|
|
125
|
+
backgroundColor: `color-mix(in srgb, var(--series-1) calc(var(--chart-fill) * ${band.weight} * 100%), transparent)`
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
`${band.from}-${band.to}`
|
|
129
|
+
)),
|
|
130
|
+
/* @__PURE__ */ jsx(
|
|
131
|
+
"span",
|
|
132
|
+
{
|
|
133
|
+
"data-slot": "bullet-bar",
|
|
134
|
+
className: "absolute block bg-(--series-1)",
|
|
135
|
+
style: {
|
|
136
|
+
insetInlineStart: 0,
|
|
137
|
+
insetBlockStart: pct((1 - BAR_SHARE) / 2),
|
|
138
|
+
blockSize: pct(BAR_SHARE),
|
|
139
|
+
inlineSize: pct(barShare)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
),
|
|
143
|
+
targetShare !== null && // A rule ACROSS the bar rather than a second bar beside it: the two
|
|
144
|
+
// are different kinds of number, and the reader has to be able to
|
|
145
|
+
// tell at a glance which one was achieved and which was asked for.
|
|
146
|
+
//
|
|
147
|
+
// The paper halo is what makes that true where the rule lands ON the
|
|
148
|
+
// bar. Both are drawn in --ink, so a target inside the achieved range
|
|
149
|
+
// — which is every measure that is doing well — was an ink rule on an
|
|
150
|
+
// ink bar and simply not there.
|
|
151
|
+
/* @__PURE__ */ jsx(
|
|
152
|
+
"span",
|
|
153
|
+
{
|
|
154
|
+
"data-slot": "bullet-target",
|
|
155
|
+
className: "absolute inset-y-1 block w-0.5 bg-(--ink) shadow-[0_0_0_1px_var(--paper)]",
|
|
156
|
+
style: {
|
|
157
|
+
insetInlineStart: pct(targetShare),
|
|
158
|
+
// Pulled back by its own width in PROPORTION to where it sits:
|
|
159
|
+
// flush at the start at 0, centred in the middle, flush at the end
|
|
160
|
+
// at 1. A fixed half-width pull put a target of zero half outside
|
|
161
|
+
// the track, where `overflow-hidden` took it — so "Open incidents,
|
|
162
|
+
// target 0" drew no target at all, on the one measure whose whole
|
|
163
|
+
// point is the distance from it.
|
|
164
|
+
marginInlineStart: `${-2 * targetShare}px`
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
),
|
|
168
|
+
runsOver && // Clamped and silent, a number past the end of the scale fills the
|
|
169
|
+
// track exactly as a number AT the end of it does — so the one thing
|
|
170
|
+
// the row cannot say is the one thing the reader most needs to know.
|
|
171
|
+
// The notch is what breaks that tie; the printed figure above still
|
|
172
|
+
// carries the real number.
|
|
173
|
+
/* @__PURE__ */ jsx(
|
|
174
|
+
"span",
|
|
175
|
+
{
|
|
176
|
+
"data-slot": "bullet-overflow",
|
|
177
|
+
className: "absolute inset-y-0 end-0 block w-1.5 bg-(--chart-surface)",
|
|
178
|
+
style: {
|
|
179
|
+
clipPath: "polygon(100% 0, 0 50%, 100% 100%)"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
),
|
|
186
|
+
showScale && /* @__PURE__ */ jsxs("div", { className: "flex justify-between mono-meta text-(--chart-axis)", children: [
|
|
187
|
+
/* @__PURE__ */ jsx("span", { children: formatValue(scale[0]) }),
|
|
188
|
+
/* @__PURE__ */ jsx("span", { children: formatValue(scale[1]) })
|
|
189
|
+
] })
|
|
190
|
+
] });
|
|
191
|
+
}
|
|
192
|
+
var BulletChart_default = BulletChart;
|
|
193
|
+
export {
|
|
194
|
+
BulletChart,
|
|
195
|
+
BulletChart_default as default
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=BulletChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/charts/BulletChart/BulletChart.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport { ChartFigure } from '../lib/figure'\nimport { type ChartEmptyProps } from '../lib/empty'\nimport { defaultTick } from '../lib/format'\nimport { clampedFraction } from '../lib/scale'\n\n/**\n * The heaviest and lightest a qualitative band may be, as multiples of\n * `--chart-fill`.\n *\n * Few's rule is no more than five bands in one hue, arranged so the low end of\n * the scale is the heaviest. The measure bar is solid ink on top of them, so\n * the ceiling has to stay well under it: bands that compete with the bar stop\n * being the ground it is read against.\n */\nconst BAND_WEIGHT = { heaviest: 1, lightest: 0.3 } as const\n\n/** How tall the measure bar is, as a share of the track. Few's is a third. */\nconst BAR_SHARE = 0.34\n\n/** One measure, its target, and the bands it is read against. */\nexport interface BulletMeasure {\n /** What is being measured. Doubles as the row's key, so it must be unique. */\n name: string\n /** The number the row is about. */\n value: number\n /**\n * The number the measure is being judged against — last year, the budget,\n * the SLO. Drawn as a rule across the bar, not as a second bar.\n */\n target?: number\n /**\n * The qualitative bands, as ascending UPPER bounds. `[60, 80]` on a 0–100\n * scale draws three bands: 0–60, 60–80, 80–100.\n *\n * Few's limit is five, and it is a real one: past that the shades stop being\n * separable and the bands become a gradient nobody can read a boundary off.\n */\n ranges?: number[]\n /** The scale, as `[min, max]`. Falls back to the chart's, then to the data. */\n domain?: [number, number]\n /** A second line under the name — the unit, the window, the owner. */\n detail?: ReactNode\n}\n\n/** A measure with its scale and bands resolved. */\ninterface ResolvedMeasure extends BulletMeasure {\n domain: [number, number]\n bands: { from: number; to: number; weight: number }[]\n /** Written out for the hidden table, which cannot print an array. */\n rangeLabel: string\n}\n\n/** Where a value sits on the scale, 0 to 1, clamped to it. */\nfunction position(value: number, [low, high]: [number, number]): number {\n return clampedFraction(value, low, high)\n}\n\n/** Whether a number is off the end of the scale it is being drawn against. */\nfunction overflows(value: number | undefined, [low, high]: [number, number]): boolean {\n return value !== undefined && Number.isFinite(value) && (value > high || value < low)\n}\n\n/**\n * A share of the track, as a CSS percentage.\n *\n * Rounded, because binary floating point turns `0.8 - 0.5` into\n * `30.000000000000004%` — a number no layout engine cares about and every\n * reader of the DOM does. Four places is finer than a subpixel on any track\n * this chart will be given.\n */\nfunction pct(share: number): string {\n return `${Number((share * 100).toFixed(4))}%`\n}\n\n/** The bands, from the ascending upper bounds, each with its own weight. */\nfunction bands(\n ranges: number[],\n [low, high]: [number, number],\n formatValue: (value: number) => string,\n): { list: ResolvedMeasure['bands']; label: string } {\n const set = [...new Set(ranges.filter(Number.isFinite))].sort((a, b) => a - b)\n // A bound off the end of the scale has no boundary to draw: it would be a\n // band with no width, or one that starts past the track. It is dropped from\n // the picture and kept in the LABEL, because a caller who pinned `[0, 50]`\n // and passed `[60, 80]` has made a mistake, and one flat band that says\n // nothing is how it stays invisible.\n const bounds = set.filter((bound) => bound > low && bound < high)\n\n const edges = [low, ...bounds, high]\n const count = edges.length - 1\n const { heaviest, lightest } = BAND_WEIGHT\n\n const list = Array.from({ length: count }, (_, index) => ({\n from: edges[index]!,\n to: edges[index + 1]!,\n // Heaviest at the low end, lightening as the scale rises — so the measure\n // bar, which is solid, stands out most where performance is best.\n weight: count === 1 ? lightest : heaviest - (index / (count - 1)) * (heaviest - lightest),\n }))\n\n // The label names the bounds the caller SET, not the band tops: the last\n // band's top is the end of the scale, which is not a threshold anybody chose\n // — and not the drawable subset either, or a bound the scale cannot hold\n // would go missing from the reading as well as from the picture.\n return { list, label: set.map(formatValue).join(', ') }\n}\n\n/** Every measure, with its scale and bands worked out. */\nfunction resolve(\n data: BulletMeasure[],\n domain: [number, number] | undefined,\n ranges: number[] | undefined,\n formatValue: (value: number) => string,\n): ResolvedMeasure[] {\n return data.map((measure) => {\n const own = measure.ranges ?? ranges ?? []\n const high = Math.max(measure.value, measure.target ?? Number.NEGATIVE_INFINITY, ...own)\n // Anchored at zero unless told otherwise: the measure is drawn as a BAR,\n // and a bar read off a scale that does not start at zero overstates every\n // difference on it.\n const scale: [number, number] = measure.domain ?? domain ?? [Math.min(0, measure.value), high || 1]\n const built = bands(own, scale, formatValue)\n\n return { ...measure, domain: scale, bands: built.list, rangeLabel: built.label }\n })\n}\n\nexport interface BulletChartProps {\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 rows 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 /** One entry per measure. Order is the reading order; it is not sorted. */\n data: BulletMeasure[]\n /**\n * The bands every measure falls back to, as ascending upper bounds.\n *\n * Shared bands only mean something when the measures share a scale. Where\n * they do not — a latency beside a conversion rate — put `ranges` and\n * `domain` on each measure instead.\n */\n ranges?: number[]\n /** The scale every measure falls back to, as `[min, max]`. */\n domain?: [number, number]\n /** Formats every number the chart prints. */\n formatValue?: (value: number) => string\n /** Prints the scale's two ends under each track. */\n showScale?: boolean\n /** Merged onto the figure, last, so a call site can size or space it. */\n className?: string\n /** Drops the hidden table view. Only correct when the page prints the data itself. */\n hideDataTable?: boolean\n /** What the chart shows when it has nothing to draw. */\n empty?: ChartEmptyProps\n}\n\n/**\n * A measure, its target, and the bands that say whether the number is any good\n * — one dense row per thing being tracked.\n *\n * Stephen Few designed this to replace the dashboard gauge, and the argument\n * has held: a speedometer spends a whole card saying one number badly, where a\n * bullet graph says the same number, its target, and the qualitative context\n * around it in the height of a line of text. Ten of them stack into a status\n * page a reader can scan in one pass.\n *\n * What it will not do is show change over time. A bullet graph is one instant,\n * and `target` is the only comparison it carries; when the question is\n * \"how did we get here\" it wants a `<LineChart>`, and when several measures\n * have to be compared against each OTHER rather than each against its own\n * target, a `<BarList>` ranks them and this does not.\n *\n * **The bands are the part to be careful with.** They are a judgement — someone\n * decided that 80 is \"good\" — drawn in the same ink as the measurement, and a\n * reader has no way to tell an agreed threshold from a number somebody typed.\n * They also compress: a value near the top of the scale sits in the same band\n * whether it cleared the boundary by a point or by thirty. The band answers\n * \"is this acceptable\", never \"by how much\".\n *\n * No rendering engine, deliberately — this is the one chart in the set with\n * nothing to compute. Each row is a single linear scale with no axis, no ticks\n * and no shared plot area, so it is laid out as HTML: the bands and the bar are\n * inline-axis offsets, which means the whole chart mirrors correctly in a\n * right-to-left document, where an SVG drawn in user space would not.\n *\n * @example\n * <BulletChart\n * title=\"Service levels against target\"\n * data={[{ name: 'Uptime', value: 99.4, target: 99.9, ranges: [98, 99.5] }]}\n * domain={[95, 100]}\n * />\n */\nexport function BulletChart({\n title,\n showTitle,\n description,\n data,\n ranges,\n domain,\n formatValue = defaultTick,\n showScale = false,\n className,\n hideDataTable = false,\n empty,\n}: BulletChartProps) {\n const measures = resolve(data, domain, ranges, formatValue)\n\n return (\n <ChartFigure\n title={title}\n showTitle={showTitle}\n description={description}\n className={className}\n table={\n hideDataTable\n ? false\n : {\n rows: measures as unknown as Record<string, unknown>[],\n rowKey: 'name',\n columns: [\n { key: 'value', label: 'Value' },\n { key: 'target', label: 'Target' },\n { key: 'rangeLabel', label: 'Range bounds' },\n ],\n }\n }\n isEmpty={measures.length === 0}\n empty={empty}\n >\n <div className=\"flex w-full flex-col gap-4\">\n {measures.map((measure) => (\n <BulletRow\n key={measure.name}\n measure={measure}\n formatValue={formatValue}\n showScale={showScale}\n />\n ))}\n </div>\n </ChartFigure>\n )\n}\n\nfunction BulletRow({\n measure,\n formatValue,\n showScale,\n}: {\n measure: ResolvedMeasure\n formatValue: (value: number) => string\n showScale: boolean\n}) {\n const scale = measure.domain\n const barShare = position(measure.value, scale)\n const targetShare = measure.target === undefined ? null : position(measure.target, scale)\n const runsOver = overflows(measure.value, scale) || overflows(measure.target, scale)\n\n return (\n <div className=\"flex w-full flex-col gap-1.5\">\n <div className=\"flex items-baseline justify-between gap-3\">\n <span className=\"truncate text-sm text-(--ink)\">\n {measure.name}\n {measure.detail && (\n <span className=\"ms-2 mono-meta text-(--ink-3-aa)\">{measure.detail}</span>\n )}\n </span>\n <span className=\"shrink-0 font-mono text-xs tabular-nums text-(--ink)\">\n {formatValue(measure.value)}\n {measure.target !== undefined && (\n <span className=\"text-(--ink-3-aa)\"> / {formatValue(measure.target)}</span>\n )}\n </span>\n </div>\n\n {/* The graphic repeats what the line above and the hidden table already\n say, so it is out of the accessibility tree entirely rather than\n announced a third time as a stack of empty boxes. */}\n <div\n aria-hidden\n data-slot=\"bullet-track\"\n className=\"relative h-6 w-full overflow-hidden rounded-(--radius-sm)\"\n >\n {measure.bands.map((band) => (\n <span\n key={`${band.from}-${band.to}`}\n data-slot=\"bullet-band\"\n className=\"absolute inset-y-0 block\"\n style={{\n insetInlineStart: pct(position(band.from, scale)),\n inlineSize: pct(position(band.to, scale) - position(band.from, scale)),\n // The one translucent-mark pair in the token layer, because it is\n // the only one that holds a different number on each ground.\n backgroundColor: `color-mix(in srgb, var(--series-1) calc(var(--chart-fill) * ${band.weight} * 100%), transparent)`,\n }}\n />\n ))}\n\n {/* Solid, and a third of the track's height. The measure is the one\n thing here that is a measurement rather than a judgement, so it is\n the only mark drawn at full weight. */}\n <span\n data-slot=\"bullet-bar\"\n className=\"absolute block bg-(--series-1)\"\n style={{\n insetInlineStart: 0,\n insetBlockStart: pct((1 - BAR_SHARE) / 2),\n blockSize: pct(BAR_SHARE),\n inlineSize: pct(barShare),\n }}\n />\n\n {targetShare !== null && (\n // A rule ACROSS the bar rather than a second bar beside it: the two\n // are different kinds of number, and the reader has to be able to\n // tell at a glance which one was achieved and which was asked for.\n //\n // The paper halo is what makes that true where the rule lands ON the\n // bar. Both are drawn in --ink, so a target inside the achieved range\n // — which is every measure that is doing well — was an ink rule on an\n // ink bar and simply not there.\n <span\n data-slot=\"bullet-target\"\n className=\"absolute inset-y-1 block w-0.5 bg-(--ink) shadow-[0_0_0_1px_var(--paper)]\"\n style={{\n insetInlineStart: pct(targetShare),\n // Pulled back by its own width in PROPORTION to where it sits:\n // flush at the start at 0, centred in the middle, flush at the end\n // at 1. A fixed half-width pull put a target of zero half outside\n // the track, where `overflow-hidden` took it — so \"Open incidents,\n // target 0\" drew no target at all, on the one measure whose whole\n // point is the distance from it.\n marginInlineStart: `${-2 * targetShare}px`,\n }}\n />\n )}\n\n {runsOver && (\n // Clamped and silent, a number past the end of the scale fills the\n // track exactly as a number AT the end of it does — so the one thing\n // the row cannot say is the one thing the reader most needs to know.\n // The notch is what breaks that tie; the printed figure above still\n // carries the real number.\n <span\n data-slot=\"bullet-overflow\"\n className=\"absolute inset-y-0 end-0 block w-1.5 bg-(--chart-surface)\"\n style={{\n clipPath: 'polygon(100% 0, 0 50%, 100% 100%)',\n }}\n />\n )}\n </div>\n\n {showScale && (\n <div className=\"flex justify-between mono-meta text-(--chart-axis)\">\n <span>{formatValue(scale[0])}</span>\n <span>{formatValue(scale[1])}</span>\n </div>\n )}\n </div>\n )\n}\n\nexport default BulletChart\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { ChartEmptyProps } from '../lib/empty.js';
|
|
4
|
+
|
|
5
|
+
interface CalendarHeatmapValue {
|
|
6
|
+
/** The day, as `YYYY-MM-DD`. */
|
|
7
|
+
date: string;
|
|
8
|
+
/** The count. `null` is drawn as an explicit gap, not as a zero. */
|
|
9
|
+
value: number | null;
|
|
10
|
+
}
|
|
11
|
+
interface CalendarHeatmapProps {
|
|
12
|
+
/** What the calendar shows. Required, and it names the table. */
|
|
13
|
+
title: string;
|
|
14
|
+
/** Prints the title above the grid instead of hiding it from sight. */
|
|
15
|
+
showTitle?: boolean;
|
|
16
|
+
/** A line under the title — the unit, the window, the caveat. */
|
|
17
|
+
description?: ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* One entry per day that has a reading. Order does not matter; the grid is
|
|
20
|
+
* built from the dates.
|
|
21
|
+
*
|
|
22
|
+
* A day inside the window with no entry is drawn as a gap rather than as a
|
|
23
|
+
* zero, which is the distinction a calendar most often loses: "nothing
|
|
24
|
+
* happened" and "nothing was recorded" are different readings, and a page
|
|
25
|
+
* that draws them alike invites the reader to explain an outage that was a
|
|
26
|
+
* gap in collection.
|
|
27
|
+
*/
|
|
28
|
+
values: CalendarHeatmapValue[];
|
|
29
|
+
/**
|
|
30
|
+
* The first day the grid covers, as `YYYY-MM-DD`. Defaults to the earliest
|
|
31
|
+
* date in `values`.
|
|
32
|
+
*
|
|
33
|
+
* Give both ends whenever the window is a fact about the QUESTION rather than
|
|
34
|
+
* about the data — "the last year", "this quarter". Derived from the values,
|
|
35
|
+
* a quiet January simply does not exist, and the grid silently becomes a
|
|
36
|
+
* different window than the one beside it.
|
|
37
|
+
*/
|
|
38
|
+
from?: string;
|
|
39
|
+
/** The last day the grid covers, as `YYYY-MM-DD`. Defaults to the latest date in `values`. */
|
|
40
|
+
to?: string;
|
|
41
|
+
/**
|
|
42
|
+
* What each cell announces, given its reading and its date.
|
|
43
|
+
*
|
|
44
|
+
* The default is the date and the number. Reach for this to name the unit —
|
|
45
|
+
* "3 commits on 2026-01-05" — because the row and column headers a cell is
|
|
46
|
+
* announced with are a weekday and a month over a block of five weeks, and
|
|
47
|
+
* neither says which day it was.
|
|
48
|
+
*/
|
|
49
|
+
describe?: (value: number, date: string) => string;
|
|
50
|
+
/**
|
|
51
|
+
* The seven row headers, Sunday first, whatever `weekStartsOn` is.
|
|
52
|
+
*
|
|
53
|
+
* Sunday first in the ARRAY and not on the grid: the labels are a
|
|
54
|
+
* translation and the first column is a calendar convention, and tying the
|
|
55
|
+
* two together would make a Monday-first German calendar a different array
|
|
56
|
+
* from a Monday-first English one.
|
|
57
|
+
*/
|
|
58
|
+
weekdayLabels?: string[];
|
|
59
|
+
/** The twelve column headers, January first. */
|
|
60
|
+
monthLabels?: string[];
|
|
61
|
+
/** Which weekday the grid's first row is. `0` is Sunday, `1` Monday. */
|
|
62
|
+
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
63
|
+
/**
|
|
64
|
+
* The domain, as `[min, max]`. Derived from the readings when omitted.
|
|
65
|
+
*
|
|
66
|
+
* Pin it whenever two calendars are meant to be compared: a quiet year and a
|
|
67
|
+
* busy one drawn on their own domains look identical, and the comparison the
|
|
68
|
+
* reader came for is not merely lost but inverted.
|
|
69
|
+
*/
|
|
70
|
+
domain?: [number, number];
|
|
71
|
+
className?: string;
|
|
72
|
+
/** What the grid shows when there is no window to draw. */
|
|
73
|
+
empty?: ChartEmptyProps;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A year of daily readings, as a week-by-week grid.
|
|
77
|
+
*
|
|
78
|
+
* `Heatmap` draws a grid of named rows and columns and knows nothing about
|
|
79
|
+
* dates; this is the arrangement everybody writes on top of it and nobody
|
|
80
|
+
* writes the same way twice — a column per week, a row per weekday, a month
|
|
81
|
+
* name on the first column it touches, and the days either side of the window
|
|
82
|
+
* left as gaps rather than as zeroes.
|
|
83
|
+
*
|
|
84
|
+
* The grid is built from the DATES rather than from the order of the array, so
|
|
85
|
+
* a gap in the data is a gap on the calendar. That is the failure this exists
|
|
86
|
+
* to prevent: given a bare list of counts, a missing Tuesday shifts every
|
|
87
|
+
* reading after it by one cell, and the result is a plausible picture of a year
|
|
88
|
+
* that did not happen.
|
|
89
|
+
*
|
|
90
|
+
* Every date is arithmetic on UTC midnights. A local-time calendar drawn in two
|
|
91
|
+
* timezones is two different calendars, and the disagreement is exactly one day
|
|
92
|
+
* wide — small enough to survive review and large enough to move a reading into
|
|
93
|
+
* the wrong week.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* <CalendarHeatmap
|
|
97
|
+
* title="Commits per day"
|
|
98
|
+
* values={days}
|
|
99
|
+
* from="2026-01-01"
|
|
100
|
+
* to="2026-12-31"
|
|
101
|
+
* describe={(value, date) => `${value} commits on ${date}`}
|
|
102
|
+
* />
|
|
103
|
+
*/
|
|
104
|
+
declare function CalendarHeatmap({ title, showTitle, description, values, from, to, describe, weekdayLabels, monthLabels, weekStartsOn, domain, className, empty, }: CalendarHeatmapProps): react.JSX.Element;
|
|
105
|
+
|
|
106
|
+
export { CalendarHeatmap, type CalendarHeatmapProps, type CalendarHeatmapValue, CalendarHeatmap as default };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Heatmap } from "../Heatmap/Heatmap.js";
|
|
3
|
+
const DAY_MS = 864e5;
|
|
4
|
+
const WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
5
|
+
const MONTHS = [
|
|
6
|
+
"Jan",
|
|
7
|
+
"Feb",
|
|
8
|
+
"Mar",
|
|
9
|
+
"Apr",
|
|
10
|
+
"May",
|
|
11
|
+
"Jun",
|
|
12
|
+
"Jul",
|
|
13
|
+
"Aug",
|
|
14
|
+
"Sep",
|
|
15
|
+
"Oct",
|
|
16
|
+
"Nov",
|
|
17
|
+
"Dec"
|
|
18
|
+
];
|
|
19
|
+
const ZERO_WIDTH_SPACE = "\u200B";
|
|
20
|
+
function parse(date) {
|
|
21
|
+
const [year = 0, month = 1, day = 1] = date.split("-").map(Number);
|
|
22
|
+
return Date.UTC(year, month - 1, day);
|
|
23
|
+
}
|
|
24
|
+
function iso(time) {
|
|
25
|
+
return new Date(time).toISOString().slice(0, 10);
|
|
26
|
+
}
|
|
27
|
+
function CalendarHeatmap({
|
|
28
|
+
title,
|
|
29
|
+
showTitle = false,
|
|
30
|
+
description,
|
|
31
|
+
values,
|
|
32
|
+
from,
|
|
33
|
+
to,
|
|
34
|
+
describe,
|
|
35
|
+
weekdayLabels = WEEKDAYS,
|
|
36
|
+
monthLabels = MONTHS,
|
|
37
|
+
weekStartsOn = 0,
|
|
38
|
+
domain,
|
|
39
|
+
className,
|
|
40
|
+
empty
|
|
41
|
+
}) {
|
|
42
|
+
const readings = new Map(values.map((entry) => [entry.date, entry.value]));
|
|
43
|
+
const dates = values.map((entry) => parse(entry.date));
|
|
44
|
+
const first = from !== void 0 ? parse(from) : Math.min(...dates);
|
|
45
|
+
const last = to !== void 0 ? parse(to) : Math.max(...dates);
|
|
46
|
+
const drawable = Number.isFinite(first) && Number.isFinite(last) && first <= last;
|
|
47
|
+
const lead = drawable ? (new Date(first).getUTCDay() - weekStartsOn + 7) % 7 : 0;
|
|
48
|
+
const start = first - lead * DAY_MS;
|
|
49
|
+
const weeks = drawable ? Math.floor((last - start) / DAY_MS / 7) + 1 : 0;
|
|
50
|
+
const rows = Array.from(
|
|
51
|
+
{ length: 7 },
|
|
52
|
+
(_, offset) => weekdayLabels[(weekStartsOn + offset) % 7] ?? ""
|
|
53
|
+
);
|
|
54
|
+
const columns = Array.from({ length: weeks }, (_, week) => week).reduce(
|
|
55
|
+
(acc, week) => {
|
|
56
|
+
const month = new Date(start + week * 7 * DAY_MS).getUTCMonth();
|
|
57
|
+
const opens = month !== acc.lastMonth;
|
|
58
|
+
return {
|
|
59
|
+
labels: [...acc.labels, `${opens ? monthLabels[month] ?? "" : ""}${ZERO_WIDTH_SPACE.repeat(week)}`],
|
|
60
|
+
lastMonth: opens ? month : acc.lastMonth
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
{ labels: [], lastMonth: -1 }
|
|
64
|
+
).labels;
|
|
65
|
+
const cells = [];
|
|
66
|
+
const dateOf = /* @__PURE__ */ new Map();
|
|
67
|
+
for (let week = 0; week < weeks; week++) {
|
|
68
|
+
for (let offset = 0; offset < 7; offset++) {
|
|
69
|
+
const time = start + (week * 7 + offset) * DAY_MS;
|
|
70
|
+
if (time < first || time > last) continue;
|
|
71
|
+
const row = rows[offset] ?? "";
|
|
72
|
+
const column = columns[week] ?? "";
|
|
73
|
+
const day = iso(time);
|
|
74
|
+
dateOf.set(`${row}\0${column}`, day);
|
|
75
|
+
cells.push({ row, column, value: readings.get(day) ?? null });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const formatValue = (value, cell) => {
|
|
79
|
+
const date = dateOf.get(`${cell.row}\0${cell.column}`) ?? "";
|
|
80
|
+
return describe ? describe(value, date) : `${date}: ${value.toLocaleString()}`;
|
|
81
|
+
};
|
|
82
|
+
return /* @__PURE__ */ jsx(
|
|
83
|
+
Heatmap,
|
|
84
|
+
{
|
|
85
|
+
title,
|
|
86
|
+
showTitle,
|
|
87
|
+
description,
|
|
88
|
+
columns,
|
|
89
|
+
rows,
|
|
90
|
+
cells,
|
|
91
|
+
domain,
|
|
92
|
+
formatValue,
|
|
93
|
+
className,
|
|
94
|
+
empty
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
var CalendarHeatmap_default = CalendarHeatmap;
|
|
99
|
+
export {
|
|
100
|
+
CalendarHeatmap,
|
|
101
|
+
CalendarHeatmap_default as default
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=CalendarHeatmap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/charts/CalendarHeatmap/CalendarHeatmap.tsx"],"sourcesContent":["import type { ReactNode } from 'react'\nimport { Heatmap, type HeatmapCell } from '../Heatmap/Heatmap'\nimport type { ChartEmptyProps } from '../lib/empty'\n\nconst DAY_MS = 86_400_000\n\n/** Sunday first, which is what `weekStartsOn` rotates. */\nconst WEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']\n\nconst MONTHS = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n]\n\n/**\n * Invisible, and never repeated: what keeps two blank column headers apart.\n *\n * `Heatmap` places a cell by looking its row and column up by name, so two\n * columns with the same label are one column as far as the grid is concerned —\n * and eleven of the twelve headers on a year are deliberately blank.\n */\nconst ZERO_WIDTH_SPACE = ''\n\n/** A calendar date as `YYYY-MM-DD`, at UTC midnight. */\nfunction parse(date: string): number {\n const [year = 0, month = 1, day = 1] = date.split('-').map(Number)\n return Date.UTC(year, month - 1, day)\n}\n\n/**\n * `YYYY-MM-DD` for a UTC instant.\n *\n * Every date in here is arithmetic on UTC midnights and nothing reads a local\n * component, which is the whole of the timezone story: a naked `new Date('…')`\n * parses in the runner's own zone, so the same grid drawn in Sydney and in\n * Berlin would disagree by a day on either side of local midnight.\n */\nfunction iso(time: number): string {\n return new Date(time).toISOString().slice(0, 10)\n}\n\nexport interface CalendarHeatmapValue {\n /** The day, as `YYYY-MM-DD`. */\n date: string\n /** The count. `null` is drawn as an explicit gap, not as a zero. */\n value: number | null\n}\n\nexport interface CalendarHeatmapProps {\n /** What the calendar shows. Required, and it names the table. */\n title: string\n /** Prints the title above the grid 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 * One entry per day that has a reading. Order does not matter; the grid is\n * built from the dates.\n *\n * A day inside the window with no entry is drawn as a gap rather than as a\n * zero, which is the distinction a calendar most often loses: \"nothing\n * happened\" and \"nothing was recorded\" are different readings, and a page\n * that draws them alike invites the reader to explain an outage that was a\n * gap in collection.\n */\n values: CalendarHeatmapValue[]\n /**\n * The first day the grid covers, as `YYYY-MM-DD`. Defaults to the earliest\n * date in `values`.\n *\n * Give both ends whenever the window is a fact about the QUESTION rather than\n * about the data — \"the last year\", \"this quarter\". Derived from the values,\n * a quiet January simply does not exist, and the grid silently becomes a\n * different window than the one beside it.\n */\n from?: string\n /** The last day the grid covers, as `YYYY-MM-DD`. Defaults to the latest date in `values`. */\n to?: string\n /**\n * What each cell announces, given its reading and its date.\n *\n * The default is the date and the number. Reach for this to name the unit —\n * \"3 commits on 2026-01-05\" — because the row and column headers a cell is\n * announced with are a weekday and a month over a block of five weeks, and\n * neither says which day it was.\n */\n describe?: (value: number, date: string) => string\n /**\n * The seven row headers, Sunday first, whatever `weekStartsOn` is.\n *\n * Sunday first in the ARRAY and not on the grid: the labels are a\n * translation and the first column is a calendar convention, and tying the\n * two together would make a Monday-first German calendar a different array\n * from a Monday-first English one.\n */\n weekdayLabels?: string[]\n /** The twelve column headers, January first. */\n monthLabels?: string[]\n /** Which weekday the grid's first row is. `0` is Sunday, `1` Monday. */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6\n /**\n * The domain, as `[min, max]`. Derived from the readings when omitted.\n *\n * Pin it whenever two calendars are meant to be compared: a quiet year and a\n * busy one drawn on their own domains look identical, and the comparison the\n * reader came for is not merely lost but inverted.\n */\n domain?: [number, number]\n className?: string\n /** What the grid shows when there is no window to draw. */\n empty?: ChartEmptyProps\n}\n\n/**\n * A year of daily readings, as a week-by-week grid.\n *\n * `Heatmap` draws a grid of named rows and columns and knows nothing about\n * dates; this is the arrangement everybody writes on top of it and nobody\n * writes the same way twice — a column per week, a row per weekday, a month\n * name on the first column it touches, and the days either side of the window\n * left as gaps rather than as zeroes.\n *\n * The grid is built from the DATES rather than from the order of the array, so\n * a gap in the data is a gap on the calendar. That is the failure this exists\n * to prevent: given a bare list of counts, a missing Tuesday shifts every\n * reading after it by one cell, and the result is a plausible picture of a year\n * that did not happen.\n *\n * Every date is arithmetic on UTC midnights. A local-time calendar drawn in two\n * timezones is two different calendars, and the disagreement is exactly one day\n * wide — small enough to survive review and large enough to move a reading into\n * the wrong week.\n *\n * @example\n * <CalendarHeatmap\n * title=\"Commits per day\"\n * values={days}\n * from=\"2026-01-01\"\n * to=\"2026-12-31\"\n * describe={(value, date) => `${value} commits on ${date}`}\n * />\n */\nexport function CalendarHeatmap({\n title,\n showTitle = false,\n description,\n values,\n from,\n to,\n describe,\n weekdayLabels = WEEKDAYS,\n monthLabels = MONTHS,\n weekStartsOn = 0,\n domain,\n className,\n empty,\n}: CalendarHeatmapProps) {\n const readings = new Map(values.map((entry) => [entry.date, entry.value]))\n const dates = values.map((entry) => parse(entry.date))\n const first = from !== undefined ? parse(from) : Math.min(...dates)\n const last = to !== undefined ? parse(to) : Math.max(...dates)\n\n // `values: []` with no window given leaves the bounds at ±Infinity, which is\n // the empty state rather than a grid with an infinite number of weeks in it.\n const drawable = Number.isFinite(first) && Number.isFinite(last) && first <= last\n\n // Back to the week the window starts in, and forward to the end of the week\n // it ends in: a calendar's first column is a week, not a Monday-shaped\n // fragment of one, and the days outside the window are drawn as gaps.\n const lead = drawable ? (new Date(first).getUTCDay() - weekStartsOn + 7) % 7 : 0\n const start = first - lead * DAY_MS\n // Integer arithmetic, not a rounded division: every bound is a UTC midnight,\n // so the span is a whole number of days and the last day's own week is the\n // one `+ 1` adds. A `Math.ceil` here drops the final column on any window\n // that happens to be an exact multiple of seven.\n const weeks = drawable ? Math.floor((last - start) / DAY_MS / 7) + 1 : 0\n\n const rows = Array.from(\n { length: 7 },\n (_, offset) => weekdayLabels[(weekStartsOn + offset) % 7] ?? '',\n )\n\n // A month name on the first column it touches, blank elsewhere — the sparse\n // header a year of activity reads by. Threaded through `reduce` rather than a\n // mutated loop variable, so nothing outlives the render that builds it, and\n // every label carries a run of zero-width spaces sized to its own position:\n // invisible on screen, unique to the lookup.\n const columns = Array.from({ length: weeks }, (_, week) => week).reduce<{\n labels: string[]\n lastMonth: number\n }>(\n (acc, week) => {\n const month = new Date(start + week * 7 * DAY_MS).getUTCMonth()\n const opens = month !== acc.lastMonth\n return {\n labels: [...acc.labels, `${opens ? (monthLabels[month] ?? '') : ''}${ZERO_WIDTH_SPACE.repeat(week)}`],\n lastMonth: opens ? month : acc.lastMonth,\n }\n },\n { labels: [], lastMonth: -1 },\n ).labels\n\n const cells: HeatmapCell[] = []\n const dateOf = new Map<string, string>()\n for (let week = 0; week < weeks; week++) {\n for (let offset = 0; offset < 7; offset++) {\n const time = start + (week * 7 + offset) * DAY_MS\n if (time < first || time > last) continue\n const row = rows[offset] ?? ''\n const column = columns[week] ?? ''\n const day = iso(time)\n dateOf.set(`${row}\u0000${column}`, day)\n cells.push({ row, column, value: readings.get(day) ?? null })\n }\n }\n\n // Keyed by the CELL rather than by the value: two days with the same count\n // are two different readings, and a formatter that only sees the number can\n // only ever describe one of them.\n const formatValue = (value: number, cell: HeatmapCell): string => {\n const date = dateOf.get(`${cell.row}\u0000${cell.column}`) ?? ''\n return describe ? describe(value, date) : `${date}: ${value.toLocaleString()}`\n }\n\n return (\n <Heatmap\n title={title}\n showTitle={showTitle}\n description={description}\n columns={columns}\n rows={rows}\n cells={cells}\n domain={domain}\n formatValue={formatValue}\n className={className}\n empty={empty}\n />\n )\n}\n\nexport default CalendarHeatmap\n"],"mappings":"AA2OI;AA1OJ,SAAS,eAAiC;AAG1C,MAAM,SAAS;AAGf,MAAM,WAAW,CAAC,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAEjE,MAAM,SAAS;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AASA,MAAM,mBAAmB;AAGzB,SAAS,MAAM,MAAsB;AACnC,QAAM,CAAC,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,MAAM;AACjE,SAAO,KAAK,IAAI,MAAM,QAAQ,GAAG,GAAG;AACtC;AAUA,SAAS,IAAI,MAAsB;AACjC,SAAO,IAAI,KAAK,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AACjD;AAuGO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,WAAW,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,MAAM,MAAM,KAAK,CAAC,CAAC;AACzE,QAAM,QAAQ,OAAO,IAAI,CAAC,UAAU,MAAM,MAAM,IAAI,CAAC;AACrD,QAAM,QAAQ,SAAS,SAAY,MAAM,IAAI,IAAI,KAAK,IAAI,GAAG,KAAK;AAClE,QAAM,OAAO,OAAO,SAAY,MAAM,EAAE,IAAI,KAAK,IAAI,GAAG,KAAK;AAI7D,QAAM,WAAW,OAAO,SAAS,KAAK,KAAK,OAAO,SAAS,IAAI,KAAK,SAAS;AAK7E,QAAM,OAAO,YAAY,IAAI,KAAK,KAAK,EAAE,UAAU,IAAI,eAAe,KAAK,IAAI;AAC/E,QAAM,QAAQ,QAAQ,OAAO;AAK7B,QAAM,QAAQ,WAAW,KAAK,OAAO,OAAO,SAAS,SAAS,CAAC,IAAI,IAAI;AAEvE,QAAM,OAAO,MAAM;AAAA,IACjB,EAAE,QAAQ,EAAE;AAAA,IACZ,CAAC,GAAG,WAAW,eAAe,eAAe,UAAU,CAAC,KAAK;AAAA,EAC/D;AAOA,QAAM,UAAU,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,CAAC,GAAG,SAAS,IAAI,EAAE;AAAA,IAI/D,CAAC,KAAK,SAAS;AACb,YAAM,QAAQ,IAAI,KAAK,QAAQ,OAAO,IAAI,MAAM,EAAE,YAAY;AAC9D,YAAM,QAAQ,UAAU,IAAI;AAC5B,aAAO;AAAA,QACL,QAAQ,CAAC,GAAG,IAAI,QAAQ,GAAG,QAAS,YAAY,KAAK,KAAK,KAAM,EAAE,GAAG,iBAAiB,OAAO,IAAI,CAAC,EAAE;AAAA,QACpG,WAAW,QAAQ,QAAQ,IAAI;AAAA,MACjC;AAAA,IACF;AAAA,IACA,EAAE,QAAQ,CAAC,GAAG,WAAW,GAAG;AAAA,EAC9B,EAAE;AAEF,QAAM,QAAuB,CAAC;AAC9B,QAAM,SAAS,oBAAI,IAAoB;AACvC,WAAS,OAAO,GAAG,OAAO,OAAO,QAAQ;AACvC,aAAS,SAAS,GAAG,SAAS,GAAG,UAAU;AACzC,YAAM,OAAO,SAAS,OAAO,IAAI,UAAU;AAC3C,UAAI,OAAO,SAAS,OAAO,KAAM;AACjC,YAAM,MAAM,KAAK,MAAM,KAAK;AAC5B,YAAM,SAAS,QAAQ,IAAI,KAAK;AAChC,YAAM,MAAM,IAAI,IAAI;AACpB,aAAO,IAAI,GAAG,GAAG,KAAI,MAAM,IAAI,GAAG;AAClC,YAAM,KAAK,EAAE,KAAK,QAAQ,OAAO,SAAS,IAAI,GAAG,KAAK,KAAK,CAAC;AAAA,IAC9D;AAAA,EACF;AAKA,QAAM,cAAc,CAAC,OAAe,SAA8B;AAChE,UAAM,OAAO,OAAO,IAAI,GAAG,KAAK,GAAG,KAAI,KAAK,MAAM,EAAE,KAAK;AACzD,WAAO,WAAW,SAAS,OAAO,IAAI,IAAI,GAAG,IAAI,KAAK,MAAM,eAAe,CAAC;AAAA,EAC9E;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,0BAAQ;","names":[]}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { ChartCurveType, AreaStrokeVariant, ChartTooltipSlotProps, ChartLegendSlotProps } from '../AreaChart/AreaChart.js';
|
|
2
|
+
import { BarVariant } from '../BarChart/BarChart.js';
|
|
3
|
+
import * as react from 'react';
|
|
4
|
+
import { ComponentProps, ReactNode, FC } from 'react';
|
|
5
|
+
import { XAxis, YAxis, Bar, ComposedChart as ComposedChart$1, Line, CartesianGrid } from 'recharts';
|
|
6
|
+
import { ChartConfig } from '../lib/chart.js';
|
|
7
|
+
import { ChartEmptyProps } from '../lib/empty.js';
|
|
8
|
+
import { ValuesProps } from '../lib/values.js';
|
|
9
|
+
import { ChartBackgroundVariant } from '../lib/background.js';
|
|
10
|
+
import { ChartDotVariant } from '../lib/dot.js';
|
|
11
|
+
import { BrushProps } from '../lib/brush.js';
|
|
12
|
+
import { ToolbarProps } from '../lib/toolbar.js';
|
|
13
|
+
import { ChartRevealType } from '../lib/paint.js';
|
|
14
|
+
import { ReferenceLine, ReferenceBand, Annotation } from '../lib/annotations.js';
|
|
15
|
+
import '../lib/sonify-control.js';
|
|
16
|
+
import '../lib/sonify.js';
|
|
17
|
+
import '../lib/legend.js';
|
|
18
|
+
import '../lib/tooltip.js';
|
|
19
|
+
import 'recharts/types/component/DefaultTooltipContent';
|
|
20
|
+
import '../lib/zoom.js';
|
|
21
|
+
import '../lib/figure.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The axis props, with `label` narrowed to a string.
|
|
25
|
+
*
|
|
26
|
+
* Recharts' own `label` accepts a render function and a config object, neither
|
|
27
|
+
* of which a call site should be reaching for to name an axis — and both of
|
|
28
|
+
* which would let a consumer opt out of the system's own axis type styling
|
|
29
|
+
* without noticing.
|
|
30
|
+
*/
|
|
31
|
+
type ChartXAxisProps = Omit<ComponentProps<typeof XAxis>, 'label'> & {
|
|
32
|
+
/** What this axis measures. Say the unit here or in the series label, once. */
|
|
33
|
+
label?: string;
|
|
34
|
+
};
|
|
35
|
+
type ChartYAxisProps = Omit<ComponentProps<typeof YAxis>, 'label'> & {
|
|
36
|
+
/** What this axis measures. Say the unit here or in the series label, once. */
|
|
37
|
+
label?: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type ValidateKeys<TData, TConfig> = {
|
|
41
|
+
[K in keyof TConfig]: K extends keyof TData ? ChartConfig[string] : never;
|
|
42
|
+
};
|
|
43
|
+
interface ComposedChartProps<TData extends Record<string, unknown>, TConfig extends Record<string, ChartConfig[string]>> {
|
|
44
|
+
config: TConfig & ValidateKeys<TData, TConfig>;
|
|
45
|
+
/** The rows the chart draws. One entry per point, bar or category. */
|
|
46
|
+
data: TData[];
|
|
47
|
+
/**
|
|
48
|
+
* What the chart shows, in a sentence a reader could act on. Required, and
|
|
49
|
+
* announced to a screen reader even when it is not printed.
|
|
50
|
+
*/
|
|
51
|
+
title: string;
|
|
52
|
+
/** Prints the title above the plot instead of hiding it from sight. */
|
|
53
|
+
showTitle?: boolean;
|
|
54
|
+
/** A line under the title — the unit, the window, the caveat. */
|
|
55
|
+
description?: ReactNode;
|
|
56
|
+
/**
|
|
57
|
+
* The composed parts — axes, grid, tooltip, legend, and the marks
|
|
58
|
+
* themselves.
|
|
59
|
+
*/
|
|
60
|
+
children: ReactNode;
|
|
61
|
+
/** Merged onto the figure, last, so a call site can size or space it. */
|
|
62
|
+
className?: string;
|
|
63
|
+
/** Escape hatch onto the raw Recharts chart element. */
|
|
64
|
+
chartProps?: ComponentProps<typeof ComposedChart$1>;
|
|
65
|
+
/**
|
|
66
|
+
* How the line between two points is interpolated. Every mark inherits it
|
|
67
|
+
* unless it says otherwise.
|
|
68
|
+
*/
|
|
69
|
+
curveType?: ChartCurveType;
|
|
70
|
+
animationType?: ChartRevealType;
|
|
71
|
+
barGap?: number;
|
|
72
|
+
barCategoryGap?: number;
|
|
73
|
+
/** The series lit on first render, when the chart keeps its own selection. */
|
|
74
|
+
defaultSelectedDataKey?: string | null;
|
|
75
|
+
/**
|
|
76
|
+
* The selected series, driven from outside.
|
|
77
|
+
*
|
|
78
|
+
* Give this and the chart follows it; leave it undefined and the chart keeps
|
|
79
|
+
* its own, starting from `defaultSelectedDataKey`.
|
|
80
|
+
*/
|
|
81
|
+
selectedDataKey?: string | null;
|
|
82
|
+
/** Fires when the selection changes, and with null when it is cleared. */
|
|
83
|
+
onSelectionChange?: (selectedDataKey: string | null) => void;
|
|
84
|
+
/**
|
|
85
|
+
* Swaps the marks for an animated skeleton, keeping the measured height so
|
|
86
|
+
* the page does not jump when the data lands.
|
|
87
|
+
*/
|
|
88
|
+
isLoading?: boolean;
|
|
89
|
+
/** How many bars the skeleton draws. */
|
|
90
|
+
loadingBars?: number;
|
|
91
|
+
/**
|
|
92
|
+
* The row field on the category axis. Needed by the brush and by the table
|
|
93
|
+
* view.
|
|
94
|
+
*/
|
|
95
|
+
xDataKey?: keyof TData & string;
|
|
96
|
+
/**
|
|
97
|
+
* Drops the hidden table view. Only correct when the page prints the data
|
|
98
|
+
* itself.
|
|
99
|
+
*/
|
|
100
|
+
hideDataTable?: boolean;
|
|
101
|
+
/**
|
|
102
|
+
* What the chart shows when it has nothing to draw.
|
|
103
|
+
*
|
|
104
|
+
* Rendered instead of the plot whenever `data` is empty and the chart is not
|
|
105
|
+
* loading — the state a real dashboard reaches within a week, and the one an
|
|
106
|
+
* empty pair of axes is indistinguishable from a failed load. `false` keeps
|
|
107
|
+
* the axes, for a chart whose emptiness is itself the reading.
|
|
108
|
+
*/
|
|
109
|
+
empty?: ChartEmptyProps | false;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Bars and lines over one axis — the shape for "the volume, and the rate it
|
|
113
|
+
* moved at".
|
|
114
|
+
*
|
|
115
|
+
* One axis, always. Two measures at different scales belong in two charts or
|
|
116
|
+
* indexed to a common base; a second y-scale lets the author choose where the
|
|
117
|
+
* lines cross, which is the single most misleading thing a chart can do.
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* <ComposedChart title="Revenue and profit" config={config} data={data}>
|
|
121
|
+
* <ComposedChart.Grid />
|
|
122
|
+
* <ComposedChart.XAxis dataKey="month" />
|
|
123
|
+
* <ComposedChart.Tooltip />
|
|
124
|
+
* <ComposedChart.Bar dataKey="revenue" variant="duotone" />
|
|
125
|
+
* <ComposedChart.Line dataKey="profit" />
|
|
126
|
+
* </ComposedChart>
|
|
127
|
+
*/
|
|
128
|
+
declare function ComposedChart<TData extends Record<string, unknown>, TConfig extends Record<string, ChartConfig[string]>>({ config, data, title, showTitle, description, children, className, chartProps, curveType, animationType, barGap, barCategoryGap, defaultSelectedDataKey, selectedDataKey: controlledDataKey, onSelectionChange, isLoading, loadingBars, xDataKey, hideDataTable, empty, }: ComposedChartProps<TData, TConfig>): react.JSX.Element;
|
|
129
|
+
declare namespace ComposedChart {
|
|
130
|
+
var Bar: ({ dataKey, variant, radius, glowing, animationType, isClickable, enableHoverHighlight, children, barProps, }: ComposedBarProps) => react.JSX.Element | null;
|
|
131
|
+
var Line: ({ dataKey, strokeVariant, curveType, animationType, connectNulls, glowing, isClickable, children, lineProps, }: ComposedLineProps) => react.JSX.Element | null;
|
|
132
|
+
var Dot: FC<DotProps>;
|
|
133
|
+
var ActiveDot: FC<DotProps>;
|
|
134
|
+
var XAxis: ({ tickLine, axisLine, tickMargin, minTickGap, label, ...rest }: ChartXAxisProps) => react.JSX.Element | null;
|
|
135
|
+
var YAxis: ({ tickLine, axisLine, tickMargin, minTickGap, width, tickFormatter, label, ...rest }: ChartYAxisProps) => react.JSX.Element | null;
|
|
136
|
+
var Grid: ({ vertical, strokeDasharray, ...rest }: ComponentProps<typeof CartesianGrid>) => react.JSX.Element;
|
|
137
|
+
var Tooltip: ({ variant, roundness, defaultIndex, cursor }: ChartTooltipSlotProps) => react.JSX.Element | null;
|
|
138
|
+
var Legend: ({ variant, align, verticalAlign, isClickable, }: ChartLegendSlotProps) => react.JSX.Element;
|
|
139
|
+
var Background: ({ variant }: {
|
|
140
|
+
variant: ChartBackgroundVariant;
|
|
141
|
+
}) => react.JSX.Element | null;
|
|
142
|
+
var ReferenceLine: typeof ReferenceLine;
|
|
143
|
+
var ReferenceBand: typeof ReferenceBand;
|
|
144
|
+
var Annotation: typeof Annotation;
|
|
145
|
+
var Values: FC<ValuesProps>;
|
|
146
|
+
var Brush: FC<BrushProps>;
|
|
147
|
+
var Toolbar: FC<ToolbarProps>;
|
|
148
|
+
}
|
|
149
|
+
interface ComposedBarProps {
|
|
150
|
+
dataKey: string;
|
|
151
|
+
variant?: BarVariant;
|
|
152
|
+
radius?: number;
|
|
153
|
+
/** A halo behind the bars. */
|
|
154
|
+
glowing?: boolean;
|
|
155
|
+
animationType?: ChartRevealType;
|
|
156
|
+
isClickable?: boolean;
|
|
157
|
+
/** Dims this series while another COLUMN is hovered. */
|
|
158
|
+
enableHoverHighlight?: boolean;
|
|
159
|
+
/** `<ComposedChart.Values>`. */
|
|
160
|
+
children?: ReactNode;
|
|
161
|
+
barProps?: ComponentProps<typeof Bar>;
|
|
162
|
+
}
|
|
163
|
+
interface ComposedLineProps {
|
|
164
|
+
dataKey: string;
|
|
165
|
+
strokeVariant?: AreaStrokeVariant;
|
|
166
|
+
curveType?: ChartCurveType;
|
|
167
|
+
animationType?: ChartRevealType;
|
|
168
|
+
connectNulls?: boolean;
|
|
169
|
+
glowing?: boolean;
|
|
170
|
+
isClickable?: boolean;
|
|
171
|
+
children?: ReactNode;
|
|
172
|
+
lineProps?: ComponentProps<typeof Line>;
|
|
173
|
+
}
|
|
174
|
+
interface DotProps {
|
|
175
|
+
variant?: ChartDotVariant;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export { type ChartXAxisProps, type ChartYAxisProps, type ComposedBarProps, ComposedChart, type ComposedChartProps, type ComposedLineProps, type DotProps, ComposedChart as default };
|