@langchain/macaw-components 1.0.0-beta.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/LICENSE +21 -0
- package/README.md +27 -0
- package/dist/_chunks/ErrorState-CmPX01HV.js +13361 -0
- package/dist/_chunks/ErrorState-CmPX01HV.js.map +1 -0
- package/dist/_chunks/LoadingIndicator-DgtU9aqD.js +80 -0
- package/dist/_chunks/LoadingIndicator-DgtU9aqD.js.map +1 -0
- package/dist/base.css +305 -0
- package/dist/catalog.json +1675 -0
- package/dist/components/Avatar/Avatar.d.ts +28 -0
- package/dist/components/Avatar/Avatar.js +47 -0
- package/dist/components/Avatar/Avatar.js.map +1 -0
- package/dist/components/Avatar/index.d.ts +2 -0
- package/dist/components/Avatar/index.js +2 -0
- package/dist/components/Badge/Badge.d.ts +25 -0
- package/dist/components/Badge/Badge.js +82 -0
- package/dist/components/Badge/Badge.js.map +1 -0
- package/dist/components/Badge/index.d.ts +2 -0
- package/dist/components/Badge/index.js +2 -0
- package/dist/components/Banner/Banner.d.ts +15 -0
- package/dist/components/Banner/Banner.js +102 -0
- package/dist/components/Banner/Banner.js.map +1 -0
- package/dist/components/Banner/index.d.ts +2 -0
- package/dist/components/Banner/index.js +2 -0
- package/dist/components/BarChart/AnimatedBar.d.ts +20 -0
- package/dist/components/BarChart/AnimatedBar.js +65 -0
- package/dist/components/BarChart/AnimatedBar.js.map +1 -0
- package/dist/components/BarChart/BarChart.d.ts +25 -0
- package/dist/components/BarChart/BarChart.js +248 -0
- package/dist/components/BarChart/BarChart.js.map +1 -0
- package/dist/components/BarChart/BarChart.types.d.ts +239 -0
- package/dist/components/BarChart/BarChart.types.js +0 -0
- package/dist/components/BarChart/BarChart.utils.d.ts +51 -0
- package/dist/components/BarChart/BarChart.utils.js +215 -0
- package/dist/components/BarChart/BarChart.utils.js.map +1 -0
- package/dist/components/BarChart/BarChartAxes.d.ts +22 -0
- package/dist/components/BarChart/BarChartAxes.js +144 -0
- package/dist/components/BarChart/BarChartAxes.js.map +1 -0
- package/dist/components/BarChart/BarChartGuides.d.ts +22 -0
- package/dist/components/BarChart/BarChartGuides.js +83 -0
- package/dist/components/BarChart/BarChartGuides.js.map +1 -0
- package/dist/components/BarChart/BarChartPlot.d.ts +40 -0
- package/dist/components/BarChart/BarChartPlot.js +262 -0
- package/dist/components/BarChart/BarChartPlot.js.map +1 -0
- package/dist/components/BarChart/constants.d.ts +21 -0
- package/dist/components/BarChart/constants.js +26 -0
- package/dist/components/BarChart/constants.js.map +1 -0
- package/dist/components/BarChart/index.d.ts +3 -0
- package/dist/components/BarChart/index.js +3 -0
- package/dist/components/Button/Button.d.ts +36 -0
- package/dist/components/Button/Button.js +99 -0
- package/dist/components/Button/Button.js.map +1 -0
- package/dist/components/Button/constants.d.ts +26 -0
- package/dist/components/Button/constants.js +31 -0
- package/dist/components/Button/constants.js.map +1 -0
- package/dist/components/Button/index.d.ts +2 -0
- package/dist/components/Button/index.js +2 -0
- package/dist/components/ButtonGroup/ButtonGroup.d.ts +30 -0
- package/dist/components/ButtonGroup/ButtonGroup.js +26 -0
- package/dist/components/ButtonGroup/ButtonGroup.js.map +1 -0
- package/dist/components/ButtonGroup/index.d.ts +2 -0
- package/dist/components/ButtonGroup/index.js +2 -0
- package/dist/components/Card/Card.d.ts +10 -0
- package/dist/components/Card/Card.js +23 -0
- package/dist/components/Card/Card.js.map +1 -0
- package/dist/components/Card/index.d.ts +2 -0
- package/dist/components/Card/index.js +2 -0
- package/dist/components/ChartCard/ChartCard.d.ts +53 -0
- package/dist/components/ChartCard/ChartCard.js +172 -0
- package/dist/components/ChartCard/ChartCard.js.map +1 -0
- package/dist/components/ChartCard/ChartCardSkeleton.d.ts +7 -0
- package/dist/components/ChartCard/ChartCardSkeleton.js +61 -0
- package/dist/components/ChartCard/ChartCardSkeleton.js.map +1 -0
- package/dist/components/ChartCard/index.d.ts +4 -0
- package/dist/components/ChartCard/index.js +3 -0
- package/dist/components/ChartLegend/ChartLegend.d.ts +19 -0
- package/dist/components/ChartLegend/ChartLegend.js +195 -0
- package/dist/components/ChartLegend/ChartLegend.js.map +1 -0
- package/dist/components/ChartLegend/ChartLegendItemRenderer.d.ts +14 -0
- package/dist/components/ChartLegend/ChartLegendItemRenderer.js +90 -0
- package/dist/components/ChartLegend/ChartLegendItemRenderer.js.map +1 -0
- package/dist/components/ChartLegend/index.d.ts +3 -0
- package/dist/components/ChartLegend/index.js +3 -0
- package/dist/components/ChartLegend/useChartLegendActiveItem.d.ts +7 -0
- package/dist/components/ChartLegend/useChartLegendActiveItem.js +35 -0
- package/dist/components/ChartLegend/useChartLegendActiveItem.js.map +1 -0
- package/dist/components/ChartLegend/utils.d.ts +20 -0
- package/dist/components/ChartLegend/utils.js +33 -0
- package/dist/components/ChartLegend/utils.js.map +1 -0
- package/dist/components/ChartTooltip/ChartTooltip.d.ts +23 -0
- package/dist/components/ChartTooltip/ChartTooltip.js +83 -0
- package/dist/components/ChartTooltip/ChartTooltip.js.map +1 -0
- package/dist/components/ChartTooltip/index.d.ts +2 -0
- package/dist/components/ChartTooltip/index.js +2 -0
- package/dist/components/Checkbox/Checkbox.d.ts +58 -0
- package/dist/components/Checkbox/Checkbox.js +50 -0
- package/dist/components/Checkbox/Checkbox.js.map +1 -0
- package/dist/components/Checkbox/constants.d.ts +28 -0
- package/dist/components/Checkbox/constants.js +57 -0
- package/dist/components/Checkbox/constants.js.map +1 -0
- package/dist/components/Checkbox/getCheckedState.d.ts +6 -0
- package/dist/components/Checkbox/getCheckedState.js +14 -0
- package/dist/components/Checkbox/getCheckedState.js.map +1 -0
- package/dist/components/Checkbox/index.d.ts +3 -0
- package/dist/components/Checkbox/index.js +3 -0
- package/dist/components/CircularProgress/CircularProgress.d.ts +54 -0
- package/dist/components/CircularProgress/CircularProgress.js +85 -0
- package/dist/components/CircularProgress/CircularProgress.js.map +1 -0
- package/dist/components/CircularProgress/index.d.ts +2 -0
- package/dist/components/CircularProgress/index.js +2 -0
- package/dist/components/Code/Code.utils.d.ts +24 -0
- package/dist/components/Code/Code.utils.js +160 -0
- package/dist/components/Code/Code.utils.js.map +1 -0
- package/dist/components/Code/CodeLite.d.ts +19 -0
- package/dist/components/Code/CodeLite.js +146 -0
- package/dist/components/Code/CodeLite.js.map +1 -0
- package/dist/components/Code/CodeLite.utils.d.ts +24 -0
- package/dist/components/Code/CodeLite.utils.js +273 -0
- package/dist/components/Code/CodeLite.utils.js.map +1 -0
- package/dist/components/Code/ImageReplacerExtension.d.ts +9 -0
- package/dist/components/Code/ImageReplacerExtension.js +227 -0
- package/dist/components/Code/ImageReplacerExtension.js.map +1 -0
- package/dist/components/Code/JsonHighlighterExtension.d.ts +4 -0
- package/dist/components/Code/JsonHighlighterExtension.js +172 -0
- package/dist/components/Code/JsonHighlighterExtension.js.map +1 -0
- package/dist/components/Code/constants.d.ts +6 -0
- package/dist/components/Code/constants.js +11 -0
- package/dist/components/Code/constants.js.map +1 -0
- package/dist/components/Code/index.d.ts +30 -0
- package/dist/components/Code/index.js +140 -0
- package/dist/components/Code/index.js.map +1 -0
- package/dist/components/Code/languages/json.d.ts +1 -0
- package/dist/components/Code/languages/json.js +7 -0
- package/dist/components/Code/languages/json.js.map +1 -0
- package/dist/components/Code/languages/languages.d.ts +7 -0
- package/dist/components/Code/languages/languages.js +12 -0
- package/dist/components/Code/languages/languages.js.map +1 -0
- package/dist/components/Code/languages/python.d.ts +1 -0
- package/dist/components/Code/languages/python.js +7 -0
- package/dist/components/Code/languages/python.js.map +1 -0
- package/dist/components/Code/languages/shell.d.ts +7 -0
- package/dist/components/Code/languages/shell.js +241 -0
- package/dist/components/Code/languages/shell.js.map +1 -0
- package/dist/components/Code/languages/typescript.d.ts +1 -0
- package/dist/components/Code/languages/typescript.js +7 -0
- package/dist/components/Code/languages/typescript.js.map +1 -0
- package/dist/components/Code/languages/yaml.d.ts +2 -0
- package/dist/components/Code/languages/yaml.js +44 -0
- package/dist/components/Code/languages/yaml.js.map +1 -0
- package/dist/components/Code/types.d.ts +8 -0
- package/dist/components/Code/types.js +0 -0
- package/dist/components/Code/utils.d.ts +4 -0
- package/dist/components/Code/utils.js +27 -0
- package/dist/components/Code/utils.js.map +1 -0
- package/dist/components/Command/Command.d.ts +78 -0
- package/dist/components/Command/Command.js +78 -0
- package/dist/components/Command/Command.js.map +1 -0
- package/dist/components/Command/CommandMenu.d.ts +65 -0
- package/dist/components/Command/CommandMenu.js +101 -0
- package/dist/components/Command/CommandMenu.js.map +1 -0
- package/dist/components/Command/index.d.ts +4 -0
- package/dist/components/Command/index.js +3 -0
- package/dist/components/ContextMenu/ContextMenu.d.ts +9 -0
- package/dist/components/ContextMenu/ContextMenu.js +43 -0
- package/dist/components/ContextMenu/ContextMenu.js.map +1 -0
- package/dist/components/ContextMenu/index.d.ts +1 -0
- package/dist/components/ContextMenu/index.js +2 -0
- package/dist/components/CopyButton/CopyButton.d.ts +24 -0
- package/dist/components/CopyButton/CopyButton.js +121 -0
- package/dist/components/CopyButton/CopyButton.js.map +1 -0
- package/dist/components/CopyButton/copyToClipboard.d.ts +1 -0
- package/dist/components/CopyButton/copyToClipboard.js +29 -0
- package/dist/components/CopyButton/copyToClipboard.js.map +1 -0
- package/dist/components/CopyButton/index.d.ts +4 -0
- package/dist/components/CopyButton/index.js +4 -0
- package/dist/components/CopyButton/useCopy.d.ts +10 -0
- package/dist/components/CopyButton/useCopy.js +46 -0
- package/dist/components/CopyButton/useCopy.js.map +1 -0
- package/dist/components/Dialog/index.d.ts +49 -0
- package/dist/components/Dialog/index.js +130 -0
- package/dist/components/Dialog/index.js.map +1 -0
- package/dist/components/Divider/Divider.d.ts +9 -0
- package/dist/components/Divider/Divider.js +27 -0
- package/dist/components/Divider/Divider.js.map +1 -0
- package/dist/components/Divider/index.d.ts +2 -0
- package/dist/components/Divider/index.js +2 -0
- package/dist/components/DonutChart/DonutChart.d.ts +101 -0
- package/dist/components/DonutChart/DonutChart.js +197 -0
- package/dist/components/DonutChart/DonutChart.js.map +1 -0
- package/dist/components/DonutChart/DonutChart.utils.d.ts +38 -0
- package/dist/components/DonutChart/DonutChart.utils.js +93 -0
- package/dist/components/DonutChart/DonutChart.utils.js.map +1 -0
- package/dist/components/DonutChart/constants.d.ts +7 -0
- package/dist/components/DonutChart/constants.js +12 -0
- package/dist/components/DonutChart/constants.js.map +1 -0
- package/dist/components/DonutChart/index.d.ts +4 -0
- package/dist/components/DonutChart/index.js +4 -0
- package/dist/components/DropdownMenu/DropdownMenu.d.ts +24 -0
- package/dist/components/DropdownMenu/DropdownMenu.js +149 -0
- package/dist/components/DropdownMenu/DropdownMenu.js.map +1 -0
- package/dist/components/DropdownMenu/index.d.ts +1 -0
- package/dist/components/DropdownMenu/index.js +2 -0
- package/dist/components/EmptyState/EmptyState.d.ts +26 -0
- package/dist/components/EmptyState/EmptyState.js +85 -0
- package/dist/components/EmptyState/EmptyState.js.map +1 -0
- package/dist/components/EmptyState/index.d.ts +2 -0
- package/dist/components/EmptyState/index.js +2 -0
- package/dist/components/ErrorBoundary.d.ts +35 -0
- package/dist/components/ErrorBoundary.js +41 -0
- package/dist/components/ErrorBoundary.js.map +1 -0
- package/dist/components/ErrorMessage/ErrorMessage.d.ts +17 -0
- package/dist/components/ErrorMessage/ErrorMessage.js +146 -0
- package/dist/components/ErrorMessage/ErrorMessage.js.map +1 -0
- package/dist/components/ErrorMessage/index.d.ts +2 -0
- package/dist/components/ErrorMessage/index.js +2 -0
- package/dist/components/ErrorState/ErrorState.d.ts +23 -0
- package/dist/components/ErrorState/ErrorState.js +2 -0
- package/dist/components/ErrorState/index.d.ts +2 -0
- package/dist/components/ErrorState/index.js +2 -0
- package/dist/components/GroupedTabs/GroupedTabs.d.ts +31 -0
- package/dist/components/GroupedTabs/GroupedTabs.js +92 -0
- package/dist/components/GroupedTabs/GroupedTabs.js.map +1 -0
- package/dist/components/GroupedTabs/index.d.ts +2 -0
- package/dist/components/GroupedTabs/index.js +2 -0
- package/dist/components/HoverCard.d.ts +4 -0
- package/dist/components/HoverCard.js +34 -0
- package/dist/components/HoverCard.js.map +1 -0
- package/dist/components/Icon/Icon.d.ts +25 -0
- package/dist/components/Icon/Icon.js +57 -0
- package/dist/components/Icon/Icon.js.map +1 -0
- package/dist/components/Icon/index.d.ts +2 -0
- package/dist/components/Icon/index.js +2 -0
- package/dist/components/IconButton/IconButton.d.ts +35 -0
- package/dist/components/IconButton/IconButton.js +73 -0
- package/dist/components/IconButton/IconButton.js.map +1 -0
- package/dist/components/IconButton/index.d.ts +2 -0
- package/dist/components/IconButton/index.js +2 -0
- package/dist/components/Input/Input.d.ts +72 -0
- package/dist/components/Input/Input.js +221 -0
- package/dist/components/Input/Input.js.map +1 -0
- package/dist/components/Input/index.d.ts +2 -0
- package/dist/components/Input/index.js +2 -0
- package/dist/components/Input/inputStyles.d.ts +28 -0
- package/dist/components/Input/inputStyles.js +45 -0
- package/dist/components/Input/inputStyles.js.map +1 -0
- package/dist/components/Kbd/Kbd.d.ts +15 -0
- package/dist/components/Kbd/Kbd.js +30 -0
- package/dist/components/Kbd/Kbd.js.map +1 -0
- package/dist/components/Kbd/index.d.ts +2 -0
- package/dist/components/Kbd/index.js +2 -0
- package/dist/components/LineChart/LineChart.d.ts +8 -0
- package/dist/components/LineChart/LineChart.js +194 -0
- package/dist/components/LineChart/LineChart.js.map +1 -0
- package/dist/components/LineChart/LineChart.types.d.ts +138 -0
- package/dist/components/LineChart/LineChart.types.js +0 -0
- package/dist/components/LineChart/LineChart.utils.d.ts +29 -0
- package/dist/components/LineChart/LineChart.utils.js +123 -0
- package/dist/components/LineChart/LineChart.utils.js.map +1 -0
- package/dist/components/LineChart/LineChartPlot.d.ts +43 -0
- package/dist/components/LineChart/LineChartPlot.js +306 -0
- package/dist/components/LineChart/LineChartPlot.js.map +1 -0
- package/dist/components/LineChart/constants.d.ts +3 -0
- package/dist/components/LineChart/constants.js +8 -0
- package/dist/components/LineChart/constants.js.map +1 -0
- package/dist/components/LineChart/index.d.ts +2 -0
- package/dist/components/LineChart/index.js +2 -0
- package/dist/components/LinearProgress/LinearProgress.d.ts +16 -0
- package/dist/components/LinearProgress/LinearProgress.js +42 -0
- package/dist/components/LinearProgress/LinearProgress.js.map +1 -0
- package/dist/components/LinearProgress/index.d.ts +2 -0
- package/dist/components/LinearProgress/index.js +2 -0
- package/dist/components/Link/Link.d.ts +30 -0
- package/dist/components/Link/Link.js +51 -0
- package/dist/components/Link/Link.js.map +1 -0
- package/dist/components/Link/index.d.ts +2 -0
- package/dist/components/Link/index.js +2 -0
- package/dist/components/Logo/index.d.ts +17 -0
- package/dist/components/Logo/index.js +705 -0
- package/dist/components/Logo/index.js.map +1 -0
- package/dist/components/MetricChart/MetricChart.d.ts +9 -0
- package/dist/components/MetricChart/MetricChart.js +42 -0
- package/dist/components/MetricChart/MetricChart.js.map +1 -0
- package/dist/components/MetricChart/formatters.d.ts +18 -0
- package/dist/components/MetricChart/formatters.js +34 -0
- package/dist/components/MetricChart/formatters.js.map +1 -0
- package/dist/components/MetricChart/index.d.ts +4 -0
- package/dist/components/MetricChart/index.js +3 -0
- package/dist/components/Pane/Pane.d.ts +29 -0
- package/dist/components/Pane/Pane.js +171 -0
- package/dist/components/Pane/Pane.js.map +1 -0
- package/dist/components/Pane/Pane.utils.d.ts +10 -0
- package/dist/components/Pane/Pane.utils.js +7 -0
- package/dist/components/Pane/Pane.utils.js.map +1 -0
- package/dist/components/Pane/index.d.ts +3 -0
- package/dist/components/Pane/index.js +3 -0
- package/dist/components/PlainTextEditor/hooks/useResizeTextEditor.d.ts +9 -0
- package/dist/components/PlainTextEditor/hooks/useResizeTextEditor.js +76 -0
- package/dist/components/PlainTextEditor/hooks/useResizeTextEditor.js.map +1 -0
- package/dist/components/PlainTextEditor/index.d.ts +18 -0
- package/dist/components/PlainTextEditor/index.js +71 -0
- package/dist/components/PlainTextEditor/index.js.map +1 -0
- package/dist/components/Popover/Popover.d.ts +13 -0
- package/dist/components/Popover/Popover.js +48 -0
- package/dist/components/Popover/Popover.js.map +1 -0
- package/dist/components/Popover/constants.d.ts +1 -0
- package/dist/components/Popover/constants.js +6 -0
- package/dist/components/Popover/constants.js.map +1 -0
- package/dist/components/Popover/index.d.ts +1 -0
- package/dist/components/Popover/index.js +2 -0
- package/dist/components/PortalSlot.d.ts +11 -0
- package/dist/components/PortalSlot.js +41 -0
- package/dist/components/PortalSlot.js.map +1 -0
- package/dist/components/ProgressBar/ProgressBar.d.ts +38 -0
- package/dist/components/ProgressBar/ProgressBar.js +82 -0
- package/dist/components/ProgressBar/ProgressBar.js.map +1 -0
- package/dist/components/ProgressBar/index.d.ts +2 -0
- package/dist/components/ProgressBar/index.js +2 -0
- package/dist/components/RadioButton/RadioButton.d.ts +62 -0
- package/dist/components/RadioButton/RadioButton.js +38 -0
- package/dist/components/RadioButton/RadioButton.js.map +1 -0
- package/dist/components/RadioButton/constants.d.ts +30 -0
- package/dist/components/RadioButton/constants.js +55 -0
- package/dist/components/RadioButton/constants.js.map +1 -0
- package/dist/components/RadioButton/index.d.ts +2 -0
- package/dist/components/RadioButton/index.js +2 -0
- package/dist/components/RadioCard/RadioCard.d.ts +26 -0
- package/dist/components/RadioCard/RadioCard.js +43 -0
- package/dist/components/RadioCard/RadioCard.js.map +1 -0
- package/dist/components/RadioCard/index.d.ts +2 -0
- package/dist/components/RadioCard/index.js +2 -0
- package/dist/components/RadioGroup/RadioGroup.d.ts +5 -0
- package/dist/components/RadioGroup/RadioGroup.js +17 -0
- package/dist/components/RadioGroup/RadioGroup.js.map +1 -0
- package/dist/components/RadioGroup/RadioGroupItem.d.ts +5 -0
- package/dist/components/RadioGroup/RadioGroupItem.js +22 -0
- package/dist/components/RadioGroup/RadioGroupItem.js.map +1 -0
- package/dist/components/RadioGroup/index.d.ts +4 -0
- package/dist/components/RadioGroup/index.js +3 -0
- package/dist/components/Select/Select.d.ts +84 -0
- package/dist/components/Select/Select.js +120 -0
- package/dist/components/Select/Select.js.map +1 -0
- package/dist/components/Select/SelectPrimitive.d.ts +17 -0
- package/dist/components/Select/SelectPrimitive.js +126 -0
- package/dist/components/Select/SelectPrimitive.js.map +1 -0
- package/dist/components/Select/index.d.ts +4 -0
- package/dist/components/Select/index.js +3 -0
- package/dist/components/Skeleton/Skeleton.d.ts +13 -0
- package/dist/components/Skeleton/Skeleton.js +25 -0
- package/dist/components/Skeleton/Skeleton.js.map +1 -0
- package/dist/components/Skeleton/index.d.ts +1 -0
- package/dist/components/Skeleton/index.js +2 -0
- package/dist/components/Slider/Slider.d.ts +33 -0
- package/dist/components/Slider/Slider.js +64 -0
- package/dist/components/Slider/Slider.js.map +1 -0
- package/dist/components/Slider/index.d.ts +2 -0
- package/dist/components/Slider/index.js +2 -0
- package/dist/components/SparkLineChart/SparkLineChart.d.ts +14 -0
- package/dist/components/SparkLineChart/SparkLineChart.js +112 -0
- package/dist/components/SparkLineChart/SparkLineChart.js.map +1 -0
- package/dist/components/SparkLineChart/index.d.ts +2 -0
- package/dist/components/SparkLineChart/index.js +2 -0
- package/dist/components/Spinner/Spinner.d.ts +12 -0
- package/dist/components/Spinner/Spinner.js +33 -0
- package/dist/components/Spinner/Spinner.js.map +1 -0
- package/dist/components/Spinner/index.d.ts +1 -0
- package/dist/components/Spinner/index.js +2 -0
- package/dist/components/SplitViewPane/SplitViewPane.d.ts +41 -0
- package/dist/components/SplitViewPane/SplitViewPane.js +314 -0
- package/dist/components/SplitViewPane/SplitViewPane.js.map +1 -0
- package/dist/components/SplitViewPane/SplitViewPaneHeader.d.ts +22 -0
- package/dist/components/SplitViewPane/SplitViewPaneHeader.js +105 -0
- package/dist/components/SplitViewPane/SplitViewPaneHeader.js.map +1 -0
- package/dist/components/SplitViewPane/index.d.ts +2 -0
- package/dist/components/SplitViewPane/index.js +3 -0
- package/dist/components/SplitViewPane/openPaneRegistry.d.ts +2 -0
- package/dist/components/SplitViewPane/openPaneRegistry.js +49 -0
- package/dist/components/SplitViewPane/openPaneRegistry.js.map +1 -0
- package/dist/components/Switch/Switch.d.ts +35 -0
- package/dist/components/Switch/Switch.js +65 -0
- package/dist/components/Switch/Switch.js.map +1 -0
- package/dist/components/Switch/index.d.ts +2 -0
- package/dist/components/Switch/index.js +2 -0
- package/dist/components/Tabs/index.d.ts +27 -0
- package/dist/components/Tabs/index.js +45 -0
- package/dist/components/Tabs/index.js.map +1 -0
- package/dist/components/Text/Text.d.ts +13 -0
- package/dist/components/Text/Text.js +58 -0
- package/dist/components/Text/Text.js.map +1 -0
- package/dist/components/Text/index.d.ts +2 -0
- package/dist/components/Text/index.js +2 -0
- package/dist/components/TextVirtualizer.d.ts +8 -0
- package/dist/components/TextVirtualizer.js +53 -0
- package/dist/components/TextVirtualizer.js.map +1 -0
- package/dist/components/TextWithLinks.d.ts +6 -0
- package/dist/components/TextWithLinks.js +61 -0
- package/dist/components/TextWithLinks.js.map +1 -0
- package/dist/components/Textarea/Textarea.d.ts +47 -0
- package/dist/components/Textarea/Textarea.js +150 -0
- package/dist/components/Textarea/Textarea.js.map +1 -0
- package/dist/components/Textarea/index.d.ts +2 -0
- package/dist/components/Textarea/index.js +2 -0
- package/dist/components/ThinkingState/LoadingIndicator.d.ts +19 -0
- package/dist/components/ThinkingState/LoadingIndicator.js +2 -0
- package/dist/components/ThinkingState/NOTICE +25 -0
- package/dist/components/ThinkingState/ThinkingState.d.ts +21 -0
- package/dist/components/ThinkingState/ThinkingState.js +42 -0
- package/dist/components/ThinkingState/ThinkingState.js.map +1 -0
- package/dist/components/ThinkingState/ThinkingStateTimer.d.ts +9 -0
- package/dist/components/ThinkingState/ThinkingStateTimer.js +43 -0
- package/dist/components/ThinkingState/ThinkingStateTimer.js.map +1 -0
- package/dist/components/ThinkingState/index.d.ts +4 -0
- package/dist/components/ThinkingState/index.js +3 -0
- package/dist/components/Toast/ToastContext.d.ts +5 -0
- package/dist/components/Toast/ToastContext.js +9 -0
- package/dist/components/Toast/ToastContext.js.map +1 -0
- package/dist/components/Toast/index.d.ts +13 -0
- package/dist/components/Toast/index.js +166 -0
- package/dist/components/Toast/index.js.map +1 -0
- package/dist/components/Toast/useToast.d.ts +3 -0
- package/dist/components/Toast/useToast.js +11 -0
- package/dist/components/Toast/useToast.js.map +1 -0
- package/dist/components/Tooltip/Tooltip.d.ts +19 -0
- package/dist/components/Tooltip/Tooltip.js +57 -0
- package/dist/components/Tooltip/Tooltip.js.map +1 -0
- package/dist/components/Tooltip/index.d.ts +3 -0
- package/dist/components/Tooltip/index.js +3 -0
- package/dist/components/TopList/TopList.d.ts +3 -0
- package/dist/components/TopList/TopList.js +186 -0
- package/dist/components/TopList/TopList.js.map +1 -0
- package/dist/components/TopList/TopList.types.d.ts +34 -0
- package/dist/components/TopList/TopList.types.js +0 -0
- package/dist/components/TopList/TopList.utils.d.ts +3 -0
- package/dist/components/TopList/TopList.utils.js +16 -0
- package/dist/components/TopList/TopList.utils.js.map +1 -0
- package/dist/components/TopList/index.d.ts +2 -0
- package/dist/components/TopList/index.js +2 -0
- package/dist/components/Typeahead/Typeahead.d.ts +5 -0
- package/dist/components/Typeahead/Typeahead.js +305 -0
- package/dist/components/Typeahead/Typeahead.js.map +1 -0
- package/dist/components/Typeahead/Typeahead.types.d.ts +99 -0
- package/dist/components/Typeahead/Typeahead.types.js +0 -0
- package/dist/components/Typeahead/Typeahead.utils.d.ts +25 -0
- package/dist/components/Typeahead/Typeahead.utils.js +73 -0
- package/dist/components/Typeahead/Typeahead.utils.js.map +1 -0
- package/dist/components/Typeahead/TypeaheadParts.d.ts +25 -0
- package/dist/components/Typeahead/TypeaheadParts.js +109 -0
- package/dist/components/Typeahead/TypeaheadParts.js.map +1 -0
- package/dist/components/Typeahead/TypeaheadView.d.ts +81 -0
- package/dist/components/Typeahead/TypeaheadView.js +228 -0
- package/dist/components/Typeahead/TypeaheadView.js.map +1 -0
- package/dist/components/Typeahead/index.d.ts +2 -0
- package/dist/components/Typeahead/index.js +2 -0
- package/dist/components/Typeahead/useTypeaheadDomSync.d.ts +15 -0
- package/dist/components/Typeahead/useTypeaheadDomSync.js +43 -0
- package/dist/components/Typeahead/useTypeaheadDomSync.js.map +1 -0
- package/dist/components/Typeahead/useTypeaheadUncontrolledInput.d.ts +11 -0
- package/dist/components/Typeahead/useTypeaheadUncontrolledInput.js +32 -0
- package/dist/components/Typeahead/useTypeaheadUncontrolledInput.js.map +1 -0
- package/dist/components/UnsavedChangesDialog.d.ts +14 -0
- package/dist/components/UnsavedChangesDialog.js +67 -0
- package/dist/components/UnsavedChangesDialog.js.map +1 -0
- package/dist/components/index.d.ts +58 -0
- package/dist/components/index.js +35 -0
- package/dist/components.css +102 -0
- package/dist/contexts/ErrorReporterContext.d.ts +6 -0
- package/dist/contexts/ErrorReporterContext.js +7 -0
- package/dist/contexts/ErrorReporterContext.js.map +1 -0
- package/dist/hooks/AppThemeProvider.d.ts +8 -0
- package/dist/hooks/AppThemeProvider.js +52 -0
- package/dist/hooks/AppThemeProvider.js.map +1 -0
- package/dist/hooks/useColorScheme.d.ts +20 -0
- package/dist/hooks/useColorScheme.js +50 -0
- package/dist/hooks/useColorScheme.js.map +1 -0
- package/dist/icons/LongTailPhosphorIcons.d.ts +51 -0
- package/dist/icons/LongTailPhosphorIcons.js +102 -0
- package/dist/icons/LongTailPhosphorIcons.js.map +1 -0
- package/dist/icons/PaddedPhosphorIcons.d.ts +17 -0
- package/dist/icons/PaddedPhosphorIcons.js +55 -0
- package/dist/icons/PaddedPhosphorIcons.js.map +1 -0
- package/dist/icons/WeightedPhosphorIcons.d.ts +45 -0
- package/dist/icons/WeightedPhosphorIcons.js +96 -0
- package/dist/icons/WeightedPhosphorIcons.js.map +1 -0
- package/dist/icons/index.d.ts +2 -0
- package/dist/icons/index.js +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +36 -0
- package/dist/styles.css +10 -0
- package/dist/utilities.css +2 -0
- package/dist/utils/VirtuosoCustomScrollParentContext/index.d.ts +7 -0
- package/dist/utils/VirtuosoCustomScrollParentContext/index.js +15 -0
- package/dist/utils/VirtuosoCustomScrollParentContext/index.js.map +1 -0
- package/dist/utils/VirtuosoCustomScrollParentContext/useScrollParent.d.ts +4 -0
- package/dist/utils/VirtuosoCustomScrollParentContext/useScrollParent.js +10 -0
- package/dist/utils/VirtuosoCustomScrollParentContext/useScrollParent.js.map +1 -0
- package/dist/utils/ZIndexContext.d.ts +5 -0
- package/dist/utils/ZIndexContext.js +13 -0
- package/dist/utils/ZIndexContext.js.map +1 -0
- package/dist/utils/animation.d.ts +37 -0
- package/dist/utils/animation.js +42 -0
- package/dist/utils/animation.js.map +1 -0
- package/dist/utils/chartAxisLayout.d.ts +6 -0
- package/dist/utils/chartAxisLayout.js +8 -0
- package/dist/utils/chartAxisLayout.js.map +1 -0
- package/dist/utils/chartColors.d.ts +38 -0
- package/dist/utils/chartColors.js +78 -0
- package/dist/utils/chartColors.js.map +1 -0
- package/dist/utils/chartConstants.d.ts +10 -0
- package/dist/utils/chartConstants.js +15 -0
- package/dist/utils/chartConstants.js.map +1 -0
- package/dist/utils/chartValues.d.ts +2 -0
- package/dist/utils/chartValues.js +36 -0
- package/dist/utils/chartValues.js.map +1 -0
- package/dist/utils/clamp.d.ts +2 -0
- package/dist/utils/clamp.js +7 -0
- package/dist/utils/clamp.js.map +1 -0
- package/dist/utils/cn.d.ts +2 -0
- package/dist/utils/cn.js +191 -0
- package/dist/utils/cn.js.map +1 -0
- package/dist/utils/componentSizes.d.ts +104 -0
- package/dist/utils/componentSizes.js +104 -0
- package/dist/utils/componentSizes.js.map +1 -0
- package/dist/utils/controlIconSizes.d.ts +10 -0
- package/dist/utils/controlIconSizes.js +32 -0
- package/dist/utils/controlIconSizes.js.map +1 -0
- package/dist/utils/csp-nonce.d.ts +11 -0
- package/dist/utils/csp-nonce.js +17 -0
- package/dist/utils/csp-nonce.js.map +1 -0
- package/dist/utils/get-closest-scroll-parent.d.ts +1 -0
- package/dist/utils/get-closest-scroll-parent.js +16 -0
- package/dist/utils/get-closest-scroll-parent.js.map +1 -0
- package/dist/utils/get-color-by-string.d.ts +1 -0
- package/dist/utils/get-color-by-string.js +10 -0
- package/dist/utils/get-color-by-string.js.map +1 -0
- package/dist/utils/getYAxisLeftMargin.d.ts +10 -0
- package/dist/utils/getYAxisLeftMargin.js +20 -0
- package/dist/utils/getYAxisLeftMargin.js.map +1 -0
- package/dist/utils/icon-types.d.ts +8 -0
- package/dist/utils/icon-types.js +0 -0
- package/dist/utils/lazy-codemirror-loader.d.ts +70 -0
- package/dist/utils/lazy-codemirror-loader.js +79 -0
- package/dist/utils/lazy-codemirror-loader.js.map +1 -0
- package/dist/utils/merge-refs.d.ts +2 -0
- package/dist/utils/merge-refs.js +13 -0
- package/dist/utils/merge-refs.js.map +1 -0
- package/dist/utils/parseTextLinks.d.ts +7 -0
- package/dist/utils/parseTextLinks.js +46 -0
- package/dist/utils/parseTextLinks.js.map +1 -0
- package/dist/utils/prettify-error-payload.d.ts +7 -0
- package/dist/utils/prettify-error-payload.js +188 -0
- package/dist/utils/prettify-error-payload.js.map +1 -0
- package/dist/utils/spacing.d.ts +30 -0
- package/dist/utils/spacing.js +34 -0
- package/dist/utils/spacing.js.map +1 -0
- package/dist/utils/useCodeMirror.d.ts +7 -0
- package/dist/utils/useCodeMirror.js +28 -0
- package/dist/utils/useCodeMirror.js.map +1 -0
- package/dist/utils/useZIndex.d.ts +52 -0
- package/dist/utils/useZIndex.js +62 -0
- package/dist/utils/useZIndex.js.map +1 -0
- package/dist/utils/zIndices.d.ts +42 -0
- package/dist/utils/zIndices.js +46 -0
- package/dist/utils/zIndices.js.map +1 -0
- package/docs/DESIGN.md +134 -0
- package/docs/STYLES.md +568 -0
- package/package.json +619 -0
- package/tailwind.preset.cjs +738 -0
- package/tailwind.preset.d.cts +5 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { cn } from "../../utils/cn.js";
|
|
2
|
+
import { Text } from "../Text/Text.js";
|
|
3
|
+
import { CHART_DIMMED_OPACITY } from "../../utils/chartConstants.js";
|
|
4
|
+
import { ChartLegend } from "../ChartLegend/ChartLegend.js";
|
|
5
|
+
import { collateDonutSegments, getDonutLegendItems, getDrawnSegments, sumSegmentValues } from "./DonutChart.utils.js";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { animated, useReducedMotion, useSpring } from "@react-spring/web";
|
|
9
|
+
import { Group } from "@visx/group";
|
|
10
|
+
import { Pie } from "@visx/shape";
|
|
11
|
+
//#region packages/components/src/components/DonutChart/DonutChart.tsx
|
|
12
|
+
var DONUT_VIEWBOX = 200;
|
|
13
|
+
var DONUT_CENTER = DONUT_VIEWBOX / 2;
|
|
14
|
+
var DONUT_OUTER_RADIUS = 92;
|
|
15
|
+
var DONUT_INNER_RADIUS = DONUT_OUTER_RADIUS * .64;
|
|
16
|
+
var numberFormatter = new Intl.NumberFormat("en-US");
|
|
17
|
+
var formatSegmentValue = (value) => numberFormatter.format(value);
|
|
18
|
+
/**
|
|
19
|
+
* Sizes the center number against the donut hole: `1cqi` is 1% of the hole's
|
|
20
|
+
* width, so a longer value resolves to a smaller size, capped at the heading
|
|
21
|
+
* size so short values do not balloon.
|
|
22
|
+
*/
|
|
23
|
+
var getFittedCenterFontSize = (value) => `min(1.75rem, ${100 / (value.length * .7)}cqi)`;
|
|
24
|
+
var AnimatedDonutArc = ({ arc, path, animationProgress, animationStartAngle, animationEndAngle, isDimmed, onPointerMove, onPointerOut, onPointerUp, onFocus, onBlur, ...ariaProps }) => {
|
|
25
|
+
const isInteractive = onPointerMove != null || onPointerOut != null || onPointerUp != null;
|
|
26
|
+
const handlePointerDown = (event) => {
|
|
27
|
+
if ((event.pointerType === "mouse" || event.pointerType === "pen") && event.currentTarget.hasAttribute("tabindex")) event.preventDefault();
|
|
28
|
+
};
|
|
29
|
+
return /* @__PURE__ */ jsx(animated.path, {
|
|
30
|
+
fill: arc.data.color,
|
|
31
|
+
opacity: isDimmed ? CHART_DIMMED_OPACITY : 1,
|
|
32
|
+
className: cn("transition-opacity duration-fast focus:outline-none focus-visible:stroke-focus focus-visible:stroke-2 motion-reduce:transition-none", isInteractive && "cursor-pointer"),
|
|
33
|
+
d: animationProgress.to((progress) => {
|
|
34
|
+
const revealAngle = animationStartAngle + (animationEndAngle - animationStartAngle) * progress;
|
|
35
|
+
const endAngle = Math.min(arc.endAngle, Math.max(arc.startAngle, revealAngle));
|
|
36
|
+
return path({
|
|
37
|
+
...arc,
|
|
38
|
+
endAngle
|
|
39
|
+
}) ?? "";
|
|
40
|
+
}),
|
|
41
|
+
role: ariaProps["aria-label"] == null ? void 0 : "graphics-symbol img",
|
|
42
|
+
tabIndex: ariaProps["aria-label"] == null ? void 0 : 0,
|
|
43
|
+
...ariaProps,
|
|
44
|
+
onPointerMove,
|
|
45
|
+
onPointerDown: handlePointerDown,
|
|
46
|
+
onPointerOut,
|
|
47
|
+
onPointerUp,
|
|
48
|
+
onFocus,
|
|
49
|
+
onBlur
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* DonutChart renders a donut and its `ChartLegend` from a flat list of
|
|
54
|
+
* segments. Consumers own the segment palette and pair the chart
|
|
55
|
+
* with `ChartCard` and their own tooltip.
|
|
56
|
+
*
|
|
57
|
+
* The legend sits below the donut in narrow containers and beside it once the
|
|
58
|
+
* container passes 496px. Pass `showLegend={false}` for the donut alone,
|
|
59
|
+
* `legendProps` to configure the legend, and `legendProps.onItemClick` with
|
|
60
|
+
* `selectedIds` to make legend entries filter the donut. A long tail of tiny
|
|
61
|
+
* slices collapses into one "Other" slice via `otherCollationThreshold`, which
|
|
62
|
+
* absorbs any segment flagged `isOther`.
|
|
63
|
+
|
|
64
|
+
*/
|
|
65
|
+
var DonutChart = ({ segments, selectedIds, centerNumber, centerDescriptor, scaleCenterNumberSize = false, activeSegmentId, activeLegendItemId, shouldAnimate = true, getSegmentAriaLabel, isRendering = true, otherCollationThreshold, showLegend = true, legendProps, formatValue = formatSegmentValue, onSegmentPointerMove, onSegmentPointerOut, onSegmentPointerUp, onSegmentFocus, onSegmentBlur, className, ...rest }) => {
|
|
66
|
+
const [activeBuiltInLegendItemId, setActiveBuiltInLegendItemId] = useState(null);
|
|
67
|
+
const isReducedMotion = (useReducedMotion() ?? false) || !shouldAnimate;
|
|
68
|
+
const ariaProps = { "aria-label": rest["aria-label"] };
|
|
69
|
+
const rootProps = { ...rest };
|
|
70
|
+
delete rootProps["aria-label"];
|
|
71
|
+
const collatedSegments = collateDonutSegments(segments, otherCollationThreshold);
|
|
72
|
+
const drawnSegments = getDrawnSegments(collatedSegments, selectedIds);
|
|
73
|
+
const renderedSegments = drawnSegments.filter((segment) => segment.value > 0);
|
|
74
|
+
const drawnTotal = sumSegmentValues(drawnSegments);
|
|
75
|
+
const drawnIds = new Set(drawnSegments.map((segment) => segment.id));
|
|
76
|
+
const drawnArcIds = new Set(renderedSegments.map((segment) => segment.id));
|
|
77
|
+
const hasDrawnSegments = isRendering && drawnTotal > 0;
|
|
78
|
+
const segmentAnimationKey = JSON.stringify(renderedSegments.map((segment) => [segment.id, segment.value]));
|
|
79
|
+
const [animation] = useSpring(() => ({
|
|
80
|
+
from: { progress: 0 },
|
|
81
|
+
to: { progress: hasDrawnSegments ? 1 : 0 },
|
|
82
|
+
reset: true,
|
|
83
|
+
immediate: isReducedMotion
|
|
84
|
+
}), [
|
|
85
|
+
segmentAnimationKey,
|
|
86
|
+
hasDrawnSegments,
|
|
87
|
+
isReducedMotion
|
|
88
|
+
]);
|
|
89
|
+
const legendItems = getDonutLegendItems({
|
|
90
|
+
segments: collatedSegments,
|
|
91
|
+
selectedIds,
|
|
92
|
+
drawnIds,
|
|
93
|
+
drawnTotal,
|
|
94
|
+
formatValue
|
|
95
|
+
});
|
|
96
|
+
const hasLegend = showLegend && collatedSegments.length > 0;
|
|
97
|
+
const legendLayout = legendProps?.layout ?? "list";
|
|
98
|
+
const requestedActiveLegendItemId = (hasLegend ? activeBuiltInLegendItemId : null) ?? activeLegendItemId;
|
|
99
|
+
const renderedActiveLegendItemId = requestedActiveLegendItemId != null && drawnArcIds.has(requestedActiveLegendItemId) ? requestedActiveLegendItemId : null;
|
|
100
|
+
const renderedActiveSegmentId = activeSegmentId != null && drawnArcIds.has(activeSegmentId) ? activeSegmentId : null;
|
|
101
|
+
const activeId = renderedActiveLegendItemId ?? renderedActiveSegmentId;
|
|
102
|
+
const donut = /* @__PURE__ */ jsx("div", {
|
|
103
|
+
className: "relative flex size-full min-h-0 min-w-0 items-center justify-center [&>svg]:max-h-[22.5rem] [&>svg]:max-w-[22.5rem]",
|
|
104
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
105
|
+
viewBox: `0 0 ${DONUT_VIEWBOX} ${DONUT_VIEWBOX}`,
|
|
106
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
107
|
+
className: "size-full",
|
|
108
|
+
role: getSegmentAriaLabel == null ? "img" : "graphics-document group",
|
|
109
|
+
...ariaProps,
|
|
110
|
+
children: isRendering && /* @__PURE__ */ jsxs(Fragment$1, { children: [drawnTotal > 0 && /* @__PURE__ */ jsx(Group, {
|
|
111
|
+
top: DONUT_CENTER,
|
|
112
|
+
left: DONUT_CENTER,
|
|
113
|
+
className: cn(activeId == null && "[&:focus-within>path:not(:focus)]:opacity-[0.45] [&>path:focus]:opacity-100"),
|
|
114
|
+
children: /* @__PURE__ */ jsx(Pie, {
|
|
115
|
+
data: renderedSegments,
|
|
116
|
+
pieValue: (segment) => segment.value,
|
|
117
|
+
pieSort: null,
|
|
118
|
+
pieSortValues: null,
|
|
119
|
+
outerRadius: DONUT_OUTER_RADIUS,
|
|
120
|
+
innerRadius: DONUT_INNER_RADIUS,
|
|
121
|
+
children: (donut) => {
|
|
122
|
+
const animationStartAngle = donut.arcs[0]?.startAngle ?? 0;
|
|
123
|
+
const animationEndAngle = donut.arcs.at(-1)?.endAngle ?? animationStartAngle;
|
|
124
|
+
return donut.arcs.map((arc) => /* @__PURE__ */ jsx(AnimatedDonutArc, {
|
|
125
|
+
arc,
|
|
126
|
+
path: donut.path,
|
|
127
|
+
animationProgress: animation.progress,
|
|
128
|
+
animationStartAngle,
|
|
129
|
+
animationEndAngle,
|
|
130
|
+
"aria-label": getSegmentAriaLabel?.(arc.data),
|
|
131
|
+
isDimmed: activeId != null && activeId !== arc.data.id,
|
|
132
|
+
onPointerMove: onSegmentPointerMove == null ? void 0 : (event) => onSegmentPointerMove(arc.data, event),
|
|
133
|
+
onPointerOut: onSegmentPointerOut,
|
|
134
|
+
onPointerUp: onSegmentPointerUp == null ? void 0 : (event) => onSegmentPointerUp(arc.data, event),
|
|
135
|
+
onFocus: onSegmentFocus == null ? void 0 : (event) => onSegmentFocus(arc.data, event),
|
|
136
|
+
onBlur: onSegmentBlur == null ? void 0 : (event) => onSegmentBlur(arc.data, event)
|
|
137
|
+
}, arc.data.id));
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
}), (centerNumber || centerDescriptor) != null && /* @__PURE__ */ jsx("foreignObject", {
|
|
141
|
+
x: 41.12,
|
|
142
|
+
y: 41.12,
|
|
143
|
+
width: DONUT_INNER_RADIUS * 2,
|
|
144
|
+
height: DONUT_INNER_RADIUS * 2,
|
|
145
|
+
className: "pointer-events-none",
|
|
146
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
147
|
+
className: "flex size-full min-w-0 flex-col items-center justify-center",
|
|
148
|
+
style: { containerType: "inline-size" },
|
|
149
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
150
|
+
as: "span",
|
|
151
|
+
variant: "h2",
|
|
152
|
+
weight: "semibold",
|
|
153
|
+
className: cn(scaleCenterNumberSize && "block w-full text-center"),
|
|
154
|
+
style: scaleCenterNumberSize && centerNumber != null ? { fontSize: getFittedCenterFontSize(centerNumber) } : void 0,
|
|
155
|
+
children: centerNumber
|
|
156
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
157
|
+
as: "span",
|
|
158
|
+
variant: "xs",
|
|
159
|
+
color: "tertiary",
|
|
160
|
+
children: centerDescriptor
|
|
161
|
+
})]
|
|
162
|
+
})
|
|
163
|
+
})] })
|
|
164
|
+
})
|
|
165
|
+
});
|
|
166
|
+
const legend = /* @__PURE__ */ jsx(ChartLegend, {
|
|
167
|
+
"aria-label": ariaProps["aria-label"] == null ? void 0 : `${ariaProps["aria-label"]} legend`,
|
|
168
|
+
...legendProps,
|
|
169
|
+
layout: legendLayout,
|
|
170
|
+
items: legendItems,
|
|
171
|
+
onItemActiveChange: (item) => {
|
|
172
|
+
setActiveBuiltInLegendItemId(item?.id ?? null);
|
|
173
|
+
legendProps?.onItemActiveChange?.(item);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
return /* @__PURE__ */ jsx("div", {
|
|
177
|
+
className: cn("size-full min-h-0 min-w-0 @container", className),
|
|
178
|
+
...rootProps,
|
|
179
|
+
children: hasLegend ? /* @__PURE__ */ jsxs("div", {
|
|
180
|
+
className: cn("grid size-full min-h-0 min-w-0 grid-cols-1 items-center justify-stretch", legendLayout === "list" ? "grid-rows-[minmax(0,1fr)_minmax(0,45%)] gap-space-3 @[496px]:grid-cols-2 @[496px]:grid-rows-[minmax(0,1fr)] @[496px]:justify-center @[496px]:gap-space-5" : "grid-rows-[minmax(0,1fr)_auto] gap-space-2"),
|
|
181
|
+
children: [donut, legendLayout === "list" ? /* @__PURE__ */ jsx("div", {
|
|
182
|
+
className: "scroll-mask-t scroll-mask-b h-full min-h-0 min-w-0 overflow-y-auto overflow-x-hidden",
|
|
183
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
184
|
+
className: "flex min-h-full flex-col",
|
|
185
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
186
|
+
className: "my-auto",
|
|
187
|
+
children: legend
|
|
188
|
+
})
|
|
189
|
+
})
|
|
190
|
+
}) : legend]
|
|
191
|
+
}) : donut
|
|
192
|
+
});
|
|
193
|
+
};
|
|
194
|
+
//#endregion
|
|
195
|
+
export { DonutChart };
|
|
196
|
+
|
|
197
|
+
//# sourceMappingURL=DonutChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DonutChart.js","names":[],"sources":["../../../src/components/DonutChart/DonutChart.tsx"],"sourcesContent":["import {\n useState,\n type AriaAttributes,\n type FocusEvent,\n type FocusEventHandler,\n type HTMLAttributes,\n type PointerEvent,\n type PointerEventHandler,\n type ReactNode,\n} from 'react';\n\nimport {\n animated,\n type SpringValue,\n useReducedMotion,\n useSpring,\n} from '@react-spring/web';\nimport { Group } from '@visx/group';\nimport { Pie as Donut } from '@visx/shape';\n\nimport { CHART_DIMMED_OPACITY } from '../../utils/chartConstants';\nimport { cn } from '../../utils/cn';\nimport { ChartLegend, type ChartLegendProps } from '../ChartLegend';\nimport { Text } from '../Text';\nimport {\n collateDonutSegments,\n getDonutLegendItems,\n getDrawnSegments,\n sumSegmentValues,\n} from './DonutChart.utils';\n\n// Viewport-invariant units. The donut renders into a fixed-size viewBox and\n// scales via `preserveAspectRatio=\"xMidYMid meet\"`.\nconst DONUT_VIEWBOX = 200;\nconst DONUT_CENTER = DONUT_VIEWBOX / 2;\nconst DONUT_OUTER_RADIUS = DONUT_CENTER - 8;\nconst DONUT_INNER_RADIUS = DONUT_OUTER_RADIUS * 0.64;\n\nconst numberFormatter = new Intl.NumberFormat('en-US');\n\nconst formatSegmentValue = (value: number) => numberFormatter.format(value);\n\n/**\n * Sizes the center number against the donut hole: `1cqi` is 1% of the hole's\n * width, so a longer value resolves to a smaller size, capped at the heading\n * size so short values do not balloon.\n */\nconst getFittedCenterFontSize = (value: string) =>\n `min(1.75rem, ${100 / (value.length * 0.7)}cqi)`;\n\nexport type DonutChartSegment = {\n id: string;\n label: ReactNode;\n value: number;\n /** Use DS CSS color token; typically a `var(--chart-...)` reference. */\n color: string;\n /**\n * Marks a segment that already stands for a group of others — a remainder the\n * data source rolled up, say. `otherCollationThreshold` merges it with the\n * tail it collates instead of drawing a second \"Other\" beside it.\n */\n isOther?: boolean;\n};\n\ntype DonutArcDatumLike<Datum> = {\n data: Datum;\n value: number;\n index: number;\n startAngle: number;\n endAngle: number;\n padAngle: number;\n};\n\n/**\n * Everything `ChartLegend` accepts except `items`, which the donut derives from\n * `segments`. Namespacing these under `legendProps` keeps `className` and the\n * other DOM attributes on the chart root unambiguous.\n */\ntype DonutChartLegendProps = Omit<ChartLegendProps, 'items'>;\n\n/**\n * `legendProps` only exists while there is a legend to configure: with\n * `showLegend={false}` it narrows to `never`, so autocomplete stops offering it\n * and passing it is a type error rather than a silently ignored prop.\n */\ntype DonutChartLegendConfig =\n | {\n /** Defaults to true. */\n showLegend?: true;\n /** Forwarded to the rendered `ChartLegend`. */\n legendProps?: DonutChartLegendProps;\n }\n | {\n showLegend: false;\n legendProps?: never;\n };\n\nexport type DonutChartProps = Omit<\n HTMLAttributes<HTMLDivElement>,\n 'children' | 'onPointerOut'\n> &\n DonutChartLegendConfig & {\n segments: readonly DonutChartSegment[];\n /**\n * When provided and non-empty, only segments whose IDs are in the set are\n * rendered in the donut. Unselected segments stay in the legend with a 0%\n * share. IDs address the collated list, so the segments behind an \"Other\"\n * slice are selected as `DONUT_OTHER_SEGMENT_ID` rather than individually. A\n * set naming none of those IDs draws everything, so a selection outliving\n * the data it was made against cannot empty the chart.\n */\n selectedIds?: ReadonlySet<string>;\n /**\n * Number to render in the donut hole.\n */\n centerNumber?: string;\n /**\n * Descriptor for the number in the donut hole.\n */\n centerDescriptor?: string;\n /**\n * Scales `centerNumber` to the width of the donut hole.\n */\n scaleCenterNumberSize?: boolean;\n /** Emphasizes one segment and dims the rest. */\n activeSegmentId?: string | null;\n /** Emphasizes the segment represented by one external legend item. Built-in legends set this automatically. */\n activeLegendItemId?: string | null;\n /** Animates segments when they are drawn. Defaults to true. */\n shouldAnimate?: boolean;\n /** Names segments and makes them focusable. */\n getSegmentAriaLabel?: (\n segment: DonutChartSegment\n ) => AriaAttributes['aria-label'];\n /**\n * Set to false to skip drawing the donut. Use it to avoid the work while a\n * parent container is actively resizing. Defaults to true.\n */\n isRendering?: boolean;\n /**\n * Collates segments less than this set number to an \"Other\" slice, automatically merging any segment flagged `isOther`. Do not pass a value to render all segments, even if they are tiny.\n */\n otherCollationThreshold?: number;\n /**\n * Formats each segment's value for the legend. Defaults to a plain\n * `en-US` number; pass a unit-aware formatter for durations, bytes, cost.\n */\n formatValue?: (value: number) => ReactNode;\n onSegmentPointerMove?: (\n segment: DonutChartSegment,\n event: PointerEvent<SVGPathElement>\n ) => void;\n onSegmentPointerOut?: () => void;\n onSegmentPointerUp?: (\n segment: DonutChartSegment,\n event: PointerEvent<SVGPathElement>\n ) => void;\n onSegmentFocus?: (\n segment: DonutChartSegment,\n event: FocusEvent<SVGPathElement>\n ) => void;\n onSegmentBlur?: (\n segment: DonutChartSegment,\n event: FocusEvent<SVGPathElement>\n ) => void;\n };\n\ntype AnimatedDonutArcProps = {\n arc: DonutArcDatumLike<DonutChartSegment>;\n path: (arc: DonutArcDatumLike<DonutChartSegment>) => string | null;\n animationProgress: SpringValue<number>;\n animationStartAngle: number;\n animationEndAngle: number;\n 'aria-label'?: AriaAttributes['aria-label'];\n isDimmed: boolean;\n onPointerMove?: PointerEventHandler<SVGPathElement>;\n onPointerOut?: () => void;\n onPointerUp?: PointerEventHandler<SVGPathElement>;\n onFocus?: FocusEventHandler<SVGPathElement>;\n onBlur?: FocusEventHandler<SVGPathElement>;\n};\n\nconst AnimatedDonutArc = ({\n arc,\n path,\n animationProgress,\n animationStartAngle,\n animationEndAngle,\n isDimmed,\n onPointerMove,\n onPointerOut,\n onPointerUp,\n onFocus,\n onBlur,\n ...ariaProps\n}: AnimatedDonutArcProps) => {\n const isInteractive =\n onPointerMove != null || onPointerOut != null || onPointerUp != null;\n const handlePointerDown = (event: PointerEvent<SVGPathElement>) => {\n // Chromium can match :focus-visible when a focusable SVG path is clicked.\n // Keep the focus indicator for keyboard navigation without showing it for\n // pointer interaction.\n if (\n (event.pointerType === 'mouse' || event.pointerType === 'pen') &&\n event.currentTarget.hasAttribute('tabindex')\n ) {\n event.preventDefault();\n }\n };\n\n return (\n <animated.path\n fill={arc.data.color}\n opacity={isDimmed ? CHART_DIMMED_OPACITY : 1}\n className={cn(\n 'transition-opacity duration-fast focus:outline-none focus-visible:stroke-focus focus-visible:stroke-2 motion-reduce:transition-none',\n isInteractive && 'cursor-pointer'\n )}\n d={animationProgress.to((progress) => {\n const revealAngle =\n animationStartAngle +\n (animationEndAngle - animationStartAngle) * progress;\n const endAngle = Math.min(\n arc.endAngle,\n Math.max(arc.startAngle, revealAngle)\n );\n return path({ ...arc, endAngle }) ?? '';\n })}\n role={ariaProps['aria-label'] == null ? undefined : 'graphics-symbol img'}\n tabIndex={ariaProps['aria-label'] == null ? undefined : 0}\n {...ariaProps}\n onPointerMove={onPointerMove}\n onPointerDown={handlePointerDown}\n onPointerOut={onPointerOut}\n onPointerUp={onPointerUp}\n onFocus={onFocus}\n onBlur={onBlur}\n />\n );\n};\n\n/**\n * DonutChart renders a donut and its `ChartLegend` from a flat list of\n * segments. Consumers own the segment palette and pair the chart\n * with `ChartCard` and their own tooltip.\n *\n * The legend sits below the donut in narrow containers and beside it once the\n * container passes 496px. Pass `showLegend={false}` for the donut alone,\n * `legendProps` to configure the legend, and `legendProps.onItemClick` with\n * `selectedIds` to make legend entries filter the donut. A long tail of tiny\n * slices collapses into one \"Other\" slice via `otherCollationThreshold`, which\n * absorbs any segment flagged `isOther`.\n\n */\nexport const DonutChart = ({\n segments,\n selectedIds,\n centerNumber,\n centerDescriptor,\n scaleCenterNumberSize = false,\n activeSegmentId,\n activeLegendItemId,\n shouldAnimate = true,\n getSegmentAriaLabel,\n isRendering = true,\n otherCollationThreshold,\n showLegend = true,\n legendProps,\n formatValue = formatSegmentValue,\n onSegmentPointerMove,\n onSegmentPointerOut,\n onSegmentPointerUp,\n onSegmentFocus,\n onSegmentBlur,\n className,\n ...rest\n}: DonutChartProps) => {\n const [activeBuiltInLegendItemId, setActiveBuiltInLegendItemId] = useState<\n string | null\n >(null);\n const isReducedMotion = (useReducedMotion() ?? false) || !shouldAnimate;\n const ariaProps = { 'aria-label': rest['aria-label'] };\n const rootProps: HTMLAttributes<HTMLDivElement> = { ...rest };\n delete rootProps['aria-label'];\n\n // Collation happens before the selection, so the legend lists the same rows\n // the donut draws arcs for and neither reflows while filtering.\n const collatedSegments = collateDonutSegments(\n segments,\n otherCollationThreshold\n );\n const drawnSegments = getDrawnSegments(collatedSegments, selectedIds);\n const renderedSegments = drawnSegments.filter((segment) => segment.value > 0);\n const drawnTotal = sumSegmentValues(drawnSegments);\n const drawnIds = new Set(drawnSegments.map((segment) => segment.id));\n const drawnArcIds = new Set(renderedSegments.map((segment) => segment.id));\n const hasDrawnSegments = isRendering && drawnTotal > 0;\n const segmentAnimationKey = JSON.stringify(\n renderedSegments.map((segment) => [segment.id, segment.value])\n );\n // A single sweep angle reveals the arcs in sequence, leaving only one moving\n // boundary regardless of how many colored segments the donut contains.\n const [animation] = useSpring(\n () => ({\n from: { progress: 0 },\n to: { progress: hasDrawnSegments ? 1 : 0 },\n reset: true,\n immediate: isReducedMotion,\n }),\n [segmentAnimationKey, hasDrawnSegments, isReducedMotion]\n );\n\n const legendItems = getDonutLegendItems({\n segments: collatedSegments,\n selectedIds,\n drawnIds,\n drawnTotal,\n formatValue,\n });\n const hasLegend = showLegend && collatedSegments.length > 0;\n const legendLayout = legendProps?.layout ?? 'list';\n const requestedActiveLegendItemId =\n (hasLegend ? activeBuiltInLegendItemId : null) ?? activeLegendItemId;\n const renderedActiveLegendItemId =\n requestedActiveLegendItemId != null &&\n drawnArcIds.has(requestedActiveLegendItemId)\n ? requestedActiveLegendItemId\n : null;\n const renderedActiveSegmentId =\n activeSegmentId != null && drawnArcIds.has(activeSegmentId)\n ? activeSegmentId\n : null;\n const activeId = renderedActiveLegendItemId ?? renderedActiveSegmentId;\n\n const donut = (\n <div className=\"relative flex size-full min-h-0 min-w-0 items-center justify-center [&>svg]:max-h-[22.5rem] [&>svg]:max-w-[22.5rem]\">\n <svg\n viewBox={`0 0 ${DONUT_VIEWBOX} ${DONUT_VIEWBOX}`}\n preserveAspectRatio=\"xMidYMid meet\"\n className=\"size-full\"\n role={getSegmentAriaLabel == null ? 'img' : 'graphics-document group'}\n {...ariaProps}\n >\n {isRendering && (\n <>\n {drawnTotal > 0 && (\n <Group\n top={DONUT_CENTER}\n left={DONUT_CENTER}\n className={cn(\n activeId == null &&\n '[&:focus-within>path:not(:focus)]:opacity-[0.45] [&>path:focus]:opacity-100'\n )}\n >\n <Donut\n data={renderedSegments}\n pieValue={(segment) => segment.value}\n pieSort={null}\n pieSortValues={null}\n outerRadius={DONUT_OUTER_RADIUS}\n innerRadius={DONUT_INNER_RADIUS}\n >\n {(donut) => {\n const animationStartAngle = donut.arcs[0]?.startAngle ?? 0;\n const animationEndAngle =\n donut.arcs.at(-1)?.endAngle ?? animationStartAngle;\n return donut.arcs.map((arc) => (\n <AnimatedDonutArc\n key={arc.data.id}\n arc={arc}\n path={donut.path}\n animationProgress={animation.progress}\n animationStartAngle={animationStartAngle}\n animationEndAngle={animationEndAngle}\n aria-label={getSegmentAriaLabel?.(arc.data)}\n isDimmed={activeId != null && activeId !== arc.data.id}\n onPointerMove={\n onSegmentPointerMove == null\n ? undefined\n : (event) => onSegmentPointerMove(arc.data, event)\n }\n onPointerOut={onSegmentPointerOut}\n onPointerUp={\n onSegmentPointerUp == null\n ? undefined\n : (event) => onSegmentPointerUp(arc.data, event)\n }\n onFocus={\n onSegmentFocus == null\n ? undefined\n : (event) => onSegmentFocus(arc.data, event)\n }\n onBlur={\n onSegmentBlur == null\n ? undefined\n : (event) => onSegmentBlur(arc.data, event)\n }\n />\n ));\n }}\n </Donut>\n </Group>\n )}\n {(centerNumber || centerDescriptor) != null && (\n <foreignObject\n x={DONUT_CENTER - DONUT_INNER_RADIUS}\n y={DONUT_CENTER - DONUT_INNER_RADIUS}\n width={DONUT_INNER_RADIUS * 2}\n height={DONUT_INNER_RADIUS * 2}\n className=\"pointer-events-none\"\n >\n <div\n className=\"flex size-full min-w-0 flex-col items-center justify-center\"\n style={{ containerType: 'inline-size' }}\n >\n <Text\n as=\"span\"\n variant=\"h2\"\n weight=\"semibold\"\n className={cn(\n scaleCenterNumberSize && 'block w-full text-center'\n )}\n style={\n scaleCenterNumberSize && centerNumber != null\n ? { fontSize: getFittedCenterFontSize(centerNumber) }\n : undefined\n }\n >\n {centerNumber}\n </Text>\n <Text as=\"span\" variant=\"xs\" color=\"tertiary\">\n {centerDescriptor}\n </Text>\n </div>\n </foreignObject>\n )}\n </>\n )}\n </svg>\n </div>\n );\n\n const legend = (\n <ChartLegend\n aria-label={\n ariaProps['aria-label'] == null\n ? undefined\n : `${ariaProps['aria-label']} legend`\n }\n {...legendProps}\n layout={legendLayout}\n items={legendItems}\n onItemActiveChange={(item) => {\n setActiveBuiltInLegendItemId(item?.id ?? null);\n legendProps?.onItemActiveChange?.(item);\n }}\n />\n );\n\n return (\n <div\n className={cn('size-full min-h-0 min-w-0 @container', className)}\n {...rootProps}\n >\n {hasLegend ? (\n <div\n className={cn(\n 'grid size-full min-h-0 min-w-0 grid-cols-1 items-center justify-stretch',\n legendLayout === 'list'\n ? 'grid-rows-[minmax(0,1fr)_minmax(0,45%)] gap-space-3 @[496px]:grid-cols-2 @[496px]:grid-rows-[minmax(0,1fr)] @[496px]:justify-center @[496px]:gap-space-5'\n : 'grid-rows-[minmax(0,1fr)_auto] gap-space-2'\n )}\n >\n {donut}\n {legendLayout === 'list' ? (\n <div className=\"scroll-mask-t scroll-mask-b h-full min-h-0 min-w-0 overflow-y-auto overflow-x-hidden\">\n <div className=\"flex min-h-full flex-col\">\n <div className=\"my-auto\">{legend}</div>\n </div>\n </div>\n ) : (\n legend\n )}\n </div>\n ) : (\n donut\n )}\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ChartLegendItem } from '../ChartLegend/index.js';
|
|
3
|
+
import type { DonutChartSegment } from './DonutChart.js';
|
|
4
|
+
export declare const sumSegmentValues: (segments: readonly DonutChartSegment[]) => number;
|
|
5
|
+
/**
|
|
6
|
+
* Folds a segment's long tail into one "Other" segment appended after the ones
|
|
7
|
+
* that clear `threshold`. Segments already flagged `isOther` — a rollup the
|
|
8
|
+
* data source computed, say — merge into that same segment rather than sitting
|
|
9
|
+
* beside a second one wearing the same label and color. Invalid values are
|
|
10
|
+
* normalized to zero. Without a threshold, valid segments pass through untouched.
|
|
11
|
+
*
|
|
12
|
+
* `DonutChart` applies this itself; call it directly when you also need the
|
|
13
|
+
* collated list — to total the values behind the center number, for instance.
|
|
14
|
+
*/
|
|
15
|
+
export declare const collateDonutSegments: (segments: readonly DonutChartSegment[], threshold: number | undefined) => readonly DonutChartSegment[];
|
|
16
|
+
/**
|
|
17
|
+
* Filters collated segments to a legend selection. An empty or absent selection
|
|
18
|
+
* draws everything, and so does a selection that names no segment the donut
|
|
19
|
+
* has: ids outlive the data they came from — a group can be collated away or
|
|
20
|
+
* disappear from a refetch — and drawing nothing would strand the chart empty
|
|
21
|
+
* with no row left to toggle the stale id off.
|
|
22
|
+
*/
|
|
23
|
+
export declare const getDrawnSegments: (segments: readonly DonutChartSegment[], selectedIds: ReadonlySet<string> | undefined) => DonutChartSegment[];
|
|
24
|
+
/**
|
|
25
|
+
* Every segment stays in the legend, including filtered-out ones — those report
|
|
26
|
+
* a 0% share so the list does not reflow while filtering. Rows correspond to
|
|
27
|
+
* arcs one for one, so shares are measured against the drawn total.
|
|
28
|
+
*
|
|
29
|
+
* A row reports a share when its arc is drawn rather than when it is selected,
|
|
30
|
+
* so the two cannot disagree about what the donut is showing.
|
|
31
|
+
*/
|
|
32
|
+
export declare const getDonutLegendItems: ({ segments, selectedIds, drawnIds, drawnTotal, formatValue, }: {
|
|
33
|
+
segments: readonly DonutChartSegment[];
|
|
34
|
+
selectedIds: ReadonlySet<string> | undefined;
|
|
35
|
+
drawnIds: ReadonlySet<string>;
|
|
36
|
+
drawnTotal: number;
|
|
37
|
+
formatValue: (value: number) => ReactNode;
|
|
38
|
+
}) => readonly ChartLegendItem[];
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { CHART_OTHER_COLOR } from "../../utils/chartColors.js";
|
|
2
|
+
import { DONUT_OTHER_SEGMENT_ID, DONUT_OTHER_SEGMENT_LABEL } from "./constants.js";
|
|
3
|
+
//#region packages/components/src/components/DonutChart/DonutChart.utils.ts
|
|
4
|
+
var percentFormatter = new Intl.NumberFormat("en-US", { maximumFractionDigits: 1 });
|
|
5
|
+
var sumSegmentValues = (segments) => segments.reduce((sum, segment) => sum + segment.value, 0);
|
|
6
|
+
/**
|
|
7
|
+
* Splits segments into the ones the donut draws on their own and the ones that
|
|
8
|
+
* fold into a single "Other": every segment flagged `isOther` or using the
|
|
9
|
+
* reserved Other ID, plus segments below `threshold` percent of the total.
|
|
10
|
+
*
|
|
11
|
+
* `collapses` is false when there is nothing to fold, and also when the only
|
|
12
|
+
* member is an existing Other segment, so replacing it would change its
|
|
13
|
+
* metadata without changing what is drawn.
|
|
14
|
+
*/
|
|
15
|
+
var partitionSegments = (segments, threshold) => {
|
|
16
|
+
const total = sumSegmentValues(segments);
|
|
17
|
+
if (threshold == null || total === 0) return {
|
|
18
|
+
kept: segments,
|
|
19
|
+
members: [],
|
|
20
|
+
collapses: false
|
|
21
|
+
};
|
|
22
|
+
const kept = [];
|
|
23
|
+
const members = [];
|
|
24
|
+
segments.forEach((segment) => {
|
|
25
|
+
if (segment.isOther || segment.id === "donut-other" || segment.value / total * 100 < threshold) members.push(segment);
|
|
26
|
+
else kept.push(segment);
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
kept,
|
|
30
|
+
members,
|
|
31
|
+
collapses: members.length > 1 || members.length === 1 && !members[0].isOther && members[0].id !== "donut-other"
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Folds a segment's long tail into one "Other" segment appended after the ones
|
|
36
|
+
* that clear `threshold`. Segments already flagged `isOther` — a rollup the
|
|
37
|
+
* data source computed, say — merge into that same segment rather than sitting
|
|
38
|
+
* beside a second one wearing the same label and color. Invalid values are
|
|
39
|
+
* normalized to zero. Without a threshold, valid segments pass through untouched.
|
|
40
|
+
*
|
|
41
|
+
* `DonutChart` applies this itself; call it directly when you also need the
|
|
42
|
+
* collated list — to total the values behind the center number, for instance.
|
|
43
|
+
*/
|
|
44
|
+
var collateDonutSegments = (segments, threshold) => {
|
|
45
|
+
const normalizedSegments = segments.some((segment) => !Number.isFinite(segment.value) || segment.value < 0) ? segments.map((segment) => ({
|
|
46
|
+
...segment,
|
|
47
|
+
value: Number.isFinite(segment.value) ? Math.max(0, segment.value) : 0
|
|
48
|
+
})) : segments;
|
|
49
|
+
const { kept, members, collapses } = partitionSegments(normalizedSegments, threshold);
|
|
50
|
+
if (!collapses) return normalizedSegments;
|
|
51
|
+
return [...kept, {
|
|
52
|
+
id: DONUT_OTHER_SEGMENT_ID,
|
|
53
|
+
label: DONUT_OTHER_SEGMENT_LABEL,
|
|
54
|
+
value: sumSegmentValues(members),
|
|
55
|
+
color: CHART_OTHER_COLOR,
|
|
56
|
+
isOther: true
|
|
57
|
+
}];
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Filters collated segments to a legend selection. An empty or absent selection
|
|
61
|
+
* draws everything, and so does a selection that names no segment the donut
|
|
62
|
+
* has: ids outlive the data they came from — a group can be collated away or
|
|
63
|
+
* disappear from a refetch — and drawing nothing would strand the chart empty
|
|
64
|
+
* with no row left to toggle the stale id off.
|
|
65
|
+
*/
|
|
66
|
+
var getDrawnSegments = (segments, selectedIds) => {
|
|
67
|
+
if (selectedIds == null || selectedIds.size === 0) return [...segments];
|
|
68
|
+
const selected = segments.filter((segment) => selectedIds.has(segment.id));
|
|
69
|
+
return selected.length > 0 ? selected : [...segments];
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Every segment stays in the legend, including filtered-out ones — those report
|
|
73
|
+
* a 0% share so the list does not reflow while filtering. Rows correspond to
|
|
74
|
+
* arcs one for one, so shares are measured against the drawn total.
|
|
75
|
+
*
|
|
76
|
+
* A row reports a share when its arc is drawn rather than when it is selected,
|
|
77
|
+
* so the two cannot disagree about what the donut is showing.
|
|
78
|
+
*/
|
|
79
|
+
var getDonutLegendItems = ({ segments, selectedIds, drawnIds, drawnTotal, formatValue }) => segments.map((segment) => {
|
|
80
|
+
const isDrawn = drawnIds.has(segment.id);
|
|
81
|
+
return {
|
|
82
|
+
id: segment.id,
|
|
83
|
+
label: segment.label,
|
|
84
|
+
markerColor: segment.color,
|
|
85
|
+
value: formatValue(segment.value),
|
|
86
|
+
secondaryValue: `${percentFormatter.format(isDrawn && drawnTotal > 0 ? segment.value / drawnTotal * 100 : 0)}%`,
|
|
87
|
+
selected: selectedIds?.has(segment.id) ?? false
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
//#endregion
|
|
91
|
+
export { collateDonutSegments, getDonutLegendItems, getDrawnSegments, sumSegmentValues };
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=DonutChart.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DonutChart.utils.js","names":[],"sources":["../../../src/components/DonutChart/DonutChart.utils.ts"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { CHART_OTHER_COLOR } from '../../utils/chartColors';\nimport type { ChartLegendItem } from '../ChartLegend';\nimport { DONUT_OTHER_SEGMENT_ID, DONUT_OTHER_SEGMENT_LABEL } from './constants';\nimport type { DonutChartSegment } from './DonutChart';\n\nconst percentFormatter = new Intl.NumberFormat('en-US', {\n maximumFractionDigits: 1,\n});\n\nexport const sumSegmentValues = (segments: readonly DonutChartSegment[]) =>\n segments.reduce((sum, segment) => sum + segment.value, 0);\n\n/**\n * Splits segments into the ones the donut draws on their own and the ones that\n * fold into a single \"Other\": every segment flagged `isOther` or using the\n * reserved Other ID, plus segments below `threshold` percent of the total.\n *\n * `collapses` is false when there is nothing to fold, and also when the only\n * member is an existing Other segment, so replacing it would change its\n * metadata without changing what is drawn.\n */\nconst partitionSegments = (\n segments: readonly DonutChartSegment[],\n threshold: number | undefined\n): {\n kept: readonly DonutChartSegment[];\n members: readonly DonutChartSegment[];\n collapses: boolean;\n} => {\n const total = sumSegmentValues(segments);\n if (threshold == null || total === 0) {\n return { kept: segments, members: [], collapses: false };\n }\n\n const kept: DonutChartSegment[] = [];\n const members: DonutChartSegment[] = [];\n segments.forEach((segment) => {\n if (\n segment.isOther ||\n segment.id === DONUT_OTHER_SEGMENT_ID ||\n (segment.value / total) * 100 < threshold\n ) {\n members.push(segment);\n } else {\n kept.push(segment);\n }\n });\n\n return {\n kept,\n members,\n collapses:\n members.length > 1 ||\n (members.length === 1 &&\n !members[0].isOther &&\n members[0].id !== DONUT_OTHER_SEGMENT_ID),\n };\n};\n\n/**\n * Folds a segment's long tail into one \"Other\" segment appended after the ones\n * that clear `threshold`. Segments already flagged `isOther` — a rollup the\n * data source computed, say — merge into that same segment rather than sitting\n * beside a second one wearing the same label and color. Invalid values are\n * normalized to zero. Without a threshold, valid segments pass through untouched.\n *\n * `DonutChart` applies this itself; call it directly when you also need the\n * collated list — to total the values behind the center number, for instance.\n */\nexport const collateDonutSegments = (\n segments: readonly DonutChartSegment[],\n threshold: number | undefined\n): readonly DonutChartSegment[] => {\n const normalizedSegments = segments.some(\n (segment) => !Number.isFinite(segment.value) || segment.value < 0\n )\n ? segments.map((segment) => ({\n ...segment,\n value: Number.isFinite(segment.value) ? Math.max(0, segment.value) : 0,\n }))\n : segments;\n const { kept, members, collapses } = partitionSegments(\n normalizedSegments,\n threshold\n );\n if (!collapses) return normalizedSegments;\n\n return [\n ...kept,\n {\n id: DONUT_OTHER_SEGMENT_ID,\n label: DONUT_OTHER_SEGMENT_LABEL,\n value: sumSegmentValues(members),\n color: CHART_OTHER_COLOR,\n isOther: true,\n },\n ];\n};\n\n/**\n * Filters collated segments to a legend selection. An empty or absent selection\n * draws everything, and so does a selection that names no segment the donut\n * has: ids outlive the data they came from — a group can be collated away or\n * disappear from a refetch — and drawing nothing would strand the chart empty\n * with no row left to toggle the stale id off.\n */\nexport const getDrawnSegments = (\n segments: readonly DonutChartSegment[],\n selectedIds: ReadonlySet<string> | undefined\n): DonutChartSegment[] => {\n if (selectedIds == null || selectedIds.size === 0) return [...segments];\n\n const selected = segments.filter((segment) => selectedIds.has(segment.id));\n return selected.length > 0 ? selected : [...segments];\n};\n\n/**\n * Every segment stays in the legend, including filtered-out ones — those report\n * a 0% share so the list does not reflow while filtering. Rows correspond to\n * arcs one for one, so shares are measured against the drawn total.\n *\n * A row reports a share when its arc is drawn rather than when it is selected,\n * so the two cannot disagree about what the donut is showing.\n */\nexport const getDonutLegendItems = ({\n segments,\n selectedIds,\n drawnIds,\n drawnTotal,\n formatValue,\n}: {\n segments: readonly DonutChartSegment[];\n selectedIds: ReadonlySet<string> | undefined;\n drawnIds: ReadonlySet<string>;\n drawnTotal: number;\n formatValue: (value: number) => ReactNode;\n}): readonly ChartLegendItem[] =>\n segments.map((segment) => {\n const isDrawn = drawnIds.has(segment.id);\n\n return {\n id: segment.id,\n label: segment.label,\n markerColor: segment.color,\n value: formatValue(segment.value),\n secondaryValue: `${percentFormatter.format(\n isDrawn && drawnTotal > 0 ? (segment.value / drawnTotal) * 100 : 0\n )}%`,\n selected: selectedIds?.has(segment.id) ?? false,\n };\n });\n"],"mappings":";;;AAOA,IAAM,mBAAmB,IAAI,KAAK,aAAa,SAAS,EACtD,uBAAuB,EACzB,CAAC;AAED,IAAa,oBAAoB,aAC/B,SAAS,QAAQ,KAAK,YAAY,MAAM,QAAQ,OAAO,CAAC;;;;;;;;;;AAW1D,IAAM,qBACJ,UACA,cAKG;CACH,MAAM,QAAQ,iBAAiB,QAAQ;CACvC,IAAI,aAAa,QAAQ,UAAU,GACjC,OAAO;EAAE,MAAM;EAAU,SAAS,CAAC;EAAG,WAAW;CAAM;CAGzD,MAAM,OAA4B,CAAC;CACnC,MAAM,UAA+B,CAAC;CACtC,SAAS,SAAS,YAAY;EAC5B,IACE,QAAQ,WACR,QAAQ,OAAA,iBACP,QAAQ,QAAQ,QAAS,MAAM,WAEhC,QAAQ,KAAK,OAAO;OAEpB,KAAK,KAAK,OAAO;CAErB,CAAC;CAED,OAAO;EACL;EACA;EACA,WACE,QAAQ,SAAS,KAChB,QAAQ,WAAW,KAClB,CAAC,QAAQ,EAAE,CAAC,WACZ,QAAQ,EAAE,CAAC,OAAA;CACjB;AACF;;;;;;;;;;;AAYA,IAAa,wBACX,UACA,cACiC;CACjC,MAAM,qBAAqB,SAAS,MACjC,YAAY,CAAC,OAAO,SAAS,QAAQ,KAAK,KAAK,QAAQ,QAAQ,CAClE,IACI,SAAS,KAAK,aAAa;EACzB,GAAG;EACH,OAAO,OAAO,SAAS,QAAQ,KAAK,IAAI,KAAK,IAAI,GAAG,QAAQ,KAAK,IAAI;CACvE,EAAE,IACF;CACJ,MAAM,EAAE,MAAM,SAAS,cAAc,kBACnC,oBACA,SACF;CACA,IAAI,CAAC,WAAW,OAAO;CAEvB,OAAO,CACL,GAAG,MACH;EACE,IAAI;EACJ,OAAO;EACP,OAAO,iBAAiB,OAAO;EAC/B,OAAO;EACP,SAAS;CACX,CACF;AACF;;;;;;;;AASA,IAAa,oBACX,UACA,gBACwB;CACxB,IAAI,eAAe,QAAQ,YAAY,SAAS,GAAG,OAAO,CAAC,GAAG,QAAQ;CAEtE,MAAM,WAAW,SAAS,QAAQ,YAAY,YAAY,IAAI,QAAQ,EAAE,CAAC;CACzE,OAAO,SAAS,SAAS,IAAI,WAAW,CAAC,GAAG,QAAQ;AACtD;;;;;;;;;AAUA,IAAa,uBAAuB,EAClC,UACA,aACA,UACA,YACA,kBAQA,SAAS,KAAK,YAAY;CACxB,MAAM,UAAU,SAAS,IAAI,QAAQ,EAAE;CAEvC,OAAO;EACL,IAAI,QAAQ;EACZ,OAAO,QAAQ;EACf,aAAa,QAAQ;EACrB,OAAO,YAAY,QAAQ,KAAK;EAChC,gBAAgB,GAAG,iBAAiB,OAClC,WAAW,aAAa,IAAK,QAAQ,QAAQ,aAAc,MAAM,CACnE,EAAE;EACF,UAAU,aAAa,IAAI,QAAQ,EAAE,KAAK;CAC5C;AACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ID of the synthetic segment that `otherCollationThreshold` collapses small
|
|
3
|
+
* segments into. Consumers can match on it to special-case the slice in a
|
|
4
|
+
* tooltip or to seed `selectedIds`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const DONUT_OTHER_SEGMENT_ID = "donut-other";
|
|
7
|
+
export declare const DONUT_OTHER_SEGMENT_LABEL = "Other";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region packages/components/src/components/DonutChart/constants.ts
|
|
2
|
+
/**
|
|
3
|
+
* ID of the synthetic segment that `otherCollationThreshold` collapses small
|
|
4
|
+
* segments into. Consumers can match on it to special-case the slice in a
|
|
5
|
+
* tooltip or to seed `selectedIds`.
|
|
6
|
+
*/
|
|
7
|
+
var DONUT_OTHER_SEGMENT_ID = "donut-other";
|
|
8
|
+
var DONUT_OTHER_SEGMENT_LABEL = "Other";
|
|
9
|
+
//#endregion
|
|
10
|
+
export { DONUT_OTHER_SEGMENT_ID, DONUT_OTHER_SEGMENT_LABEL };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","names":[],"sources":["../../../src/components/DonutChart/constants.ts"],"sourcesContent":["/**\n * ID of the synthetic segment that `otherCollationThreshold` collapses small\n * segments into. Consumers can match on it to special-case the slice in a\n * tooltip or to seed `selectedIds`.\n */\nexport const DONUT_OTHER_SEGMENT_ID = 'donut-other';\n\nexport const DONUT_OTHER_SEGMENT_LABEL = 'Other';\n"],"mappings":";;;;;;AAKA,IAAa,yBAAyB;AAEtC,IAAa,4BAA4B"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { DONUT_OTHER_SEGMENT_ID, DONUT_OTHER_SEGMENT_LABEL } from "./constants.js";
|
|
2
|
+
import { collateDonutSegments } from "./DonutChart.utils.js";
|
|
3
|
+
import { DonutChart } from "./DonutChart.js";
|
|
4
|
+
export { DONUT_OTHER_SEGMENT_ID, DONUT_OTHER_SEGMENT_LABEL, DonutChart, collateDonutSegments };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
3
|
+
export declare const DropdownMenu: typeof DropdownMenuPrimitive.Root;
|
|
4
|
+
export declare const DropdownMenuTrigger: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuTriggerProps & React.RefAttributes<HTMLButtonElement>>;
|
|
5
|
+
export declare const DropdownMenuPortal: React.FC<DropdownMenuPrimitive.DropdownMenuPortalProps>;
|
|
6
|
+
export declare const DropdownMenuGroup: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
7
|
+
export declare const DropdownMenuLabel: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuLabelProps & React.RefAttributes<HTMLDivElement>>;
|
|
8
|
+
export declare const DropdownMenuContent: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
9
|
+
/**
|
|
10
|
+
* When true, stops clicks outside the open menu from reaching elements
|
|
11
|
+
* underneath (e.g. table rows), while leaving scrolling of that content
|
|
12
|
+
* intact. Radix's outside-click dismiss still works normally.
|
|
13
|
+
*/
|
|
14
|
+
preventClickThrough?: boolean;
|
|
15
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
16
|
+
export declare const DropdownMenuItem: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuItemProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
17
|
+
inset?: boolean;
|
|
18
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
19
|
+
export declare const DropdownMenuSeparator: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSeparatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
20
|
+
export declare const DropdownMenuSub: React.FC<DropdownMenuPrimitive.DropdownMenuSubProps>;
|
|
21
|
+
export declare const DropdownMenuSubTrigger: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubTriggerProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
|
|
22
|
+
inset?: boolean;
|
|
23
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
24
|
+
export declare const DropdownMenuSubContent: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSubContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { cn } from "../../utils/cn.js";
|
|
2
|
+
import zIndices from "../../utils/zIndices.js";
|
|
3
|
+
import { useZIndex } from "../../utils/useZIndex.js";
|
|
4
|
+
import { ZIndexProvider } from "../../utils/ZIndexContext.js";
|
|
5
|
+
import * as React$1 from "react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
8
|
+
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
9
|
+
//#region packages/components/src/components/DropdownMenu/DropdownMenu.tsx
|
|
10
|
+
var DropdownMenu = (props) => {
|
|
11
|
+
const [open = false, onOpenChange] = useControllableState({
|
|
12
|
+
prop: props.open,
|
|
13
|
+
defaultProp: props.defaultOpen ?? false,
|
|
14
|
+
onChange: props.onOpenChange
|
|
15
|
+
});
|
|
16
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Root, {
|
|
17
|
+
...props,
|
|
18
|
+
open,
|
|
19
|
+
onOpenChange,
|
|
20
|
+
defaultOpen: void 0
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
24
|
+
var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
25
|
+
var DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
26
|
+
var DropdownMenuLabel = DropdownMenuPrimitive.Label;
|
|
27
|
+
/**
|
|
28
|
+
* Stops clicks outside an open dropdown from reaching elements underneath it
|
|
29
|
+
* (e.g. a table row's `onClick`) without covering the viewport, so scrolling
|
|
30
|
+
* the content behind the menu keeps working natively.
|
|
31
|
+
*
|
|
32
|
+
* React delegates `onClick` at the root in the bubble phase, so a capture-phase
|
|
33
|
+
* `click` listener on `document` runs first and can stop the event before it
|
|
34
|
+
* gets there. pointerdown is left alone so Radix's outside-dismiss keeps
|
|
35
|
+
* working; the wheel listener is passive so native scroll is never interrupted,
|
|
36
|
+
* it just also dismisses the menu (an open menu jitters as Radix repositions it
|
|
37
|
+
* to follow its trigger while scrolling).
|
|
38
|
+
*
|
|
39
|
+
* "Inside" is any element with `role="menu"` in its ancestry — Radix gives that
|
|
40
|
+
* role to both the content and its submenus (which portal out separately), so
|
|
41
|
+
* clicks and scrolls inside a submenu are correctly treated as inside.
|
|
42
|
+
*/
|
|
43
|
+
var OutsideClickGuard = () => {
|
|
44
|
+
const cleanupTimerRef = React$1.useRef(void 0);
|
|
45
|
+
const pointerDownOutsideRef = React$1.useRef(false);
|
|
46
|
+
React$1.useLayoutEffect(() => {
|
|
47
|
+
clearTimeout(cleanupTimerRef.current);
|
|
48
|
+
pointerDownOutsideRef.current = false;
|
|
49
|
+
const isOutside = (target) => !(target instanceof Element) || !target.closest("[role=\"menu\"]");
|
|
50
|
+
const onPointerDown = (event) => {
|
|
51
|
+
if (isOutside(event.target)) pointerDownOutsideRef.current = true;
|
|
52
|
+
};
|
|
53
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
54
|
+
const onClick = (event) => {
|
|
55
|
+
if (isOutside(event.target)) {
|
|
56
|
+
event.preventDefault();
|
|
57
|
+
event.stopPropagation();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
document.addEventListener("click", onClick, true);
|
|
61
|
+
const onWheel = (event) => {
|
|
62
|
+
if (isOutside(event.target)) document.dispatchEvent(new KeyboardEvent("keydown", {
|
|
63
|
+
key: "Escape",
|
|
64
|
+
bubbles: true
|
|
65
|
+
}));
|
|
66
|
+
};
|
|
67
|
+
document.addEventListener("wheel", onWheel, { passive: true });
|
|
68
|
+
return () => {
|
|
69
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
70
|
+
document.removeEventListener("click", onClick, true);
|
|
71
|
+
document.removeEventListener("wheel", onWheel);
|
|
72
|
+
if (!pointerDownOutsideRef.current) return;
|
|
73
|
+
const absorb = (event) => {
|
|
74
|
+
event.preventDefault();
|
|
75
|
+
event.stopPropagation();
|
|
76
|
+
};
|
|
77
|
+
const opts = {
|
|
78
|
+
capture: true,
|
|
79
|
+
once: true
|
|
80
|
+
};
|
|
81
|
+
document.addEventListener("pointerup", absorb, opts);
|
|
82
|
+
document.addEventListener("mouseup", absorb, opts);
|
|
83
|
+
document.addEventListener("click", absorb, opts);
|
|
84
|
+
cleanupTimerRef.current = setTimeout(() => {
|
|
85
|
+
if (typeof document === "undefined") return;
|
|
86
|
+
document.removeEventListener("pointerup", absorb, { capture: true });
|
|
87
|
+
document.removeEventListener("mouseup", absorb, { capture: true });
|
|
88
|
+
document.removeEventListener("click", absorb, { capture: true });
|
|
89
|
+
}, 300);
|
|
90
|
+
};
|
|
91
|
+
}, []);
|
|
92
|
+
return null;
|
|
93
|
+
};
|
|
94
|
+
var DropdownMenuContent = React$1.forwardRef(({ className, sideOffset = 4, children, preventClickThrough, ...props }, ref) => {
|
|
95
|
+
const zIndex = useZIndex(zIndices.popover);
|
|
96
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsxs(DropdownMenuPrimitive.Content, {
|
|
97
|
+
ref,
|
|
98
|
+
sideOffset,
|
|
99
|
+
className: cn("min-w-[8rem] overflow-hidden rounded-md border border-subtle bg-popover p-space-1 shadow-lg", className),
|
|
100
|
+
...props,
|
|
101
|
+
style: {
|
|
102
|
+
zIndex,
|
|
103
|
+
...props.style
|
|
104
|
+
},
|
|
105
|
+
children: [preventClickThrough && /* @__PURE__ */ jsx(OutsideClickGuard, {}), /* @__PURE__ */ jsx(ZIndexProvider, {
|
|
106
|
+
value: zIndex,
|
|
107
|
+
children
|
|
108
|
+
})]
|
|
109
|
+
}) });
|
|
110
|
+
});
|
|
111
|
+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
|
|
112
|
+
var DropdownMenuItem = React$1.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Item, {
|
|
113
|
+
ref,
|
|
114
|
+
className: cn("text-md flex cursor-pointer select-none items-center rounded-sm px-space-2 py-1.5 outline-none transition-colors focus:bg-surface-level-2 data-[disabled]:pointer-events-none data-[disabled]:opacity-50", inset && "pl-space-6", className),
|
|
115
|
+
...props
|
|
116
|
+
}));
|
|
117
|
+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
|
|
118
|
+
var DropdownMenuSeparator = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Separator, {
|
|
119
|
+
ref,
|
|
120
|
+
className: cn("my-space-1 h-px bg-surface-level-2", className),
|
|
121
|
+
...props
|
|
122
|
+
}));
|
|
123
|
+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
|
|
124
|
+
var DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
125
|
+
var DropdownMenuSubTrigger = React$1.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.SubTrigger, {
|
|
126
|
+
ref,
|
|
127
|
+
className: cn("text-md flex cursor-pointer select-none items-center rounded-sm px-space-2 py-1.5 outline-none transition-colors focus:bg-surface-level-2 data-[state=open]:bg-surface-level-2", inset && "pl-space-6", className),
|
|
128
|
+
...props,
|
|
129
|
+
children
|
|
130
|
+
}));
|
|
131
|
+
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
|
|
132
|
+
var DropdownMenuSubContent = React$1.forwardRef(({ className, children, ...props }, ref) => {
|
|
133
|
+
const zIndex = useZIndex(zIndices.popover);
|
|
134
|
+
return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.SubContent, {
|
|
135
|
+
ref,
|
|
136
|
+
className: cn("min-w-[8rem] overflow-hidden rounded-md border border-subtle bg-popover p-space-1 shadow-lg", className),
|
|
137
|
+
style: { zIndex },
|
|
138
|
+
...props,
|
|
139
|
+
children: /* @__PURE__ */ jsx(ZIndexProvider, {
|
|
140
|
+
value: zIndex,
|
|
141
|
+
children
|
|
142
|
+
})
|
|
143
|
+
}) });
|
|
144
|
+
});
|
|
145
|
+
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
|
|
146
|
+
//#endregion
|
|
147
|
+
export { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
|
|
148
|
+
|
|
149
|
+
//# sourceMappingURL=DropdownMenu.js.map
|