@alpic-ai/ui 0.0.0-dev.g378c8b6 → 0.0.0-dev.g380fab7
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/dist/components/accordion-card.d.mts +5 -5
- package/dist/components/accordion.d.mts +5 -5
- package/dist/components/alert.d.mts +8 -8
- package/dist/components/area-chart.d.mts +62 -0
- package/dist/components/area-chart.mjs +269 -0
- package/dist/components/attachment-tile.d.mts +1 -1
- package/dist/components/avatar.d.mts +7 -7
- package/dist/components/badge.d.mts +1 -1
- package/dist/components/bar-chart.d.mts +48 -0
- package/dist/components/bar-chart.mjs +245 -0
- package/dist/components/bar-list.d.mts +28 -0
- package/dist/components/bar-list.mjs +98 -0
- package/dist/components/breadcrumb.d.mts +10 -10
- package/dist/components/button.d.mts +5 -5
- package/dist/components/card.d.mts +9 -9
- package/dist/components/chart-card.d.mts +25 -0
- package/dist/components/chart-card.mjs +48 -0
- package/dist/components/chart-container.d.mts +20 -0
- package/dist/components/chart-container.mjs +37 -0
- package/dist/components/chart-legend.d.mts +16 -0
- package/dist/components/chart-legend.mjs +26 -0
- package/dist/components/chart-tooltip.d.mts +33 -0
- package/dist/components/chart-tooltip.mjs +52 -0
- package/dist/components/checkbox.d.mts +2 -2
- package/dist/components/collapsible.d.mts +4 -4
- package/dist/components/combobox.d.mts +10 -10
- package/dist/components/command.d.mts +9 -9
- package/dist/components/copyable.d.mts +2 -2
- package/dist/components/description-list.d.mts +5 -5
- package/dist/components/dialog.d.mts +13 -13
- package/dist/components/donut-chart.d.mts +46 -0
- package/dist/components/donut-chart.mjs +185 -0
- package/dist/components/dropdown-menu.d.mts +17 -17
- package/dist/components/form.d.mts +18 -18
- package/dist/components/form.mjs +6 -6
- package/dist/components/github-button.d.mts +1 -1
- package/dist/components/grid-fx.d.mts +13 -0
- package/dist/components/grid-fx.mjs +188 -0
- package/dist/components/heatmap-chart.d.mts +40 -0
- package/dist/components/heatmap-chart.mjs +198 -0
- package/dist/components/input-group.d.mts +4 -4
- package/dist/components/input.d.mts +4 -4
- package/dist/components/input.mjs +2 -2
- package/dist/components/label.d.mts +2 -2
- package/dist/components/line-chart.d.mts +55 -0
- package/dist/components/line-chart.mjs +211 -0
- package/dist/components/page-loader.d.mts +1 -1
- package/dist/components/pagination.d.mts +3 -3
- package/dist/components/popover.d.mts +5 -5
- package/dist/components/radio-group.d.mts +3 -3
- package/dist/components/scroll-area.d.mts +3 -3
- package/dist/components/select.d.mts +9 -9
- package/dist/components/separator.d.mts +2 -2
- package/dist/components/sheet.d.mts +11 -11
- package/dist/components/shimmer-text.d.mts +3 -1
- package/dist/components/sidebar.d.mts +33 -33
- package/dist/components/sidebar.mjs +10 -10
- package/dist/components/skeleton.d.mts +1 -1
- package/dist/components/sonner.d.mts +5 -5
- package/dist/components/spinner.d.mts +2 -2
- package/dist/components/stat.d.mts +30 -0
- package/dist/components/stat.mjs +107 -0
- package/dist/components/status-dot.d.mts +1 -1
- package/dist/components/switch.d.mts +2 -2
- package/dist/components/table.d.mts +10 -10
- package/dist/components/tabs.d.mts +10 -10
- package/dist/components/tag.d.mts +3 -3
- package/dist/components/task-progress.d.mts +1 -1
- package/dist/components/textarea.d.mts +3 -3
- package/dist/components/textarea.mjs +2 -2
- package/dist/components/toggle-group.d.mts +3 -3
- package/dist/components/toggle-group.mjs +3 -3
- package/dist/components/tooltip.d.mts +5 -5
- package/dist/components/typography.d.mts +4 -4
- package/dist/components/wizard.d.mts +4 -4
- package/dist/hooks/use-chart-theme.d.mts +18 -0
- package/dist/hooks/use-chart-theme.mjs +57 -0
- package/dist/hooks/use-mobile.mjs +3 -3
- package/dist/hooks/use-reduced-motion.d.mts +4 -0
- package/dist/hooks/use-reduced-motion.mjs +16 -0
- package/dist/lib/chart-palette.d.mts +4 -0
- package/dist/lib/chart-palette.mjs +95 -0
- package/dist/lib/chart.d.mts +14 -0
- package/dist/lib/chart.mjs +27 -0
- package/package.json +30 -29
- package/src/components/area-chart.tsx +339 -0
- package/src/components/bar-chart.tsx +300 -0
- package/src/components/bar-list.tsx +150 -0
- package/src/components/chart-card.tsx +63 -0
- package/src/components/chart-container.tsx +49 -0
- package/src/components/chart-legend.tsx +41 -0
- package/src/components/chart-tooltip.tsx +93 -0
- package/src/components/donut-chart.tsx +217 -0
- package/src/components/grid-fx.tsx +238 -0
- package/src/components/heatmap-chart.tsx +287 -0
- package/src/components/line-chart.tsx +264 -0
- package/src/components/stat.tsx +109 -0
- package/src/hooks/use-chart-theme.ts +75 -0
- package/src/hooks/use-reduced-motion.ts +17 -0
- package/src/lib/chart-palette.ts +110 -0
- package/src/lib/chart.ts +56 -0
- package/src/stories/area-chart.stories.tsx +200 -0
- package/src/stories/bar-chart.stories.tsx +169 -0
- package/src/stories/bar-list.stories.tsx +85 -0
- package/src/stories/donut-chart.stories.tsx +112 -0
- package/src/stories/heatmap-chart.stories.tsx +107 -0
- package/src/stories/line-chart.stories.tsx +146 -0
- package/src/stories/stat.stories.tsx +64 -0
- package/src/styles/tokens.css +63 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/components/chart-tooltip.d.ts
|
|
2
|
+
interface ChartTooltipItem {
|
|
3
|
+
name?: string | number;
|
|
4
|
+
value?: number | string;
|
|
5
|
+
color?: string;
|
|
6
|
+
stroke?: string;
|
|
7
|
+
fill?: string;
|
|
8
|
+
dataKey?: string | number;
|
|
9
|
+
}
|
|
10
|
+
interface ChartTooltipContentProps {
|
|
11
|
+
active?: boolean;
|
|
12
|
+
payload?: ChartTooltipItem[];
|
|
13
|
+
label?: string | number;
|
|
14
|
+
valueFormatter?: (value: number) => string;
|
|
15
|
+
labelFormatter?: (label: string | number) => string;
|
|
16
|
+
hideLabel?: boolean;
|
|
17
|
+
showTotal?: boolean;
|
|
18
|
+
totalLabel?: string;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
declare function ChartTooltipContent({
|
|
22
|
+
active,
|
|
23
|
+
payload,
|
|
24
|
+
label,
|
|
25
|
+
valueFormatter,
|
|
26
|
+
labelFormatter,
|
|
27
|
+
hideLabel,
|
|
28
|
+
showTotal,
|
|
29
|
+
totalLabel,
|
|
30
|
+
className
|
|
31
|
+
}: ChartTooltipContentProps): import("react").JSX.Element | null;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { ChartTooltipContent, ChartTooltipContentProps, ChartTooltipItem };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.mjs";
|
|
3
|
+
import { useChartContext } from "./chart-container.mjs";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/chart-tooltip.tsx
|
|
6
|
+
function ChartTooltipContent({ active, payload, label, valueFormatter = (value) => value.toLocaleString("en-US"), labelFormatter, hideLabel, showTotal, totalLabel = "Total", className }) {
|
|
7
|
+
const { theme } = useChartContext();
|
|
8
|
+
if (!active || !payload?.length) return null;
|
|
9
|
+
const total = payload.reduce((sum, item) => sum + (typeof item.value === "number" ? item.value : Number(item.value ?? 0)), 0);
|
|
10
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
11
|
+
className: cn("min-w-[130px] rounded-lg border px-3 py-2.5 shadow-lg", "border-border bg-popover text-popover-foreground", className),
|
|
12
|
+
children: [!hideLabel && label !== void 0 && /* @__PURE__ */ jsx("p", {
|
|
13
|
+
className: "font-mono text-[10px] uppercase tracking-wider text-quaternary-foreground mb-1.5",
|
|
14
|
+
children: labelFormatter ? labelFormatter(label) : label
|
|
15
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
16
|
+
className: "flex flex-col gap-1",
|
|
17
|
+
children: [payload.map((item, index) => {
|
|
18
|
+
const swatch = [
|
|
19
|
+
item.color,
|
|
20
|
+
item.stroke,
|
|
21
|
+
item.fill
|
|
22
|
+
].find((candidate) => typeof candidate === "string" && candidate.length > 0 && !candidate.startsWith("url(")) ?? theme.mutedForeground;
|
|
23
|
+
const numeric = typeof item.value === "number" ? item.value : Number(item.value ?? 0);
|
|
24
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
25
|
+
className: "flex items-center justify-between gap-4 text-text-xs",
|
|
26
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
27
|
+
className: "inline-flex items-center gap-2 text-muted-foreground",
|
|
28
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
29
|
+
"aria-hidden": true,
|
|
30
|
+
className: "size-2 shrink-0 rounded-[2px]",
|
|
31
|
+
style: { background: swatch }
|
|
32
|
+
}), item.name]
|
|
33
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
34
|
+
className: "font-mono font-semibold tabular-nums text-foreground",
|
|
35
|
+
children: valueFormatter(numeric)
|
|
36
|
+
})]
|
|
37
|
+
}, `${item.dataKey ?? index}`);
|
|
38
|
+
}), showTotal && /* @__PURE__ */ jsxs("div", {
|
|
39
|
+
className: "mt-1 flex items-center justify-between gap-4 border-border border-t pt-1.5 text-text-xs",
|
|
40
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
41
|
+
className: "font-mono text-quaternary-foreground uppercase tracking-wider text-[10px]",
|
|
42
|
+
children: totalLabel
|
|
43
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
44
|
+
className: "font-mono font-semibold tabular-nums text-foreground",
|
|
45
|
+
children: valueFormatter(total)
|
|
46
|
+
})]
|
|
47
|
+
})]
|
|
48
|
+
})]
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { ChartTooltipContent };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as React from "react";
|
|
1
|
+
import * as React$1 from "react";
|
|
2
2
|
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
3
3
|
|
|
4
4
|
//#region src/components/checkbox.d.ts
|
|
5
5
|
declare function Checkbox({
|
|
6
6
|
className,
|
|
7
7
|
...props
|
|
8
|
-
}: React.ComponentProps<typeof CheckboxPrimitive.Root>):
|
|
8
|
+
}: React$1.ComponentProps<typeof CheckboxPrimitive.Root>): React$1.JSX.Element;
|
|
9
9
|
//#endregion
|
|
10
10
|
export { Checkbox };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import * as React from "react";
|
|
1
|
+
import * as React$1 from "react";
|
|
2
2
|
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
|
|
3
3
|
|
|
4
4
|
//#region src/components/collapsible.d.ts
|
|
5
5
|
declare function Collapsible({
|
|
6
6
|
...props
|
|
7
|
-
}: React.ComponentProps<typeof CollapsiblePrimitive.Root>):
|
|
7
|
+
}: React$1.ComponentProps<typeof CollapsiblePrimitive.Root>): React$1.JSX.Element;
|
|
8
8
|
declare function CollapsibleTrigger({
|
|
9
9
|
...props
|
|
10
|
-
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>):
|
|
10
|
+
}: React$1.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>): React$1.JSX.Element;
|
|
11
11
|
declare function CollapsibleContent({
|
|
12
12
|
...props
|
|
13
|
-
}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>):
|
|
13
|
+
}: React$1.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>): React$1.JSX.Element;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { Collapsible, CollapsibleContent, CollapsibleTrigger };
|
|
@@ -26,7 +26,7 @@ interface ComboboxMultipleProps extends ComboboxBaseProps {
|
|
|
26
26
|
onValueChange?: (value: string[]) => void;
|
|
27
27
|
}
|
|
28
28
|
type ComboboxProps = ComboboxSingleProps | ComboboxMultipleProps;
|
|
29
|
-
declare function Combobox(props: ComboboxProps): import("react
|
|
29
|
+
declare function Combobox(props: ComboboxProps): import("react").JSX.Element;
|
|
30
30
|
interface ComboboxTriggerProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "size">, VariantProps<typeof selectTriggerVariants> {
|
|
31
31
|
placeholder?: string;
|
|
32
32
|
}
|
|
@@ -36,7 +36,7 @@ declare function ComboboxTrigger({
|
|
|
36
36
|
placeholder,
|
|
37
37
|
children,
|
|
38
38
|
...props
|
|
39
|
-
}: ComboboxTriggerProps): import("react
|
|
39
|
+
}: ComboboxTriggerProps): import("react").JSX.Element;
|
|
40
40
|
interface ComboboxContentProps extends React.ComponentProps<typeof PopoverContent> {
|
|
41
41
|
className?: string;
|
|
42
42
|
children?: ReactNode;
|
|
@@ -47,27 +47,27 @@ declare function ComboboxContent({
|
|
|
47
47
|
children,
|
|
48
48
|
filter,
|
|
49
49
|
...props
|
|
50
|
-
}: ComboboxContentProps): import("react
|
|
50
|
+
}: ComboboxContentProps): import("react").JSX.Element;
|
|
51
51
|
declare function ComboboxSearch({
|
|
52
52
|
className,
|
|
53
53
|
...props
|
|
54
|
-
}: React.ComponentProps<typeof Command.Input>): import("react
|
|
54
|
+
}: React.ComponentProps<typeof Command.Input>): import("react").JSX.Element;
|
|
55
55
|
declare function ComboboxList({
|
|
56
56
|
className,
|
|
57
57
|
...props
|
|
58
|
-
}: React.ComponentProps<typeof Command.List>): import("react
|
|
58
|
+
}: React.ComponentProps<typeof Command.List>): import("react").JSX.Element;
|
|
59
59
|
declare function ComboboxEmpty({
|
|
60
60
|
className,
|
|
61
61
|
...props
|
|
62
|
-
}: React.ComponentProps<typeof Command.Empty>): import("react
|
|
62
|
+
}: React.ComponentProps<typeof Command.Empty>): import("react").JSX.Element;
|
|
63
63
|
declare function ComboboxGroup({
|
|
64
64
|
className,
|
|
65
65
|
...props
|
|
66
|
-
}: React.ComponentProps<typeof Command.Group>): import("react
|
|
66
|
+
}: React.ComponentProps<typeof Command.Group>): import("react").JSX.Element;
|
|
67
67
|
declare function ComboboxSeparator({
|
|
68
68
|
className,
|
|
69
69
|
...props
|
|
70
|
-
}: React.ComponentProps<typeof Command.Separator>): import("react
|
|
70
|
+
}: React.ComponentProps<typeof Command.Separator>): import("react").JSX.Element;
|
|
71
71
|
interface ComboboxItemProps extends Omit<React.ComponentProps<typeof Command.Item>, "onSelect"> {
|
|
72
72
|
/** The value stored when this item is selected */
|
|
73
73
|
itemValue: string;
|
|
@@ -77,11 +77,11 @@ declare function ComboboxItem({
|
|
|
77
77
|
children,
|
|
78
78
|
itemValue,
|
|
79
79
|
...props
|
|
80
|
-
}: ComboboxItemProps): import("react
|
|
80
|
+
}: ComboboxItemProps): import("react").JSX.Element;
|
|
81
81
|
declare function ComboboxItemText({
|
|
82
82
|
className,
|
|
83
83
|
children,
|
|
84
84
|
...props
|
|
85
|
-
}: React.HTMLAttributes<HTMLSpanElement>): import("react
|
|
85
|
+
}: React.HTMLAttributes<HTMLSpanElement>): import("react").JSX.Element;
|
|
86
86
|
//#endregion
|
|
87
87
|
export { Combobox, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxItem, ComboboxItemText, ComboboxList, ComboboxSearch, ComboboxSeparator, ComboboxTrigger };
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import * as React from "react";
|
|
1
|
+
import * as React$1 from "react";
|
|
2
2
|
import { Command as Command$1 } from "cmdk";
|
|
3
3
|
|
|
4
4
|
//#region src/components/command.d.ts
|
|
5
5
|
declare function Command({
|
|
6
6
|
className,
|
|
7
7
|
...props
|
|
8
|
-
}: React.ComponentProps<typeof Command$1>):
|
|
8
|
+
}: React$1.ComponentProps<typeof Command$1>): React$1.JSX.Element;
|
|
9
9
|
declare function CommandInput({
|
|
10
10
|
className,
|
|
11
11
|
...props
|
|
12
|
-
}: React.ComponentProps<typeof Command$1.Input>):
|
|
12
|
+
}: React$1.ComponentProps<typeof Command$1.Input>): React$1.JSX.Element;
|
|
13
13
|
declare function CommandList({
|
|
14
14
|
className,
|
|
15
15
|
...props
|
|
16
|
-
}: React.ComponentProps<typeof Command$1.List>):
|
|
16
|
+
}: React$1.ComponentProps<typeof Command$1.List>): React$1.JSX.Element;
|
|
17
17
|
declare function CommandEmpty({
|
|
18
18
|
...props
|
|
19
|
-
}: React.ComponentProps<typeof Command$1.Empty>):
|
|
19
|
+
}: React$1.ComponentProps<typeof Command$1.Empty>): React$1.JSX.Element;
|
|
20
20
|
declare function CommandGroup({
|
|
21
21
|
className,
|
|
22
22
|
...props
|
|
23
|
-
}: React.ComponentProps<typeof Command$1.Group>):
|
|
23
|
+
}: React$1.ComponentProps<typeof Command$1.Group>): React$1.JSX.Element;
|
|
24
24
|
declare function CommandSeparator({
|
|
25
25
|
className,
|
|
26
26
|
...props
|
|
27
|
-
}: React.ComponentProps<typeof Command$1.Separator>):
|
|
27
|
+
}: React$1.ComponentProps<typeof Command$1.Separator>): React$1.JSX.Element;
|
|
28
28
|
declare function CommandItem({
|
|
29
29
|
className,
|
|
30
30
|
...props
|
|
31
|
-
}: React.ComponentProps<typeof Command$1.Item>):
|
|
31
|
+
}: React$1.ComponentProps<typeof Command$1.Item>): React$1.JSX.Element;
|
|
32
32
|
declare function CommandShortcut({
|
|
33
33
|
className,
|
|
34
34
|
...props
|
|
35
|
-
}: React.ComponentProps<"span">):
|
|
35
|
+
}: React$1.ComponentProps<"span">): React$1.JSX.Element;
|
|
36
36
|
//#endregion
|
|
37
37
|
export { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut };
|
|
@@ -10,12 +10,12 @@ declare function Copyable({
|
|
|
10
10
|
content,
|
|
11
11
|
children,
|
|
12
12
|
className
|
|
13
|
-
}: CopyableProps): import("react
|
|
13
|
+
}: CopyableProps): import("react").JSX.Element;
|
|
14
14
|
interface CopyableUrlProps {
|
|
15
15
|
url: URL;
|
|
16
16
|
}
|
|
17
17
|
declare function CopyableUrl({
|
|
18
18
|
url
|
|
19
|
-
}: CopyableUrlProps): import("react
|
|
19
|
+
}: CopyableUrlProps): import("react").JSX.Element;
|
|
20
20
|
//#endregion
|
|
21
21
|
export { Copyable, type CopyableProps, CopyableUrl, type CopyableUrlProps };
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import * as React from "react";
|
|
1
|
+
import * as React$1 from "react";
|
|
2
2
|
|
|
3
3
|
//#region src/components/description-list.d.ts
|
|
4
4
|
declare function DescriptionList({
|
|
5
5
|
className,
|
|
6
6
|
...props
|
|
7
|
-
}: React.ComponentProps<"dl">):
|
|
7
|
+
}: React$1.ComponentProps<"dl">): React$1.JSX.Element;
|
|
8
8
|
declare function DescriptionItem({
|
|
9
9
|
className,
|
|
10
10
|
...props
|
|
11
|
-
}: React.ComponentProps<"div">):
|
|
11
|
+
}: React$1.ComponentProps<"div">): React$1.JSX.Element;
|
|
12
12
|
declare function DescriptionTitle({
|
|
13
13
|
className,
|
|
14
14
|
...props
|
|
15
|
-
}: React.ComponentProps<"dt">):
|
|
15
|
+
}: React$1.ComponentProps<"dt">): React$1.JSX.Element;
|
|
16
16
|
declare function DescriptionValue({
|
|
17
17
|
className,
|
|
18
18
|
...props
|
|
19
|
-
}: React.ComponentProps<"dd">):
|
|
19
|
+
}: React$1.ComponentProps<"dd">): React$1.JSX.Element;
|
|
20
20
|
//#endregion
|
|
21
21
|
export { DescriptionItem, DescriptionList, DescriptionTitle, DescriptionValue };
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import { ButtonProps } from "./button.mjs";
|
|
2
2
|
import { VariantProps } from "class-variance-authority";
|
|
3
|
-
import * as React from "react";
|
|
3
|
+
import * as React$1 from "react";
|
|
4
4
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
5
5
|
|
|
6
6
|
//#region src/components/dialog.d.ts
|
|
7
7
|
declare function Dialog({
|
|
8
8
|
...props
|
|
9
|
-
}: React.ComponentProps<typeof DialogPrimitive.Root>):
|
|
9
|
+
}: React$1.ComponentProps<typeof DialogPrimitive.Root>): React$1.JSX.Element;
|
|
10
10
|
declare function DialogTrigger({
|
|
11
11
|
...props
|
|
12
|
-
}: React.ComponentProps<typeof DialogPrimitive.Trigger>):
|
|
12
|
+
}: React$1.ComponentProps<typeof DialogPrimitive.Trigger>): React$1.JSX.Element;
|
|
13
13
|
declare function DialogPortal({
|
|
14
14
|
...props
|
|
15
|
-
}: React.ComponentProps<typeof DialogPrimitive.Portal>):
|
|
15
|
+
}: React$1.ComponentProps<typeof DialogPrimitive.Portal>): React$1.JSX.Element;
|
|
16
16
|
declare function DialogOverlay({
|
|
17
17
|
className,
|
|
18
18
|
...props
|
|
19
|
-
}: React.ComponentProps<typeof DialogPrimitive.Overlay>):
|
|
19
|
+
}: React$1.ComponentProps<typeof DialogPrimitive.Overlay>): React$1.JSX.Element;
|
|
20
20
|
declare const dialogContentVariants: (props?: ({
|
|
21
21
|
size?: "sm" | "lg" | null | undefined;
|
|
22
22
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
23
|
-
interface DialogContentProps extends React.ComponentProps<typeof DialogPrimitive.Content>, VariantProps<typeof dialogContentVariants> {
|
|
23
|
+
interface DialogContentProps extends React$1.ComponentProps<typeof DialogPrimitive.Content>, VariantProps<typeof dialogContentVariants> {
|
|
24
24
|
showCloseButton?: boolean;
|
|
25
25
|
}
|
|
26
26
|
declare function DialogContent({
|
|
@@ -29,31 +29,31 @@ declare function DialogContent({
|
|
|
29
29
|
size,
|
|
30
30
|
showCloseButton,
|
|
31
31
|
...props
|
|
32
|
-
}: DialogContentProps):
|
|
32
|
+
}: DialogContentProps): React$1.JSX.Element;
|
|
33
33
|
declare function DialogHeader({
|
|
34
34
|
className,
|
|
35
35
|
...props
|
|
36
|
-
}: React.ComponentProps<"div">):
|
|
36
|
+
}: React$1.ComponentProps<"div">): React$1.JSX.Element;
|
|
37
37
|
declare const dialogFooterVariants: (props?: ({
|
|
38
38
|
layout?: "horizontal" | "vertical" | null | undefined;
|
|
39
39
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
40
|
-
interface DialogFooterProps extends React.ComponentProps<"div">, VariantProps<typeof dialogFooterVariants> {}
|
|
40
|
+
interface DialogFooterProps extends React$1.ComponentProps<"div">, VariantProps<typeof dialogFooterVariants> {}
|
|
41
41
|
declare function DialogFooter({
|
|
42
42
|
className,
|
|
43
43
|
layout,
|
|
44
44
|
...props
|
|
45
|
-
}: DialogFooterProps):
|
|
45
|
+
}: DialogFooterProps): React$1.JSX.Element;
|
|
46
46
|
declare function DialogTitle({
|
|
47
47
|
className,
|
|
48
48
|
...props
|
|
49
|
-
}: React.ComponentProps<typeof DialogPrimitive.Title>):
|
|
49
|
+
}: React$1.ComponentProps<typeof DialogPrimitive.Title>): React$1.JSX.Element;
|
|
50
50
|
declare function DialogClose({
|
|
51
51
|
children,
|
|
52
52
|
...props
|
|
53
|
-
}: Omit<ButtonProps, "variant" | "asChild">):
|
|
53
|
+
}: Omit<ButtonProps, "variant" | "asChild">): React$1.JSX.Element;
|
|
54
54
|
declare function DialogDescription({
|
|
55
55
|
className,
|
|
56
56
|
...props
|
|
57
|
-
}: React.ComponentProps<typeof DialogPrimitive.Description>):
|
|
57
|
+
}: React$1.ComponentProps<typeof DialogPrimitive.Description>): React$1.JSX.Element;
|
|
58
58
|
//#endregion
|
|
59
59
|
export { Dialog, DialogClose, DialogContent, type DialogContentProps, DialogDescription, DialogFooter, type DialogFooterProps, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, dialogContentVariants, dialogFooterVariants };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ChartPaletteName } from "../lib/chart-palette.mjs";
|
|
2
|
+
import * as React$1 from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/components/donut-chart.d.ts
|
|
5
|
+
declare const GEOMETRY: {
|
|
6
|
+
readonly donut: {
|
|
7
|
+
readonly inner: "64%";
|
|
8
|
+
readonly outer: "92%";
|
|
9
|
+
};
|
|
10
|
+
readonly ring: {
|
|
11
|
+
readonly inner: "78%";
|
|
12
|
+
readonly outer: "92%";
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
interface DonutChartProps {
|
|
16
|
+
data: ReadonlyArray<Record<string, string | number | null | undefined>>;
|
|
17
|
+
index: string;
|
|
18
|
+
dataKey?: string;
|
|
19
|
+
variant?: keyof typeof GEOMETRY;
|
|
20
|
+
legend?: boolean;
|
|
21
|
+
paddingAngle?: number;
|
|
22
|
+
height?: number;
|
|
23
|
+
palette?: ChartPaletteName;
|
|
24
|
+
centerLabel?: string;
|
|
25
|
+
loading?: boolean;
|
|
26
|
+
valueFormatter?: (value: number) => string;
|
|
27
|
+
labelFormatter?: (label: string | number) => string;
|
|
28
|
+
className?: string;
|
|
29
|
+
}
|
|
30
|
+
declare function DonutChart({
|
|
31
|
+
data,
|
|
32
|
+
index,
|
|
33
|
+
dataKey,
|
|
34
|
+
variant,
|
|
35
|
+
legend,
|
|
36
|
+
paddingAngle,
|
|
37
|
+
height,
|
|
38
|
+
palette,
|
|
39
|
+
centerLabel,
|
|
40
|
+
loading,
|
|
41
|
+
valueFormatter,
|
|
42
|
+
labelFormatter,
|
|
43
|
+
className
|
|
44
|
+
}: DonutChartProps): React$1.JSX.Element;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { DonutChart, DonutChartProps };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.mjs";
|
|
3
|
+
import { useReducedMotion } from "../hooks/use-reduced-motion.mjs";
|
|
4
|
+
import { paletteColor } from "../lib/chart-palette.mjs";
|
|
5
|
+
import { formatShare } from "../lib/chart.mjs";
|
|
6
|
+
import { useChartContext } from "./chart-container.mjs";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import * as React$1 from "react";
|
|
9
|
+
import { Cell, Pie, PieChart, ResponsiveContainer } from "recharts";
|
|
10
|
+
//#region src/components/donut-chart.tsx
|
|
11
|
+
const GEOMETRY = {
|
|
12
|
+
donut: {
|
|
13
|
+
inner: "64%",
|
|
14
|
+
outer: "92%"
|
|
15
|
+
},
|
|
16
|
+
ring: {
|
|
17
|
+
inner: "78%",
|
|
18
|
+
outer: "92%"
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
function DonutChart({ data, index, dataKey = "value", variant = "donut", legend = false, paddingAngle = 1, height = 220, palette, centerLabel = "total", loading = false, valueFormatter = (value) => value.toLocaleString("en-US"), labelFormatter, className }) {
|
|
22
|
+
const { palette: paletteColors, theme } = useChartContext(palette);
|
|
23
|
+
const reactId = React$1.useId().replace(/:/g, "");
|
|
24
|
+
const animated = !useReducedMotion();
|
|
25
|
+
const [active, setActive] = React$1.useState(null);
|
|
26
|
+
const rowRefs = React$1.useRef([]);
|
|
27
|
+
const slices = React$1.useMemo(() => {
|
|
28
|
+
const mapped = data.map((row) => ({
|
|
29
|
+
name: String(row[index] ?? ""),
|
|
30
|
+
value: Number(row[dataKey]) || 0
|
|
31
|
+
}));
|
|
32
|
+
mapped.sort((lower, upper) => upper.value - lower.value);
|
|
33
|
+
return mapped.map((slice, rank) => ({
|
|
34
|
+
...slice,
|
|
35
|
+
color: paletteColor(paletteColors, rank)
|
|
36
|
+
}));
|
|
37
|
+
}, [
|
|
38
|
+
data,
|
|
39
|
+
index,
|
|
40
|
+
dataKey,
|
|
41
|
+
paletteColors
|
|
42
|
+
]);
|
|
43
|
+
const total = slices.reduce((sum, slice) => sum + slice.value, 0);
|
|
44
|
+
const maxValue = slices.reduce((max, slice) => slice.value > max ? slice.value : max, 0);
|
|
45
|
+
const geometry = GEOMETRY[variant] ?? GEOMETRY.donut;
|
|
46
|
+
const formatName = (name) => labelFormatter ? labelFormatter(name) : name;
|
|
47
|
+
const isEmpty = slices.length === 0 || total <= 0;
|
|
48
|
+
const activeSlice = active !== null ? slices[active] : void 0;
|
|
49
|
+
const centerTitle = activeSlice ? formatName(activeSlice.name) : centerLabel;
|
|
50
|
+
const centerValue = valueFormatter(activeSlice ? activeSlice.value : total);
|
|
51
|
+
React$1.useEffect(() => {
|
|
52
|
+
if (active !== null) rowRefs.current[active]?.scrollIntoView({ block: "nearest" });
|
|
53
|
+
}, [active]);
|
|
54
|
+
return /* @__PURE__ */ jsx("div", {
|
|
55
|
+
"data-slot": "donut-chart",
|
|
56
|
+
className: cn("@container flex w-full flex-col gap-3", className),
|
|
57
|
+
children: loading ? /* @__PURE__ */ jsxs("div", {
|
|
58
|
+
className: "flex items-center justify-center gap-2.5 font-mono text-quaternary-foreground text-text-xs",
|
|
59
|
+
style: { height },
|
|
60
|
+
children: [/* @__PURE__ */ jsx("span", { className: "size-4 animate-spin rounded-full border-2 border-border border-t-foreground" }), "loading…"]
|
|
61
|
+
}) : isEmpty ? /* @__PURE__ */ jsx("div", {
|
|
62
|
+
className: "flex items-center justify-center rounded-lg border border-border border-dashed font-mono text-quaternary-foreground text-text-xs",
|
|
63
|
+
style: { height },
|
|
64
|
+
children: "no data in range"
|
|
65
|
+
}) : /* @__PURE__ */ jsxs("div", {
|
|
66
|
+
className: "flex flex-col items-center gap-5 @md:flex-row",
|
|
67
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
68
|
+
className: "relative shrink-0",
|
|
69
|
+
style: {
|
|
70
|
+
width: height,
|
|
71
|
+
height
|
|
72
|
+
},
|
|
73
|
+
children: [/* @__PURE__ */ jsx(ResponsiveContainer, {
|
|
74
|
+
width: "100%",
|
|
75
|
+
height: "100%",
|
|
76
|
+
children: /* @__PURE__ */ jsxs(PieChart, { children: [/* @__PURE__ */ jsx("defs", { children: slices.map((slice, slot) => /* @__PURE__ */ jsxs("linearGradient", {
|
|
77
|
+
id: `donut-${reactId}-${slot}`,
|
|
78
|
+
x1: "0",
|
|
79
|
+
y1: "0",
|
|
80
|
+
x2: "0",
|
|
81
|
+
y2: "1",
|
|
82
|
+
children: [/* @__PURE__ */ jsx("stop", {
|
|
83
|
+
offset: "0%",
|
|
84
|
+
stopColor: slice.color,
|
|
85
|
+
stopOpacity: 1
|
|
86
|
+
}), /* @__PURE__ */ jsx("stop", {
|
|
87
|
+
offset: "100%",
|
|
88
|
+
stopColor: slice.color,
|
|
89
|
+
stopOpacity: .7
|
|
90
|
+
})]
|
|
91
|
+
}, slice.name)) }), /* @__PURE__ */ jsx(Pie, {
|
|
92
|
+
data: slices,
|
|
93
|
+
dataKey: "value",
|
|
94
|
+
nameKey: "name",
|
|
95
|
+
innerRadius: geometry.inner,
|
|
96
|
+
outerRadius: geometry.outer,
|
|
97
|
+
paddingAngle,
|
|
98
|
+
startAngle: 90,
|
|
99
|
+
endAngle: -270,
|
|
100
|
+
cornerRadius: 2,
|
|
101
|
+
stroke: theme.card,
|
|
102
|
+
strokeWidth: 1.5,
|
|
103
|
+
isAnimationActive: animated,
|
|
104
|
+
animationDuration: 650,
|
|
105
|
+
animationEasing: "ease-out",
|
|
106
|
+
onMouseEnter: (_entry, sliceIndex) => setActive(sliceIndex),
|
|
107
|
+
onMouseLeave: () => setActive(null),
|
|
108
|
+
children: slices.map((slice, slot) => /* @__PURE__ */ jsx(Cell, {
|
|
109
|
+
className: "motion-safe:[transition:fill-opacity_180ms_ease-out]",
|
|
110
|
+
fill: `url(#donut-${reactId}-${slot})`,
|
|
111
|
+
fillOpacity: active === null || active === slot ? 1 : .55,
|
|
112
|
+
stroke: theme.card,
|
|
113
|
+
strokeWidth: 1.5
|
|
114
|
+
}, slice.name))
|
|
115
|
+
})] })
|
|
116
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
117
|
+
className: "pointer-events-none absolute inset-0 flex flex-col items-center justify-center gap-1 text-center",
|
|
118
|
+
children: [
|
|
119
|
+
/* @__PURE__ */ jsx("span", {
|
|
120
|
+
className: "max-w-[72%] truncate font-mono text-[10px] text-quaternary-foreground uppercase tracking-[0.18em]",
|
|
121
|
+
children: centerTitle
|
|
122
|
+
}),
|
|
123
|
+
/* @__PURE__ */ jsx("span", {
|
|
124
|
+
className: "font-mono font-semibold text-[28px] text-foreground leading-none tabular-nums",
|
|
125
|
+
children: centerValue
|
|
126
|
+
}),
|
|
127
|
+
activeSlice && /* @__PURE__ */ jsx("span", {
|
|
128
|
+
className: "font-mono font-medium text-[11px] tabular-nums",
|
|
129
|
+
style: { color: activeSlice.color },
|
|
130
|
+
children: formatShare(activeSlice.value / total)
|
|
131
|
+
})
|
|
132
|
+
]
|
|
133
|
+
})]
|
|
134
|
+
}), legend && /* @__PURE__ */ jsx("div", {
|
|
135
|
+
"data-slot": "donut-readout",
|
|
136
|
+
className: "flex min-w-0 flex-1 flex-col overflow-y-auto pr-1",
|
|
137
|
+
style: { maxHeight: height },
|
|
138
|
+
children: slices.map((slice, slot) => /* @__PURE__ */ jsxs("div", {
|
|
139
|
+
ref: (node) => {
|
|
140
|
+
rowRefs.current[slot] = node;
|
|
141
|
+
},
|
|
142
|
+
onMouseEnter: () => setActive(slot),
|
|
143
|
+
onMouseLeave: () => setActive(null),
|
|
144
|
+
className: cn("flex flex-col gap-1.5 border-border/40 border-b px-2 py-2 text-text-xs last:border-b-0 motion-safe:transition-colors", active === slot ? "bg-muted/50" : "bg-transparent"),
|
|
145
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
146
|
+
className: "flex items-center justify-between gap-3",
|
|
147
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
148
|
+
className: "inline-flex min-w-0 items-center gap-2 text-muted-foreground",
|
|
149
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
150
|
+
"aria-hidden": true,
|
|
151
|
+
className: "h-2 w-2.5 shrink-0 rounded-[3px]",
|
|
152
|
+
style: { background: slice.color }
|
|
153
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
154
|
+
className: "truncate",
|
|
155
|
+
children: formatName(slice.name)
|
|
156
|
+
})]
|
|
157
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
158
|
+
className: "flex shrink-0 items-center gap-3 font-mono tabular-nums",
|
|
159
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
160
|
+
className: "min-w-[3.5rem] text-right font-semibold text-foreground",
|
|
161
|
+
children: valueFormatter(slice.value)
|
|
162
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
163
|
+
className: "w-10 text-right text-quaternary-foreground",
|
|
164
|
+
children: formatShare(slice.value / total)
|
|
165
|
+
})]
|
|
166
|
+
})]
|
|
167
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
168
|
+
"aria-hidden": true,
|
|
169
|
+
className: "relative block h-[2px] w-full overflow-hidden rounded-full bg-border/40",
|
|
170
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
171
|
+
className: "absolute inset-y-0 left-0 rounded-full motion-safe:transition-[width] motion-safe:duration-500",
|
|
172
|
+
style: {
|
|
173
|
+
width: `${maxValue > 0 ? slice.value / maxValue * 100 : 0}%`,
|
|
174
|
+
background: slice.color,
|
|
175
|
+
opacity: active === null || active === slot ? 1 : .45
|
|
176
|
+
}
|
|
177
|
+
})
|
|
178
|
+
})]
|
|
179
|
+
}, slice.name))
|
|
180
|
+
})]
|
|
181
|
+
})
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
//#endregion
|
|
185
|
+
export { DonutChart };
|