@alpic-ai/ui 0.0.0-staging.08782cb → 0.0.0-staging.09784ec

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 (41) hide show
  1. package/dist/components/avatar.d.mts +1 -1
  2. package/dist/components/button.d.mts +3 -1
  3. package/dist/components/button.mjs +20 -6
  4. package/dist/components/form.d.mts +36 -1
  5. package/dist/components/form.mjs +111 -1
  6. package/dist/components/github-button.d.mts +13 -0
  7. package/dist/components/github-button.mjs +24 -0
  8. package/dist/components/page-loader.d.mts +11 -0
  9. package/dist/components/page-loader.mjs +122 -0
  10. package/dist/components/shimmer-text.d.mts +12 -0
  11. package/dist/components/shimmer-text.mjs +22 -0
  12. package/dist/components/sidebar.mjs +39 -10
  13. package/dist/components/spinner.d.mts +1 -1
  14. package/dist/components/table.d.mts +10 -1
  15. package/dist/components/table.mjs +4 -4
  16. package/dist/components/tabs.mjs +4 -4
  17. package/dist/components/task-progress.d.mts +27 -0
  18. package/dist/components/task-progress.mjs +66 -0
  19. package/dist/components/wizard.d.mts +34 -0
  20. package/dist/components/wizard.mjs +46 -0
  21. package/package.json +13 -13
  22. package/src/components/button.tsx +13 -9
  23. package/src/components/combobox.tsx +18 -6
  24. package/src/components/form.tsx +161 -0
  25. package/src/components/github-button.tsx +34 -0
  26. package/src/components/page-loader.tsx +59 -0
  27. package/src/components/shimmer-text.tsx +23 -0
  28. package/src/components/sidebar.tsx +48 -10
  29. package/src/components/table.tsx +17 -4
  30. package/src/components/tabs.tsx +4 -4
  31. package/src/components/task-progress.tsx +107 -0
  32. package/src/components/wizard.tsx +69 -0
  33. package/src/hooks/use-copy-to-clipboard.ts +6 -2
  34. package/src/stories/button.stories.tsx +23 -1
  35. package/src/stories/form.stories.tsx +64 -2
  36. package/src/stories/sidebar.stories.tsx +6 -3
  37. package/src/stories/table.stories.tsx +2 -2
  38. package/src/stories/tabs.stories.tsx +4 -2
  39. package/src/stories/task-progress.stories.tsx +81 -0
  40. package/src/stories/wizard.stories.tsx +64 -0
  41. package/src/styles/tokens.css +193 -4
@@ -6,7 +6,7 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
6
6
 
7
7
  //#region src/components/avatar.d.ts
8
8
  declare const avatarVariants: (props?: ({
9
- size?: "sm" | "lg" | "xs" | "md" | "xl" | null | undefined;
9
+ size?: "xs" | "sm" | "md" | "lg" | "xl" | null | undefined;
10
10
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
11
11
  type AvatarSize = NonNullable<VariantProps<typeof avatarVariants>["size"]>;
12
12
  type AvatarStatus = "online";
@@ -5,13 +5,14 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
5
5
 
6
6
  //#region src/components/button.d.ts
7
7
  declare const buttonVariants: (props?: ({
8
- variant?: "destructive" | "secondary" | "primary" | "tertiary" | "link" | "link-muted" | null | undefined;
8
+ variant?: "destructive" | "secondary" | "primary" | "tertiary" | "link" | "link-muted" | "cta" | null | undefined;
9
9
  size?: "default" | "icon" | "icon-rounded" | "pill" | null | undefined;
10
10
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
11
11
  interface ButtonProps extends React.ComponentProps<"button">, VariantProps<typeof buttonVariants> {
12
12
  asChild?: boolean;
13
13
  loading?: boolean;
14
14
  icon?: React.ReactNode;
15
+ iconTrailing?: React.ReactNode;
15
16
  }
16
17
  declare function Button({
17
18
  className,
@@ -21,6 +22,7 @@ declare function Button({
21
22
  asChild,
22
23
  loading,
23
24
  icon,
25
+ iconTrailing,
24
26
  disabled,
25
27
  children,
26
28
  ...props
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.mjs";
3
3
  import { Loader2 } from "lucide-react";
4
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { cva } from "class-variance-authority";
6
- import { Slot } from "@radix-ui/react-slot";
6
+ import { Slot, Slottable } from "@radix-ui/react-slot";
7
7
  //#region src/components/button.tsx
8
8
  const buttonVariants = cva([
9
9
  "inline-flex items-center justify-center gap-1 whitespace-nowrap",
@@ -35,7 +35,14 @@ const buttonVariants = cva([
35
35
  "[@media(hover:hover)]:hover:underline",
36
36
  "focus-visible:bg-background"
37
37
  ].join(" "),
38
- destructive: ["bg-destructive text-destructive-foreground", "[@media(hover:hover)]:hover:bg-destructive-hover"].join(" ")
38
+ destructive: ["bg-destructive text-destructive-foreground", "[@media(hover:hover)]:hover:bg-destructive-hover"].join(" "),
39
+ cta: [
40
+ "button-cta",
41
+ "h-9 px-4 gap-2 rounded-md",
42
+ "dark:bg-inverted text-foreground",
43
+ "transition-[transform,filter] duration-300 ease-out",
44
+ "active:scale-[0.99]"
45
+ ].join(" ")
39
46
  },
40
47
  size: {
41
48
  default: "type-text-sm",
@@ -49,8 +56,8 @@ const buttonVariants = cva([
49
56
  size: "default"
50
57
  }
51
58
  });
52
- function Button({ className, variant, size, type = "button", asChild = false, loading = false, icon, disabled, children, ...props }) {
53
- return /* @__PURE__ */ jsx(asChild ? Slot : "button", {
59
+ function Button({ className, variant, size, type = "button", asChild = false, loading = false, icon, iconTrailing, disabled, children, ...props }) {
60
+ return /* @__PURE__ */ jsxs(asChild ? Slot : "button", {
54
61
  "data-slot": "button",
55
62
  className: cn(buttonVariants({
56
63
  variant,
@@ -60,7 +67,14 @@ function Button({ className, variant, size, type = "button", asChild = false, lo
60
67
  disabled: disabled || loading,
61
68
  "aria-busy": loading || void 0,
62
69
  ...props,
63
- children: asChild ? children : /* @__PURE__ */ jsxs(Fragment, { children: [loading ? /* @__PURE__ */ jsx(Loader2, { className: "motion-safe:animate-spin" }) : icon, children] })
70
+ children: [
71
+ loading ? /* @__PURE__ */ jsx(Loader2, { className: "motion-safe:animate-spin" }) : icon,
72
+ asChild ? /* @__PURE__ */ jsx(Slottable, { children }) : children,
73
+ !loading && iconTrailing ? /* @__PURE__ */ jsx("span", {
74
+ "data-cta-icon-trailing": true,
75
+ children: iconTrailing
76
+ }) : null
77
+ ]
64
78
  });
65
79
  }
66
80
  //#endregion
@@ -115,5 +115,40 @@ declare function SelectField<TFieldValues extends FieldValues, TName extends Fie
115
115
  options,
116
116
  placeholder
117
117
  }: SelectFieldProps<TFieldValues, TName>): _$react_jsx_runtime0.JSX.Element;
118
+ interface RadioFieldProps<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>> extends FormFieldBaseProps<TFieldValues, TName> {
119
+ options: SelectFieldOption[];
120
+ }
121
+ declare function RadioField<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>>({
122
+ control,
123
+ name,
124
+ rules,
125
+ required,
126
+ label,
127
+ description,
128
+ tooltip,
129
+ options
130
+ }: RadioFieldProps<TFieldValues, TName>): _$react_jsx_runtime0.JSX.Element;
131
+ interface ChecklistFieldProps<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>> extends FormFieldBaseProps<TFieldValues, TName> {
132
+ options: SelectFieldOption[];
133
+ }
134
+ declare function ChecklistField<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>>({
135
+ control,
136
+ name,
137
+ rules,
138
+ required,
139
+ label,
140
+ description,
141
+ tooltip,
142
+ options
143
+ }: ChecklistFieldProps<TFieldValues, TName>): _$react_jsx_runtime0.JSX.Element;
144
+ interface CheckboxFieldProps<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>> extends Omit<FormFieldBaseProps<TFieldValues, TName>, "required"> {}
145
+ declare function CheckboxField<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>>({
146
+ control,
147
+ name,
148
+ rules,
149
+ label,
150
+ description,
151
+ tooltip
152
+ }: CheckboxFieldProps<TFieldValues, TName>): _$react_jsx_runtime0.JSX.Element;
118
153
  //#endregion
119
- export { Form, FormControl, FormDescription, FormField, FormFields, FormHeader, FormItem, FormLabel, FormMessage, InputField, SelectField, type SelectFieldOption, TextareaField, useFormField };
154
+ export { CheckboxField, ChecklistField, Form, FormControl, FormDescription, FormField, FormFields, FormHeader, FormItem, FormLabel, FormMessage, InputField, RadioField, SelectField, type SelectFieldOption, TextareaField, useFormField };
@@ -1,8 +1,10 @@
1
1
  "use client";
2
2
  import { cn } from "../lib/cn.mjs";
3
3
  import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.mjs";
4
+ import { Checkbox } from "./checkbox.mjs";
4
5
  import { Label } from "./label.mjs";
5
6
  import { Input } from "./input.mjs";
7
+ import { RadioGroup, RadioGroupItem } from "./radio-group.mjs";
6
8
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select.mjs";
7
9
  import { Textarea } from "./textarea.mjs";
8
10
  import { Info } from "lucide-react";
@@ -188,5 +190,113 @@ function SelectField({ control, name, rules, required, label, description, toolt
188
190
  ] })
189
191
  });
190
192
  }
193
+ function RadioField({ control, name, rules, required, label, description, tooltip, options }) {
194
+ return /* @__PURE__ */ jsx(FormField, {
195
+ control,
196
+ name,
197
+ rules,
198
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, { children: [
199
+ label && /* @__PURE__ */ jsx(FormLabel, {
200
+ required,
201
+ tooltip,
202
+ children: label
203
+ }),
204
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(RadioGroup, {
205
+ value: field.value ?? "",
206
+ onValueChange: field.onChange,
207
+ onBlur: field.onBlur,
208
+ children: options.map((option) => {
209
+ const itemId = `${field.name}-${option.value}`;
210
+ return /* @__PURE__ */ jsxs("div", {
211
+ className: "flex items-center gap-2",
212
+ children: [/* @__PURE__ */ jsx(RadioGroupItem, {
213
+ id: itemId,
214
+ value: option.value,
215
+ disabled: option.disabled
216
+ }), /* @__PURE__ */ jsx(Label, {
217
+ htmlFor: itemId,
218
+ className: "type-text-sm font-normal",
219
+ children: option.label
220
+ })]
221
+ }, option.value);
222
+ })
223
+ }) }),
224
+ description && /* @__PURE__ */ jsx(FormDescription, { children: description }),
225
+ /* @__PURE__ */ jsx(FormMessage, {})
226
+ ] })
227
+ });
228
+ }
229
+ function ChecklistField({ control, name, rules, required, label, description, tooltip, options }) {
230
+ return /* @__PURE__ */ jsx(FormField, {
231
+ control,
232
+ name,
233
+ rules,
234
+ render: ({ field }) => {
235
+ const selected = Array.isArray(field.value) ? field.value : [];
236
+ const toggle = (value, checked) => {
237
+ if (checked) field.onChange([...selected, value]);
238
+ else field.onChange(selected.filter((existing) => existing !== value));
239
+ };
240
+ return /* @__PURE__ */ jsxs(FormItem, { children: [
241
+ label && /* @__PURE__ */ jsx(FormLabel, {
242
+ required,
243
+ tooltip,
244
+ children: label
245
+ }),
246
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx("fieldset", {
247
+ className: "m-0 flex flex-col gap-2 border-0 p-0",
248
+ onBlur: field.onBlur,
249
+ children: options.map((option) => {
250
+ const itemId = `${field.name}-${option.value}`;
251
+ return /* @__PURE__ */ jsxs("div", {
252
+ className: "flex items-start gap-2",
253
+ children: [/* @__PURE__ */ jsx(Checkbox, {
254
+ id: itemId,
255
+ checked: selected.includes(option.value),
256
+ onCheckedChange: (next) => toggle(option.value, Boolean(next)),
257
+ disabled: option.disabled
258
+ }), /* @__PURE__ */ jsx(Label, {
259
+ htmlFor: itemId,
260
+ className: "type-text-sm font-normal leading-tight",
261
+ children: option.label
262
+ })]
263
+ }, option.value);
264
+ })
265
+ }) }),
266
+ description && /* @__PURE__ */ jsx(FormDescription, { children: description }),
267
+ /* @__PURE__ */ jsx(FormMessage, {})
268
+ ] });
269
+ }
270
+ });
271
+ }
272
+ function CheckboxField({ control, name, rules, label, description, tooltip }) {
273
+ return /* @__PURE__ */ jsx(FormField, {
274
+ control,
275
+ name,
276
+ rules,
277
+ render: ({ field }) => /* @__PURE__ */ jsxs(FormItem, {
278
+ className: "gap-1.5",
279
+ children: [
280
+ /* @__PURE__ */ jsxs("div", {
281
+ className: "flex items-start gap-2",
282
+ children: [/* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(Checkbox, {
283
+ checked: field.value ?? false,
284
+ onCheckedChange: (next) => field.onChange(Boolean(next)),
285
+ onBlur: field.onBlur
286
+ }) }), label && /* @__PURE__ */ jsx(FormLabel, {
287
+ tooltip,
288
+ className: "font-normal",
289
+ children: label
290
+ })]
291
+ }),
292
+ description && /* @__PURE__ */ jsx(FormDescription, {
293
+ className: "ml-6",
294
+ children: description
295
+ }),
296
+ /* @__PURE__ */ jsx(FormMessage, { className: "ml-6" })
297
+ ]
298
+ })
299
+ });
300
+ }
191
301
  //#endregion
192
- export { Form, FormControl, FormDescription, FormField, FormFields, FormHeader, FormItem, FormLabel, FormMessage, InputField, SelectField, TextareaField, useFormField };
302
+ export { CheckboxField, ChecklistField, Form, FormControl, FormDescription, FormField, FormFields, FormHeader, FormItem, FormLabel, FormMessage, InputField, RadioField, SelectField, TextareaField, useFormField };
@@ -0,0 +1,13 @@
1
+ import { Button } from "./button.mjs";
2
+ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
3
+ import { ComponentProps } from "react";
4
+
5
+ //#region src/components/github-button.d.ts
6
+ type GitHubButtonProps = Omit<ComponentProps<typeof Button>, "variant" | "icon">;
7
+ declare function GitHubButton({
8
+ className,
9
+ children,
10
+ ...props
11
+ }: GitHubButtonProps): _$react_jsx_runtime0.JSX.Element;
12
+ //#endregion
13
+ export { GitHubButton, type GitHubButtonProps };
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.mjs";
3
+ import { Button } from "./button.mjs";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/components/github-button.tsx
6
+ const GITHUB_ICON_PATH = "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12";
7
+ function GitHubIcon() {
8
+ return /* @__PURE__ */ jsx("svg", {
9
+ fill: "currentColor",
10
+ viewBox: "0 0 24 24",
11
+ "aria-hidden": "true",
12
+ children: /* @__PURE__ */ jsx("path", { d: GITHUB_ICON_PATH })
13
+ });
14
+ }
15
+ function GitHubButton({ className, children, ...props }) {
16
+ return /* @__PURE__ */ jsx(Button, {
17
+ ...props,
18
+ icon: /* @__PURE__ */ jsx(GitHubIcon, {}),
19
+ className: cn("bg-foreground text-background [@media(hover:hover)]:hover:bg-foreground/90", className),
20
+ children
21
+ });
22
+ }
23
+ //#endregion
24
+ export { GitHubButton };
@@ -0,0 +1,11 @@
1
+ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
2
+
3
+ //#region src/components/page-loader.d.ts
4
+ interface PageLoaderProps {
5
+ className?: string;
6
+ }
7
+ declare function PageLoader({
8
+ className
9
+ }: PageLoaderProps): _$react_jsx_runtime0.JSX.Element;
10
+ //#endregion
11
+ export { PageLoader, type PageLoaderProps };
@@ -0,0 +1,122 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.mjs";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/components/page-loader.tsx
5
+ const CABLE_CAR_SVG = /* @__PURE__ */ jsxs("svg", {
6
+ xmlns: "http://www.w3.org/2000/svg",
7
+ viewBox: "0 0 120 130",
8
+ width: "240",
9
+ height: "260",
10
+ "aria-hidden": "true",
11
+ className: "block h-auto w-full",
12
+ children: [
13
+ /* @__PURE__ */ jsx("line", {
14
+ x1: "60",
15
+ y1: "3",
16
+ x2: "60",
17
+ y2: "58",
18
+ stroke: "#333",
19
+ strokeWidth: "4"
20
+ }),
21
+ /* @__PURE__ */ jsx("circle", {
22
+ cx: "60",
23
+ cy: "11",
24
+ r: "10",
25
+ fill: "#555"
26
+ }),
27
+ /* @__PURE__ */ jsx("rect", {
28
+ x: "5",
29
+ y: "58",
30
+ width: "110",
31
+ height: "64",
32
+ rx: "4",
33
+ fill: "#e90060"
34
+ }),
35
+ /* @__PURE__ */ jsx("rect", {
36
+ x: "5",
37
+ y: "58",
38
+ width: "110",
39
+ height: "20",
40
+ rx: "4",
41
+ fill: "#F5F0E8"
42
+ }),
43
+ /* @__PURE__ */ jsx("rect", {
44
+ x: "5",
45
+ y: "68",
46
+ width: "110",
47
+ height: "10",
48
+ fill: "#F5F0E8"
49
+ }),
50
+ /* @__PURE__ */ jsx("rect", {
51
+ x: "14",
52
+ y: "66",
53
+ width: "26",
54
+ height: "30",
55
+ rx: "2",
56
+ fill: "#5B8EC9",
57
+ stroke: "#C4B9A8",
58
+ strokeWidth: "1.5"
59
+ }),
60
+ /* @__PURE__ */ jsx("rect", {
61
+ x: "47",
62
+ y: "66",
63
+ width: "26",
64
+ height: "30",
65
+ rx: "2",
66
+ fill: "#5B8EC9",
67
+ stroke: "#C4B9A8",
68
+ strokeWidth: "1.5"
69
+ }),
70
+ /* @__PURE__ */ jsx("rect", {
71
+ x: "80",
72
+ y: "66",
73
+ width: "26",
74
+ height: "30",
75
+ rx: "2",
76
+ fill: "#5B8EC9",
77
+ stroke: "#C4B9A8",
78
+ strokeWidth: "1.5"
79
+ }),
80
+ /* @__PURE__ */ jsx("rect", {
81
+ x: "5",
82
+ y: "115",
83
+ width: "110",
84
+ height: "7",
85
+ rx: "3",
86
+ fill: "#9f0042"
87
+ })
88
+ ]
89
+ });
90
+ function PageLoader({ className }) {
91
+ return /* @__PURE__ */ jsx("div", {
92
+ className: cn("flex min-h-screen items-center justify-center bg-background", className),
93
+ role: "status",
94
+ "aria-label": "Loading Alpic…",
95
+ children: /* @__PURE__ */ jsxs("div", {
96
+ className: "relative h-[120px] w-[200px]",
97
+ children: [
98
+ /* @__PURE__ */ jsx("div", {
99
+ className: "absolute top-[30px] left-0 h-[3px] w-full rounded-sm bg-[#6c6c77]",
100
+ style: {
101
+ transform: "rotate(-15deg)",
102
+ transformOrigin: "left center"
103
+ }
104
+ }),
105
+ /* @__PURE__ */ jsx("div", {
106
+ className: "absolute top-[33px] -left-[45px] w-[45px] motion-safe:animate-[alpic-ride_4s_linear_infinite]",
107
+ children: CABLE_CAR_SVG
108
+ }),
109
+ /* @__PURE__ */ jsx("div", {
110
+ className: "pointer-events-none absolute -top-[40px] -left-[45px] z-10 h-[200px] w-[95px]",
111
+ style: { background: "linear-gradient(to right, var(--color-background) 47%, transparent)" }
112
+ }),
113
+ /* @__PURE__ */ jsx("div", {
114
+ className: "pointer-events-none absolute -top-[40px] left-[142px] z-10 h-[200px] w-[95px]",
115
+ style: { background: "linear-gradient(to right, transparent, var(--color-background) 53%)" }
116
+ })
117
+ ]
118
+ })
119
+ });
120
+ }
121
+ //#endregion
122
+ export { PageLoader };
@@ -0,0 +1,12 @@
1
+ import * as _$react_jsx_runtime0 from "react/jsx-runtime";
2
+
3
+ //#region src/components/shimmer-text.d.ts
4
+ declare function ShimmerText({
5
+ children,
6
+ className
7
+ }: {
8
+ children: string | number;
9
+ className?: string;
10
+ }): _$react_jsx_runtime0.JSX.Element;
11
+ //#endregion
12
+ export { ShimmerText };
@@ -0,0 +1,22 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.mjs";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/components/shimmer-text.tsx
5
+ const shimmerStyle = {
6
+ background: `linear-gradient(90deg, #0000 calc(50% - 60px), var(--color-foreground), #0000 calc(50% + 60px)), linear-gradient(color-mix(in oklab, var(--color-muted-foreground) 70%, transparent), color-mix(in oklab, var(--color-muted-foreground) 70%, transparent))`,
7
+ backgroundSize: "250% 100%, auto",
8
+ backgroundRepeat: "no-repeat, padding-box",
9
+ WebkitBackgroundClip: "text",
10
+ WebkitTextFillColor: "transparent",
11
+ backgroundClip: "text",
12
+ animation: "shimmer-text 2.5s linear infinite"
13
+ };
14
+ function ShimmerText({ children, className }) {
15
+ return /* @__PURE__ */ jsx("span", {
16
+ className: cn(className),
17
+ style: shimmerStyle,
18
+ children
19
+ });
20
+ }
21
+ //#endregion
22
+ export { ShimmerText };
@@ -17,6 +17,18 @@ const SIDEBAR_WIDTH = "15rem";
17
17
  const SIDEBAR_WIDTH_MOBILE = "16rem";
18
18
  const SIDEBAR_WIDTH_ICON = "3.5rem";
19
19
  const SIDEBAR_KEYBOARD_SHORTCUT = "b";
20
+ const INTERACTIVE_SIDEBAR_ELEMENT_SELECTOR = [
21
+ "a",
22
+ "button",
23
+ "input",
24
+ "select",
25
+ "textarea",
26
+ "[role='button']",
27
+ "[role='link']",
28
+ "[role='menuitem']",
29
+ "[contenteditable='true']",
30
+ "[tabindex]:not([tabindex='-1'])"
31
+ ].join(", ");
20
32
  const SidebarContext = React.createContext(null);
21
33
  function useSidebar() {
22
34
  const context = React.useContext(SidebarContext);
@@ -80,10 +92,20 @@ function SidebarProvider({ defaultOpen = true, open: openProp, onOpenChange: set
80
92
  });
81
93
  }
82
94
  function Sidebar({ side = "left", variant = "sidebar", collapsible = "offcanvas", className, children, ...props }) {
83
- const { isMobile, state, openMobile, setOpenMobile } = useSidebar();
95
+ const { isMobile, state, openMobile, setOpenMobile, open, setOpen } = useSidebar();
96
+ function handleSurfaceClickCapture(event) {
97
+ if (event.target instanceof Element && event.target.closest(INTERACTIVE_SIDEBAR_ELEMENT_SELECTOR)) return;
98
+ if (!open) {
99
+ event.preventDefault();
100
+ event.stopPropagation();
101
+ setOpen(true);
102
+ return;
103
+ }
104
+ setOpen(false);
105
+ }
84
106
  if (collapsible === "none") return /* @__PURE__ */ jsx("div", {
85
107
  "data-slot": "sidebar",
86
- className: cn("bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col", className),
108
+ className: cn("bg-sidebar-surface text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col", className),
87
109
  ...props,
88
110
  children
89
111
  });
@@ -95,7 +117,7 @@ function Sidebar({ side = "left", variant = "sidebar", collapsible = "offcanvas"
95
117
  "data-sidebar": "sidebar",
96
118
  "data-slot": "sidebar",
97
119
  "data-mobile": "true",
98
- className: "bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden",
120
+ className: "bg-sidebar-surface text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden",
99
121
  style: { "--sidebar-width": SIDEBAR_WIDTH_MOBILE },
100
122
  side,
101
123
  children: [/* @__PURE__ */ jsxs(SheetHeader, {
@@ -119,12 +141,13 @@ function Sidebar({ side = "left", variant = "sidebar", collapsible = "offcanvas"
119
141
  className: cn("relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-out", "group-data-[collapsible=offcanvas]:w-0", "group-data-[side=right]:rotate-180", variant === "floating" || variant === "inset" ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)")
120
142
  }), /* @__PURE__ */ jsx("div", {
121
143
  "data-slot": "sidebar-container",
122
- className: cn("fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-out md:flex", side === "left" ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]" : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]", variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l", className),
144
+ className: cn("fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-out md:flex", side === "left" ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]" : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]", variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "border-sidebar-border group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l", className),
123
145
  ...props,
124
146
  children: /* @__PURE__ */ jsx("div", {
125
147
  "data-sidebar": "sidebar",
126
148
  "data-slot": "sidebar-inner",
127
- className: "bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm",
149
+ className: "bg-sidebar-surface group-data-[variant=floating]:border-sidebar-border flex h-full w-full cursor-pointer flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm",
150
+ onClickCapture: handleSurfaceClickCapture,
128
151
  children
129
152
  })
130
153
  })]
@@ -181,7 +204,7 @@ function SidebarRail({ className, ...props }) {
181
204
  tabIndex: -1,
182
205
  onClick: toggleSidebar,
183
206
  title: "Toggle Sidebar",
184
- className: cn("[@media(hover:hover)]:hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex", "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize", "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize", "[@media(hover:hover)]:hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full", "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2", "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2", className),
207
+ className: cn("absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex", "[@media(hover:hover)]:hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full", "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2", "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2", className),
185
208
  ...props
186
209
  });
187
210
  }
@@ -203,14 +226,20 @@ function SidebarHeader({ className, icon, title, children, ...props }) {
203
226
  return /* @__PURE__ */ jsxs("div", {
204
227
  "data-slot": "sidebar-header",
205
228
  "data-sidebar": "header",
206
- className: cn("flex flex-col gap-2 p-2", className),
229
+ className: cn("flex flex-col gap-2 py-2", className),
207
230
  ...props,
208
231
  children: [/* @__PURE__ */ jsxs("div", {
209
232
  className: "flex h-8 items-center gap-2 px-3",
210
233
  children: [
211
- /* @__PURE__ */ jsx("div", {
212
- className: "shrink-0",
213
- children: icon
234
+ /* @__PURE__ */ jsxs("span", {
235
+ className: "relative flex size-8 shrink-0 items-center justify-center",
236
+ children: [/* @__PURE__ */ jsx("span", {
237
+ className: "transition-opacity duration-200 group-data-[collapsible=icon]:group-hover:opacity-0",
238
+ children: icon
239
+ }), /* @__PURE__ */ jsx(SidebarTrigger, {
240
+ tabIndex: -1,
241
+ className: "absolute inset-0 opacity-0 transition-opacity duration-200 group-data-[collapsible=icon]:group-hover:opacity-100"
242
+ })]
214
243
  }),
215
244
  /* @__PURE__ */ jsx("span", {
216
245
  className: "text-foreground text-md min-w-0 truncate font-medium group-data-[collapsible=icon]:hidden",
@@ -5,7 +5,7 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
5
5
  //#region src/components/spinner.d.ts
6
6
  declare const spinnerVariants: (props?: ({
7
7
  variant?: "secondary" | "primary" | null | undefined;
8
- size?: "sm" | "lg" | "md" | "xl" | null | undefined;
8
+ size?: "sm" | "md" | "lg" | "xl" | null | undefined;
9
9
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
10
10
  interface SpinnerProps extends Omit<React.ComponentProps<"svg">, "children">, VariantProps<typeof spinnerVariants> {}
11
11
  declare function Spinner({
@@ -26,10 +26,19 @@ declare function TableHead({
26
26
  className,
27
27
  ...props
28
28
  }: React.ComponentProps<"th">): _$react_jsx_runtime0.JSX.Element;
29
+ interface TableCellProps extends React.ComponentProps<"td"> {
30
+ /**
31
+ * When true, the cell renders edge-to-edge so the child can act as the
32
+ * interactive surface (e.g. a button or popover trigger filling the cell).
33
+ * Defaults to false (standard padded cell).
34
+ */
35
+ interactive?: boolean;
36
+ }
29
37
  declare function TableCell({
30
38
  className,
39
+ interactive,
31
40
  ...props
32
- }: React.ComponentProps<"td">): _$react_jsx_runtime0.JSX.Element;
41
+ }: TableCellProps): _$react_jsx_runtime0.JSX.Element;
33
42
  declare function TableCaption({
34
43
  className,
35
44
  ...props
@@ -36,21 +36,21 @@ function TableFooter({ className, ...props }) {
36
36
  function TableRow({ className, ...props }) {
37
37
  return /* @__PURE__ */ jsx("tr", {
38
38
  "data-slot": "table-row",
39
- className: cn("border-b border-border-secondary transition-colors", "data-[state=selected]:bg-muted", "[@media(hover:hover)]:hover:bg-background-hover dark:[@media(hover:hover)]:hover:bg-muted", "[@media(hover:hover)]:[&:hover_button:hover]:bg-subtle", className),
39
+ className: cn("border-b border-border-secondary transition-colors", "data-[state=selected]:bg-muted", "[@media(hover:hover)]:hover:bg-background-hover dark:[@media(hover:hover)]:hover:bg-muted", className),
40
40
  ...props
41
41
  });
42
42
  }
43
43
  function TableHead({ className, ...props }) {
44
44
  return /* @__PURE__ */ jsx("th", {
45
45
  "data-slot": "table-head",
46
- className: cn("h-11 px-6 py-3 bg-muted text-left align-middle type-text-xs font-semibold text-placeholder dark:text-subtle-foreground whitespace-nowrap", "[&:has([role=checkbox])]:w-px [&:has([role=checkbox])]:pr-3", className),
46
+ className: cn("h-11 px-6 py-3 bg-muted text-left align-middle type-text-xs font-semibold text-placeholder dark:text-subtle-foreground whitespace-nowrap", "[&:has([role=checkbox])]:w-px [&:has([role=checkbox])]:px-0", className),
47
47
  ...props
48
48
  });
49
49
  }
50
- function TableCell({ className, ...props }) {
50
+ function TableCell({ className, interactive = false, ...props }) {
51
51
  return /* @__PURE__ */ jsx("td", {
52
52
  "data-slot": "table-cell",
53
- className: cn("px-6 py-2 align-middle", "[&:has([role=checkbox])]:w-px [&:has([role=checkbox])]:pr-3", className),
53
+ className: cn("align-middle", interactive ? "h-px p-0" : "px-6 py-2", "[&:has([role=checkbox])]:w-px [&:has([role=checkbox])]:px-0", className),
54
54
  ...props
55
55
  });
56
56
  }
@@ -21,10 +21,10 @@ const tabsTriggerVariants = cva([
21
21
  "data-[state=active]:border-b-2 data-[state=active]:border-foreground data-[state=active]:text-foreground"
22
22
  ],
23
23
  pill: [
24
- "rounded-lg px-4 py-2",
25
- "text-muted-foreground",
26
- "[@media(hover:hover)]:hover:bg-accent [@media(hover:hover)]:hover:text-accent-foreground",
27
- "data-[state=active]:bg-accent data-[state=active]:text-accent-foreground"
24
+ "rounded-md px-2 py-1.5",
25
+ "text-quaternary-foreground",
26
+ "[@media(hover:hover)]:hover:bg-accent [@media(hover:hover)]:hover:text-muted-foreground",
27
+ "data-[state=active]:bg-accent data-[state=active]:text-muted-foreground"
28
28
  ]
29
29
  } },
30
30
  defaultVariants: { variant: "default" }