@codefast/ui 0.3.16-canary.2 → 0.4.0-canary.4
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/CHANGELOG.md +81 -0
- package/README.md +28 -17
- package/dist/components/accordion.d.mts +7 -22
- package/dist/components/accordion.mjs +26 -29
- package/dist/components/alert-dialog.d.mts +27 -26
- package/dist/components/alert-dialog.mjs +53 -45
- package/dist/components/alert.d.mts +14 -14
- package/dist/components/alert.mjs +17 -28
- package/dist/components/aspect-ratio.d.mts +2 -2
- package/dist/components/aspect-ratio.mjs +2 -3
- package/dist/components/avatar.d.mts +41 -5
- package/dist/components/avatar.mjs +40 -10
- package/dist/components/badge.d.mts +3 -15
- package/dist/components/badge.mjs +6 -48
- package/dist/components/breadcrumb.d.mts +1 -0
- package/dist/components/breadcrumb.mjs +11 -10
- package/dist/components/button-group.d.mts +3 -13
- package/dist/components/button-group.mjs +9 -31
- package/dist/components/button.d.mts +3 -26
- package/dist/components/button.mjs +9 -79
- package/dist/components/calendar.d.mts +6 -2
- package/dist/components/calendar.mjs +41 -44
- package/dist/components/card.d.mts +4 -2
- package/dist/components/card.mjs +9 -9
- package/dist/components/carousel.d.mts +16 -5
- package/dist/components/carousel.mjs +24 -11
- package/dist/components/chart.d.mts +9 -6
- package/dist/components/chart.mjs +21 -15
- package/dist/components/checkbox-cards.mjs +4 -4
- package/dist/components/checkbox-group.mjs +3 -4
- package/dist/components/checkbox.d.mts +2 -2
- package/dist/components/checkbox.mjs +6 -7
- package/dist/components/collapsible.d.mts +4 -4
- package/dist/components/collapsible.mjs +4 -5
- package/dist/components/command.d.mts +11 -1
- package/dist/components/command.mjs +35 -32
- package/dist/components/context-menu.d.mts +22 -15
- package/dist/components/context-menu.mjs +44 -39
- package/dist/components/dialog.d.mts +19 -23
- package/dist/components/dialog.mjs +48 -47
- package/dist/components/direction.d.mts +24 -0
- package/dist/components/direction.mjs +18 -0
- package/dist/components/drawer.d.mts +3 -21
- package/dist/components/drawer.mjs +19 -27
- package/dist/components/dropdown-menu.d.mts +22 -15
- package/dist/components/dropdown-menu.mjs +41 -37
- package/dist/components/empty.d.mts +3 -13
- package/dist/components/empty.mjs +8 -23
- package/dist/components/field.d.mts +3 -14
- package/dist/components/field.mjs +14 -44
- package/dist/components/form.d.mts +7 -10
- package/dist/components/form.mjs +6 -7
- package/dist/components/hover-card.d.mts +5 -5
- package/dist/components/hover-card.mjs +14 -12
- package/dist/components/input-group.d.mts +4 -31
- package/dist/components/input-group.mjs +14 -96
- package/dist/components/input-number.d.mts +3 -1
- package/dist/components/input-number.mjs +50 -28
- package/dist/components/input-otp.mjs +9 -7
- package/dist/components/input-password.mjs +1 -4
- package/dist/components/input-search.mjs +3 -5
- package/dist/components/input.mjs +1 -2
- package/dist/components/item.d.mts +4 -29
- package/dist/components/item.mjs +12 -65
- package/dist/components/kbd.mjs +1 -1
- package/dist/components/label.d.mts +2 -2
- package/dist/components/label.mjs +3 -4
- package/dist/components/menubar.d.mts +22 -16
- package/dist/components/menubar.mjs +54 -47
- package/dist/components/native-select.d.mts +5 -1
- package/dist/components/native-select.mjs +9 -6
- package/dist/components/navigation-menu.d.mts +30 -13
- package/dist/components/navigation-menu.mjs +35 -32
- package/dist/components/pagination.d.mts +7 -1
- package/dist/components/pagination.mjs +27 -12
- package/dist/components/popover.d.mts +40 -7
- package/dist/components/popover.mjs +46 -14
- package/dist/components/progress-circle.d.mts +3 -47
- package/dist/components/progress-circle.mjs +2 -48
- package/dist/components/progress.d.mts +2 -2
- package/dist/components/progress.mjs +5 -6
- package/dist/components/radio-cards.d.mts +3 -3
- package/dist/components/radio-cards.mjs +11 -11
- package/dist/components/radio-group.d.mts +3 -3
- package/dist/components/radio-group.mjs +9 -9
- package/dist/components/radio.mjs +2 -3
- package/dist/components/resizable.mjs +3 -8
- package/dist/components/scroll-area.d.mts +8 -24
- package/dist/components/scroll-area.mjs +16 -70
- package/dist/components/select.d.mts +14 -14
- package/dist/components/select.mjs +47 -47
- package/dist/components/separator.d.mts +4 -19
- package/dist/components/separator.mjs +6 -27
- package/dist/components/sheet.d.mts +18 -31
- package/dist/components/sheet.mjs +46 -87
- package/dist/components/sidebar.d.mts +3 -19
- package/dist/components/sidebar.mjs +48 -84
- package/dist/components/skeleton.mjs +1 -1
- package/dist/components/slider.d.mts +2 -2
- package/dist/components/slider.mjs +9 -11
- package/dist/components/sonner.mjs +11 -3
- package/dist/components/spinner.mjs +6 -7
- package/dist/components/switch.d.mts +5 -2
- package/dist/components/switch.mjs +7 -7
- package/dist/components/table.mjs +10 -10
- package/dist/components/tabs.d.mts +8 -5
- package/dist/components/tabs.mjs +18 -12
- package/dist/components/textarea.mjs +1 -1
- package/dist/components/toggle-group.d.mts +11 -7
- package/dist/components/toggle-group.mjs +20 -21
- package/dist/components/toggle.d.mts +4 -24
- package/dist/components/toggle.mjs +6 -45
- package/dist/components/tooltip.d.mts +7 -6
- package/dist/components/tooltip.mjs +19 -17
- package/dist/hooks/use-animated-value.mjs +0 -1
- package/dist/hooks/use-copy-to-clipboard.mjs +0 -1
- package/dist/hooks/use-is-mobile.mjs +0 -1
- package/dist/hooks/use-media-query.mjs +0 -1
- package/dist/hooks/use-mutation-observer.mjs +0 -1
- package/dist/hooks/use-pagination.mjs +0 -1
- package/dist/index.d.mts +38 -21
- package/dist/index.mjs +40 -23
- package/dist/lib/utils.d.mts +1 -12
- package/dist/lib/utils.mjs +1 -9
- package/dist/primitives/checkbox-group.d.mts +9 -11
- package/dist/primitives/checkbox-group.mjs +14 -19
- package/dist/primitives/input-number.d.mts +3 -4
- package/dist/primitives/input-number.mjs +3 -5
- package/dist/primitives/input.d.mts +4 -5
- package/dist/primitives/input.mjs +2 -3
- package/dist/primitives/progress-circle.d.mts +3 -4
- package/dist/primitives/progress-circle.mjs +2 -3
- package/dist/variants/alert.d.mts +18 -0
- package/dist/variants/alert.mjs +15 -0
- package/dist/variants/badge.d.mts +22 -0
- package/dist/variants/badge.mjs +19 -0
- package/dist/variants/button-group.d.mts +18 -0
- package/dist/variants/button-group.mjs +15 -0
- package/dist/variants/button.d.mts +32 -0
- package/dist/variants/button.mjs +34 -0
- package/dist/variants/empty.d.mts +18 -0
- package/dist/variants/empty.mjs +15 -0
- package/dist/variants/field.d.mts +19 -0
- package/dist/variants/field.mjs +16 -0
- package/dist/variants/input-group.d.mts +43 -0
- package/dist/variants/input-group.mjs +34 -0
- package/dist/variants/input-number.d.mts +45 -0
- package/dist/variants/input-number.mjs +40 -0
- package/dist/variants/item.d.mts +38 -0
- package/dist/variants/item.mjs +38 -0
- package/dist/variants/navigation-menu.d.mts +13 -0
- package/dist/variants/navigation-menu.mjs +8 -0
- package/dist/variants/progress-circle.d.mts +52 -0
- package/dist/variants/progress-circle.mjs +45 -0
- package/dist/variants/scroll-area.d.mts +24 -0
- package/dist/variants/scroll-area.mjs +58 -0
- package/dist/variants/separator.d.mts +23 -0
- package/dist/variants/separator.mjs +25 -0
- package/dist/variants/sheet.d.mts +20 -0
- package/dist/variants/sheet.mjs +17 -0
- package/dist/variants/sidebar.d.mts +23 -0
- package/dist/variants/sidebar.mjs +25 -0
- package/dist/variants/tabs.d.mts +18 -0
- package/dist/variants/tabs.mjs +15 -0
- package/dist/variants/toggle.d.mts +23 -0
- package/dist/variants/toggle.mjs +25 -0
- package/package.json +186 -55
- package/src/components/accordion.tsx +114 -0
- package/src/components/alert-dialog.tsx +298 -0
- package/src/components/alert.tsx +94 -0
- package/src/components/aspect-ratio.tsx +25 -0
- package/src/components/avatar.tsx +171 -0
- package/src/components/badge.tsx +35 -0
- package/src/components/breadcrumb.tsx +191 -0
- package/src/components/button-group.tsx +97 -0
- package/src/components/button.tsx +55 -0
- package/src/components/calendar.tsx +222 -0
- package/src/components/card.tsx +169 -0
- package/src/components/carousel.tsx +349 -0
- package/src/components/chart.tsx +536 -0
- package/src/components/checkbox-cards.tsx +72 -0
- package/src/components/checkbox-group.tsx +60 -0
- package/src/components/checkbox.tsx +44 -0
- package/src/components/collapsible.tsx +57 -0
- package/src/components/command.tsx +298 -0
- package/src/components/context-menu.tsx +410 -0
- package/src/components/dialog.tsx +243 -0
- package/src/components/direction.tsx +32 -0
- package/src/components/drawer.tsx +209 -0
- package/src/components/dropdown-menu.tsx +419 -0
- package/src/components/empty.tsx +155 -0
- package/src/components/field.tsx +329 -0
- package/src/components/form.tsx +258 -0
- package/src/components/hover-card.tsx +93 -0
- package/src/components/input-group.tsx +185 -0
- package/src/components/input-number.tsx +141 -0
- package/src/components/input-otp.tsx +132 -0
- package/src/components/input-password.tsx +50 -0
- package/src/components/input-search.tsx +81 -0
- package/src/components/input.tsx +36 -0
- package/src/components/item.tsx +266 -0
- package/src/components/kbd.tsx +47 -0
- package/src/components/label.tsx +36 -0
- package/src/components/menubar.tsx +440 -0
- package/src/components/native-select.tsx +87 -0
- package/src/components/navigation-menu.tsx +235 -0
- package/src/components/pagination.tsx +198 -0
- package/src/components/popover.tsx +170 -0
- package/src/components/progress-circle.tsx +185 -0
- package/src/components/progress.tsx +41 -0
- package/src/components/radio-cards.tsx +66 -0
- package/src/components/radio-group.tsx +59 -0
- package/src/components/radio.tsx +40 -0
- package/src/components/resizable.tsx +78 -0
- package/src/components/scroll-area.tsx +95 -0
- package/src/components/select.tsx +296 -0
- package/src/components/separator.tsx +60 -0
- package/src/components/sheet.tsx +241 -0
- package/src/components/sidebar.tsx +926 -0
- package/src/components/skeleton.tsx +35 -0
- package/src/components/slider.tsx +66 -0
- package/src/components/sonner.tsx +57 -0
- package/src/components/spinner.tsx +66 -0
- package/src/components/switch.tsx +44 -0
- package/src/components/table.tsx +183 -0
- package/src/components/tabs.tsx +110 -0
- package/src/components/textarea.tsx +35 -0
- package/src/components/toggle-group.tsx +137 -0
- package/src/components/toggle.tsx +30 -0
- package/src/components/tooltip.tsx +115 -0
- package/src/css/foundation/base.css +50 -0
- package/src/css/foundation/motion.css +36 -0
- package/src/css/foundation/source.css +3 -0
- package/src/css/foundation/tokens.css +71 -0
- package/src/css/foundation/variants.css +113 -0
- package/src/css/preset.css +5 -195
- package/src/css/style.css +1 -1
- package/src/css/{amber.css → themes/amber.css} +59 -22
- package/src/css/{blue.css → themes/blue.css} +59 -22
- package/src/css/{cyan.css → themes/cyan.css} +59 -22
- package/src/css/{emerald.css → themes/emerald.css} +59 -22
- package/src/css/{fuchsia.css → themes/fuchsia.css} +59 -22
- package/src/css/{gray.css → themes/gray.css} +59 -22
- package/src/css/{green.css → themes/green.css} +59 -22
- package/src/css/{indigo.css → themes/indigo.css} +59 -22
- package/src/css/{lime.css → themes/lime.css} +59 -22
- package/src/css/{neutral.css → themes/neutral.css} +59 -22
- package/src/css/{orange.css → themes/orange.css} +59 -22
- package/src/css/{pink.css → themes/pink.css} +59 -22
- package/src/css/{purple.css → themes/purple.css} +59 -22
- package/src/css/{red.css → themes/red.css} +59 -22
- package/src/css/{rose.css → themes/rose.css} +59 -22
- package/src/css/{sky.css → themes/sky.css} +59 -22
- package/src/css/{slate.css → themes/slate.css} +59 -22
- package/src/css/{stone.css → themes/stone.css} +59 -22
- package/src/css/{teal.css → themes/teal.css} +59 -22
- package/src/css/{violet.css → themes/violet.css} +59 -22
- package/src/css/{yellow.css → themes/yellow.css} +59 -22
- package/src/css/{zinc.css → themes/zinc.css} +59 -22
- package/src/hooks/use-animated-value.ts +91 -0
- package/src/hooks/use-copy-to-clipboard.ts +58 -0
- package/src/hooks/use-is-mobile.ts +25 -0
- package/src/hooks/use-media-query.ts +69 -0
- package/src/hooks/use-mutation-observer.ts +51 -0
- package/src/hooks/use-pagination.ts +164 -0
- package/src/index.ts +679 -0
- package/src/lib/utils.ts +5 -0
- package/src/primitives/checkbox-group.tsx +346 -0
- package/src/primitives/input-number.tsx +967 -0
- package/src/primitives/input.tsx +227 -0
- package/src/primitives/progress-circle.tsx +507 -0
- package/src/variants/alert.ts +34 -0
- package/src/variants/badge.ts +39 -0
- package/src/variants/button-group.ts +36 -0
- package/src/variants/button.ts +56 -0
- package/src/variants/empty.ts +34 -0
- package/src/variants/field.ts +37 -0
- package/src/variants/input-group.ts +80 -0
- package/src/variants/input-number.ts +65 -0
- package/src/variants/item.ts +68 -0
- package/src/variants/navigation-menu.ts +25 -0
- package/src/variants/progress-circle.ts +46 -0
- package/src/variants/scroll-area.ts +73 -0
- package/src/variants/separator.ts +40 -0
- package/src/variants/sheet.ts +37 -0
- package/src/variants/sidebar.ts +41 -0
- package/src/variants/tabs.ts +34 -0
- package/src/variants/toggle.ts +40 -0
- package/dist/node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/clsx.d.mts +0 -6
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
import { Context } from "radix-ui/internal";
|
|
2
|
+
import type { ComponentProps, ComponentType, CSSProperties, JSX, ReactNode } from "react";
|
|
3
|
+
import { useId, useMemo } from "react";
|
|
4
|
+
import type { TooltipContentProps, TooltipProps } from "recharts";
|
|
5
|
+
import * as RechartsPrimitive from "recharts";
|
|
6
|
+
import type { NameType, Payload, ValueType } from "recharts/types/component/DefaultTooltipContent";
|
|
7
|
+
|
|
8
|
+
import { cn } from "#/lib/utils";
|
|
9
|
+
|
|
10
|
+
/* -----------------------------------------------------------------------------
|
|
11
|
+
* Type Definitions and Utilities
|
|
12
|
+
* -------------------------------------------------------------------------- */
|
|
13
|
+
|
|
14
|
+
type ExtractProps<T> = T extends (props: infer P) => ReactNode ? P : never;
|
|
15
|
+
|
|
16
|
+
type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
17
|
+
|
|
18
|
+
/* -----------------------------------------------------------------------------
|
|
19
|
+
* Chart Configuration and Theme Constants
|
|
20
|
+
* --------------------------------------------------------------------------- */
|
|
21
|
+
|
|
22
|
+
const THEMES = { dark: ".dark", light: "" } as const;
|
|
23
|
+
|
|
24
|
+
const INITIAL_DIMENSION = { height: 200, width: 320 } as const;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @since 0.3.16-canary.0
|
|
28
|
+
*/
|
|
29
|
+
type ChartConfig = Record<
|
|
30
|
+
string,
|
|
31
|
+
{
|
|
32
|
+
label?: ReactNode;
|
|
33
|
+
icon?: ComponentType;
|
|
34
|
+
} & ({ color?: never; theme: Record<keyof typeof THEMES, string> } | { color?: string; theme?: never })
|
|
35
|
+
>;
|
|
36
|
+
|
|
37
|
+
/* -----------------------------------------------------------------------------
|
|
38
|
+
* Context: ChartProvider
|
|
39
|
+
* --------------------------------------------------------------------------- */
|
|
40
|
+
|
|
41
|
+
const CHART_PROVIDER_NAME = "ChartProvider";
|
|
42
|
+
|
|
43
|
+
type ScopedProps<P> = P & { __scopeChart?: Context.Scope };
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Value provided by Chart Context
|
|
47
|
+
*/
|
|
48
|
+
interface ChartContextValue {
|
|
49
|
+
/**
|
|
50
|
+
* Display configuration for the chart
|
|
51
|
+
*/
|
|
52
|
+
config: ChartConfig;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const [createChartContext, createChartScope] = Context.createContextScope(CHART_PROVIDER_NAME);
|
|
56
|
+
|
|
57
|
+
const [ChartContextProvider, useChartContext] = createChartContext<ChartContextValue>(CHART_PROVIDER_NAME);
|
|
58
|
+
|
|
59
|
+
/* -----------------------------------------------------------------------------
|
|
60
|
+
* Component: Chart
|
|
61
|
+
* -------------------------------------------------------------------------- */
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @since 0.3.16-canary.0
|
|
65
|
+
*/
|
|
66
|
+
interface ChartContainerProps extends ComponentProps<"div"> {
|
|
67
|
+
children: ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>["children"];
|
|
68
|
+
config: ChartConfig;
|
|
69
|
+
initialDimension?: {
|
|
70
|
+
height: number;
|
|
71
|
+
width: number;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @since 0.3.16-canary.0
|
|
77
|
+
*/
|
|
78
|
+
function ChartContainer({
|
|
79
|
+
__scopeChart,
|
|
80
|
+
children,
|
|
81
|
+
className,
|
|
82
|
+
config,
|
|
83
|
+
id,
|
|
84
|
+
initialDimension = INITIAL_DIMENSION,
|
|
85
|
+
...props
|
|
86
|
+
}: ScopedProps<ChartContainerProps>): JSX.Element {
|
|
87
|
+
const uniqueId = useId();
|
|
88
|
+
const chartId = `chart-${id ?? uniqueId.replace(/:/g, "")}`;
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<ChartContextProvider config={config} scope={__scopeChart}>
|
|
92
|
+
<div
|
|
93
|
+
className={cn(
|
|
94
|
+
"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
|
|
95
|
+
className,
|
|
96
|
+
)}
|
|
97
|
+
data-chart={chartId}
|
|
98
|
+
data-slot="chart"
|
|
99
|
+
{...props}
|
|
100
|
+
>
|
|
101
|
+
<ChartStyle config={config} id={chartId} />
|
|
102
|
+
<RechartsPrimitive.ResponsiveContainer initialDimension={initialDimension}>
|
|
103
|
+
{children}
|
|
104
|
+
</RechartsPrimitive.ResponsiveContainer>
|
|
105
|
+
</div>
|
|
106
|
+
</ChartContextProvider>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* -----------------------------------------------------------------------------
|
|
111
|
+
* Component: ChartStyle
|
|
112
|
+
* -------------------------------------------------------------------------- */
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @since 0.3.16-canary.0
|
|
116
|
+
*/
|
|
117
|
+
interface ChartStyleProps {
|
|
118
|
+
config: ChartConfig;
|
|
119
|
+
id: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @since 0.3.16-canary.0
|
|
124
|
+
*/
|
|
125
|
+
function ChartStyle({ config, id }: ChartStyleProps): ReactNode {
|
|
126
|
+
const colorConfig = Object.entries(config).filter(([, itemConfig]) => itemConfig.theme ?? itemConfig.color);
|
|
127
|
+
|
|
128
|
+
if (colorConfig.length === 0) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<style
|
|
134
|
+
dangerouslySetInnerHTML={{
|
|
135
|
+
__html: generateChartStyles(id, colorConfig),
|
|
136
|
+
}}
|
|
137
|
+
/>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* -----------------------------------------------------------------------------
|
|
142
|
+
* Component: ChartTooltip
|
|
143
|
+
* -------------------------------------------------------------------------- */
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* @since 0.3.16-canary.0
|
|
147
|
+
*/
|
|
148
|
+
type ChartTooltipProps<TValue extends ValueType, TName extends NameType> = TooltipProps<TValue, TName>;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @since 0.3.16-canary.0
|
|
152
|
+
*/
|
|
153
|
+
const ChartTooltip = RechartsPrimitive.Tooltip;
|
|
154
|
+
|
|
155
|
+
/* -----------------------------------------------------------------------------
|
|
156
|
+
* Component: ChartTooltipContent
|
|
157
|
+
* -------------------------------------------------------------------------- */
|
|
158
|
+
|
|
159
|
+
const CHART_TOOLTIP_CONTENT_NAME = "ChartTooltipContent";
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @since 0.3.16-canary.0
|
|
163
|
+
*/
|
|
164
|
+
type ChartTooltipContentProps<TValue extends ValueType, TName extends NameType> = Omit<
|
|
165
|
+
MakeOptional<
|
|
166
|
+
TooltipContentProps<TValue, TName>,
|
|
167
|
+
"accessibilityLayer" | "active" | "activeIndex" | "coordinate" | "payload"
|
|
168
|
+
>,
|
|
169
|
+
"payload"
|
|
170
|
+
> & {
|
|
171
|
+
hideIndicator?: boolean;
|
|
172
|
+
hideLabel?: boolean;
|
|
173
|
+
indicator?: "dashed" | "dot" | "line";
|
|
174
|
+
labelKey?: string;
|
|
175
|
+
nameKey?: string;
|
|
176
|
+
color?: string | undefined;
|
|
177
|
+
className?: string | undefined;
|
|
178
|
+
payload?: Array<Payload<TValue, TName>>;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @since 0.3.16-canary.0
|
|
183
|
+
*/
|
|
184
|
+
function ChartTooltipContent<TValue extends ValueType, TName extends NameType>({
|
|
185
|
+
__scopeChart,
|
|
186
|
+
active,
|
|
187
|
+
className,
|
|
188
|
+
color,
|
|
189
|
+
formatter,
|
|
190
|
+
hideIndicator = false,
|
|
191
|
+
hideLabel = false,
|
|
192
|
+
indicator = "dot",
|
|
193
|
+
label,
|
|
194
|
+
labelClassName,
|
|
195
|
+
labelFormatter,
|
|
196
|
+
labelKey,
|
|
197
|
+
nameKey,
|
|
198
|
+
payload = [],
|
|
199
|
+
}: ScopedProps<ChartTooltipContentProps<TValue, TName>>): ReactNode {
|
|
200
|
+
const { config } = useChartContext(CHART_TOOLTIP_CONTENT_NAME, __scopeChart);
|
|
201
|
+
|
|
202
|
+
const tooltipLabel = useMemo((): ReactNode => {
|
|
203
|
+
if (hideLabel || payload.length === 0) {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const item = payload[0];
|
|
208
|
+
if (item === undefined) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
const key = safeToString(labelKey ?? item.dataKey ?? item.name ?? "value");
|
|
212
|
+
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
213
|
+
const configEntry = typeof label === "string" && label in config ? config[label] : undefined;
|
|
214
|
+
const value =
|
|
215
|
+
!labelKey && typeof label === "string"
|
|
216
|
+
? configEntry !== undefined
|
|
217
|
+
? (configEntry.label ?? label)
|
|
218
|
+
: label
|
|
219
|
+
: itemConfig?.label;
|
|
220
|
+
|
|
221
|
+
if (labelFormatter) {
|
|
222
|
+
return <div className={cn("font-medium", labelClassName)}>{labelFormatter(value, payload)}</div>;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (!value) {
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return <div className={cn("font-medium", labelClassName)}>{value}</div>;
|
|
230
|
+
}, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);
|
|
231
|
+
|
|
232
|
+
if (!active || payload.length === 0) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const nestLabel = payload.length === 1 && indicator !== "dot";
|
|
237
|
+
|
|
238
|
+
return (
|
|
239
|
+
<div
|
|
240
|
+
className={cn(
|
|
241
|
+
"grid min-w-32 items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
|
|
242
|
+
className,
|
|
243
|
+
)}
|
|
244
|
+
>
|
|
245
|
+
{nestLabel ? null : tooltipLabel}
|
|
246
|
+
<div className="grid gap-1.5">
|
|
247
|
+
{payload.map((item, index) => {
|
|
248
|
+
const key = safeToString(nameKey ?? item.name ?? item.dataKey ?? "value");
|
|
249
|
+
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
250
|
+
const indicatorColor =
|
|
251
|
+
color ??
|
|
252
|
+
(isRecord(item.payload) && "fill" in item.payload && typeof item.payload.fill === "string"
|
|
253
|
+
? item.payload.fill
|
|
254
|
+
: undefined) ??
|
|
255
|
+
item.color;
|
|
256
|
+
|
|
257
|
+
return (
|
|
258
|
+
<div
|
|
259
|
+
key={key}
|
|
260
|
+
className={cn(
|
|
261
|
+
"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
|
|
262
|
+
indicator === "dot" && "items-center",
|
|
263
|
+
)}
|
|
264
|
+
>
|
|
265
|
+
{formatter && item.value !== undefined && item.name ? (
|
|
266
|
+
formatter(item.value, item.name, item, index, [item])
|
|
267
|
+
) : (
|
|
268
|
+
<>
|
|
269
|
+
{itemConfig?.icon ? (
|
|
270
|
+
<itemConfig.icon />
|
|
271
|
+
) : (
|
|
272
|
+
!hideIndicator && (
|
|
273
|
+
<div
|
|
274
|
+
className={cn("shrink-0 rounded-xs border-(--color-border) bg-(--color-bg)", {
|
|
275
|
+
"h-2.5 w-2.5": indicator === "dot",
|
|
276
|
+
"my-0.5": nestLabel && indicator === "dashed",
|
|
277
|
+
"w-0 border-[1.5px] border-dashed bg-transparent": indicator === "dashed",
|
|
278
|
+
"w-1": indicator === "line",
|
|
279
|
+
})}
|
|
280
|
+
style={
|
|
281
|
+
{
|
|
282
|
+
"--color-bg": indicatorColor,
|
|
283
|
+
"--color-border": indicatorColor,
|
|
284
|
+
} as CSSProperties
|
|
285
|
+
}
|
|
286
|
+
/>
|
|
287
|
+
)
|
|
288
|
+
)}
|
|
289
|
+
<div
|
|
290
|
+
className={cn("flex flex-1 justify-between leading-none", nestLabel ? "items-end" : "items-center")}
|
|
291
|
+
>
|
|
292
|
+
<div className="grid gap-1.5">
|
|
293
|
+
{nestLabel ? tooltipLabel : null}
|
|
294
|
+
<span className="text-muted-foreground">{itemConfig?.label ?? item.name}</span>
|
|
295
|
+
</div>
|
|
296
|
+
{item.value != null && (
|
|
297
|
+
<span className="font-mono font-medium text-foreground tabular-nums">
|
|
298
|
+
{typeof item.value === "number" ? item.value.toLocaleString() : safeToString(item.value)}
|
|
299
|
+
</span>
|
|
300
|
+
)}
|
|
301
|
+
</div>
|
|
302
|
+
</>
|
|
303
|
+
)}
|
|
304
|
+
</div>
|
|
305
|
+
);
|
|
306
|
+
})}
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/* -----------------------------------------------------------------------------
|
|
313
|
+
* Component: ChartLegend
|
|
314
|
+
* -------------------------------------------------------------------------- */
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* @since 0.3.16-canary.0
|
|
318
|
+
*/
|
|
319
|
+
type ChartLegendProps = ComponentProps<typeof RechartsPrimitive.Legend>;
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* @since 0.3.16-canary.0
|
|
323
|
+
*/
|
|
324
|
+
const ChartLegend: typeof RechartsPrimitive.Legend = RechartsPrimitive.Legend;
|
|
325
|
+
|
|
326
|
+
/* -----------------------------------------------------------------------------
|
|
327
|
+
* Component: ChartLegendContent
|
|
328
|
+
* -------------------------------------------------------------------------- */
|
|
329
|
+
|
|
330
|
+
const CHART_LEGEND_CONTENT_NAME = "ChartLegendContent";
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* @since 0.3.16-canary.0
|
|
334
|
+
*/
|
|
335
|
+
type ChartLegendContentProps = ComponentProps<"div"> &
|
|
336
|
+
ExtractProps<RechartsPrimitive.LegendProps["content"]> & {
|
|
337
|
+
hideIcon?: boolean;
|
|
338
|
+
nameKey?: string;
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* @since 0.3.16-canary.0
|
|
343
|
+
*/
|
|
344
|
+
function ChartLegendContent({
|
|
345
|
+
__scopeChart,
|
|
346
|
+
className,
|
|
347
|
+
hideIcon = false,
|
|
348
|
+
nameKey,
|
|
349
|
+
payload,
|
|
350
|
+
verticalAlign = "bottom",
|
|
351
|
+
}: ScopedProps<ChartLegendContentProps>): ReactNode {
|
|
352
|
+
const { config } = useChartContext(CHART_LEGEND_CONTENT_NAME, __scopeChart);
|
|
353
|
+
|
|
354
|
+
if (!payload?.length) {
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return (
|
|
359
|
+
<div className={cn("flex items-center justify-center gap-4", verticalAlign === "top" ? "pb-3" : "pt-3", className)}>
|
|
360
|
+
{payload.map((item) => {
|
|
361
|
+
let key = "value";
|
|
362
|
+
|
|
363
|
+
if (nameKey) {
|
|
364
|
+
key = nameKey;
|
|
365
|
+
} else if (item.dataKey != null) {
|
|
366
|
+
key = safeToString(item.dataKey);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const itemConfig = getPayloadConfigFromPayload(config, item, key);
|
|
370
|
+
|
|
371
|
+
return (
|
|
372
|
+
<div
|
|
373
|
+
key={nameKey ? safeToString(itemConfig?.color ?? "") : safeToString(item.value ?? "")}
|
|
374
|
+
className="flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"
|
|
375
|
+
>
|
|
376
|
+
{itemConfig?.icon && !hideIcon ? (
|
|
377
|
+
<itemConfig.icon />
|
|
378
|
+
) : (
|
|
379
|
+
<div
|
|
380
|
+
className="h-2 w-2 shrink-0 rounded-xs"
|
|
381
|
+
style={{
|
|
382
|
+
backgroundColor: item.color,
|
|
383
|
+
}}
|
|
384
|
+
/>
|
|
385
|
+
)}
|
|
386
|
+
{itemConfig?.label}
|
|
387
|
+
</div>
|
|
388
|
+
);
|
|
389
|
+
})}
|
|
390
|
+
</div>
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/* -----------------------------------------------------------------------------
|
|
395
|
+
* Helpers
|
|
396
|
+
* -------------------------------------------------------------------------- */
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Type guard to check if an unknown value is a record with string keys
|
|
400
|
+
*/
|
|
401
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
402
|
+
return typeof value === "object" && value !== null;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Safely gets a string value from a record by key
|
|
407
|
+
*/
|
|
408
|
+
function getStringValue(record: Record<string, unknown>, key: string): string | undefined {
|
|
409
|
+
if (key in record) {
|
|
410
|
+
const value = record[key];
|
|
411
|
+
|
|
412
|
+
return typeof value === "string" ? value : undefined;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
return undefined;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Safely converts a value to string without type coercion
|
|
420
|
+
*/
|
|
421
|
+
function safeToString(value: unknown): string {
|
|
422
|
+
if (typeof value === "string") {
|
|
423
|
+
return value;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (typeof value === "number") {
|
|
427
|
+
return value.toString();
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (value === null || value === undefined) {
|
|
431
|
+
return "";
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (typeof value === "boolean") {
|
|
435
|
+
return value.toString();
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (typeof value === "bigint") {
|
|
439
|
+
return value.toString();
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (typeof value === "symbol") {
|
|
443
|
+
return value.toString();
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// For objects, arrays, functions, and other complex types, return empty string to avoid [object Object]
|
|
447
|
+
return "";
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
function getPayloadConfigFromPayload(
|
|
451
|
+
config: ChartConfig,
|
|
452
|
+
payload: unknown,
|
|
453
|
+
key: string,
|
|
454
|
+
): ChartConfig[string] | undefined {
|
|
455
|
+
if (!isRecord(payload)) {
|
|
456
|
+
return undefined;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
const payloadPayload = isRecord(payload.payload) ? payload.payload : undefined;
|
|
460
|
+
let configLabelKey: string = key;
|
|
461
|
+
|
|
462
|
+
// Try to get the config key from the payload first
|
|
463
|
+
const payloadValue = getStringValue(payload, key);
|
|
464
|
+
|
|
465
|
+
if (payloadValue) {
|
|
466
|
+
configLabelKey = payloadValue;
|
|
467
|
+
} else if (payloadPayload) {
|
|
468
|
+
// If not found in the payload, try the nested payload
|
|
469
|
+
const nestedValue = getStringValue(payloadPayload, key);
|
|
470
|
+
|
|
471
|
+
if (nestedValue) {
|
|
472
|
+
configLabelKey = nestedValue;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return configLabelKey in config ? config[configLabelKey] : config[key];
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Generates CSS custom property for a specific theme and config item
|
|
481
|
+
*/
|
|
482
|
+
function generateCssVariable(key: string, itemConfig: ChartConfig[string], theme: string): null | string {
|
|
483
|
+
const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ?? itemConfig.color;
|
|
484
|
+
|
|
485
|
+
return color ? ` --color-${key}: ${color};` : null;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* Generates CSS rules for a specific theme
|
|
490
|
+
*/
|
|
491
|
+
function generateThemeStyles(
|
|
492
|
+
theme: string,
|
|
493
|
+
prefix: string,
|
|
494
|
+
id: string,
|
|
495
|
+
colorConfig: Array<[string, ChartConfig[string]]>,
|
|
496
|
+
): string {
|
|
497
|
+
const cssVariables = colorConfig
|
|
498
|
+
.map(([key, itemConfig]) => generateCssVariable(key, itemConfig, theme))
|
|
499
|
+
.filter(Boolean)
|
|
500
|
+
.join("\n");
|
|
501
|
+
|
|
502
|
+
return `${prefix} [data-chart=${id}] {\n${cssVariables}\n}`;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Generates complete CSS styles for all themes
|
|
507
|
+
*/
|
|
508
|
+
function generateChartStyles(id: string, colorConfig: Array<[string, ChartConfig[string]]>): string {
|
|
509
|
+
return Object.entries(THEMES)
|
|
510
|
+
.map(([theme, prefix]) => generateThemeStyles(theme, prefix, id, colorConfig))
|
|
511
|
+
.join("\n\n");
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/* -----------------------------------------------------------------------------
|
|
515
|
+
* Exports
|
|
516
|
+
* -------------------------------------------------------------------------- */
|
|
517
|
+
|
|
518
|
+
export type {
|
|
519
|
+
ChartConfig,
|
|
520
|
+
ChartContainerProps,
|
|
521
|
+
ChartLegendContentProps,
|
|
522
|
+
ChartLegendProps,
|
|
523
|
+
ChartStyleProps,
|
|
524
|
+
ChartTooltipContentProps,
|
|
525
|
+
ChartTooltipProps,
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
export {
|
|
529
|
+
ChartContainer,
|
|
530
|
+
ChartLegend,
|
|
531
|
+
ChartLegendContent,
|
|
532
|
+
ChartStyle,
|
|
533
|
+
ChartTooltip,
|
|
534
|
+
ChartTooltipContent,
|
|
535
|
+
createChartScope,
|
|
536
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { CheckIcon } from "lucide-react";
|
|
2
|
+
import type { ComponentProps, JSX } from "react";
|
|
3
|
+
|
|
4
|
+
import { Label } from "#/components/label";
|
|
5
|
+
import { cn } from "#/lib/utils";
|
|
6
|
+
import * as CheckboxGroupPrimitive from "#/primitives/checkbox-group";
|
|
7
|
+
|
|
8
|
+
/* -----------------------------------------------------------------------------
|
|
9
|
+
* Component: CheckboxCards
|
|
10
|
+
* -------------------------------------------------------------------------- */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @since 0.3.16-canary.0
|
|
14
|
+
*/
|
|
15
|
+
type CheckboxCardsProps = ComponentProps<typeof CheckboxGroupPrimitive.Root>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @since 0.3.16-canary.0
|
|
19
|
+
*/
|
|
20
|
+
function CheckboxCards(props: CheckboxCardsProps): JSX.Element {
|
|
21
|
+
return <CheckboxGroupPrimitive.Root data-slot="checkbox-cards" {...props} />;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* -----------------------------------------------------------------------------
|
|
25
|
+
* Component: CheckboxCardsItem
|
|
26
|
+
* -------------------------------------------------------------------------- */
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @since 0.3.16-canary.0
|
|
30
|
+
*/
|
|
31
|
+
interface CheckboxCardsItemProps extends ComponentProps<typeof CheckboxGroupPrimitive.Item> {
|
|
32
|
+
checkboxClassName?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @since 0.3.16-canary.0
|
|
37
|
+
*/
|
|
38
|
+
function CheckboxCardsItem({ checkboxClassName, children, className, ...props }: CheckboxCardsItemProps): JSX.Element {
|
|
39
|
+
return (
|
|
40
|
+
<Label
|
|
41
|
+
className={cn(
|
|
42
|
+
"flex items-start gap-3 rounded-md border border-input p-3 transition has-focus-visible:border-ring has-disabled:opacity-50 has-data-checked:border-primary/30 has-data-checked:bg-primary/5",
|
|
43
|
+
className,
|
|
44
|
+
)}
|
|
45
|
+
data-slot="checkbox-card"
|
|
46
|
+
>
|
|
47
|
+
<CheckboxGroupPrimitive.Item
|
|
48
|
+
className={cn(
|
|
49
|
+
"peer relative flex size-4 shrink-0 items-center justify-center rounded-sm border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",
|
|
50
|
+
checkboxClassName,
|
|
51
|
+
)}
|
|
52
|
+
data-slot="checkbox-card-item"
|
|
53
|
+
{...props}
|
|
54
|
+
>
|
|
55
|
+
<CheckboxGroupPrimitive.CheckboxGroupIndicator
|
|
56
|
+
className="grid place-content-center text-current transition-none [&>svg]:size-3.5"
|
|
57
|
+
data-slot="checkbox-card-indicator"
|
|
58
|
+
>
|
|
59
|
+
<CheckIcon />
|
|
60
|
+
</CheckboxGroupPrimitive.CheckboxGroupIndicator>
|
|
61
|
+
</CheckboxGroupPrimitive.Item>
|
|
62
|
+
{children}
|
|
63
|
+
</Label>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* -----------------------------------------------------------------------------
|
|
68
|
+
* Exports
|
|
69
|
+
* -------------------------------------------------------------------------- */
|
|
70
|
+
|
|
71
|
+
export { CheckboxCards, CheckboxCardsItem };
|
|
72
|
+
export type { CheckboxCardsItemProps, CheckboxCardsProps };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { CheckIcon } from "lucide-react";
|
|
2
|
+
import type { ComponentProps, JSX } from "react";
|
|
3
|
+
|
|
4
|
+
import { cn } from "#/lib/utils";
|
|
5
|
+
import * as CheckboxGroupPrimitive from "#/primitives/checkbox-group";
|
|
6
|
+
|
|
7
|
+
/* -----------------------------------------------------------------------------
|
|
8
|
+
* Component: CheckboxGroup
|
|
9
|
+
* -------------------------------------------------------------------------- */
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @since 0.3.16-canary.0
|
|
13
|
+
*/
|
|
14
|
+
type CheckboxGroupProps = ComponentProps<typeof CheckboxGroupPrimitive.Root>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @since 0.3.16-canary.0
|
|
18
|
+
*/
|
|
19
|
+
function CheckboxGroup({ className, ...props }: CheckboxGroupProps): JSX.Element {
|
|
20
|
+
return <CheckboxGroupPrimitive.Root className={cn("grid gap-2", className)} data-slot="checkbox-group" {...props} />;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/* -----------------------------------------------------------------------------
|
|
24
|
+
* Component: CheckboxGroupItem
|
|
25
|
+
* -------------------------------------------------------------------------- */
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @since 0.3.16-canary.0
|
|
29
|
+
*/
|
|
30
|
+
type CheckboxGroupItemProps = ComponentProps<typeof CheckboxGroupPrimitive.Item>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @since 0.3.16-canary.0
|
|
34
|
+
*/
|
|
35
|
+
function CheckboxGroupItem({ className, ...props }: CheckboxGroupItemProps): JSX.Element {
|
|
36
|
+
return (
|
|
37
|
+
<CheckboxGroupPrimitive.Item
|
|
38
|
+
className={cn(
|
|
39
|
+
"peer relative flex size-4 shrink-0 items-center justify-center rounded-sm border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",
|
|
40
|
+
className,
|
|
41
|
+
)}
|
|
42
|
+
data-slot="checkbox-group-item"
|
|
43
|
+
{...props}
|
|
44
|
+
>
|
|
45
|
+
<CheckboxGroupPrimitive.CheckboxGroupIndicator
|
|
46
|
+
className="grid place-content-center text-current transition-none [&>svg]:size-3.5"
|
|
47
|
+
data-slot="checkbox-group-indicator"
|
|
48
|
+
>
|
|
49
|
+
<CheckIcon />
|
|
50
|
+
</CheckboxGroupPrimitive.CheckboxGroupIndicator>
|
|
51
|
+
</CheckboxGroupPrimitive.Item>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* -----------------------------------------------------------------------------
|
|
56
|
+
* Exports
|
|
57
|
+
* -------------------------------------------------------------------------- */
|
|
58
|
+
|
|
59
|
+
export { CheckboxGroup, CheckboxGroupItem };
|
|
60
|
+
export type { CheckboxGroupItemProps, CheckboxGroupProps };
|