@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.
Files changed (109) hide show
  1. package/dist/components/accordion-card.d.mts +5 -5
  2. package/dist/components/accordion.d.mts +5 -5
  3. package/dist/components/alert.d.mts +8 -8
  4. package/dist/components/area-chart.d.mts +62 -0
  5. package/dist/components/area-chart.mjs +269 -0
  6. package/dist/components/attachment-tile.d.mts +1 -1
  7. package/dist/components/avatar.d.mts +7 -7
  8. package/dist/components/badge.d.mts +1 -1
  9. package/dist/components/bar-chart.d.mts +48 -0
  10. package/dist/components/bar-chart.mjs +245 -0
  11. package/dist/components/bar-list.d.mts +28 -0
  12. package/dist/components/bar-list.mjs +98 -0
  13. package/dist/components/breadcrumb.d.mts +10 -10
  14. package/dist/components/button.d.mts +5 -5
  15. package/dist/components/card.d.mts +9 -9
  16. package/dist/components/chart-card.d.mts +25 -0
  17. package/dist/components/chart-card.mjs +48 -0
  18. package/dist/components/chart-container.d.mts +20 -0
  19. package/dist/components/chart-container.mjs +37 -0
  20. package/dist/components/chart-legend.d.mts +16 -0
  21. package/dist/components/chart-legend.mjs +26 -0
  22. package/dist/components/chart-tooltip.d.mts +33 -0
  23. package/dist/components/chart-tooltip.mjs +52 -0
  24. package/dist/components/checkbox.d.mts +2 -2
  25. package/dist/components/collapsible.d.mts +4 -4
  26. package/dist/components/combobox.d.mts +10 -10
  27. package/dist/components/command.d.mts +9 -9
  28. package/dist/components/copyable.d.mts +2 -2
  29. package/dist/components/description-list.d.mts +5 -5
  30. package/dist/components/dialog.d.mts +13 -13
  31. package/dist/components/donut-chart.d.mts +46 -0
  32. package/dist/components/donut-chart.mjs +185 -0
  33. package/dist/components/dropdown-menu.d.mts +17 -17
  34. package/dist/components/form.d.mts +18 -18
  35. package/dist/components/form.mjs +6 -6
  36. package/dist/components/github-button.d.mts +1 -1
  37. package/dist/components/grid-fx.d.mts +13 -0
  38. package/dist/components/grid-fx.mjs +188 -0
  39. package/dist/components/heatmap-chart.d.mts +40 -0
  40. package/dist/components/heatmap-chart.mjs +198 -0
  41. package/dist/components/input-group.d.mts +4 -4
  42. package/dist/components/input.d.mts +4 -4
  43. package/dist/components/input.mjs +2 -2
  44. package/dist/components/label.d.mts +2 -2
  45. package/dist/components/line-chart.d.mts +55 -0
  46. package/dist/components/line-chart.mjs +211 -0
  47. package/dist/components/page-loader.d.mts +1 -1
  48. package/dist/components/pagination.d.mts +3 -3
  49. package/dist/components/popover.d.mts +5 -5
  50. package/dist/components/radio-group.d.mts +3 -3
  51. package/dist/components/scroll-area.d.mts +3 -3
  52. package/dist/components/select.d.mts +9 -9
  53. package/dist/components/separator.d.mts +2 -2
  54. package/dist/components/sheet.d.mts +11 -11
  55. package/dist/components/shimmer-text.d.mts +3 -1
  56. package/dist/components/sidebar.d.mts +33 -33
  57. package/dist/components/sidebar.mjs +10 -10
  58. package/dist/components/skeleton.d.mts +1 -1
  59. package/dist/components/sonner.d.mts +5 -5
  60. package/dist/components/spinner.d.mts +2 -2
  61. package/dist/components/stat.d.mts +30 -0
  62. package/dist/components/stat.mjs +107 -0
  63. package/dist/components/status-dot.d.mts +1 -1
  64. package/dist/components/switch.d.mts +2 -2
  65. package/dist/components/table.d.mts +10 -10
  66. package/dist/components/tabs.d.mts +10 -10
  67. package/dist/components/tag.d.mts +3 -3
  68. package/dist/components/task-progress.d.mts +1 -1
  69. package/dist/components/textarea.d.mts +3 -3
  70. package/dist/components/textarea.mjs +2 -2
  71. package/dist/components/toggle-group.d.mts +3 -3
  72. package/dist/components/toggle-group.mjs +3 -3
  73. package/dist/components/tooltip.d.mts +5 -5
  74. package/dist/components/typography.d.mts +4 -4
  75. package/dist/components/wizard.d.mts +4 -4
  76. package/dist/hooks/use-chart-theme.d.mts +18 -0
  77. package/dist/hooks/use-chart-theme.mjs +57 -0
  78. package/dist/hooks/use-mobile.mjs +3 -3
  79. package/dist/hooks/use-reduced-motion.d.mts +4 -0
  80. package/dist/hooks/use-reduced-motion.mjs +16 -0
  81. package/dist/lib/chart-palette.d.mts +4 -0
  82. package/dist/lib/chart-palette.mjs +95 -0
  83. package/dist/lib/chart.d.mts +14 -0
  84. package/dist/lib/chart.mjs +27 -0
  85. package/package.json +30 -29
  86. package/src/components/area-chart.tsx +339 -0
  87. package/src/components/bar-chart.tsx +300 -0
  88. package/src/components/bar-list.tsx +150 -0
  89. package/src/components/chart-card.tsx +63 -0
  90. package/src/components/chart-container.tsx +49 -0
  91. package/src/components/chart-legend.tsx +41 -0
  92. package/src/components/chart-tooltip.tsx +93 -0
  93. package/src/components/donut-chart.tsx +217 -0
  94. package/src/components/grid-fx.tsx +238 -0
  95. package/src/components/heatmap-chart.tsx +287 -0
  96. package/src/components/line-chart.tsx +264 -0
  97. package/src/components/stat.tsx +109 -0
  98. package/src/hooks/use-chart-theme.ts +75 -0
  99. package/src/hooks/use-reduced-motion.ts +17 -0
  100. package/src/lib/chart-palette.ts +110 -0
  101. package/src/lib/chart.ts +56 -0
  102. package/src/stories/area-chart.stories.tsx +200 -0
  103. package/src/stories/bar-chart.stories.tsx +169 -0
  104. package/src/stories/bar-list.stories.tsx +85 -0
  105. package/src/stories/donut-chart.stories.tsx +112 -0
  106. package/src/stories/heatmap-chart.stories.tsx +107 -0
  107. package/src/stories/line-chart.stories.tsx +146 -0
  108. package/src/stories/stat.stories.tsx +64 -0
  109. 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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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">): import("react/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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/jsx-runtime").JSX.Element;
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">): import("react/jsx-runtime").JSX.Element;
7
+ }: React$1.ComponentProps<"dl">): React$1.JSX.Element;
8
8
  declare function DescriptionItem({
9
9
  className,
10
10
  ...props
11
- }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
11
+ }: React$1.ComponentProps<"div">): React$1.JSX.Element;
12
12
  declare function DescriptionTitle({
13
13
  className,
14
14
  ...props
15
- }: React.ComponentProps<"dt">): import("react/jsx-runtime").JSX.Element;
15
+ }: React$1.ComponentProps<"dt">): React$1.JSX.Element;
16
16
  declare function DescriptionValue({
17
17
  className,
18
18
  ...props
19
- }: React.ComponentProps<"dd">): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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): import("react/jsx-runtime").JSX.Element;
32
+ }: DialogContentProps): React$1.JSX.Element;
33
33
  declare function DialogHeader({
34
34
  className,
35
35
  ...props
36
- }: React.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
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): import("react/jsx-runtime").JSX.Element;
45
+ }: DialogFooterProps): React$1.JSX.Element;
46
46
  declare function DialogTitle({
47
47
  className,
48
48
  ...props
49
- }: React.ComponentProps<typeof DialogPrimitive.Title>): import("react/jsx-runtime").JSX.Element;
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">): import("react/jsx-runtime").JSX.Element;
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>): import("react/jsx-runtime").JSX.Element;
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 };