@allbluecn/ui 0.3.14 → 0.4.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.
Files changed (146) hide show
  1. package/dist/ai-command-button.d.ts +10 -0
  2. package/dist/ai-command-button.js +12 -0
  3. package/dist/ai-stream-text.d.ts +9 -0
  4. package/dist/ai-stream-text.js +12 -0
  5. package/dist/alert-dialog.d.ts +20 -0
  6. package/dist/alert-dialog.js +101 -0
  7. package/dist/animated-theme-toggler.d.ts +11 -0
  8. package/dist/animated-theme-toggler.js +169 -0
  9. package/dist/auth-client.d.ts +27 -0
  10. package/dist/auth-client.js +86 -0
  11. package/dist/auth-layout.d.ts +14 -0
  12. package/dist/auth-layout.js +43 -0
  13. package/dist/avatar.d.ts +13 -0
  14. package/dist/avatar.js +51 -0
  15. package/dist/badge.d.ts +11 -0
  16. package/dist/badge.js +28 -0
  17. package/dist/button.d.ts +12 -0
  18. package/dist/button.js +48 -0
  19. package/dist/card.d.ts +13 -0
  20. package/dist/card.js +56 -0
  21. package/dist/checkbox.d.ts +6 -0
  22. package/dist/checkbox.js +22 -0
  23. package/dist/context-menu.d.ts +33 -0
  24. package/dist/context-menu.js +125 -0
  25. package/dist/dialog.d.ts +19 -0
  26. package/dist/dialog.js +95 -0
  27. package/dist/dropdown-menu.d.ts +31 -0
  28. package/dist/dropdown-menu.js +128 -0
  29. package/dist/empty.d.ts +13 -0
  30. package/dist/empty.js +59 -0
  31. package/dist/grid-pattern.d.ts +14 -0
  32. package/dist/grid-pattern.js +47 -0
  33. package/dist/icon-packs/index.d.ts +2 -0
  34. package/dist/icon-packs/index.js +4 -0
  35. package/dist/icon-packs/knowledge.d.ts +2 -0
  36. package/dist/icon-packs/knowledge.js +70 -0
  37. package/dist/icon-packs/prd.d.ts +2 -0
  38. package/dist/icon-packs/prd.js +86 -0
  39. package/dist/icon-packs/project.d.ts +2 -0
  40. package/dist/icon-packs/project.js +74 -0
  41. package/dist/icon-picker.d.ts +11 -0
  42. package/dist/icon-picker.js +39 -0
  43. package/dist/index-CQsbeClc.d.ts +17 -0
  44. package/dist/index.d.ts +7 -0
  45. package/dist/index.js +7 -0
  46. package/dist/input.d.ts +5 -0
  47. package/dist/input.js +14 -0
  48. package/dist/item.d.ts +25 -0
  49. package/dist/item.js +118 -0
  50. package/dist/kbd.d.ts +4 -0
  51. package/dist/kbd.js +12 -0
  52. package/dist/label.d.ts +6 -0
  53. package/dist/label.js +14 -0
  54. package/dist/layout-panel-top.d.ts +12 -0
  55. package/dist/layout-panel-top.js +127 -0
  56. package/dist/name-confirm-dialog.d.ts +15 -0
  57. package/dist/name-confirm-dialog.js +105 -0
  58. package/dist/nav-float-button.d.ts +12 -0
  59. package/dist/nav-float-button.js +249 -0
  60. package/dist/notion-avatar.d.ts +13 -0
  61. package/dist/notion-avatar.js +83 -0
  62. package/dist/placeholder-page.d.ts +10 -0
  63. package/dist/placeholder-page.js +28 -0
  64. package/dist/popover.d.ts +12 -0
  65. package/dist/popover.js +56 -0
  66. package/dist/reference-inline.d.ts +10 -0
  67. package/dist/reference-inline.js +35 -0
  68. package/dist/reference-search.d.ts +12 -0
  69. package/dist/reference-search.js +26 -0
  70. package/dist/resizable.d.ts +9 -0
  71. package/dist/resizable.js +28 -0
  72. package/dist/select.d.ts +17 -0
  73. package/dist/select.js +99 -0
  74. package/dist/separator.d.ts +6 -0
  75. package/dist/separator.js +17 -0
  76. package/dist/sheet.d.ts +16 -0
  77. package/dist/sheet.js +90 -0
  78. package/dist/sidebar.d.ts +71 -0
  79. package/dist/sidebar.js +369 -0
  80. package/dist/skeleton.d.ts +4 -0
  81. package/dist/skeleton.js +12 -0
  82. package/dist/sonner.d.ts +5 -0
  83. package/dist/sonner.js +19 -0
  84. package/dist/switch.d.ts +8 -0
  85. package/dist/switch.js +19 -0
  86. package/dist/textarea.d.ts +5 -0
  87. package/dist/textarea.js +13 -0
  88. package/dist/timezone-provider.d.ts +18 -0
  89. package/dist/timezone-provider.js +29 -0
  90. package/dist/tooltip.d.ts +9 -0
  91. package/dist/tooltip.js +35 -0
  92. package/dist/use-mobile.d.ts +4 -0
  93. package/dist/use-mobile.js +18 -0
  94. package/dist/user-avatar.d.ts +14 -0
  95. package/dist/user-avatar.js +34 -0
  96. package/dist/utils.d.ts +5 -0
  97. package/dist/utils.js +8 -0
  98. package/package.json +178 -49
  99. package/src/ai-command-button.tsx +0 -36
  100. package/src/ai-stream-text.tsx +0 -37
  101. package/src/alert-dialog.tsx +0 -216
  102. package/src/animated-theme-toggler.tsx +0 -272
  103. package/src/auth-client.ts +0 -108
  104. package/src/auth-layout.tsx +0 -66
  105. package/src/avatar.tsx +0 -129
  106. package/src/badge.tsx +0 -66
  107. package/src/button.tsx +0 -84
  108. package/src/card.tsx +0 -120
  109. package/src/checkbox.tsx +0 -50
  110. package/src/context-menu.tsx +0 -280
  111. package/src/dialog.tsx +0 -183
  112. package/src/dropdown-menu.tsx +0 -286
  113. package/src/empty.tsx +0 -121
  114. package/src/grid-pattern.tsx +0 -87
  115. package/src/icon-packs/index.ts +0 -27
  116. package/src/icon-packs/knowledge.ts +0 -55
  117. package/src/icon-packs/prd.ts +0 -63
  118. package/src/icon-packs/project.ts +0 -59
  119. package/src/icon-picker.tsx +0 -68
  120. package/src/index.ts +0 -23
  121. package/src/input.tsx +0 -36
  122. package/src/item.tsx +0 -213
  123. package/src/kbd.tsx +0 -33
  124. package/src/label.tsx +0 -39
  125. package/src/layout-panel-top.tsx +0 -160
  126. package/src/name-confirm-dialog.tsx +0 -153
  127. package/src/nav-float-button.tsx +0 -301
  128. package/src/notion-avatar.tsx +0 -126
  129. package/src/placeholder-page.tsx +0 -42
  130. package/src/popover.tsx +0 -106
  131. package/src/reference-inline.tsx +0 -53
  132. package/src/reference-search.tsx +0 -52
  133. package/src/resizable.tsx +0 -67
  134. package/src/select.tsx +0 -207
  135. package/src/separator.tsx +0 -45
  136. package/src/sheet.tsx +0 -164
  137. package/src/sidebar.tsx +0 -708
  138. package/src/skeleton.tsx +0 -30
  139. package/src/sonner.tsx +0 -37
  140. package/src/switch.tsx +0 -48
  141. package/src/textarea.tsx +0 -35
  142. package/src/timezone-provider.tsx +0 -55
  143. package/src/tooltip.tsx +0 -72
  144. package/src/use-mobile.ts +0 -36
  145. package/src/user-avatar.tsx +0 -79
  146. 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 };
@@ -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 };
@@ -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 };
@@ -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 };