@ponti-studios/ui 2.0.2 → 3.0.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/README.md +36 -3
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.js +3 -0
- package/dist/components/data-display/accordion.d.ts +10 -0
- package/dist/components/data-display/accordion.js +53 -0
- package/{src/components/data-display/index.ts → dist/components/data-display/index.d.ts} +1 -10
- package/dist/components/data-display/index.js +8 -0
- package/dist/components/data-display/metric-card.d.ts +9 -0
- package/dist/components/data-display/metric-card.js +25 -0
- package/dist/components/data-display/sort-controls.d.ts +13 -0
- package/dist/components/data-display/sort-controls.js +57 -0
- package/dist/components/data-display/sort-row.d.ts +10 -0
- package/dist/components/data-display/sort-row.js +52 -0
- package/dist/components/data-display/table.d.ts +10 -0
- package/dist/components/data-display/table.js +57 -0
- package/dist/components/feedback/alert.d.ts +9 -0
- package/dist/components/feedback/alert.js +38 -0
- package/dist/components/feedback/empty-state.d.ts +18 -0
- package/dist/components/feedback/empty-state.js +36 -0
- package/{src/components/feedback/index.ts → dist/components/feedback/index.d.ts} +2 -0
- package/dist/components/feedback/index.js +7 -0
- package/dist/components/feedback/progress.d.ts +6 -0
- package/dist/components/feedback/progress.js +25 -0
- package/dist/components/feedback/skeleton.d.ts +2 -0
- package/dist/components/feedback/skeleton.js +11 -0
- package/dist/components/feedback/spinner.d.ts +14 -0
- package/dist/components/feedback/spinner.js +27 -0
- package/dist/components/feedback/update-guard.d.ts +13 -0
- package/dist/components/feedback/update-guard.js +38 -0
- package/dist/components/filters/active-filters-bar.d.ts +14 -0
- package/dist/components/filters/active-filters-bar.js +44 -0
- package/dist/components/filters/filter-chip.d.ts +11 -0
- package/dist/components/filters/filter-chip.js +33 -0
- package/dist/components/filters/filter-select.d.ts +17 -0
- package/dist/components/filters/filter-select.js +46 -0
- package/dist/components/filters/index.js +4 -0
- package/dist/components/forms/checkbox.d.ts +4 -0
- package/dist/components/forms/checkbox.js +24 -0
- package/dist/components/forms/date-month-select.d.ts +11 -0
- package/dist/components/forms/date-month-select.js +47 -0
- package/dist/components/forms/date-picker.d.ts +60 -0
- package/dist/components/forms/date-picker.js +193 -0
- package/dist/components/forms/date-utils.d.ts +14 -0
- package/dist/components/forms/date-utils.js +18 -0
- package/dist/components/forms/drop-zone.d.ts +42 -0
- package/dist/components/forms/drop-zone.js +184 -0
- package/{src/components/forms/index.ts → dist/components/forms/index.d.ts} +3 -9
- package/dist/components/forms/index.js +17 -0
- package/dist/components/forms/input.d.ts +3 -0
- package/dist/components/forms/input.js +15 -0
- package/dist/components/forms/label.d.ts +3 -0
- package/dist/components/forms/label.js +14 -0
- package/dist/components/forms/passkey-management.d.ts +14 -0
- package/dist/components/forms/passkey-management.js +132 -0
- package/dist/components/forms/radio-group.d.ts +6 -0
- package/dist/components/forms/radio-group.js +28 -0
- package/dist/components/forms/select.d.ts +18 -0
- package/dist/components/forms/select.js +103 -0
- package/dist/components/forms/slider.d.ts +9 -0
- package/dist/components/forms/slider.js +25 -0
- package/dist/components/forms/stepper.d.ts +15 -0
- package/dist/components/forms/stepper.js +41 -0
- package/dist/components/forms/switch.d.ts +6 -0
- package/dist/components/forms/switch.js +21 -0
- package/dist/components/forms/text-field.d.ts +15 -0
- package/dist/components/forms/text-field.js +46 -0
- package/dist/components/forms/text-field.types.d.ts +8 -0
- package/dist/components/forms/textarea.d.ts +3 -0
- package/dist/components/forms/textarea.js +14 -0
- package/dist/components/layout/index.js +5 -0
- package/dist/components/layout/particle-background.d.ts +19 -0
- package/dist/components/layout/particle-background.js +171 -0
- package/dist/components/layout/scroll-area.d.ts +9 -0
- package/dist/components/layout/scroll-area.js +35 -0
- package/dist/components/layout/section-intro.d.ts +12 -0
- package/dist/components/layout/section-intro.js +28 -0
- package/dist/components/layout/surface-panel.d.ts +7 -0
- package/dist/components/layout/surface-panel.js +11 -0
- package/dist/components/navigation/app-navigation.d.ts +67 -0
- package/dist/components/navigation/app-navigation.js +106 -0
- package/{src/components/navigation/index.ts → dist/components/navigation/index.d.ts} +1 -7
- package/dist/components/navigation/index.js +4 -0
- package/dist/components/navigation/pagination-controls.d.ts +7 -0
- package/dist/components/navigation/pagination-controls.js +50 -0
- package/dist/components/navigation/tabs.d.ts +7 -0
- package/dist/components/navigation/tabs.js +35 -0
- package/dist/components/overlays/bottom-sheet.d.ts +20 -0
- package/dist/components/overlays/bottom-sheet.js +101 -0
- package/dist/components/overlays/command.d.ts +29 -0
- package/dist/components/overlays/command.js +123 -0
- package/dist/components/overlays/dialog.d.ts +30 -0
- package/dist/components/overlays/dialog.js +105 -0
- package/dist/components/overlays/dropdown-menu.d.ts +29 -0
- package/dist/components/overlays/dropdown-menu.js +128 -0
- package/dist/components/overlays/index.d.ts +7 -0
- package/dist/components/overlays/index.js +8 -0
- package/dist/components/overlays/popover.d.ts +14 -0
- package/dist/components/overlays/popover.js +56 -0
- package/dist/components/overlays/sheet.d.ts +27 -0
- package/dist/components/overlays/sheet.js +81 -0
- package/dist/components/overlays/tooltip.d.ts +10 -0
- package/dist/components/overlays/tooltip.js +23 -0
- package/dist/components/primitives/avatar.d.ts +14 -0
- package/dist/components/primitives/avatar.js +72 -0
- package/dist/components/primitives/badge.d.ts +7 -0
- package/dist/components/primitives/badge.js +27 -0
- package/dist/components/primitives/button.d.ts +13 -0
- package/dist/components/primitives/button.js +113 -0
- package/{src/components/primitives/button.types.ts → dist/components/primitives/button.types.d.ts} +4 -6
- package/dist/components/primitives/card.d.ts +9 -0
- package/dist/components/primitives/card.js +56 -0
- package/{src/components/primitives/index.ts → dist/components/primitives/index.d.ts} +1 -9
- package/dist/components/primitives/index.js +7 -0
- package/dist/components/primitives/segmented-control.d.ts +20 -0
- package/dist/components/primitives/segmented-control.js +27 -0
- package/dist/components/primitives/separator.d.ts +4 -0
- package/dist/components/primitives/separator.js +16 -0
- package/dist/constants/chart-colors.d.ts +33 -0
- package/dist/constants/chart-colors.js +31 -0
- package/dist/hooks/index.js +9 -0
- package/{src/hooks/sort.types.ts → dist/hooks/sort.types.d.ts} +2 -4
- package/dist/hooks/use-api-client.d.ts +30 -0
- package/dist/hooks/use-api-client.js +106 -0
- package/dist/hooks/use-debounced-value.d.ts +1 -0
- package/dist/hooks/use-debounced-value.js +12 -0
- package/dist/hooks/use-derived-filter-state.d.ts +20 -0
- package/dist/hooks/use-derived-filter-state.js +39 -0
- package/dist/hooks/use-filter-state.d.ts +12 -0
- package/dist/hooks/use-filter-state.js +37 -0
- package/dist/hooks/use-media-query.d.ts +6 -0
- package/dist/hooks/use-media-query.js +27 -0
- package/dist/hooks/use-mobile.d.ts +1 -0
- package/dist/hooks/use-mobile.js +14 -0
- package/dist/hooks/use-sort.d.ts +11 -0
- package/dist/hooks/use-sort.js +14 -0
- package/{src/index.ts → dist/index.d.ts} +4 -32
- package/dist/index.js +15 -0
- package/dist/integrations/service-worker.d.ts +2 -0
- package/dist/integrations/service-worker.js +2 -0
- package/dist/lib/auth.d.ts +2 -0
- package/dist/lib/auth.js +7 -0
- package/dist/lib/clipboard.d.ts +1 -0
- package/dist/lib/clipboard.js +10 -0
- package/dist/lib/index.js +4 -0
- package/{src/lib/slot.tsx → dist/lib/slot.d.ts} +2 -15
- package/dist/lib/slot.js +14 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +8 -0
- package/dist/native/components.d.ts +41 -0
- package/dist/native/components.js +135 -0
- package/dist/native/index.js +3 -0
- package/dist/native/theme.d.ts +19 -0
- package/dist/native/theme.js +58 -0
- package/dist/styles/tokens/css-vars.d.ts +7 -0
- package/dist/styles/tokens/css-vars.js +5 -0
- package/dist/styles/tokens/generated/dark.colors.generated.d.ts +40 -0
- package/dist/styles/tokens/generated/dark.colors.generated.js +39 -0
- package/dist/styles/tokens/generated/foundations.generated.d.ts +323 -0
- package/dist/styles/tokens/generated/foundations.generated.js +453 -0
- package/dist/styles/tokens/generated/light.colors.generated.d.ts +40 -0
- package/dist/styles/tokens/generated/light.colors.generated.js +39 -0
- package/dist/styles/tokens/index.d.ts +317 -0
- package/dist/styles/tokens/index.js +14 -0
- package/dist/styles.css +1 -1
- package/dist/translations/en.d.ts +34 -0
- package/dist/translations/index.d.ts +39 -0
- package/dist/translations/ui-provider.d.ts +9 -0
- package/dist/translations/ui-provider.js +16 -0
- package/dist/types/upload.d.ts +36 -0
- package/package.json +50 -34
- package/src/components/data-display/accordion.stories.tsx +0 -57
- package/src/components/data-display/accordion.tsx +0 -86
- package/src/components/data-display/metric-card.stories.tsx +0 -48
- package/src/components/data-display/metric-card.tsx +0 -20
- package/src/components/data-display/sort-controls.stories.tsx +0 -45
- package/src/components/data-display/sort-controls.tsx +0 -96
- package/src/components/data-display/sort-row.tsx +0 -88
- package/src/components/data-display/table.stories.tsx +0 -75
- package/src/components/data-display/table.tsx +0 -80
- package/src/components/feedback/alert.stories.tsx +0 -51
- package/src/components/feedback/alert.tsx +0 -64
- package/src/components/feedback/empty-state.tsx +0 -76
- package/src/components/feedback/progress.stories.tsx +0 -54
- package/src/components/feedback/progress.tsx +0 -41
- package/src/components/feedback/skeleton.stories.tsx +0 -36
- package/src/components/feedback/skeleton.tsx +0 -7
- package/src/components/feedback/spinner.stories.tsx +0 -52
- package/src/components/feedback/spinner.tsx +0 -47
- package/src/components/feedback/update-guard.stories.tsx +0 -28
- package/src/components/feedback/update-guard.tsx +0 -57
- package/src/components/filters/active-filters-bar.stories.tsx +0 -114
- package/src/components/filters/active-filters-bar.tsx +0 -61
- package/src/components/filters/filter-chip.tsx +0 -57
- package/src/components/filters/filter-select.stories.tsx +0 -71
- package/src/components/filters/filter-select.tsx +0 -68
- package/src/components/forms/checkbox.stories.tsx +0 -35
- package/src/components/forms/checkbox.tsx +0 -38
- package/src/components/forms/date-month-select.stories.tsx +0 -26
- package/src/components/forms/date-month-select.tsx +0 -79
- package/src/components/forms/date-picker.stories.tsx +0 -188
- package/src/components/forms/date-picker.tsx +0 -303
- package/src/components/forms/date-utils.ts +0 -37
- package/src/components/forms/drop-zone.stories.tsx +0 -140
- package/src/components/forms/drop-zone.tsx +0 -298
- package/src/components/forms/input.stories.tsx +0 -47
- package/src/components/forms/input.tsx +0 -24
- package/src/components/forms/label.stories.tsx +0 -16
- package/src/components/forms/label.tsx +0 -25
- package/src/components/forms/passkey-management.stories.tsx +0 -85
- package/src/components/forms/passkey-management.tsx +0 -168
- package/src/components/forms/radio-group.stories.tsx +0 -46
- package/src/components/forms/radio-group.tsx +0 -44
- package/src/components/forms/select.stories.tsx +0 -207
- package/src/components/forms/select.tsx +0 -182
- package/src/components/forms/slider.stories.tsx +0 -70
- package/src/components/forms/slider.tsx +0 -50
- package/src/components/forms/stepper.stories.tsx +0 -111
- package/src/components/forms/stepper.tsx +0 -66
- package/src/components/forms/switch.stories.tsx +0 -144
- package/src/components/forms/switch.tsx +0 -39
- package/src/components/forms/text-field.stories.tsx +0 -87
- package/src/components/forms/text-field.tsx +0 -75
- package/src/components/forms/text-field.types.ts +0 -9
- package/src/components/forms/textarea.stories.tsx +0 -150
- package/src/components/forms/textarea.tsx +0 -22
- package/src/components/layout/particle-background.stories.tsx +0 -38
- package/src/components/layout/particle-background.tsx +0 -378
- package/src/components/layout/scroll-area.stories.tsx +0 -91
- package/src/components/layout/scroll-area.tsx +0 -79
- package/src/components/layout/section-intro.stories.tsx +0 -29
- package/src/components/layout/section-intro.tsx +0 -31
- package/src/components/layout/surface-panel.stories.tsx +0 -32
- package/src/components/layout/surface-panel.tsx +0 -23
- package/src/components/navigation/app-navigation.stories.tsx +0 -217
- package/src/components/navigation/app-navigation.tsx +0 -234
- package/src/components/navigation/pagination-controls.stories.tsx +0 -41
- package/src/components/navigation/pagination-controls.tsx +0 -46
- package/src/components/navigation/tabs.stories.tsx +0 -48
- package/src/components/navigation/tabs.tsx +0 -52
- package/src/components/overlays/bottom-sheet.stories.tsx +0 -52
- package/src/components/overlays/bottom-sheet.tsx +0 -179
- package/src/components/overlays/command.stories.tsx +0 -65
- package/src/components/overlays/command.tsx +0 -227
- package/src/components/overlays/dialog.stories.tsx +0 -148
- package/src/components/overlays/dialog.tsx +0 -203
- package/src/components/overlays/dropdown-menu.stories.tsx +0 -74
- package/src/components/overlays/dropdown-menu.tsx +0 -236
- package/src/components/overlays/index.ts +0 -56
- package/src/components/overlays/popover.stories.tsx +0 -51
- package/src/components/overlays/popover.tsx +0 -78
- package/src/components/overlays/sheet.stories.tsx +0 -68
- package/src/components/overlays/sheet.tsx +0 -155
- package/src/components/overlays/tooltip.stories.tsx +0 -29
- package/src/components/overlays/tooltip.tsx +0 -41
- package/src/components/primitives/avatar-placeholder.svg +0 -13
- package/src/components/primitives/avatar.stories.tsx +0 -72
- package/src/components/primitives/avatar.tsx +0 -136
- package/src/components/primitives/badge.stories.tsx +0 -43
- package/src/components/primitives/badge.tsx +0 -43
- package/src/components/primitives/button.stories.tsx +0 -113
- package/src/components/primitives/button.tsx +0 -131
- package/src/components/primitives/card.stories.tsx +0 -59
- package/src/components/primitives/card.tsx +0 -66
- package/src/components/primitives/segmented-control.stories.tsx +0 -54
- package/src/components/primitives/segmented-control.tsx +0 -73
- package/src/components/primitives/separator.stories.tsx +0 -34
- package/src/components/primitives/separator.tsx +0 -27
- package/src/constants/chart-colors.ts +0 -39
- package/src/env.d.ts +0 -9
- package/src/hooks/use-api-client.ts +0 -122
- package/src/hooks/use-debounced-value.ts +0 -12
- package/src/hooks/use-derived-filter-state.ts +0 -70
- package/src/hooks/use-filter-state.ts +0 -66
- package/src/hooks/use-media-query.ts +0 -69
- package/src/hooks/use-mobile.tsx +0 -19
- package/src/hooks/use-sort.ts +0 -20
- package/src/lib/auth.ts +0 -5
- package/src/lib/clipboard.ts +0 -8
- package/src/lib/utils.ts +0 -6
- package/src/native/components.tsx +0 -198
- package/src/native/theme.tsx +0 -69
- package/src/storybook/controls.ts +0 -117
- package/src/storybook/options.ts +0 -52
- package/src/styles/build.ts +0 -1
- package/src/styles/index.css +0 -423
- package/src/styles/nokia.css +0 -36
- package/src/styles/package.css +0 -3
- package/src/styles/tokens/chart-colors.stories.tsx +0 -189
- package/src/styles/tokens/color-systems.stories.tsx +0 -190
- package/src/styles/tokens/css-vars.ts +0 -15
- package/src/styles/tokens/generated/dark-class.css +0 -39
- package/src/styles/tokens/generated/dark.colors.generated.ts +0 -39
- package/src/styles/tokens/generated/dark.css +0 -39
- package/src/styles/tokens/generated/foundations.css +0 -149
- package/src/styles/tokens/generated/foundations.generated.ts +0 -454
- package/src/styles/tokens/generated/light.colors.generated.ts +0 -39
- package/src/styles/tokens/generated/light.css +0 -39
- package/src/styles/tokens/index.ts +0 -70
- package/src/styles/tokens/layout.stories.tsx +0 -50
- package/src/styles/tokens/scripts/check-foundations.mjs +0 -126
- package/src/styles/tokens/scripts/check-source.mjs +0 -53
- package/src/styles/tokens/source/dark.tokens.json +0 -138
- package/src/styles/tokens/source/foundations.tokens.json +0 -344
- package/src/styles/tokens/source/light.tokens.json +0 -138
- package/src/styles/tokens/style-dictionary.dark-class.json +0 -16
- package/src/styles/tokens/style-dictionary.dark-storybook.json +0 -16
- package/src/styles/tokens/style-dictionary.dark.json +0 -21
- package/src/styles/tokens/style-dictionary.foundations.json +0 -21
- package/src/styles/tokens/style-dictionary.light-storybook.json +0 -16
- package/src/styles/tokens/style-dictionary.light.json +0 -21
- package/src/styles/tokens/typography.stories.tsx +0 -157
- package/src/translations/en.ts +0 -34
- package/src/translations/index.ts +0 -32
- package/src/types/upload.ts +0 -42
- /package/{src/components/filters/index.ts → dist/components/filters/index.d.ts} +0 -0
- /package/{src/components/layout/index.ts → dist/components/layout/index.d.ts} +0 -0
- /package/{src/hooks/index.ts → dist/hooks/index.d.ts} +0 -0
- /package/{src/lib/index.ts → dist/lib/index.d.ts} +0 -0
- /package/{src/native/index.ts → dist/native/index.d.ts} +0 -0
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
import { Plus, Trash2 } from "lucide-react";
|
|
3
|
-
import { expect, userEvent, within } from "storybook/test";
|
|
4
|
-
|
|
5
|
-
import { booleanControl, hiddenControl, selectControl } from "../../storybook/controls";
|
|
6
|
-
import { buttonVariantOptions } from "../../storybook/options";
|
|
7
|
-
import { Button } from "./button";
|
|
8
|
-
|
|
9
|
-
const meta: Meta = {
|
|
10
|
-
title: "Primitives/Button",
|
|
11
|
-
component: Button,
|
|
12
|
-
tags: ["autodocs"],
|
|
13
|
-
argTypes: {
|
|
14
|
-
variant: selectControl(buttonVariantOptions, "Visual style variant of the button", {
|
|
15
|
-
defaultValue: "default",
|
|
16
|
-
}),
|
|
17
|
-
disabled: booleanControl("Prevents user interaction and applies disabled styling", false),
|
|
18
|
-
asChild: hiddenControl,
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export default meta;
|
|
23
|
-
type Story = StoryObj<typeof meta>;
|
|
24
|
-
|
|
25
|
-
export const Default: Story = {
|
|
26
|
-
args: { children: "Button" },
|
|
27
|
-
play: async ({ canvasElement }) => {
|
|
28
|
-
const canvas = within(canvasElement);
|
|
29
|
-
const button = canvas.getByRole("button", { name: "Button" });
|
|
30
|
-
|
|
31
|
-
await userEvent.hover(button);
|
|
32
|
-
await userEvent.click(button);
|
|
33
|
-
|
|
34
|
-
await expect(button).toHaveFocus();
|
|
35
|
-
await expect(button).toBeEnabled();
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export const Variants: Story = {
|
|
40
|
-
render: () => (
|
|
41
|
-
<div className="flex flex-wrap gap-3">
|
|
42
|
-
<Button variant="default">Default</Button>
|
|
43
|
-
<Button variant="secondary">Secondary</Button>
|
|
44
|
-
<Button variant="ghost">Ghost</Button>
|
|
45
|
-
<Button variant="destructive">Destructive</Button>
|
|
46
|
-
<Button variant="ghost" size="icon" aria-label="Add">
|
|
47
|
-
<Plus className="size-4" />
|
|
48
|
-
</Button>
|
|
49
|
-
<Button variant="link">Link</Button>
|
|
50
|
-
</div>
|
|
51
|
-
),
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const Icon: Story = {
|
|
55
|
-
render: () => (
|
|
56
|
-
<div className="flex items-center gap-3">
|
|
57
|
-
<Button>Standard</Button>
|
|
58
|
-
<Button size="icon" aria-label="Add">
|
|
59
|
-
<Plus className="size-4" />
|
|
60
|
-
</Button>
|
|
61
|
-
</div>
|
|
62
|
-
),
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const WithIcon: Story = {
|
|
66
|
-
render: () => (
|
|
67
|
-
<div className="flex gap-3">
|
|
68
|
-
<Button>
|
|
69
|
-
<Plus className="size-4" />
|
|
70
|
-
Create
|
|
71
|
-
</Button>
|
|
72
|
-
<Button variant="destructive">
|
|
73
|
-
<Trash2 className="size-4" />
|
|
74
|
-
Delete
|
|
75
|
-
</Button>
|
|
76
|
-
</div>
|
|
77
|
-
),
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export const Disabled: Story = {
|
|
81
|
-
render: () => (
|
|
82
|
-
<div className="flex gap-3">
|
|
83
|
-
<Button disabled>Default</Button>
|
|
84
|
-
<Button variant="outline" disabled>
|
|
85
|
-
Outline
|
|
86
|
-
</Button>
|
|
87
|
-
<Button variant="destructive" disabled>
|
|
88
|
-
Destructive
|
|
89
|
-
</Button>
|
|
90
|
-
</div>
|
|
91
|
-
),
|
|
92
|
-
play: async ({ canvasElement }) => {
|
|
93
|
-
const canvas = within(canvasElement);
|
|
94
|
-
|
|
95
|
-
await expect(canvas.getByRole("button", { name: "Default" })).toBeDisabled();
|
|
96
|
-
await expect(canvas.getByRole("button", { name: "Outline" })).toBeDisabled();
|
|
97
|
-
await expect(canvas.getByRole("button", { name: "Destructive" })).toBeDisabled();
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export const Loading: Story = {
|
|
102
|
-
render: () => (
|
|
103
|
-
<Button isLoading loadingLabel="Saving">
|
|
104
|
-
Save
|
|
105
|
-
</Button>
|
|
106
|
-
),
|
|
107
|
-
play: async ({ canvasElement }) => {
|
|
108
|
-
const canvas = within(canvasElement);
|
|
109
|
-
const button = canvas.getByRole("button", { name: "Saving" });
|
|
110
|
-
|
|
111
|
-
await expect(button).toBeDisabled();
|
|
112
|
-
},
|
|
113
|
-
};
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { Button as BaseButton } from "@base-ui/react/button";
|
|
2
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
|
|
5
|
-
import { cn } from "../../lib/utils";
|
|
6
|
-
import { Spinner } from "../feedback/spinner";
|
|
7
|
-
|
|
8
|
-
const buttonVariants = cva(
|
|
9
|
-
[
|
|
10
|
-
"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md border border-transparent font-medium transition-colors outline-none",
|
|
11
|
-
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
12
|
-
"disabled:pointer-events-none disabled:opacity-50",
|
|
13
|
-
"[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
14
|
-
],
|
|
15
|
-
{
|
|
16
|
-
variants: {
|
|
17
|
-
variant: {
|
|
18
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
19
|
-
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
20
|
-
outline: "border-input bg-background hover:bg-muted hover:text-muted-foreground",
|
|
21
|
-
secondary: "border-input bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
22
|
-
ghost: "border-transparent bg-transparent hover:bg-muted hover:text-muted-foreground",
|
|
23
|
-
link: "border-transparent bg-transparent px-0 text-accent-text underline-offset-4 hover:underline",
|
|
24
|
-
},
|
|
25
|
-
size: {
|
|
26
|
-
sm: "min-h-8 px-2.5 text-xs",
|
|
27
|
-
md: "min-h-9 px-3 text-sm",
|
|
28
|
-
lg: "min-h-10 px-4 text-base",
|
|
29
|
-
icon: "size-9 rounded-md p-0",
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
defaultVariants: {
|
|
33
|
-
variant: "default",
|
|
34
|
-
size: "md",
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
interface ButtonProps
|
|
40
|
-
extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
41
|
-
asChild?: boolean;
|
|
42
|
-
isLoading?: boolean;
|
|
43
|
-
loadingLabel?: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
47
|
-
(
|
|
48
|
-
{
|
|
49
|
-
children,
|
|
50
|
-
className,
|
|
51
|
-
disabled,
|
|
52
|
-
isLoading = false,
|
|
53
|
-
loadingLabel = "Loading",
|
|
54
|
-
variant,
|
|
55
|
-
size,
|
|
56
|
-
asChild = false,
|
|
57
|
-
// Defaults to "button" — same safe default the native element loses
|
|
58
|
-
// once it's rendered inside a <form> — but must stay overridable so
|
|
59
|
-
// consumers can pass type="submit"/"reset".
|
|
60
|
-
type = "button",
|
|
61
|
-
"aria-label": ariaLabel,
|
|
62
|
-
...props
|
|
63
|
-
},
|
|
64
|
-
ref,
|
|
65
|
-
) => {
|
|
66
|
-
if (asChild && React.isValidElement(children)) {
|
|
67
|
-
const child = children as React.ReactElement<{ children?: React.ReactNode }>;
|
|
68
|
-
const renderedChild = React.cloneElement(child, {
|
|
69
|
-
children: isLoading ? (
|
|
70
|
-
<>
|
|
71
|
-
<span className="opacity-0" aria-hidden="true">
|
|
72
|
-
{child.props.children}
|
|
73
|
-
</span>
|
|
74
|
-
<span className="absolute inset-0 inline-flex items-center justify-center">
|
|
75
|
-
<Spinner size="sm" aria-hidden="true" />
|
|
76
|
-
</span>
|
|
77
|
-
<span className="sr-only">{loadingLabel}</span>
|
|
78
|
-
</>
|
|
79
|
-
) : (
|
|
80
|
-
child.props.children
|
|
81
|
-
),
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
return (
|
|
85
|
-
<BaseButton
|
|
86
|
-
{...props}
|
|
87
|
-
type={type}
|
|
88
|
-
render={renderedChild}
|
|
89
|
-
nativeButton={false}
|
|
90
|
-
className={cn(buttonVariants({ variant, size, className }), isLoading && "relative")}
|
|
91
|
-
disabled={disabled || isLoading}
|
|
92
|
-
aria-busy={isLoading}
|
|
93
|
-
aria-label={isLoading ? loadingLabel : ariaLabel}
|
|
94
|
-
ref={ref}
|
|
95
|
-
/>
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
return (
|
|
99
|
-
<button
|
|
100
|
-
{...props}
|
|
101
|
-
className={cn(buttonVariants({ variant, size, className }), isLoading && "relative")}
|
|
102
|
-
style={{
|
|
103
|
-
...props.style,
|
|
104
|
-
cursor: disabled || isLoading ? "default" : "pointer",
|
|
105
|
-
}}
|
|
106
|
-
type={type}
|
|
107
|
-
ref={ref}
|
|
108
|
-
disabled={disabled || isLoading}
|
|
109
|
-
aria-busy={isLoading}
|
|
110
|
-
aria-label={isLoading ? loadingLabel : ariaLabel}
|
|
111
|
-
>
|
|
112
|
-
{isLoading ? (
|
|
113
|
-
<>
|
|
114
|
-
<span className="opacity-0" aria-hidden="true">
|
|
115
|
-
{children}
|
|
116
|
-
</span>
|
|
117
|
-
<span className="absolute inset-0 inline-flex items-center justify-center">
|
|
118
|
-
<Spinner size="sm" aria-hidden="true" />
|
|
119
|
-
</span>
|
|
120
|
-
<span className="sr-only">{loadingLabel}</span>
|
|
121
|
-
</>
|
|
122
|
-
) : (
|
|
123
|
-
children
|
|
124
|
-
)}
|
|
125
|
-
</button>
|
|
126
|
-
);
|
|
127
|
-
},
|
|
128
|
-
);
|
|
129
|
-
Button.displayName = "Button";
|
|
130
|
-
|
|
131
|
-
export { Button, buttonVariants };
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
import { expect, userEvent, within } from "storybook/test";
|
|
3
|
-
|
|
4
|
-
import { Button } from "./button";
|
|
5
|
-
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "./card";
|
|
6
|
-
|
|
7
|
-
const meta = {
|
|
8
|
-
title: "Primitives/Card",
|
|
9
|
-
tags: ["autodocs"],
|
|
10
|
-
component: Card,
|
|
11
|
-
} satisfies Meta<typeof Card>;
|
|
12
|
-
|
|
13
|
-
export default meta;
|
|
14
|
-
type Story = StoryObj<typeof meta>;
|
|
15
|
-
|
|
16
|
-
export const Default: Story = {
|
|
17
|
-
render: () => (
|
|
18
|
-
<Card>
|
|
19
|
-
<CardHeader>
|
|
20
|
-
<CardTitle>Card Title</CardTitle>
|
|
21
|
-
<CardDescription>A short description of the card's content.</CardDescription>
|
|
22
|
-
</CardHeader>
|
|
23
|
-
<CardContent>
|
|
24
|
-
<p className="text-muted-foreground text-sm">
|
|
25
|
-
Card body content goes here. It can be any React node.
|
|
26
|
-
</p>
|
|
27
|
-
</CardContent>
|
|
28
|
-
<CardFooter className="flex justify-end gap-2">
|
|
29
|
-
<Button variant="outline">Cancel</Button>
|
|
30
|
-
<Button>Confirm</Button>
|
|
31
|
-
</CardFooter>
|
|
32
|
-
</Card>
|
|
33
|
-
),
|
|
34
|
-
play: async ({ canvasElement }) => {
|
|
35
|
-
const canvas = within(canvasElement);
|
|
36
|
-
const cancelButton = canvas.getByRole("button", { name: "Cancel" });
|
|
37
|
-
|
|
38
|
-
await userEvent.tab();
|
|
39
|
-
|
|
40
|
-
await expect(canvas.getByText("Card Title")).toBeInTheDocument();
|
|
41
|
-
await expect(cancelButton).toHaveFocus();
|
|
42
|
-
await expect(canvas.getByRole("button", { name: "Confirm" })).toBeInTheDocument();
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export const Minimal: Story = {
|
|
47
|
-
render: () => (
|
|
48
|
-
<Card className="w-80">
|
|
49
|
-
<CardContent>
|
|
50
|
-
<p className="text-muted-foreground text-sm">Minimal card with only content.</p>
|
|
51
|
-
</CardContent>
|
|
52
|
-
</Card>
|
|
53
|
-
),
|
|
54
|
-
play: async ({ canvasElement }) => {
|
|
55
|
-
const canvas = within(canvasElement);
|
|
56
|
-
|
|
57
|
-
await expect(canvas.getByText("Minimal card with only content.")).toBeInTheDocument();
|
|
58
|
-
},
|
|
59
|
-
};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import { cn } from "../../lib/utils";
|
|
4
|
-
|
|
5
|
-
function Card({ className, ...props }: React.ComponentProps<"div">) {
|
|
6
|
-
return (
|
|
7
|
-
<div
|
|
8
|
-
data-slot="card"
|
|
9
|
-
className={cn("bg-card text-card-foreground flex flex-col gap-4 rounded border", className)}
|
|
10
|
-
{...props}
|
|
11
|
-
/>
|
|
12
|
-
);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
16
|
-
return (
|
|
17
|
-
<div
|
|
18
|
-
data-slot="card-header"
|
|
19
|
-
className={cn(
|
|
20
|
-
"flex flex-col items-start justify-between gap-1 p-4 has-data-[slot=card-action]:grid has-data-[slot=card-action]:grid-cols-[1fr_auto]",
|
|
21
|
-
className,
|
|
22
|
-
)}
|
|
23
|
-
{...props}
|
|
24
|
-
/>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function CardTitle({ className, ...props }: React.ComponentProps<"h3">) {
|
|
29
|
-
return (
|
|
30
|
-
<h3 data-slot="card-title" className={cn("text-xl", className)} {...props}>
|
|
31
|
-
{props.children}
|
|
32
|
-
</h3>
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
|
|
37
|
-
return (
|
|
38
|
-
<div
|
|
39
|
-
data-slot="card-description"
|
|
40
|
-
className={cn("text-muted-foreground text-xs", className)}
|
|
41
|
-
{...props}
|
|
42
|
-
/>
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
|
|
47
|
-
return (
|
|
48
|
-
<div
|
|
49
|
-
data-slot="card-action"
|
|
50
|
-
className={cn("col-start-2 self-start justify-self-end", className)}
|
|
51
|
-
{...props}
|
|
52
|
-
/>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
57
|
-
return <div data-slot="card-content" className={cn("p-4", className)} {...props} />;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
61
|
-
return (
|
|
62
|
-
<div data-slot="card-footer" className={cn("flex items-center p-4", className)} {...props} />
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
|
|
3
|
-
import { SegmentedControl } from "./segmented-control";
|
|
4
|
-
|
|
5
|
-
const meta = {
|
|
6
|
-
title: "Primitives/SegmentedControl",
|
|
7
|
-
component: SegmentedControl,
|
|
8
|
-
tags: ["autodocs"],
|
|
9
|
-
} satisfies Meta<typeof SegmentedControl>;
|
|
10
|
-
|
|
11
|
-
export default meta;
|
|
12
|
-
type Story = StoryObj<typeof meta>;
|
|
13
|
-
|
|
14
|
-
export const Single: Story = {
|
|
15
|
-
args: {
|
|
16
|
-
label: "Layers",
|
|
17
|
-
options: [
|
|
18
|
-
{ value: "cameras", label: "Cameras" },
|
|
19
|
-
{ value: "places", label: "Places" },
|
|
20
|
-
],
|
|
21
|
-
},
|
|
22
|
-
render: () => (
|
|
23
|
-
<SegmentedControl
|
|
24
|
-
label="Layers"
|
|
25
|
-
defaultValue={["cameras"]}
|
|
26
|
-
options={[
|
|
27
|
-
{ value: "cameras", label: "Cameras" },
|
|
28
|
-
{ value: "places", label: "Places" },
|
|
29
|
-
]}
|
|
30
|
-
/>
|
|
31
|
-
),
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const Multiple: Story = {
|
|
35
|
-
args: {
|
|
36
|
-
label: "Layers",
|
|
37
|
-
options: [
|
|
38
|
-
{ value: "cameras", label: "Cameras" },
|
|
39
|
-
{ value: "places", label: "Places" },
|
|
40
|
-
],
|
|
41
|
-
},
|
|
42
|
-
render: () => (
|
|
43
|
-
<SegmentedControl
|
|
44
|
-
label="Layers"
|
|
45
|
-
multiple
|
|
46
|
-
defaultValue={["cameras", "places"]}
|
|
47
|
-
options={[
|
|
48
|
-
{ value: "cameras", label: "Cameras" },
|
|
49
|
-
{ value: "places", label: "Places" },
|
|
50
|
-
{ value: "trains", label: "Trains" },
|
|
51
|
-
]}
|
|
52
|
-
/>
|
|
53
|
-
),
|
|
54
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { ToggleGroup as SegmentedPrimitive } from "@base-ui/react/toggle-group";
|
|
4
|
-
import { Toggle as SegmentedItemPrimitive } from "@base-ui/react/toggle";
|
|
5
|
-
import * as React from "react";
|
|
6
|
-
|
|
7
|
-
import { cn } from "../../lib/utils";
|
|
8
|
-
|
|
9
|
-
export type SegmentedOption = {
|
|
10
|
-
value: string;
|
|
11
|
-
label: React.ReactNode;
|
|
12
|
-
ariaLabel?: string;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type SegmentedControlProps = {
|
|
16
|
-
options: SegmentedOption[];
|
|
17
|
-
/** Selected values. Single mode: pass at most one. */
|
|
18
|
-
value?: string[];
|
|
19
|
-
defaultValue?: string[];
|
|
20
|
-
onValueChange?: (value: string[]) => void;
|
|
21
|
-
/** @default false — single-select. True allows several pressed. */
|
|
22
|
-
multiple?: boolean;
|
|
23
|
-
/** Accessible name for the group. Falls back to joining option labels. */
|
|
24
|
-
label?: string;
|
|
25
|
-
className?: string;
|
|
26
|
-
itemClassName?: string;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// Pill-group single/multi toggle. Shape + pressed states are kit-owned;
|
|
30
|
-
// elevation and placement are app-owned via className.
|
|
31
|
-
export function SegmentedControl({
|
|
32
|
-
options,
|
|
33
|
-
value,
|
|
34
|
-
defaultValue,
|
|
35
|
-
onValueChange,
|
|
36
|
-
multiple = false,
|
|
37
|
-
label,
|
|
38
|
-
className,
|
|
39
|
-
itemClassName,
|
|
40
|
-
}: SegmentedControlProps) {
|
|
41
|
-
return (
|
|
42
|
-
<SegmentedPrimitive
|
|
43
|
-
data-slot="segmented-control"
|
|
44
|
-
aria-label={label ?? options.map((o) => o.ariaLabel ?? o.value).join(", ")}
|
|
45
|
-
multiple={multiple}
|
|
46
|
-
value={value}
|
|
47
|
-
defaultValue={defaultValue}
|
|
48
|
-
onValueChange={onValueChange}
|
|
49
|
-
className={cn(
|
|
50
|
-
"border-border bg-card inline-flex items-center gap-0.5 rounded-full border p-0.5",
|
|
51
|
-
className,
|
|
52
|
-
)}
|
|
53
|
-
>
|
|
54
|
-
{options.map((option) => (
|
|
55
|
-
<SegmentedItemPrimitive
|
|
56
|
-
key={option.value}
|
|
57
|
-
data-slot="segmented-control-item"
|
|
58
|
-
value={option.value}
|
|
59
|
-
aria-label={option.ariaLabel ?? (typeof option.label === "string" ? option.label : option.value)}
|
|
60
|
-
className={cn(
|
|
61
|
-
"text-muted-foreground hover:text-foreground rounded-full px-4 py-1.5 text-[11px] font-semibold tracking-wider whitespace-nowrap uppercase transition-colors",
|
|
62
|
-
"data-pressed:bg-foreground data-pressed:text-background",
|
|
63
|
-
"focus-visible:outline-ring focus-visible:outline-2 focus-visible:outline-offset-2",
|
|
64
|
-
"data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
65
|
-
itemClassName,
|
|
66
|
-
)}
|
|
67
|
-
>
|
|
68
|
-
{option.label}
|
|
69
|
-
</SegmentedItemPrimitive>
|
|
70
|
-
))}
|
|
71
|
-
</SegmentedPrimitive>
|
|
72
|
-
);
|
|
73
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
-
|
|
3
|
-
import { Separator } from "./separator";
|
|
4
|
-
|
|
5
|
-
const meta = {
|
|
6
|
-
title: "Primitives/Separator",
|
|
7
|
-
component: Separator,
|
|
8
|
-
tags: ["autodocs"],
|
|
9
|
-
} satisfies Meta<typeof Separator>;
|
|
10
|
-
|
|
11
|
-
export default meta;
|
|
12
|
-
type Story = StoryObj<typeof meta>;
|
|
13
|
-
|
|
14
|
-
export const Horizontal: Story = {
|
|
15
|
-
args: {},
|
|
16
|
-
render: () => (
|
|
17
|
-
<div className="w-64">
|
|
18
|
-
<p className="text-sm">Above</p>
|
|
19
|
-
<Separator className="my-2" />
|
|
20
|
-
<p className="text-sm">Below</p>
|
|
21
|
-
</div>
|
|
22
|
-
),
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const Vertical: Story = {
|
|
26
|
-
args: { orientation: "vertical" },
|
|
27
|
-
render: () => (
|
|
28
|
-
<div className="flex h-8 items-center gap-2">
|
|
29
|
-
<p className="text-sm">Left</p>
|
|
30
|
-
<Separator orientation="vertical" />
|
|
31
|
-
<p className="text-sm">Right</p>
|
|
32
|
-
</div>
|
|
33
|
-
),
|
|
34
|
-
};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { Separator as SeparatorPrimitive } from "@base-ui/react/separator";
|
|
4
|
-
import * as React from "react";
|
|
5
|
-
|
|
6
|
-
import { cn } from "../../lib/utils";
|
|
7
|
-
|
|
8
|
-
function Separator({
|
|
9
|
-
className,
|
|
10
|
-
orientation = "horizontal",
|
|
11
|
-
...props
|
|
12
|
-
}: React.ComponentProps<typeof SeparatorPrimitive>) {
|
|
13
|
-
return (
|
|
14
|
-
<SeparatorPrimitive
|
|
15
|
-
data-slot="separator"
|
|
16
|
-
orientation={orientation}
|
|
17
|
-
className={cn(
|
|
18
|
-
"bg-border shrink-0",
|
|
19
|
-
orientation === "horizontal" ? "h-px w-full" : "h-full w-px",
|
|
20
|
-
className,
|
|
21
|
-
)}
|
|
22
|
-
{...props}
|
|
23
|
-
/>
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export { Separator };
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Chart colors are CSS-variable-backed so they stay in sync with the active
|
|
3
|
-
* color system and mode at runtime.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export const CHART_COLORS = {
|
|
7
|
-
chart1: "var(--chart-1)",
|
|
8
|
-
chart2: "var(--chart-2)",
|
|
9
|
-
chart3: "var(--chart-3)",
|
|
10
|
-
chart4: "var(--chart-4)",
|
|
11
|
-
chart5: "var(--chart-5)",
|
|
12
|
-
|
|
13
|
-
positive: "var(--chart-positive)",
|
|
14
|
-
negative: "var(--chart-negative)",
|
|
15
|
-
neutral: "var(--chart-neutral)",
|
|
16
|
-
|
|
17
|
-
background: "var(--color-background)",
|
|
18
|
-
grid: "var(--color-border)",
|
|
19
|
-
|
|
20
|
-
axis: "var(--color-muted-foreground)",
|
|
21
|
-
label: "var(--color-muted-foreground)",
|
|
22
|
-
|
|
23
|
-
tooltip: {
|
|
24
|
-
background: "var(--color-card)",
|
|
25
|
-
text: "var(--color-foreground)",
|
|
26
|
-
border: "var(--color-border)",
|
|
27
|
-
},
|
|
28
|
-
} as const;
|
|
29
|
-
|
|
30
|
-
export const CHART_CSS_VARS = {
|
|
31
|
-
positive: "var(--chart-positive)",
|
|
32
|
-
negative: "var(--chart-negative)",
|
|
33
|
-
neutral: "var(--chart-neutral)",
|
|
34
|
-
chart1: "var(--chart-1)",
|
|
35
|
-
chart2: "var(--chart-2)",
|
|
36
|
-
chart3: "var(--chart-3)",
|
|
37
|
-
chart4: "var(--chart-4)",
|
|
38
|
-
chart5: "var(--chart-5)",
|
|
39
|
-
} as const;
|