@vuer-ai/vuer-uikit 0.0.12 → 0.0.13
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/package.json +3 -2
- package/src/highlight-cursor/cursor-context.tsx +23 -0
- package/src/highlight-cursor/cursor-provider.tsx +264 -0
- package/src/highlight-cursor/enhanced-components.tsx +16 -0
- package/src/highlight-cursor/index.ts +21 -0
- package/src/highlight-cursor/tabs-cursor-context.tsx +121 -0
- package/src/highlight-cursor/types.ts +40 -0
- package/src/highlight-cursor/with-cursor.tsx +144 -0
- package/src/index.css +5 -0
- package/src/index.ts +5 -0
- package/src/styles/theme.css +80 -0
- package/src/styles/toast.css +64 -0
- package/src/styles/variables.css +194 -0
- package/src/ui/avatar.tsx +92 -0
- package/src/ui/badge.tsx +68 -0
- package/src/ui/button.tsx +100 -0
- package/src/ui/card.tsx +88 -0
- package/src/ui/checkbox.tsx +76 -0
- package/src/ui/collapsible.tsx +36 -0
- package/src/ui/dropdown.tsx +375 -0
- package/src/ui/index.ts +31 -0
- package/src/ui/input-numbers.tsx +201 -0
- package/src/ui/input.tsx +141 -0
- package/src/ui/layout.tsx +41 -0
- package/src/ui/modal.tsx +198 -0
- package/src/ui/popover.tsx +59 -0
- package/src/ui/radio-group.tsx +56 -0
- package/src/ui/select.tsx +292 -0
- package/src/ui/sheet.tsx +131 -0
- package/src/ui/slider.tsx +189 -0
- package/src/ui/switch.tsx +43 -0
- package/src/ui/tabs.tsx +128 -0
- package/src/ui/textarea.tsx +52 -0
- package/src/ui/theme-context.tsx +80 -0
- package/src/ui/timeline.tsx +717 -0
- package/src/ui/toast.tsx +27 -0
- package/src/ui/toggle-group.tsx +82 -0
- package/src/ui/toggle.tsx +88 -0
- package/src/ui/tooltip.tsx +132 -0
- package/src/ui/tree-view-v2.tsx +300 -0
- package/src/ui/tree-view.tsx +550 -0
- package/src/ui/version-badge.tsx +65 -0
- package/src/utils/cn.ts +21 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/use-local-storage.ts +59 -0
package/src/ui/tabs.tsx
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
import { type ComponentProps, createContext, useContext } from "react";
|
|
4
|
+
|
|
5
|
+
import { TabsCursorProvider, useTabsCursor } from "../highlight-cursor/tabs-cursor-context";
|
|
6
|
+
import { cn } from "../utils";
|
|
7
|
+
|
|
8
|
+
interface TabsContextType {
|
|
9
|
+
size?: "sm" | "base" | "lg";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const TabsContext = createContext<TabsContextType | undefined>(undefined);
|
|
13
|
+
|
|
14
|
+
const useTabsContext = () => {
|
|
15
|
+
const context = useContext(TabsContext);
|
|
16
|
+
if (!context) {
|
|
17
|
+
throw new Error("Tabs components must be used within a Tabs component");
|
|
18
|
+
}
|
|
19
|
+
return context;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
interface TabsProps extends ComponentProps<typeof TabsPrimitive.Root> {
|
|
23
|
+
size?: "sm" | "base" | "lg";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function Tabs({ className, size = "base", ...props }: TabsProps) {
|
|
27
|
+
return (
|
|
28
|
+
<TabsContext.Provider value={{ size }}>
|
|
29
|
+
<TabsPrimitive.Root
|
|
30
|
+
data-slot="tabs"
|
|
31
|
+
className={cn("flex w-full flex-col", className)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
</TabsContext.Provider>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const tabsListVariants = cva(["inline-flex", "items-center", "justify-center"], {
|
|
39
|
+
variants: {
|
|
40
|
+
size: {
|
|
41
|
+
sm: "gap-xs",
|
|
42
|
+
base: "gap-sm",
|
|
43
|
+
lg: "gap-md",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
defaultVariants: {
|
|
47
|
+
size: "base",
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
type TabsListProps = ComponentProps<typeof TabsPrimitive.List>;
|
|
52
|
+
|
|
53
|
+
function TabsList({ className, ...props }: TabsListProps) {
|
|
54
|
+
const { setCursorTarget } = useTabsCursor();
|
|
55
|
+
const { size } = useTabsContext();
|
|
56
|
+
return (
|
|
57
|
+
<TabsCursorProvider>
|
|
58
|
+
<TabsPrimitive.List
|
|
59
|
+
onMouseLeave={() => setCursorTarget(null)}
|
|
60
|
+
data-slot="tabs-list"
|
|
61
|
+
className={cn(tabsListVariants({ size }), "justify-start", className)}
|
|
62
|
+
{...props}
|
|
63
|
+
/>
|
|
64
|
+
</TabsCursorProvider>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const tabsTriggerVariants = cva(
|
|
69
|
+
[
|
|
70
|
+
"inline-flex",
|
|
71
|
+
"items-center",
|
|
72
|
+
"justify-center",
|
|
73
|
+
"font-medium",
|
|
74
|
+
"whitespace-nowrap",
|
|
75
|
+
"transition-all",
|
|
76
|
+
"disabled:pointer-events-none",
|
|
77
|
+
"disabled:bg-bg-tertiary",
|
|
78
|
+
"[&_svg]:pointer-events-none",
|
|
79
|
+
"[&_svg:not([class*='size-'])]:size-xl",
|
|
80
|
+
"shrink-0",
|
|
81
|
+
"[&_svg]:shrink-0",
|
|
82
|
+
"outline-none",
|
|
83
|
+
"text-text-primary",
|
|
84
|
+
"data-[state=active]:bg-bg-secondary",
|
|
85
|
+
],
|
|
86
|
+
{
|
|
87
|
+
variants: {
|
|
88
|
+
size: {
|
|
89
|
+
sm: "text-uk-sm leading-uk-sm px-md py-xs rounded-uk-sm",
|
|
90
|
+
base: "text-uk-md leading-uk-md px-lg py-sm rounded-uk-md",
|
|
91
|
+
lg: "text-uk-lg leading-uk-lg px-xl py-sm rounded-uk-md",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
defaultVariants: {
|
|
95
|
+
size: "base",
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
type TabsTriggerProps = ComponentProps<typeof TabsPrimitive.Trigger>;
|
|
101
|
+
|
|
102
|
+
function TabsTrigger({ className, ...props }: TabsTriggerProps) {
|
|
103
|
+
const { setCursorTarget } = useTabsCursor();
|
|
104
|
+
const { size } = useTabsContext();
|
|
105
|
+
return (
|
|
106
|
+
<TabsPrimitive.Trigger
|
|
107
|
+
onMouseEnter={(e) => setCursorTarget(e.currentTarget)}
|
|
108
|
+
data-slot="tabs-trigger"
|
|
109
|
+
className={cn(tabsTriggerVariants({ size }), className)}
|
|
110
|
+
{...props}
|
|
111
|
+
/>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
type TabsContentProps = ComponentProps<typeof TabsPrimitive.Content>;
|
|
116
|
+
|
|
117
|
+
function TabsContent({ className, ...props }: TabsContentProps) {
|
|
118
|
+
return (
|
|
119
|
+
<TabsPrimitive.Content
|
|
120
|
+
data-slot="tabs-content"
|
|
121
|
+
className={cn("flex-1 outline-none", className)}
|
|
122
|
+
{...props}
|
|
123
|
+
/>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
|
128
|
+
export type { TabsProps, TabsListProps, TabsTriggerProps, TabsContentProps };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
|
+
import { type ComponentProps } from "react";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../utils";
|
|
5
|
+
|
|
6
|
+
const textareaVariants = cva(
|
|
7
|
+
[
|
|
8
|
+
"bg-bg-secondary",
|
|
9
|
+
"disabled:bg-bg-tertiary",
|
|
10
|
+
"disabled:text-text-tertiary",
|
|
11
|
+
"disabled:cursor-not-allowed",
|
|
12
|
+
"outline-transparent",
|
|
13
|
+
"placehoder:text-text-secondary/20",
|
|
14
|
+
"min-h-16",
|
|
15
|
+
"flex",
|
|
16
|
+
"w-full",
|
|
17
|
+
],
|
|
18
|
+
{
|
|
19
|
+
variants: {
|
|
20
|
+
state: {
|
|
21
|
+
default: ["hover:bg-bg-tertiary", "focus:bg-bg-quaternary"],
|
|
22
|
+
error: ["hover:bg-danger-primary/10", "bg-danger-primary/20"],
|
|
23
|
+
},
|
|
24
|
+
size: {
|
|
25
|
+
sm: ["text-uk-sm", "leading-uk-sm", "rounded-uk-sm", "px-sm", "py-xs"],
|
|
26
|
+
base: ["text-uk-md", "leading-uk-md", "rounded-uk-md", "px-md", "py-sm"],
|
|
27
|
+
lg: ["text-uk-lg", "leading-uk-lg", "rounded-uk-md", "px-lg", "py-sm"],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: {
|
|
31
|
+
state: "default",
|
|
32
|
+
size: "base",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
interface TextareaProps extends ComponentProps<"textarea">, VariantProps<typeof textareaVariants> {
|
|
38
|
+
state?: "default" | "error";
|
|
39
|
+
size?: "sm" | "base" | "lg";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function Textarea({ className, state, size, ...props }: TextareaProps) {
|
|
43
|
+
return (
|
|
44
|
+
<textarea
|
|
45
|
+
className={cn(textareaVariants({ className, state, size }))}
|
|
46
|
+
data-slot="textarea"
|
|
47
|
+
{...props}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { Textarea };
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createContext, type ReactNode, useContext, useEffect, useMemo } from "react";
|
|
2
|
+
|
|
3
|
+
import { useLocalStorage } from "../utils";
|
|
4
|
+
|
|
5
|
+
type Theme = "dark" | "light" | "liquidlight" | "liquiddark" | "system";
|
|
6
|
+
|
|
7
|
+
type ThemeProviderProps = {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
defaultTheme?: Theme;
|
|
10
|
+
storageKey?: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type ThemeProviderState = {
|
|
14
|
+
theme: Theme;
|
|
15
|
+
setTheme: (theme: Theme) => void;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const initialState: ThemeProviderState = {
|
|
19
|
+
theme: "system",
|
|
20
|
+
setTheme: () => null,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const ThemeProviderContext = createContext<ThemeProviderState>(initialState);
|
|
24
|
+
|
|
25
|
+
function ThemeProvider({
|
|
26
|
+
children,
|
|
27
|
+
defaultTheme = "system",
|
|
28
|
+
storageKey = "vuer-theme",
|
|
29
|
+
...props
|
|
30
|
+
}: ThemeProviderProps) {
|
|
31
|
+
const [theme, setTheme] = useLocalStorage<Theme>(storageKey, defaultTheme);
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (typeof window === "undefined") return;
|
|
35
|
+
|
|
36
|
+
const root = window.document.documentElement;
|
|
37
|
+
|
|
38
|
+
// Remove both class and data-theme attributes
|
|
39
|
+
root.classList.remove("light", "dark", "liquidlight", "liquiddark", "system");
|
|
40
|
+
root.removeAttribute("data-theme");
|
|
41
|
+
|
|
42
|
+
if (theme === "system") {
|
|
43
|
+
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
44
|
+
? "dark"
|
|
45
|
+
: "light";
|
|
46
|
+
|
|
47
|
+
root.classList.add(systemTheme);
|
|
48
|
+
root.setAttribute("data-theme", "auto");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
root.classList.add(theme);
|
|
53
|
+
root.setAttribute("data-theme", theme);
|
|
54
|
+
}, [theme]);
|
|
55
|
+
|
|
56
|
+
const value = useMemo(
|
|
57
|
+
() => ({
|
|
58
|
+
theme,
|
|
59
|
+
setTheme,
|
|
60
|
+
}),
|
|
61
|
+
[theme, setTheme],
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<ThemeProviderContext.Provider {...props} value={value}>
|
|
66
|
+
{children}
|
|
67
|
+
</ThemeProviderContext.Provider>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const useTheme = () => {
|
|
72
|
+
const context = useContext(ThemeProviderContext);
|
|
73
|
+
|
|
74
|
+
if (context === undefined) throw new Error("useTheme must be used within a ThemeProvider");
|
|
75
|
+
|
|
76
|
+
return context;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export { useTheme, ThemeProvider };
|
|
80
|
+
export type { Theme };
|