@alpic-ai/ui 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/accordion-card.d.mts +41 -0
- package/dist/components/accordion-card.mjs +61 -0
- package/dist/components/accordion.d.mts +29 -0
- package/dist/components/accordion.mjs +48 -0
- package/dist/components/alert.d.mts +40 -0
- package/dist/components/alert.mjs +63 -0
- package/dist/components/attachment-tile.d.mts +26 -0
- package/dist/components/attachment-tile.mjs +35 -0
- package/dist/components/avatar.d.mts +52 -0
- package/dist/components/avatar.mjs +81 -0
- package/dist/components/badge.d.mts +20 -0
- package/dist/components/badge.mjs +36 -0
- package/dist/components/breadcrumb.d.mts +42 -0
- package/dist/components/breadcrumb.mjs +79 -0
- package/dist/components/button.d.mts +29 -0
- package/dist/components/button.mjs +67 -0
- package/dist/components/card.d.mts +37 -0
- package/dist/components/card.mjs +54 -0
- package/dist/components/checkbox.d.mts +11 -0
- package/dist/components/checkbox.mjs +26 -0
- package/dist/components/collapsible.d.mts +16 -0
- package/dist/components/collapsible.mjs +24 -0
- package/dist/components/combobox.d.mts +86 -0
- package/dist/components/combobox.mjs +207 -0
- package/dist/components/command.d.mts +38 -0
- package/dist/components/command.mjs +68 -0
- package/dist/components/copyable.d.mts +22 -0
- package/dist/components/copyable.mjs +33 -0
- package/dist/components/description-list.d.mts +22 -0
- package/dist/components/description-list.mjs +34 -0
- package/dist/components/dialog.d.mts +61 -0
- package/dist/components/dialog.mjs +110 -0
- package/dist/components/dropdown-menu.d.mts +72 -0
- package/dist/components/dropdown-menu.mjs +122 -0
- package/dist/components/input-group.d.mts +25 -0
- package/dist/components/input-group.mjs +43 -0
- package/dist/components/input.d.mts +27 -0
- package/dist/components/input.mjs +90 -0
- package/dist/components/label.d.mts +11 -0
- package/dist/components/label.mjs +14 -0
- package/dist/components/pagination.d.mts +18 -0
- package/dist/components/pagination.mjs +42 -0
- package/dist/components/popover.d.mts +22 -0
- package/dist/components/popover.mjs +34 -0
- package/dist/components/radio-group.d.mts +15 -0
- package/dist/components/radio-group.mjs +26 -0
- package/dist/components/scroll-area.d.mts +17 -0
- package/dist/components/scroll-area.mjs +35 -0
- package/dist/components/select-trigger-variants.d.mts +13 -0
- package/dist/components/select-trigger-variants.mjs +23 -0
- package/dist/components/select.d.mts +51 -0
- package/dist/components/select.mjs +95 -0
- package/dist/components/separator.d.mts +13 -0
- package/dist/components/separator.mjs +16 -0
- package/dist/components/sheet.d.mts +43 -0
- package/dist/components/sheet.mjs +74 -0
- package/dist/components/sidebar.d.mts +163 -0
- package/dist/components/sidebar.mjs +378 -0
- package/dist/components/skeleton.d.mts +16 -0
- package/dist/components/skeleton.mjs +21 -0
- package/dist/components/sonner.d.mts +29 -0
- package/dist/components/sonner.mjs +76 -0
- package/dist/components/spinner.d.mts +30 -0
- package/dist/components/spinner.mjs +46 -0
- package/dist/components/status-dot.d.mts +19 -0
- package/dist/components/status-dot.mjs +34 -0
- package/dist/components/switch.d.mts +11 -0
- package/dist/components/switch.mjs +18 -0
- package/dist/components/table.d.mts +38 -0
- package/dist/components/table.mjs +65 -0
- package/dist/components/tabs.d.mts +58 -0
- package/dist/components/tabs.mjs +119 -0
- package/dist/components/tag.d.mts +35 -0
- package/dist/components/tag.mjs +65 -0
- package/dist/components/textarea.d.mts +21 -0
- package/dist/components/textarea.mjs +44 -0
- package/dist/components/toggle-group.d.mts +28 -0
- package/dist/components/toggle-group.mjs +72 -0
- package/dist/components/tooltip-icon-button.d.mts +12 -0
- package/dist/components/tooltip-icon-button.mjs +27 -0
- package/dist/components/tooltip.d.mts +23 -0
- package/dist/components/tooltip.mjs +35 -0
- package/dist/hooks/use-copy-to-clipboard.d.mts +11 -0
- package/dist/hooks/use-copy-to-clipboard.mjs +24 -0
- package/dist/hooks/use-mobile.d.mts +4 -0
- package/dist/hooks/use-mobile.mjs +16 -0
- package/dist/lib/cn.d.mts +6 -0
- package/dist/lib/cn.mjs +8 -0
- package/package.json +88 -0
- package/src/components/accordion-card.tsx +103 -0
- package/src/components/accordion.tsx +63 -0
- package/src/components/alert.tsx +74 -0
- package/src/components/attachment-tile.tsx +68 -0
- package/src/components/avatar.tsx +127 -0
- package/src/components/badge.tsx +41 -0
- package/src/components/breadcrumb.tsx +98 -0
- package/src/components/button.tsx +106 -0
- package/src/components/card.tsx +62 -0
- package/src/components/checkbox.tsx +35 -0
- package/src/components/collapsible.tsx +18 -0
- package/src/components/combobox.tsx +393 -0
- package/src/components/command.tsx +112 -0
- package/src/components/copyable.tsx +47 -0
- package/src/components/description-list.tsx +36 -0
- package/src/components/dialog.tsx +161 -0
- package/src/components/dropdown-menu.tsx +234 -0
- package/src/components/input-group.tsx +97 -0
- package/src/components/input.tsx +145 -0
- package/src/components/label.tsx +20 -0
- package/src/components/pagination.tsx +53 -0
- package/src/components/popover.tsx +49 -0
- package/src/components/radio-group.tsx +33 -0
- package/src/components/scroll-area.tsx +48 -0
- package/src/components/select-trigger-variants.ts +28 -0
- package/src/components/select.tsx +186 -0
- package/src/components/separator.tsx +30 -0
- package/src/components/sheet.tsx +112 -0
- package/src/components/sidebar.tsx +682 -0
- package/src/components/skeleton.tsx +24 -0
- package/src/components/sonner.tsx +91 -0
- package/src/components/spinner.tsx +62 -0
- package/src/components/status-dot.tsx +33 -0
- package/src/components/switch.tsx +33 -0
- package/src/components/table.tsx +89 -0
- package/src/components/tabs.tsx +226 -0
- package/src/components/tag.tsx +82 -0
- package/src/components/textarea.tsx +70 -0
- package/src/components/toggle-group.tsx +96 -0
- package/src/components/tooltip-icon-button.tsx +33 -0
- package/src/components/tooltip.tsx +54 -0
- package/src/hooks/use-copy-to-clipboard.ts +27 -0
- package/src/hooks/use-mobile.ts +17 -0
- package/src/lib/cn.ts +6 -0
- package/src/styles/tokens.css +352 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.mjs";
|
|
3
|
+
import { Label } from "./label.mjs";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
//#region src/components/textarea.tsx
|
|
7
|
+
function Textarea({ className, id, label, required, hint, error, ...props }) {
|
|
8
|
+
const generatedId = React.useId();
|
|
9
|
+
const fieldId = id ?? generatedId;
|
|
10
|
+
const textarea = /* @__PURE__ */ jsx("textarea", {
|
|
11
|
+
id: fieldId,
|
|
12
|
+
"data-slot": "textarea",
|
|
13
|
+
className: cn("block w-full min-h-[120px] resize-none", "px-3.5 py-3", "type-text-md text-foreground placeholder:text-placeholder", "bg-background border border-border rounded-md", "transition-colors", "outline-none focus-visible:border-ring focus-visible:border-2", "disabled:bg-disabled disabled:text-disabled-foreground disabled:cursor-not-allowed", "aria-invalid:border-border-error [@media(hover:hover)]:aria-invalid:hover:border-border-error", error && "border-border-error [@media(hover:hover)]:hover:border-border-error", className),
|
|
14
|
+
required,
|
|
15
|
+
"aria-invalid": error ? true : void 0,
|
|
16
|
+
"aria-describedby": fieldId && (hint || error) ? `${fieldId}-description` : void 0,
|
|
17
|
+
...props
|
|
18
|
+
});
|
|
19
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
20
|
+
className: "flex flex-col gap-1.5",
|
|
21
|
+
children: [
|
|
22
|
+
label && /* @__PURE__ */ jsxs("div", {
|
|
23
|
+
className: "flex items-center gap-0.5",
|
|
24
|
+
children: [/* @__PURE__ */ jsx(Label, {
|
|
25
|
+
htmlFor: fieldId,
|
|
26
|
+
className: "type-text-sm font-medium text-muted-foreground",
|
|
27
|
+
children: label
|
|
28
|
+
}), required && /* @__PURE__ */ jsx("span", {
|
|
29
|
+
"aria-hidden": true,
|
|
30
|
+
className: "type-text-sm font-medium text-required",
|
|
31
|
+
children: "*"
|
|
32
|
+
})]
|
|
33
|
+
}),
|
|
34
|
+
textarea,
|
|
35
|
+
(hint || error) && /* @__PURE__ */ jsx("p", {
|
|
36
|
+
id: fieldId ? `${fieldId}-description` : void 0,
|
|
37
|
+
className: cn("type-text-sm", error ? "text-destructive" : "text-subtle-foreground"),
|
|
38
|
+
children: error ?? hint
|
|
39
|
+
})
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
export { Textarea };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
|
|
5
|
+
import * as _$class_variance_authority_types0 from "class-variance-authority/types";
|
|
6
|
+
|
|
7
|
+
//#region src/components/toggle-group.d.ts
|
|
8
|
+
declare const toggleGroupItemVariants: (props?: ({
|
|
9
|
+
variant?: "default" | "outline" | null | undefined;
|
|
10
|
+
size?: "sm" | "default" | null | undefined;
|
|
11
|
+
} & _$class_variance_authority_types0.ClassProp) | undefined) => string;
|
|
12
|
+
type ToggleGroupContextValue = VariantProps<typeof toggleGroupItemVariants>;
|
|
13
|
+
declare function ToggleGroup({
|
|
14
|
+
className,
|
|
15
|
+
variant,
|
|
16
|
+
size,
|
|
17
|
+
children,
|
|
18
|
+
...props
|
|
19
|
+
}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> & ToggleGroupContextValue): _$react_jsx_runtime0.JSX.Element;
|
|
20
|
+
declare function ToggleGroupItem({
|
|
21
|
+
className,
|
|
22
|
+
children,
|
|
23
|
+
variant,
|
|
24
|
+
size,
|
|
25
|
+
...props
|
|
26
|
+
}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleGroupItemVariants>): _$react_jsx_runtime0.JSX.Element;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { ToggleGroup, ToggleGroupItem, toggleGroupItemVariants };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.mjs";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { cva } from "class-variance-authority";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
|
|
7
|
+
//#region src/components/toggle-group.tsx
|
|
8
|
+
const toggleGroupItemVariants = cva([
|
|
9
|
+
"inline-flex items-center justify-center gap-1 whitespace-nowrap",
|
|
10
|
+
"type-text-sm font-medium",
|
|
11
|
+
"transition-colors",
|
|
12
|
+
"outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background focus:z-10 focus-visible:z-10",
|
|
13
|
+
"[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0",
|
|
14
|
+
"disabled:pointer-events-none disabled:opacity-50"
|
|
15
|
+
].join(" "), {
|
|
16
|
+
variants: {
|
|
17
|
+
variant: {
|
|
18
|
+
default: [
|
|
19
|
+
"bg-transparent text-muted-foreground",
|
|
20
|
+
"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
|
|
21
|
+
"[@media(hover:hover)]:hover:bg-background-hover [@media(hover:hover)]:hover:text-muted-foreground-hover"
|
|
22
|
+
].join(" "),
|
|
23
|
+
outline: [
|
|
24
|
+
"border border-border bg-transparent text-muted-foreground",
|
|
25
|
+
"data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
|
|
26
|
+
"[@media(hover:hover)]:hover:bg-background-hover [@media(hover:hover)]:hover:text-muted-foreground-hover"
|
|
27
|
+
].join(" ")
|
|
28
|
+
},
|
|
29
|
+
size: {
|
|
30
|
+
default: "h-8 px-2 min-w-8",
|
|
31
|
+
sm: "h-7 px-1.5 min-w-7"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
variant: "default",
|
|
36
|
+
size: "default"
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
const ToggleGroupContext = React.createContext({
|
|
40
|
+
size: "default",
|
|
41
|
+
variant: "default"
|
|
42
|
+
});
|
|
43
|
+
function ToggleGroup({ className, variant, size, children, ...props }) {
|
|
44
|
+
return /* @__PURE__ */ jsx(ToggleGroupPrimitive.Root, {
|
|
45
|
+
"data-slot": "toggle-group",
|
|
46
|
+
className: cn("group/toggle-group flex h-fit w-fit items-center rounded-md", className),
|
|
47
|
+
...props,
|
|
48
|
+
children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, {
|
|
49
|
+
value: {
|
|
50
|
+
variant,
|
|
51
|
+
size
|
|
52
|
+
},
|
|
53
|
+
children
|
|
54
|
+
})
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function ToggleGroupItem({ className, children, variant, size, ...props }) {
|
|
58
|
+
const context = React.useContext(ToggleGroupContext);
|
|
59
|
+
const resolvedVariant = context.variant ?? variant;
|
|
60
|
+
const resolvedSize = context.size ?? size;
|
|
61
|
+
return /* @__PURE__ */ jsx(ToggleGroupPrimitive.Item, {
|
|
62
|
+
"data-slot": "toggle-group-item",
|
|
63
|
+
className: cn(toggleGroupItemVariants({
|
|
64
|
+
variant: resolvedVariant,
|
|
65
|
+
size: resolvedSize
|
|
66
|
+
}), "min-w-0 flex-1 shrink-0 rounded-none first:rounded-l-md last:rounded-r-md", resolvedVariant === "outline" && "border-l-0 first:border-l", className),
|
|
67
|
+
...props,
|
|
68
|
+
children
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
72
|
+
export { ToggleGroup, ToggleGroupItem, toggleGroupItemVariants };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Button } from "./button.mjs";
|
|
2
|
+
import * as _$react from "react";
|
|
3
|
+
import { ComponentPropsWithRef } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/components/tooltip-icon-button.d.ts
|
|
6
|
+
type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
|
|
7
|
+
tooltip: string;
|
|
8
|
+
side?: "top" | "bottom" | "left" | "right";
|
|
9
|
+
};
|
|
10
|
+
declare const TooltipIconButton: _$react.ForwardRefExoticComponent<Omit<TooltipIconButtonProps, "ref"> & _$react.RefAttributes<HTMLButtonElement>>;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { TooltipIconButton, type TooltipIconButtonProps };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Button } from "./button.mjs";
|
|
3
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.mjs";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { forwardRef } from "react";
|
|
6
|
+
import { Slottable } from "@radix-ui/react-slot";
|
|
7
|
+
//#region src/components/tooltip-icon-button.tsx
|
|
8
|
+
const TooltipIconButton = forwardRef(({ children, tooltip, side = "bottom", ...rest }, ref) => {
|
|
9
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
10
|
+
asChild: true,
|
|
11
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
12
|
+
size: "icon",
|
|
13
|
+
...rest,
|
|
14
|
+
ref,
|
|
15
|
+
children: [/* @__PURE__ */ jsx(Slottable, { children }), /* @__PURE__ */ jsx("span", {
|
|
16
|
+
className: "sr-only",
|
|
17
|
+
children: tooltip
|
|
18
|
+
})]
|
|
19
|
+
})
|
|
20
|
+
}), /* @__PURE__ */ jsx(TooltipContent, {
|
|
21
|
+
side,
|
|
22
|
+
children: tooltip
|
|
23
|
+
})] });
|
|
24
|
+
});
|
|
25
|
+
TooltipIconButton.displayName = "TooltipIconButton";
|
|
26
|
+
//#endregion
|
|
27
|
+
export { TooltipIconButton };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
4
|
+
|
|
5
|
+
//#region src/components/tooltip.d.ts
|
|
6
|
+
declare function TooltipProvider({
|
|
7
|
+
delayDuration,
|
|
8
|
+
...props
|
|
9
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Provider>): _$react_jsx_runtime0.JSX.Element;
|
|
10
|
+
declare function Tooltip({
|
|
11
|
+
...props
|
|
12
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Root>): _$react_jsx_runtime0.JSX.Element;
|
|
13
|
+
declare function TooltipTrigger({
|
|
14
|
+
...props
|
|
15
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Trigger>): _$react_jsx_runtime0.JSX.Element;
|
|
16
|
+
declare function TooltipContent({
|
|
17
|
+
className,
|
|
18
|
+
sideOffset,
|
|
19
|
+
children,
|
|
20
|
+
...props
|
|
21
|
+
}: React.ComponentProps<typeof TooltipPrimitive.Content>): _$react_jsx_runtime0.JSX.Element;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "../lib/cn.mjs";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
5
|
+
//#region src/components/tooltip.tsx
|
|
6
|
+
function TooltipProvider({ delayDuration = 0, ...props }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(TooltipPrimitive.Provider, {
|
|
8
|
+
"data-slot": "tooltip-provider",
|
|
9
|
+
delayDuration,
|
|
10
|
+
...props
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function Tooltip({ ...props }) {
|
|
14
|
+
return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsx(TooltipPrimitive.Root, {
|
|
15
|
+
"data-slot": "tooltip",
|
|
16
|
+
...props
|
|
17
|
+
}) });
|
|
18
|
+
}
|
|
19
|
+
function TooltipTrigger({ ...props }) {
|
|
20
|
+
return /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, {
|
|
21
|
+
"data-slot": "tooltip-trigger",
|
|
22
|
+
...props
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function TooltipContent({ className, sideOffset = 6, children, ...props }) {
|
|
26
|
+
return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs(TooltipPrimitive.Content, {
|
|
27
|
+
"data-slot": "tooltip-content",
|
|
28
|
+
sideOffset,
|
|
29
|
+
className: cn("bg-inverted text-inverted-foreground dark:bg-subtle dark:text-foreground", "z-50 w-fit rounded-md px-3 py-2 shadow-lg dark:shadow-none dark:drop-shadow-[0_0_0.5px_var(--color-border)]", "type-text-xs font-semibold text-balance text-center", "animate-in fade-in-0 zoom-in-95", "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", "origin-(--radix-tooltip-content-transform-origin)", className),
|
|
30
|
+
...props,
|
|
31
|
+
children: [children, /* @__PURE__ */ jsx(TooltipPrimitive.Arrow, { className: "bg-inverted fill-inverted dark:bg-subtle dark:fill-subtle z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })]
|
|
32
|
+
}) });
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
+
//#region src/hooks/use-copy-to-clipboard.ts
|
|
4
|
+
function useCopyToClipboard({ resetDelay = 2e3 } = {}) {
|
|
5
|
+
const [isCopied, setIsCopied] = useState(false);
|
|
6
|
+
const timeoutRef = useRef(null);
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
return () => {
|
|
9
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
10
|
+
};
|
|
11
|
+
}, []);
|
|
12
|
+
return {
|
|
13
|
+
copy: useCallback((text) => {
|
|
14
|
+
navigator.clipboard.writeText(text).then(() => {
|
|
15
|
+
setIsCopied(true);
|
|
16
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
17
|
+
timeoutRef.current = setTimeout(() => setIsCopied(false), resetDelay);
|
|
18
|
+
});
|
|
19
|
+
}, [resetDelay]),
|
|
20
|
+
isCopied
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { useCopyToClipboard };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
//#region src/hooks/use-mobile.ts
|
|
3
|
+
const MOBILE_BREAKPOINT = 768;
|
|
4
|
+
function useIsMobile() {
|
|
5
|
+
const [isMobile, setIsMobile] = React.useState(void 0);
|
|
6
|
+
React.useEffect(() => {
|
|
7
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
8
|
+
const onChange = () => setIsMobile(mql.matches);
|
|
9
|
+
mql.addEventListener("change", onChange);
|
|
10
|
+
setIsMobile(mql.matches);
|
|
11
|
+
return () => mql.removeEventListener("change", onChange);
|
|
12
|
+
}, []);
|
|
13
|
+
return !!isMobile;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { useIsMobile };
|
package/dist/lib/cn.mjs
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@alpic-ai/ui",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Alpic design system — shared UI components",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./components/*": "./src/components/*.tsx",
|
|
8
|
+
"./hooks/*": "./src/hooks/*.ts",
|
|
9
|
+
"./lib/cn": "./src/lib/cn.ts",
|
|
10
|
+
"./theme": "./src/styles/tokens.css"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"src/components",
|
|
15
|
+
"src/hooks",
|
|
16
|
+
"src/lib",
|
|
17
|
+
"src/styles/tokens.css"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"exports": {
|
|
21
|
+
"./components/*": {
|
|
22
|
+
"types": "./dist/components/*.d.mts",
|
|
23
|
+
"default": "./dist/components/*.mjs"
|
|
24
|
+
},
|
|
25
|
+
"./hooks/*": {
|
|
26
|
+
"types": "./dist/hooks/*.d.mts",
|
|
27
|
+
"default": "./dist/hooks/*.mjs"
|
|
28
|
+
},
|
|
29
|
+
"./lib/cn": {
|
|
30
|
+
"types": "./dist/lib/cn.d.mts",
|
|
31
|
+
"default": "./dist/lib/cn.mjs"
|
|
32
|
+
},
|
|
33
|
+
"./theme": "./src/styles/tokens.css"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "shx rm -rf dist && tsdown",
|
|
38
|
+
"format": "biome check --write --error-on-warnings .",
|
|
39
|
+
"test:type": "tsc --noEmit",
|
|
40
|
+
"test:format": "biome check --error-on-warnings .",
|
|
41
|
+
"dev:ui": "ladle serve",
|
|
42
|
+
"publish:npm": "pnpm publish --tag \"${NPM_TAG}\" --access public --no-git-checks"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"lucide-react": "^1.0.0",
|
|
46
|
+
"react": "^19.0.0",
|
|
47
|
+
"react-dom": "^19.0.0",
|
|
48
|
+
"sonner": "^2.0.0",
|
|
49
|
+
"tailwindcss": "^4.0.0",
|
|
50
|
+
"tw-animate-css": "^1.0.0"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@radix-ui/react-accordion": "^1.2.12",
|
|
54
|
+
"@radix-ui/react-avatar": "^1.1.11",
|
|
55
|
+
"@radix-ui/react-checkbox": "^1.3.3",
|
|
56
|
+
"@radix-ui/react-collapsible": "^1.1.12",
|
|
57
|
+
"@radix-ui/react-dialog": "^1.1.15",
|
|
58
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
59
|
+
"@radix-ui/react-label": "^2.1.8",
|
|
60
|
+
"@radix-ui/react-popover": "^1.1.15",
|
|
61
|
+
"@radix-ui/react-radio-group": "^1.3.8",
|
|
62
|
+
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
63
|
+
"@radix-ui/react-select": "^2.2.6",
|
|
64
|
+
"@radix-ui/react-separator": "^1.1.8",
|
|
65
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
66
|
+
"@radix-ui/react-switch": "^1.2.6",
|
|
67
|
+
"@radix-ui/react-tabs": "^1.1.13",
|
|
68
|
+
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
69
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
70
|
+
"class-variance-authority": "^0.7.1",
|
|
71
|
+
"clsx": "^2.1.1",
|
|
72
|
+
"cmdk": "^1.1.1",
|
|
73
|
+
"tailwind-merge": "^3.5.0"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@ladle/react": "^5.1.1",
|
|
77
|
+
"@tailwindcss/postcss": "^4.2.2",
|
|
78
|
+
"@types/react": "19.2.14",
|
|
79
|
+
"@types/react-dom": "19.2.3",
|
|
80
|
+
"lucide-react": "^1.7.0",
|
|
81
|
+
"shx": "^0.4.0",
|
|
82
|
+
"sonner": "^2.0.7",
|
|
83
|
+
"tailwindcss": "^4.2.2",
|
|
84
|
+
"tsdown": "^0.21.7",
|
|
85
|
+
"tw-animate-css": "^1.4.0",
|
|
86
|
+
"typescript": "^6.0.2"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as AccordionPrimitive from "@radix-ui/react-accordion";
|
|
4
|
+
import { ChevronDownIcon } from "lucide-react";
|
|
5
|
+
import type * as React from "react";
|
|
6
|
+
|
|
7
|
+
import { cn } from "../lib/cn";
|
|
8
|
+
|
|
9
|
+
const ACCORDION_CARD_VALUE = "accordion-card";
|
|
10
|
+
|
|
11
|
+
function AccordionCard({
|
|
12
|
+
defaultOpen = false,
|
|
13
|
+
open,
|
|
14
|
+
onOpenChange,
|
|
15
|
+
disabled,
|
|
16
|
+
className,
|
|
17
|
+
children,
|
|
18
|
+
...props
|
|
19
|
+
}: {
|
|
20
|
+
defaultOpen?: boolean;
|
|
21
|
+
open?: boolean;
|
|
22
|
+
onOpenChange?: (nextOpen: boolean) => void;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
} & Omit<
|
|
25
|
+
React.ComponentProps<typeof AccordionPrimitive.Root>,
|
|
26
|
+
"type" | "collapsible" | "defaultValue" | "value" | "onValueChange" | "disabled"
|
|
27
|
+
>) {
|
|
28
|
+
return (
|
|
29
|
+
<AccordionPrimitive.Root
|
|
30
|
+
data-slot="accordion-card"
|
|
31
|
+
className={cn("rounded-xl border bg-card text-card-foreground data-[disabled]:opacity-50", className)}
|
|
32
|
+
{...props}
|
|
33
|
+
type="single"
|
|
34
|
+
collapsible
|
|
35
|
+
disabled={disabled}
|
|
36
|
+
defaultValue={defaultOpen ? ACCORDION_CARD_VALUE : undefined}
|
|
37
|
+
{...(open !== undefined ? { value: open ? ACCORDION_CARD_VALUE : "" } : {})}
|
|
38
|
+
{...(onOpenChange !== undefined ? { onValueChange: (value: string) => onOpenChange(value !== "") } : {})}
|
|
39
|
+
>
|
|
40
|
+
<AccordionPrimitive.Item value={ACCORDION_CARD_VALUE} disabled={disabled}>
|
|
41
|
+
{children}
|
|
42
|
+
</AccordionPrimitive.Item>
|
|
43
|
+
</AccordionPrimitive.Root>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function AccordionCardHeader({
|
|
48
|
+
className,
|
|
49
|
+
children,
|
|
50
|
+
...props
|
|
51
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
|
|
52
|
+
return (
|
|
53
|
+
<AccordionPrimitive.Header className="flex">
|
|
54
|
+
<AccordionPrimitive.Trigger
|
|
55
|
+
data-slot="accordion-card-header"
|
|
56
|
+
className={cn(
|
|
57
|
+
"flex flex-1 items-center justify-between gap-4 p-4",
|
|
58
|
+
"type-text-md font-semibold text-foreground",
|
|
59
|
+
"rounded-xl outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-card",
|
|
60
|
+
"[@media(hover:hover)]:hover:underline",
|
|
61
|
+
"disabled:pointer-events-none",
|
|
62
|
+
"[&[data-state=open]>svg]:rotate-180",
|
|
63
|
+
className,
|
|
64
|
+
)}
|
|
65
|
+
{...props}
|
|
66
|
+
>
|
|
67
|
+
{children}
|
|
68
|
+
<ChevronDownIcon className="size-5 shrink-0 text-muted-foreground transition-transform duration-200" />
|
|
69
|
+
</AccordionPrimitive.Trigger>
|
|
70
|
+
</AccordionPrimitive.Header>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function AccordionCardTitle({ className, children, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {
|
|
75
|
+
return (
|
|
76
|
+
<h3 className={cn("type-text-md font-semibold", className)} {...props}>
|
|
77
|
+
{children}
|
|
78
|
+
</h3>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* `className` is forwarded to the inner padding wrapper, not the Radix Content root.
|
|
84
|
+
* The root always applies overflow-hidden and the accordion animations.
|
|
85
|
+
* To override overflow or animation behavior, wrap this component in an additional element.
|
|
86
|
+
*/
|
|
87
|
+
function AccordionCardContent({
|
|
88
|
+
className,
|
|
89
|
+
children,
|
|
90
|
+
...props
|
|
91
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Content>) {
|
|
92
|
+
return (
|
|
93
|
+
<AccordionPrimitive.Content
|
|
94
|
+
data-slot="accordion-card-content"
|
|
95
|
+
className="overflow-hidden data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
|
96
|
+
{...props}
|
|
97
|
+
>
|
|
98
|
+
<div className={cn("px-4 pb-4 type-text-sm text-muted-foreground", className)}>{children}</div>
|
|
99
|
+
</AccordionPrimitive.Content>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export { AccordionCard, AccordionCardContent, AccordionCardHeader, AccordionCardTitle };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as AccordionPrimitive from "@radix-ui/react-accordion";
|
|
4
|
+
import { ChevronDownIcon } from "lucide-react";
|
|
5
|
+
import type * as React from "react";
|
|
6
|
+
|
|
7
|
+
import { cn } from "../lib/cn";
|
|
8
|
+
|
|
9
|
+
function Accordion({ ...props }: React.ComponentProps<typeof AccordionPrimitive.Root>) {
|
|
10
|
+
return <AccordionPrimitive.Root data-slot="accordion" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function AccordionItem({ className, ...props }: React.ComponentProps<typeof AccordionPrimitive.Item>) {
|
|
14
|
+
return (
|
|
15
|
+
<AccordionPrimitive.Item
|
|
16
|
+
data-slot="accordion-item"
|
|
17
|
+
className={cn("border-b border-border-secondary", className)}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function AccordionTrigger({ className, children, ...props }: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
|
|
24
|
+
return (
|
|
25
|
+
<AccordionPrimitive.Header className="flex">
|
|
26
|
+
<AccordionPrimitive.Trigger
|
|
27
|
+
data-slot="accordion-trigger"
|
|
28
|
+
className={cn(
|
|
29
|
+
"flex flex-1 items-center justify-between gap-4 py-4",
|
|
30
|
+
"type-text-md font-semibold text-foreground",
|
|
31
|
+
"outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded-sm",
|
|
32
|
+
"[@media(hover:hover)]:hover:underline",
|
|
33
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
34
|
+
"[&[data-state=open]>svg]:rotate-180",
|
|
35
|
+
className,
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
>
|
|
39
|
+
{children}
|
|
40
|
+
<ChevronDownIcon className="size-6 shrink-0 text-muted-foreground transition-transform duration-200" />
|
|
41
|
+
</AccordionPrimitive.Trigger>
|
|
42
|
+
</AccordionPrimitive.Header>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* `className` is forwarded to the inner padding wrapper, not the Radix Content root.
|
|
48
|
+
* The root always applies overflow-hidden and the accordion animations.
|
|
49
|
+
* To override overflow or animation behavior, wrap this component in an additional element.
|
|
50
|
+
*/
|
|
51
|
+
function AccordionContent({ className, children, ...props }: React.ComponentProps<typeof AccordionPrimitive.Content>) {
|
|
52
|
+
return (
|
|
53
|
+
<AccordionPrimitive.Content
|
|
54
|
+
data-slot="accordion-content"
|
|
55
|
+
className="overflow-hidden data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
|
56
|
+
{...props}
|
|
57
|
+
>
|
|
58
|
+
<div className={cn("pb-4 type-text-sm text-muted-foreground", className)}>{children}</div>
|
|
59
|
+
</AccordionPrimitive.Content>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@alpic-ai/ui/lib/cn";
|
|
4
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
5
|
+
import { AlertTriangleIcon } from "lucide-react";
|
|
6
|
+
import type * as React from "react";
|
|
7
|
+
|
|
8
|
+
const alertVariants = cva(
|
|
9
|
+
[
|
|
10
|
+
"w-full rounded-md border px-4 py-3",
|
|
11
|
+
"grid grid-cols-[auto_1fr] gap-x-3 gap-y-0.5 items-start",
|
|
12
|
+
"[&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:mt-0.5",
|
|
13
|
+
"[&>:not(svg)]:col-start-2",
|
|
14
|
+
].join(" "),
|
|
15
|
+
{
|
|
16
|
+
variants: {
|
|
17
|
+
variant: {
|
|
18
|
+
default: "bg-muted border-border [&>svg]:text-muted-foreground",
|
|
19
|
+
destructive: "bg-destructive/10 border-destructive/30 [&>svg]:text-destructive",
|
|
20
|
+
warning: "bg-badge-warning/10 border-badge-warning/30 [&>svg]:text-badge-warning",
|
|
21
|
+
success: "bg-badge-success/10 border-badge-success/30 [&>svg]:text-badge-success",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: {
|
|
25
|
+
variant: "default",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
interface AlertProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof alertVariants> {}
|
|
31
|
+
|
|
32
|
+
function Alert({ className, variant, ...props }: AlertProps) {
|
|
33
|
+
return <div role="alert" className={cn(alertVariants({ variant }), className)} {...props} />;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function AlertTitle({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) {
|
|
37
|
+
return <p className={cn("type-text-sm font-semibold leading-snug", className)} {...props} />;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function AlertDescription({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
|
41
|
+
return <div className={cn("type-text-sm text-muted-foreground [&_p]:leading-relaxed", className)} {...props} />;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface ConvenienceAlertProps {
|
|
45
|
+
title?: string;
|
|
46
|
+
description?: React.ReactNode;
|
|
47
|
+
className?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function ErrorAlert({
|
|
51
|
+
title = "An unexpected error occurred",
|
|
52
|
+
description = "Please try again later or contact support if the problem persists.",
|
|
53
|
+
className,
|
|
54
|
+
}: ConvenienceAlertProps) {
|
|
55
|
+
return (
|
|
56
|
+
<Alert variant="destructive" className={className}>
|
|
57
|
+
<AlertTriangleIcon />
|
|
58
|
+
<AlertTitle>{title}</AlertTitle>
|
|
59
|
+
<AlertDescription>{description}</AlertDescription>
|
|
60
|
+
</Alert>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function WarningAlert({ title, description, className }: ConvenienceAlertProps) {
|
|
65
|
+
return (
|
|
66
|
+
<Alert variant="warning" className={className}>
|
|
67
|
+
<AlertTriangleIcon />
|
|
68
|
+
<AlertTitle>{title}</AlertTitle>
|
|
69
|
+
<AlertDescription>{description}</AlertDescription>
|
|
70
|
+
</Alert>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { Alert, AlertDescription, AlertTitle, ErrorAlert, WarningAlert };
|