@allbluecn/ui 0.3.14 → 0.4.1
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/ai-command-button.d.ts +10 -0
- package/dist/ai-command-button.js +12 -0
- package/dist/ai-stream-text.d.ts +9 -0
- package/dist/ai-stream-text.js +12 -0
- package/dist/alert-dialog.d.ts +20 -0
- package/dist/alert-dialog.js +101 -0
- package/dist/animated-theme-toggler.d.ts +11 -0
- package/dist/animated-theme-toggler.js +169 -0
- package/dist/auth-client.d.ts +27 -0
- package/dist/auth-client.js +86 -0
- package/dist/auth-layout.d.ts +14 -0
- package/dist/auth-layout.js +43 -0
- package/dist/avatar.d.ts +13 -0
- package/dist/avatar.js +51 -0
- package/dist/badge.d.ts +11 -0
- package/dist/badge.js +28 -0
- package/dist/button.d.ts +12 -0
- package/dist/button.js +48 -0
- package/dist/card.d.ts +13 -0
- package/dist/card.js +56 -0
- package/dist/checkbox.d.ts +6 -0
- package/dist/checkbox.js +22 -0
- package/dist/context-menu.d.ts +33 -0
- package/dist/context-menu.js +125 -0
- package/dist/dialog.d.ts +19 -0
- package/dist/dialog.js +95 -0
- package/dist/dropdown-menu.d.ts +31 -0
- package/dist/dropdown-menu.js +128 -0
- package/dist/empty.d.ts +13 -0
- package/dist/empty.js +59 -0
- package/dist/grid-pattern.d.ts +14 -0
- package/dist/grid-pattern.js +47 -0
- package/dist/icon-packs/index.d.ts +2 -0
- package/dist/icon-packs/index.js +4 -0
- package/dist/icon-packs/knowledge.d.ts +2 -0
- package/dist/icon-packs/knowledge.js +70 -0
- package/dist/icon-packs/prd.d.ts +2 -0
- package/dist/icon-packs/prd.js +86 -0
- package/dist/icon-packs/project.d.ts +2 -0
- package/dist/icon-packs/project.js +74 -0
- package/dist/icon-picker.d.ts +11 -0
- package/dist/icon-picker.js +39 -0
- package/dist/index-CQsbeClc.d.ts +17 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/input.d.ts +5 -0
- package/dist/input.js +14 -0
- package/dist/item.d.ts +25 -0
- package/dist/item.js +118 -0
- package/dist/kbd.d.ts +4 -0
- package/dist/kbd.js +12 -0
- package/dist/label.d.ts +6 -0
- package/dist/label.js +14 -0
- package/dist/layout-panel-top.d.ts +12 -0
- package/dist/layout-panel-top.js +127 -0
- package/dist/name-confirm-dialog.d.ts +15 -0
- package/dist/name-confirm-dialog.js +105 -0
- package/dist/nav-float-button.d.ts +12 -0
- package/dist/nav-float-button.js +249 -0
- package/dist/notion-avatar.d.ts +13 -0
- package/dist/notion-avatar.js +83 -0
- package/dist/placeholder-page.d.ts +10 -0
- package/dist/placeholder-page.js +28 -0
- package/dist/popover.d.ts +12 -0
- package/dist/popover.js +56 -0
- package/dist/reference-inline.d.ts +10 -0
- package/dist/reference-inline.js +35 -0
- package/dist/reference-search.d.ts +12 -0
- package/dist/reference-search.js +26 -0
- package/dist/resizable.d.ts +9 -0
- package/dist/resizable.js +28 -0
- package/dist/select.d.ts +17 -0
- package/dist/select.js +99 -0
- package/dist/separator.d.ts +6 -0
- package/dist/separator.js +17 -0
- package/dist/sheet.d.ts +16 -0
- package/dist/sheet.js +90 -0
- package/dist/sidebar.d.ts +71 -0
- package/dist/sidebar.js +369 -0
- package/dist/skeleton.d.ts +4 -0
- package/dist/skeleton.js +12 -0
- package/dist/sonner.d.ts +5 -0
- package/dist/sonner.js +19 -0
- package/dist/switch.d.ts +8 -0
- package/dist/switch.js +19 -0
- package/dist/textarea.d.ts +5 -0
- package/dist/textarea.js +13 -0
- package/dist/timezone-provider.d.ts +18 -0
- package/dist/timezone-provider.js +29 -0
- package/dist/tooltip.d.ts +9 -0
- package/dist/tooltip.js +35 -0
- package/dist/use-mobile.d.ts +4 -0
- package/dist/use-mobile.js +18 -0
- package/dist/user-avatar.d.ts +14 -0
- package/dist/user-avatar.js +34 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +8 -0
- package/package.json +178 -49
- package/src/ai-command-button.tsx +0 -36
- package/src/ai-stream-text.tsx +0 -37
- package/src/alert-dialog.tsx +0 -216
- package/src/animated-theme-toggler.tsx +0 -272
- package/src/auth-client.ts +0 -108
- package/src/auth-layout.tsx +0 -66
- package/src/avatar.tsx +0 -129
- package/src/badge.tsx +0 -66
- package/src/button.tsx +0 -84
- package/src/card.tsx +0 -120
- package/src/checkbox.tsx +0 -50
- package/src/context-menu.tsx +0 -280
- package/src/dialog.tsx +0 -183
- package/src/dropdown-menu.tsx +0 -286
- package/src/empty.tsx +0 -121
- package/src/grid-pattern.tsx +0 -87
- package/src/icon-packs/index.ts +0 -27
- package/src/icon-packs/knowledge.ts +0 -55
- package/src/icon-packs/prd.ts +0 -63
- package/src/icon-packs/project.ts +0 -59
- package/src/icon-picker.tsx +0 -68
- package/src/index.ts +0 -23
- package/src/input.tsx +0 -36
- package/src/item.tsx +0 -213
- package/src/kbd.tsx +0 -33
- package/src/label.tsx +0 -39
- package/src/layout-panel-top.tsx +0 -160
- package/src/name-confirm-dialog.tsx +0 -153
- package/src/nav-float-button.tsx +0 -301
- package/src/notion-avatar.tsx +0 -126
- package/src/placeholder-page.tsx +0 -42
- package/src/popover.tsx +0 -106
- package/src/reference-inline.tsx +0 -53
- package/src/reference-search.tsx +0 -52
- package/src/resizable.tsx +0 -67
- package/src/select.tsx +0 -207
- package/src/separator.tsx +0 -45
- package/src/sheet.tsx +0 -164
- package/src/sidebar.tsx +0 -708
- package/src/skeleton.tsx +0 -30
- package/src/sonner.tsx +0 -37
- package/src/switch.tsx +0 -48
- package/src/textarea.tsx +0 -35
- package/src/timezone-provider.tsx +0 -55
- package/src/tooltip.tsx +0 -72
- package/src/use-mobile.ts +0 -36
- package/src/user-avatar.tsx +0 -79
- package/src/utils.ts +0 -6
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AICommandDef } from "@allbluecn/shared";
|
|
2
|
+
//#region src/ai-command-button.d.ts
|
|
3
|
+
interface Props {
|
|
4
|
+
command: AICommandDef;
|
|
5
|
+
onClick: () => void;
|
|
6
|
+
loading?: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare function AICommandButton({ command, onClick, loading }: Props): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { AICommandButton };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
//#region src/ai-command-button.tsx
|
|
3
|
+
function AICommandButton({ command, onClick, loading }) {
|
|
4
|
+
return /* @__PURE__ */ jsx("button", {
|
|
5
|
+
className: "inline-flex items-center gap-1 px-2 py-1 text-xs rounded bg-primary/10 text-primary hover:bg-primary/20",
|
|
6
|
+
onClick,
|
|
7
|
+
disabled: loading,
|
|
8
|
+
children: loading ? "..." : command.label
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { AICommandButton };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/ai-stream-text.d.ts
|
|
2
|
+
interface Props {
|
|
3
|
+
text: string;
|
|
4
|
+
streaming?: boolean;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
declare function AIStreamText({ text, streaming, className }: Props): import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { AIStreamText };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
//#region src/ai-stream-text.tsx
|
|
4
|
+
function AIStreamText({ text, streaming = false, className }) {
|
|
5
|
+
if (!text && !streaming) return null;
|
|
6
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
7
|
+
className: "prose prose-sm max-w-none" + (className ? " " + className : ""),
|
|
8
|
+
children: [text || "\xA0", streaming && /* @__PURE__ */ jsx("span", { className: "inline-block w-2 h-4 ml-0.5 bg-primary animate-pulse rounded-sm align-middle" })]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { AIStreamText };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Button } from "./button.js";
|
|
2
|
+
import * as React$1 from "react";
|
|
3
|
+
import { AlertDialog as AlertDialog$1 } from "radix-ui";
|
|
4
|
+
//#region src/alert-dialog.d.ts
|
|
5
|
+
declare function AlertDialog({ ...props }: React$1.ComponentProps<typeof AlertDialog$1.Root>): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
declare function AlertDialogTrigger({ ...props }: React$1.ComponentProps<typeof AlertDialog$1.Trigger>): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
declare function AlertDialogPortal({ ...props }: React$1.ComponentProps<typeof AlertDialog$1.Portal>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
declare function AlertDialogOverlay({ className, ...props }: React$1.ComponentProps<typeof AlertDialog$1.Overlay>): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
declare function AlertDialogContent({ className, size, ...props }: React$1.ComponentProps<typeof AlertDialog$1.Content> & {
|
|
10
|
+
size?: "default" | "sm";
|
|
11
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
declare function AlertDialogHeader({ className, ...props }: React$1.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
declare function AlertDialogFooter({ className, ...props }: React$1.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
declare function AlertDialogMedia({ className, ...props }: React$1.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
declare function AlertDialogTitle({ className, ...props }: React$1.ComponentProps<typeof AlertDialog$1.Title>): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
declare function AlertDialogDescription({ className, ...props }: React$1.ComponentProps<typeof AlertDialog$1.Description>): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
declare function AlertDialogAction({ className, variant, size, ...props }: React$1.ComponentProps<typeof AlertDialog$1.Action> & Pick<React$1.ComponentProps<typeof Button>, "variant" | "size">): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
declare function AlertDialogCancel({ className, variant, size, ...props }: React$1.ComponentProps<typeof AlertDialog$1.Cancel> & Pick<React$1.ComponentProps<typeof Button>, "variant" | "size">): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger };
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "./utils.js";
|
|
3
|
+
import { Button } from "./button.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import "react";
|
|
6
|
+
import { AlertDialog as AlertDialog$1 } from "radix-ui";
|
|
7
|
+
//#region src/alert-dialog.tsx
|
|
8
|
+
function AlertDialog({ ...props }) {
|
|
9
|
+
return /* @__PURE__ */ jsx(AlertDialog$1.Root, {
|
|
10
|
+
"data-slot": "alert-dialog",
|
|
11
|
+
...props
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function AlertDialogTrigger({ ...props }) {
|
|
15
|
+
return /* @__PURE__ */ jsx(AlertDialog$1.Trigger, {
|
|
16
|
+
"data-slot": "alert-dialog-trigger",
|
|
17
|
+
...props
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function AlertDialogPortal({ ...props }) {
|
|
21
|
+
return /* @__PURE__ */ jsx(AlertDialog$1.Portal, {
|
|
22
|
+
"data-slot": "alert-dialog-portal",
|
|
23
|
+
...props
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function AlertDialogOverlay({ className, ...props }) {
|
|
27
|
+
return /* @__PURE__ */ jsx(AlertDialog$1.Overlay, {
|
|
28
|
+
"data-slot": "alert-dialog-overlay",
|
|
29
|
+
className: cn("fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0", className),
|
|
30
|
+
...props
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function AlertDialogContent({ className, size = "default", ...props }) {
|
|
34
|
+
return /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [/* @__PURE__ */ jsx(AlertDialogOverlay, {}), /* @__PURE__ */ jsx(AlertDialog$1.Content, {
|
|
35
|
+
"data-slot": "alert-dialog-content",
|
|
36
|
+
"data-size": size,
|
|
37
|
+
className: cn("group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95", className),
|
|
38
|
+
...props
|
|
39
|
+
})] });
|
|
40
|
+
}
|
|
41
|
+
function AlertDialogHeader({ className, ...props }) {
|
|
42
|
+
return /* @__PURE__ */ jsx("div", {
|
|
43
|
+
"data-slot": "alert-dialog-header",
|
|
44
|
+
className: cn("grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]", className),
|
|
45
|
+
...props
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function AlertDialogFooter({ className, ...props }) {
|
|
49
|
+
return /* @__PURE__ */ jsx("div", {
|
|
50
|
+
"data-slot": "alert-dialog-footer",
|
|
51
|
+
className: cn("-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end", className),
|
|
52
|
+
...props
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function AlertDialogMedia({ className, ...props }) {
|
|
56
|
+
return /* @__PURE__ */ jsx("div", {
|
|
57
|
+
"data-slot": "alert-dialog-media",
|
|
58
|
+
className: cn("mb-2 inline-flex size-10 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6", className),
|
|
59
|
+
...props
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function AlertDialogTitle({ className, ...props }) {
|
|
63
|
+
return /* @__PURE__ */ jsx(AlertDialog$1.Title, {
|
|
64
|
+
"data-slot": "alert-dialog-title",
|
|
65
|
+
className: cn("text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2", className),
|
|
66
|
+
...props
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function AlertDialogDescription({ className, ...props }) {
|
|
70
|
+
return /* @__PURE__ */ jsx(AlertDialog$1.Description, {
|
|
71
|
+
"data-slot": "alert-dialog-description",
|
|
72
|
+
className: cn("text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground", className),
|
|
73
|
+
...props
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function AlertDialogAction({ className, variant = "default", size = "default", ...props }) {
|
|
77
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
78
|
+
variant,
|
|
79
|
+
size,
|
|
80
|
+
asChild: true,
|
|
81
|
+
children: /* @__PURE__ */ jsx(AlertDialog$1.Action, {
|
|
82
|
+
"data-slot": "alert-dialog-action",
|
|
83
|
+
className: cn(className),
|
|
84
|
+
...props
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function AlertDialogCancel({ className, variant = "outline", size = "default", ...props }) {
|
|
89
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
90
|
+
variant,
|
|
91
|
+
size,
|
|
92
|
+
asChild: true,
|
|
93
|
+
children: /* @__PURE__ */ jsx(AlertDialog$1.Cancel, {
|
|
94
|
+
"data-slot": "alert-dialog-cancel",
|
|
95
|
+
className: cn(className),
|
|
96
|
+
...props
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/animated-theme-toggler.d.ts
|
|
2
|
+
type TransitionVariant = "circle" | "square" | "triangle" | "diamond" | "hexagon" | "rectangle" | "star";
|
|
3
|
+
interface AnimatedThemeTogglerProps extends React.ComponentPropsWithoutRef<"button"> {
|
|
4
|
+
duration?: number;
|
|
5
|
+
variant?: TransitionVariant;
|
|
6
|
+
/** When true, the transition expands from the viewport center instead of the button center. */
|
|
7
|
+
fromCenter?: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare const AnimatedThemeToggler: ({ className, duration, variant, fromCenter, ...props }: AnimatedThemeTogglerProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { AnimatedThemeToggler, TransitionVariant };
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { cn } from "./utils.js";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
import { Moon, Sun } from "lucide-react";
|
|
5
|
+
import { flushSync } from "react-dom";
|
|
6
|
+
import { useTheme } from "next-themes";
|
|
7
|
+
//#region src/animated-theme-toggler.tsx
|
|
8
|
+
function polygonCollapsed(cx, cy, vertexCount) {
|
|
9
|
+
return `polygon(${Array.from({ length: vertexCount }, () => `${cx}px ${cy}px`).join(", ")})`;
|
|
10
|
+
}
|
|
11
|
+
function getThemeTransitionClipPaths(variant, cx, cy, maxRadius, viewportWidth, viewportHeight) {
|
|
12
|
+
switch (variant) {
|
|
13
|
+
case "circle": return [`circle(0px at ${cx}px ${cy}px)`, `circle(${maxRadius}px at ${cx}px ${cy}px)`];
|
|
14
|
+
case "square": {
|
|
15
|
+
const halfW = Math.max(cx, viewportWidth - cx);
|
|
16
|
+
const halfH = Math.max(cy, viewportHeight - cy);
|
|
17
|
+
const halfSide = Math.max(halfW, halfH) * 1.05;
|
|
18
|
+
const end = [
|
|
19
|
+
`${cx - halfSide}px ${cy - halfSide}px`,
|
|
20
|
+
`${cx + halfSide}px ${cy - halfSide}px`,
|
|
21
|
+
`${cx + halfSide}px ${cy + halfSide}px`,
|
|
22
|
+
`${cx - halfSide}px ${cy + halfSide}px`
|
|
23
|
+
].join(", ");
|
|
24
|
+
return [polygonCollapsed(cx, cy, 4), `polygon(${end})`];
|
|
25
|
+
}
|
|
26
|
+
case "triangle": {
|
|
27
|
+
const scale = maxRadius * 2.2;
|
|
28
|
+
const dx = Math.sqrt(3) / 2 * scale;
|
|
29
|
+
const verts = [
|
|
30
|
+
`${cx}px ${cy - scale}px`,
|
|
31
|
+
`${cx + dx}px ${cy + .5 * scale}px`,
|
|
32
|
+
`${cx - dx}px ${cy + .5 * scale}px`
|
|
33
|
+
].join(", ");
|
|
34
|
+
return [polygonCollapsed(cx, cy, 3), `polygon(${verts})`];
|
|
35
|
+
}
|
|
36
|
+
case "diamond": {
|
|
37
|
+
const R = maxRadius * Math.SQRT2;
|
|
38
|
+
const end = [
|
|
39
|
+
`${cx}px ${cy - R}px`,
|
|
40
|
+
`${cx + R}px ${cy}px`,
|
|
41
|
+
`${cx}px ${cy + R}px`,
|
|
42
|
+
`${cx - R}px ${cy}px`
|
|
43
|
+
].join(", ");
|
|
44
|
+
return [polygonCollapsed(cx, cy, 4), `polygon(${end})`];
|
|
45
|
+
}
|
|
46
|
+
case "hexagon": {
|
|
47
|
+
const R = maxRadius * Math.SQRT2;
|
|
48
|
+
const verts = [];
|
|
49
|
+
for (let i = 0; i < 6; i++) {
|
|
50
|
+
const a = -Math.PI / 2 + i * Math.PI / 3;
|
|
51
|
+
verts.push(`${cx + R * Math.cos(a)}px ${cy + R * Math.sin(a)}px`);
|
|
52
|
+
}
|
|
53
|
+
return [polygonCollapsed(cx, cy, 6), `polygon(${verts.join(", ")})`];
|
|
54
|
+
}
|
|
55
|
+
case "rectangle": {
|
|
56
|
+
const halfW = Math.max(cx, viewportWidth - cx);
|
|
57
|
+
const halfH = Math.max(cy, viewportHeight - cy);
|
|
58
|
+
const end = [
|
|
59
|
+
`${cx - halfW}px ${cy - halfH}px`,
|
|
60
|
+
`${cx + halfW}px ${cy - halfH}px`,
|
|
61
|
+
`${cx + halfW}px ${cy + halfH}px`,
|
|
62
|
+
`${cx - halfW}px ${cy + halfH}px`
|
|
63
|
+
].join(", ");
|
|
64
|
+
return [polygonCollapsed(cx, cy, 4), `polygon(${end})`];
|
|
65
|
+
}
|
|
66
|
+
case "star": {
|
|
67
|
+
const R = maxRadius * Math.SQRT2 * 1.03;
|
|
68
|
+
const innerRatio = .42;
|
|
69
|
+
const starPolygon = (radius) => {
|
|
70
|
+
const verts = [];
|
|
71
|
+
for (let i = 0; i < 5; i++) {
|
|
72
|
+
const outerA = -Math.PI / 2 + i * 2 * Math.PI / 5;
|
|
73
|
+
verts.push(`${cx + radius * Math.cos(outerA)}px ${cy + radius * Math.sin(outerA)}px`);
|
|
74
|
+
const innerA = outerA + Math.PI / 5;
|
|
75
|
+
verts.push(`${cx + radius * innerRatio * Math.cos(innerA)}px ${cy + radius * innerRatio * Math.sin(innerA)}px`);
|
|
76
|
+
}
|
|
77
|
+
return `polygon(${verts.join(", ")})`;
|
|
78
|
+
};
|
|
79
|
+
return [starPolygon(Math.max(2, R * .025)), starPolygon(R)];
|
|
80
|
+
}
|
|
81
|
+
default: return [`circle(0px at ${cx}px ${cy}px)`, `circle(${maxRadius}px at ${cx}px ${cy}px)`];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const AnimatedThemeToggler = ({ className, duration = 400, variant, fromCenter = false, ...props }) => {
|
|
85
|
+
const shape = variant ?? "circle";
|
|
86
|
+
const { theme, setTheme } = useTheme();
|
|
87
|
+
const [isDark, setIsDark] = useState(false);
|
|
88
|
+
const buttonRef = useRef(null);
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
setIsDark(theme === "dark");
|
|
91
|
+
}, [theme]);
|
|
92
|
+
const toggleTheme = useCallback(() => {
|
|
93
|
+
const button = buttonRef.current;
|
|
94
|
+
if (!button) return;
|
|
95
|
+
const viewportWidth = window.visualViewport?.width ?? window.innerWidth;
|
|
96
|
+
const viewportHeight = window.visualViewport?.height ?? window.innerHeight;
|
|
97
|
+
let x;
|
|
98
|
+
let y;
|
|
99
|
+
if (fromCenter) {
|
|
100
|
+
x = viewportWidth / 2;
|
|
101
|
+
y = viewportHeight / 2;
|
|
102
|
+
} else {
|
|
103
|
+
const { top, left, width, height } = button.getBoundingClientRect();
|
|
104
|
+
x = left + width / 2;
|
|
105
|
+
y = top + height / 2;
|
|
106
|
+
}
|
|
107
|
+
const maxRadius = Math.hypot(Math.max(x, viewportWidth - x), Math.max(y, viewportHeight - y));
|
|
108
|
+
const newTheme = !isDark;
|
|
109
|
+
const applyTheme = () => {
|
|
110
|
+
setIsDark(newTheme);
|
|
111
|
+
document.documentElement.classList.toggle("dark", newTheme);
|
|
112
|
+
};
|
|
113
|
+
const syncNextThemes = () => {
|
|
114
|
+
setTheme(newTheme ? "dark" : "light");
|
|
115
|
+
};
|
|
116
|
+
if (typeof document.startViewTransition !== "function") {
|
|
117
|
+
applyTheme();
|
|
118
|
+
syncNextThemes();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const clipPath = getThemeTransitionClipPaths(shape, x, y, maxRadius, viewportWidth, viewportHeight);
|
|
122
|
+
const root = document.documentElement;
|
|
123
|
+
root.dataset.magicuiThemeVt = "active";
|
|
124
|
+
root.style.setProperty("--magicui-theme-toggle-vt-duration", `${duration}ms`);
|
|
125
|
+
root.style.setProperty("--magicui-theme-vt-clip-from", clipPath[0]);
|
|
126
|
+
const cleanup = () => {
|
|
127
|
+
delete root.dataset.magicuiThemeVt;
|
|
128
|
+
root.style.removeProperty("--magicui-theme-toggle-vt-duration");
|
|
129
|
+
root.style.removeProperty("--magicui-theme-vt-clip-from");
|
|
130
|
+
};
|
|
131
|
+
const transition = document.startViewTransition(() => {
|
|
132
|
+
flushSync(applyTheme);
|
|
133
|
+
});
|
|
134
|
+
const onFinish = () => {
|
|
135
|
+
cleanup();
|
|
136
|
+
syncNextThemes();
|
|
137
|
+
};
|
|
138
|
+
if (typeof transition?.finished?.then === "function") transition.finished.then(onFinish);
|
|
139
|
+
else onFinish();
|
|
140
|
+
const ready = transition?.ready;
|
|
141
|
+
if (ready && typeof ready.then === "function") ready.then(() => {
|
|
142
|
+
document.documentElement.animate({ clipPath }, {
|
|
143
|
+
duration,
|
|
144
|
+
easing: shape === "star" ? "linear" : "ease-in-out",
|
|
145
|
+
fill: "forwards",
|
|
146
|
+
pseudoElement: "::view-transition-new(root)"
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}, [
|
|
150
|
+
shape,
|
|
151
|
+
fromCenter,
|
|
152
|
+
duration,
|
|
153
|
+
isDark,
|
|
154
|
+
setTheme
|
|
155
|
+
]);
|
|
156
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
157
|
+
type: "button",
|
|
158
|
+
ref: buttonRef,
|
|
159
|
+
onClick: toggleTheme,
|
|
160
|
+
className: cn(className),
|
|
161
|
+
...props,
|
|
162
|
+
children: [isDark ? /* @__PURE__ */ jsx(Sun, { className: cn("size-5", className) }) : /* @__PURE__ */ jsx(Moon, { className: cn("size-5", className) }), /* @__PURE__ */ jsx("span", {
|
|
163
|
+
className: "sr-only",
|
|
164
|
+
children: "Toggle theme"
|
|
165
|
+
})]
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
//#endregion
|
|
169
|
+
export { AnimatedThemeToggler };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region src/auth-client.d.ts
|
|
2
|
+
interface Session {
|
|
3
|
+
user: {
|
|
4
|
+
id: string;
|
|
5
|
+
email: string;
|
|
6
|
+
name: string;
|
|
7
|
+
role: 'USER' | 'ADMIN' | 'SUPER_ADMIN';
|
|
8
|
+
image?: string | null;
|
|
9
|
+
aiProvider?: string | null;
|
|
10
|
+
aiModel?: string | null;
|
|
11
|
+
hasAiKey?: boolean | null;
|
|
12
|
+
timezone?: string | null;
|
|
13
|
+
};
|
|
14
|
+
expires: string;
|
|
15
|
+
}
|
|
16
|
+
declare function useSession(): import("@tanstack/react-query").UseQueryResult<NoInfer<Session | null>, Error>;
|
|
17
|
+
declare function signIn(provider: string, options?: {
|
|
18
|
+
redirectTo?: string;
|
|
19
|
+
email?: string;
|
|
20
|
+
password?: string;
|
|
21
|
+
remember?: boolean;
|
|
22
|
+
}): Promise<void>;
|
|
23
|
+
declare function signOut(): Promise<{
|
|
24
|
+
success: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { Session, signIn, signOut, useSession };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
//#region src/auth-client.ts
|
|
3
|
+
function useSession() {
|
|
4
|
+
return useQuery({
|
|
5
|
+
queryKey: ["session"],
|
|
6
|
+
queryFn: async () => {
|
|
7
|
+
const res = await fetch("/api/auth/session", { credentials: "include" });
|
|
8
|
+
if (!res.ok) return null;
|
|
9
|
+
const data = await res.json();
|
|
10
|
+
return data?.user ? data : null;
|
|
11
|
+
},
|
|
12
|
+
staleTime: 0,
|
|
13
|
+
refetchOnMount: true
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async function signIn(provider, options) {
|
|
17
|
+
if (provider !== "credentials") {
|
|
18
|
+
const { csrfToken } = await (await fetch("/api/auth/csrf", { credentials: "include" })).json();
|
|
19
|
+
const redirectPath = options?.redirectTo ?? "/dashboard";
|
|
20
|
+
const callbackUrl = `${window.location.origin}${redirectPath}`;
|
|
21
|
+
const form = document.createElement("form");
|
|
22
|
+
form.method = "POST";
|
|
23
|
+
form.action = `/api/auth/signin/${provider}`;
|
|
24
|
+
form.style.display = "none";
|
|
25
|
+
const csrfInput = document.createElement("input");
|
|
26
|
+
csrfInput.name = "csrfToken";
|
|
27
|
+
csrfInput.value = csrfToken;
|
|
28
|
+
form.appendChild(csrfInput);
|
|
29
|
+
const cbInput = document.createElement("input");
|
|
30
|
+
cbInput.name = "callbackUrl";
|
|
31
|
+
cbInput.value = callbackUrl;
|
|
32
|
+
form.appendChild(cbInput);
|
|
33
|
+
document.body.appendChild(form);
|
|
34
|
+
form.submit();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const { csrfToken } = await (await fetch("/api/auth/csrf", { credentials: "include" })).json();
|
|
38
|
+
const callbackUrl = options?.redirectTo ?? "/";
|
|
39
|
+
const form = document.createElement("form");
|
|
40
|
+
form.method = "POST";
|
|
41
|
+
form.action = "/api/auth/callback/credentials";
|
|
42
|
+
form.style.display = "none";
|
|
43
|
+
const fields = [
|
|
44
|
+
{
|
|
45
|
+
name: "email",
|
|
46
|
+
value: options?.email ?? ""
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "password",
|
|
50
|
+
value: options?.password ?? ""
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "remember",
|
|
54
|
+
value: String(options?.remember ?? false)
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: "callbackUrl",
|
|
58
|
+
value: callbackUrl
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "csrfToken",
|
|
62
|
+
value: csrfToken
|
|
63
|
+
}
|
|
64
|
+
];
|
|
65
|
+
for (const field of fields) {
|
|
66
|
+
const input = document.createElement("input");
|
|
67
|
+
input.type = "hidden";
|
|
68
|
+
input.name = field.name;
|
|
69
|
+
input.value = field.value;
|
|
70
|
+
form.appendChild(input);
|
|
71
|
+
}
|
|
72
|
+
document.body.appendChild(form);
|
|
73
|
+
form.submit();
|
|
74
|
+
}
|
|
75
|
+
async function signOut() {
|
|
76
|
+
const { csrfToken } = await (await fetch("/api/auth/csrf", { credentials: "include" })).json();
|
|
77
|
+
await fetch("/api/auth/signout", {
|
|
78
|
+
method: "POST",
|
|
79
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
80
|
+
body: new URLSearchParams({ csrfToken }).toString(),
|
|
81
|
+
credentials: "include"
|
|
82
|
+
});
|
|
83
|
+
return { success: true };
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
export { signIn, signOut, useSession };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/auth-layout.d.ts
|
|
3
|
+
interface AuthLayoutProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
}
|
|
6
|
+
declare function AuthLayout({ children }: AuthLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
declare function AuthLayoutLeft({ children }: {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
declare function AuthLayoutRight({ children }: {
|
|
11
|
+
children: ReactNode;
|
|
12
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { AuthLayout, AuthLayoutLeft, AuthLayoutRight };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AnimatedThemeToggler } from "./animated-theme-toggler.js";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
//#region src/auth-layout.tsx
|
|
4
|
+
function AuthLayout({ children }) {
|
|
5
|
+
const left = findChild(children, AuthLayoutLeft);
|
|
6
|
+
const right = findChild(children, AuthLayoutRight);
|
|
7
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
8
|
+
className: "flex min-h-screen",
|
|
9
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
10
|
+
className: "relative flex flex-1 items-center justify-center p-6",
|
|
11
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
12
|
+
className: "absolute",
|
|
13
|
+
style: {
|
|
14
|
+
top: "1.5rem",
|
|
15
|
+
right: "1.5rem"
|
|
16
|
+
},
|
|
17
|
+
children: /* @__PURE__ */ jsx(AnimatedThemeToggler, { className: "flex size-6 items-center justify-center rounded-full hover:bg-accent" })
|
|
18
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
19
|
+
className: "w-full max-w-sm space-y-6",
|
|
20
|
+
children: left
|
|
21
|
+
})]
|
|
22
|
+
}), right && /* @__PURE__ */ jsx("div", {
|
|
23
|
+
className: "hidden lg:flex flex-1 bg-linear-to-br from-primary/10 via-primary/5 to-background items-center justify-center p-12",
|
|
24
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
25
|
+
className: "w-full max-w-md text-center space-y-8",
|
|
26
|
+
children: right
|
|
27
|
+
})
|
|
28
|
+
})]
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function AuthLayoutLeft({ children }) {
|
|
32
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
33
|
+
}
|
|
34
|
+
function AuthLayoutRight({ children }) {
|
|
35
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
36
|
+
}
|
|
37
|
+
function findChild(children, type) {
|
|
38
|
+
const arr = Array.isArray(children) ? children : [children];
|
|
39
|
+
for (const child of arr) if (child?.type === type) return child.props.children;
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { AuthLayout, AuthLayoutLeft, AuthLayoutRight };
|
package/dist/avatar.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as React$1 from "react";
|
|
2
|
+
import { Avatar as Avatar$1 } from "radix-ui";
|
|
3
|
+
//#region src/avatar.d.ts
|
|
4
|
+
declare function Avatar({ className, size, ...props }: React$1.ComponentProps<typeof Avatar$1.Root> & {
|
|
5
|
+
size?: "default" | "sm" | "lg";
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
declare function AvatarImage({ className, ...props }: React$1.ComponentProps<typeof Avatar$1.Image>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
declare function AvatarFallback({ className, ...props }: React$1.ComponentProps<typeof Avatar$1.Fallback>): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
declare function AvatarBadge({ className, ...props }: React$1.ComponentProps<"span">): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
declare function AvatarGroup({ className, ...props }: React$1.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
declare function AvatarGroupCount({ className, ...props }: React$1.ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage };
|
package/dist/avatar.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn } from "./utils.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import "react";
|
|
5
|
+
import { Avatar as Avatar$1 } from "radix-ui";
|
|
6
|
+
//#region src/avatar.tsx
|
|
7
|
+
function Avatar({ className, size = "default", ...props }) {
|
|
8
|
+
return /* @__PURE__ */ jsx(Avatar$1.Root, {
|
|
9
|
+
"data-slot": "avatar",
|
|
10
|
+
"data-size": size,
|
|
11
|
+
className: cn("group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten", className),
|
|
12
|
+
...props
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function AvatarImage({ className, ...props }) {
|
|
16
|
+
return /* @__PURE__ */ jsx(Avatar$1.Image, {
|
|
17
|
+
"data-slot": "avatar-image",
|
|
18
|
+
className: cn("aspect-square size-full rounded-full object-cover", className),
|
|
19
|
+
...props
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function AvatarFallback({ className, ...props }) {
|
|
23
|
+
return /* @__PURE__ */ jsx(Avatar$1.Fallback, {
|
|
24
|
+
"data-slot": "avatar-fallback",
|
|
25
|
+
className: cn("flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs", className),
|
|
26
|
+
...props
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function AvatarBadge({ className, ...props }) {
|
|
30
|
+
return /* @__PURE__ */ jsx("span", {
|
|
31
|
+
"data-slot": "avatar-badge",
|
|
32
|
+
className: cn("absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none", "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden", "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2", "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2", className),
|
|
33
|
+
...props
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function AvatarGroup({ className, ...props }) {
|
|
37
|
+
return /* @__PURE__ */ jsx("div", {
|
|
38
|
+
"data-slot": "avatar-group",
|
|
39
|
+
className: cn("group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background", className),
|
|
40
|
+
...props
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function AvatarGroupCount({ className, ...props }) {
|
|
44
|
+
return /* @__PURE__ */ jsx("div", {
|
|
45
|
+
"data-slot": "avatar-group-count",
|
|
46
|
+
className: cn("relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3", className),
|
|
47
|
+
...props
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { Avatar, AvatarBadge, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarImage };
|
package/dist/badge.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React$1 from "react";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
//#region src/badge.d.ts
|
|
4
|
+
declare const badgeVariants: (props?: ({
|
|
5
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
declare function Badge({ className, variant, asChild, ...props }: React$1.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { Badge, badgeVariants };
|
package/dist/badge.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { cn } from "./utils.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import "react";
|
|
4
|
+
import { Slot } from "radix-ui";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
//#region src/badge.tsx
|
|
7
|
+
const badgeVariants = cva("group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!", {
|
|
8
|
+
variants: { variant: {
|
|
9
|
+
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
|
10
|
+
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
|
|
11
|
+
destructive: "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
|
|
12
|
+
outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
|
|
13
|
+
ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
|
|
14
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
15
|
+
} },
|
|
16
|
+
defaultVariants: { variant: "default" }
|
|
17
|
+
});
|
|
18
|
+
function Badge({ className, variant = "default", asChild = false, ...props }) {
|
|
19
|
+
const Comp = asChild ? Slot.Root : "span";
|
|
20
|
+
return /* @__PURE__ */ jsx(Comp, {
|
|
21
|
+
"data-slot": "badge",
|
|
22
|
+
"data-variant": variant,
|
|
23
|
+
className: cn(badgeVariants({ variant }), className),
|
|
24
|
+
...props
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { Badge, badgeVariants };
|
package/dist/button.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React$1 from "react";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
//#region src/button.d.ts
|
|
4
|
+
declare const buttonVariants: (props?: ({
|
|
5
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
|
|
6
|
+
size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | null | undefined;
|
|
7
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
8
|
+
declare function Button({ className, variant, size, asChild, ...props }: React$1.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
|
|
9
|
+
asChild?: boolean;
|
|
10
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { Button, buttonVariants };
|