@openui-xio/ui 0.0.2
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/CHANGELOG.md +13 -0
- package/LICENSE +661 -0
- package/README.md +9 -0
- package/components.json +20 -0
- package/package.json +74 -0
- package/postcss.config.mjs +6 -0
- package/src/components/.gitkeep +0 -0
- package/src/components/accordion.tsx +66 -0
- package/src/components/alert-dialog.tsx +157 -0
- package/src/components/alert.tsx +66 -0
- package/src/components/aspect-ratio.tsx +11 -0
- package/src/components/avatar.tsx +53 -0
- package/src/components/badge.tsx +46 -0
- package/src/components/breadcrumb.tsx +109 -0
- package/src/components/button.tsx +46 -0
- package/src/components/calendar.tsx +85 -0
- package/src/components/card.tsx +92 -0
- package/src/components/carousel.tsx +241 -0
- package/src/components/chart.tsx +353 -0
- package/src/components/checkbox.tsx +32 -0
- package/src/components/collapsible.tsx +33 -0
- package/src/components/command.tsx +177 -0
- package/src/components/context-menu.tsx +252 -0
- package/src/components/dialog.tsx +135 -0
- package/src/components/drawer.tsx +132 -0
- package/src/components/dropdown-menu.tsx +257 -0
- package/src/components/form.tsx +168 -0
- package/src/components/hover-card.tsx +44 -0
- package/src/components/input-otp.tsx +77 -0
- package/src/components/input.tsx +21 -0
- package/src/components/label.tsx +24 -0
- package/src/components/menubar.tsx +276 -0
- package/src/components/navigation-menu.tsx +168 -0
- package/src/components/pagination.tsx +126 -0
- package/src/components/popover.tsx +48 -0
- package/src/components/progress.tsx +31 -0
- package/src/components/radio-group.tsx +45 -0
- package/src/components/resizable.tsx +56 -0
- package/src/components/scroll-area.tsx +58 -0
- package/src/components/select.tsx +185 -0
- package/src/components/separator.tsx +28 -0
- package/src/components/sheet.tsx +139 -0
- package/src/components/sidebar.tsx +726 -0
- package/src/components/skeleton.tsx +13 -0
- package/src/components/slider.tsx +63 -0
- package/src/components/sonner.tsx +25 -0
- package/src/components/switch.tsx +31 -0
- package/src/components/table.tsx +116 -0
- package/src/components/tabs.tsx +66 -0
- package/src/components/textarea.tsx +18 -0
- package/src/components/toggle-group.tsx +73 -0
- package/src/components/toggle.tsx +47 -0
- package/src/components/tooltip.tsx +61 -0
- package/src/hooks/.gitkeep +0 -0
- package/src/hooks/use-mobile.ts +21 -0
- package/src/lib/utils.ts +6 -0
- package/src/styles/globals.css +161 -0
- package/tsconfig.json +11 -0
- package/tsconfig.lint.json +8 -0
package/README.md
ADDED
package/components.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "new-york",
|
|
4
|
+
"rsc": true,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "",
|
|
8
|
+
"css": "src/styles/globals.css",
|
|
9
|
+
"baseColor": "neutral",
|
|
10
|
+
"cssVariables": true
|
|
11
|
+
},
|
|
12
|
+
"iconLibrary": "lucide",
|
|
13
|
+
"aliases": {
|
|
14
|
+
"components": "@openui-xio/ui/components",
|
|
15
|
+
"utils": "@openui-xio/ui/lib/utils",
|
|
16
|
+
"hooks": "@openui-xio/ui/hooks",
|
|
17
|
+
"lib": "@openui-xio/ui/lib",
|
|
18
|
+
"ui": "@openui-xio/ui/components"
|
|
19
|
+
}
|
|
20
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openui-xio/ui",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"private": false,
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@hookform/resolvers": "^5.2.1",
|
|
7
|
+
"@radix-ui/react-accordion": "^1.2.10",
|
|
8
|
+
"@radix-ui/react-alert-dialog": "^1.1.13",
|
|
9
|
+
"@radix-ui/react-aspect-ratio": "^1.1.6",
|
|
10
|
+
"@radix-ui/react-avatar": "^1.1.9",
|
|
11
|
+
"@radix-ui/react-checkbox": "^1.3.1",
|
|
12
|
+
"@radix-ui/react-collapsible": "^1.1.10",
|
|
13
|
+
"@radix-ui/react-context-menu": "^2.2.14",
|
|
14
|
+
"@radix-ui/react-dialog": "^1.1.13",
|
|
15
|
+
"@radix-ui/react-dropdown-menu": "^2.1.14",
|
|
16
|
+
"@radix-ui/react-hover-card": "^1.1.13",
|
|
17
|
+
"@radix-ui/react-label": "^2.1.6",
|
|
18
|
+
"@radix-ui/react-menubar": "^1.1.14",
|
|
19
|
+
"@radix-ui/react-navigation-menu": "^1.2.12",
|
|
20
|
+
"@radix-ui/react-popover": "^1.1.13",
|
|
21
|
+
"@radix-ui/react-progress": "^1.1.6",
|
|
22
|
+
"@radix-ui/react-radio-group": "^1.3.6",
|
|
23
|
+
"@radix-ui/react-scroll-area": "^1.2.8",
|
|
24
|
+
"@radix-ui/react-select": "^2.2.4",
|
|
25
|
+
"@radix-ui/react-separator": "^1.1.6",
|
|
26
|
+
"@radix-ui/react-slider": "^1.3.4",
|
|
27
|
+
"@radix-ui/react-slot": "^1.2.2",
|
|
28
|
+
"@radix-ui/react-switch": "^1.2.4",
|
|
29
|
+
"@radix-ui/react-tabs": "^1.1.11",
|
|
30
|
+
"@radix-ui/react-toggle": "^1.1.8",
|
|
31
|
+
"@radix-ui/react-toggle-group": "^1.1.9",
|
|
32
|
+
"@radix-ui/react-tooltip": "^1.2.6",
|
|
33
|
+
"class-variance-authority": "^0.7.1",
|
|
34
|
+
"clsx": "^2.1.1",
|
|
35
|
+
"cmdk": "^1.1.1",
|
|
36
|
+
"date-fns": "^4.1.0",
|
|
37
|
+
"embla-carousel-react": "^8.6.0",
|
|
38
|
+
"input-otp": "^1.4.2",
|
|
39
|
+
"lucide-react": "^0.523.0",
|
|
40
|
+
"next-themes": "^0.4.6",
|
|
41
|
+
"react": "19.1.2",
|
|
42
|
+
"react-day-picker": "8.10.1",
|
|
43
|
+
"react-dom": "19.1.2",
|
|
44
|
+
"react-hook-form": "^7.62.0",
|
|
45
|
+
"react-resizable-panels": "^2.1.9",
|
|
46
|
+
"recharts": "^2.15.3",
|
|
47
|
+
"sonner": "^2.0.7",
|
|
48
|
+
"tailwind-merge": "^3.2.0",
|
|
49
|
+
"tw-animate-css": "^1.3.5",
|
|
50
|
+
"vaul": "^1.1.2",
|
|
51
|
+
"zod": "3.25.76"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@tailwindcss/postcss": "^4.1.5",
|
|
55
|
+
"@turbo/gen": "^2.5.3",
|
|
56
|
+
"@types/node": "22.15.2",
|
|
57
|
+
"@types/react": "^19.1.3",
|
|
58
|
+
"@types/react-dom": "^19.1.3",
|
|
59
|
+
"tailwindcss": "^4.1.5",
|
|
60
|
+
"typescript": "^5.8.3",
|
|
61
|
+
"@openui-xio/typescript-config": "0.0.1"
|
|
62
|
+
},
|
|
63
|
+
"exports": {
|
|
64
|
+
"./globals.css": "./src/styles/globals.css",
|
|
65
|
+
"./postcss.config": "./postcss.config.mjs",
|
|
66
|
+
"./lib/*": "./src/lib/*.ts",
|
|
67
|
+
"./components/*": "./src/components/*.tsx",
|
|
68
|
+
"./hooks/*": "./src/hooks/*.ts"
|
|
69
|
+
},
|
|
70
|
+
"version": "0.0.2",
|
|
71
|
+
"scripts": {
|
|
72
|
+
"lint": "biome lint . --max-warnings 0"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
|
5
|
+
import { ChevronDownIcon } from 'lucide-react';
|
|
6
|
+
|
|
7
|
+
import { cn } from '@openui-xio/ui/lib/utils';
|
|
8
|
+
|
|
9
|
+
function Accordion({
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Root>) {
|
|
12
|
+
return <AccordionPrimitive.Root data-slot="accordion" {...props} />;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function AccordionItem({
|
|
16
|
+
className,
|
|
17
|
+
...props
|
|
18
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Item>) {
|
|
19
|
+
return (
|
|
20
|
+
<AccordionPrimitive.Item
|
|
21
|
+
data-slot="accordion-item"
|
|
22
|
+
className={cn('border-b last:border-b-0', className)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function AccordionTrigger({
|
|
29
|
+
className,
|
|
30
|
+
children,
|
|
31
|
+
...props
|
|
32
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
|
|
33
|
+
return (
|
|
34
|
+
<AccordionPrimitive.Header className="flex">
|
|
35
|
+
<AccordionPrimitive.Trigger
|
|
36
|
+
data-slot="accordion-trigger"
|
|
37
|
+
className={cn(
|
|
38
|
+
'flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left font-medium text-sm outline-none transition-all hover:underline focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180',
|
|
39
|
+
className,
|
|
40
|
+
)}
|
|
41
|
+
{...props}
|
|
42
|
+
>
|
|
43
|
+
{children}
|
|
44
|
+
<ChevronDownIcon className="pointer-events-none size-4 shrink-0 translate-y-0.5 text-muted-foreground transition-transform duration-200" />
|
|
45
|
+
</AccordionPrimitive.Trigger>
|
|
46
|
+
</AccordionPrimitive.Header>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function AccordionContent({
|
|
51
|
+
className,
|
|
52
|
+
children,
|
|
53
|
+
...props
|
|
54
|
+
}: React.ComponentProps<typeof AccordionPrimitive.Content>) {
|
|
55
|
+
return (
|
|
56
|
+
<AccordionPrimitive.Content
|
|
57
|
+
data-slot="accordion-content"
|
|
58
|
+
className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
|
59
|
+
{...props}
|
|
60
|
+
>
|
|
61
|
+
<div className={cn('pt-0 pb-4', className)}>{children}</div>
|
|
62
|
+
</AccordionPrimitive.Content>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
|
|
5
|
+
|
|
6
|
+
import { cn } from '@openui-xio/ui/lib/utils';
|
|
7
|
+
import { buttonVariants } from '@openui-xio/ui/components/button';
|
|
8
|
+
|
|
9
|
+
function AlertDialog({
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
|
|
12
|
+
return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function AlertDialogTrigger({
|
|
16
|
+
...props
|
|
17
|
+
}: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
|
|
18
|
+
return (
|
|
19
|
+
<AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function AlertDialogPortal({
|
|
24
|
+
...props
|
|
25
|
+
}: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
|
|
26
|
+
return (
|
|
27
|
+
<AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function AlertDialogOverlay({
|
|
32
|
+
className,
|
|
33
|
+
...props
|
|
34
|
+
}: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
|
|
35
|
+
return (
|
|
36
|
+
<AlertDialogPrimitive.Overlay
|
|
37
|
+
data-slot="alert-dialog-overlay"
|
|
38
|
+
className={cn(
|
|
39
|
+
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=open]:animate-in',
|
|
40
|
+
className,
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function AlertDialogContent({
|
|
48
|
+
className,
|
|
49
|
+
...props
|
|
50
|
+
}: React.ComponentProps<typeof AlertDialogPrimitive.Content>) {
|
|
51
|
+
return (
|
|
52
|
+
<AlertDialogPortal>
|
|
53
|
+
<AlertDialogOverlay />
|
|
54
|
+
<AlertDialogPrimitive.Content
|
|
55
|
+
data-slot="alert-dialog-content"
|
|
56
|
+
className={cn(
|
|
57
|
+
'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in sm:max-w-lg',
|
|
58
|
+
className,
|
|
59
|
+
)}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
</AlertDialogPortal>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function AlertDialogHeader({
|
|
67
|
+
className,
|
|
68
|
+
...props
|
|
69
|
+
}: React.ComponentProps<'div'>) {
|
|
70
|
+
return (
|
|
71
|
+
<div
|
|
72
|
+
data-slot="alert-dialog-header"
|
|
73
|
+
className={cn('flex flex-col gap-2 text-center sm:text-left', className)}
|
|
74
|
+
{...props}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function AlertDialogFooter({
|
|
80
|
+
className,
|
|
81
|
+
...props
|
|
82
|
+
}: React.ComponentProps<'div'>) {
|
|
83
|
+
return (
|
|
84
|
+
<div
|
|
85
|
+
data-slot="alert-dialog-footer"
|
|
86
|
+
className={cn(
|
|
87
|
+
'flex flex-col-reverse gap-2 sm:flex-row sm:justify-end',
|
|
88
|
+
className,
|
|
89
|
+
)}
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function AlertDialogTitle({
|
|
96
|
+
className,
|
|
97
|
+
...props
|
|
98
|
+
}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
|
|
99
|
+
return (
|
|
100
|
+
<AlertDialogPrimitive.Title
|
|
101
|
+
data-slot="alert-dialog-title"
|
|
102
|
+
className={cn('font-semibold text-lg', className)}
|
|
103
|
+
{...props}
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function AlertDialogDescription({
|
|
109
|
+
className,
|
|
110
|
+
...props
|
|
111
|
+
}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
|
|
112
|
+
return (
|
|
113
|
+
<AlertDialogPrimitive.Description
|
|
114
|
+
data-slot="alert-dialog-description"
|
|
115
|
+
className={cn('text-muted-foreground text-sm', className)}
|
|
116
|
+
{...props}
|
|
117
|
+
/>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function AlertDialogAction({
|
|
122
|
+
className,
|
|
123
|
+
...props
|
|
124
|
+
}: React.ComponentProps<typeof AlertDialogPrimitive.Action>) {
|
|
125
|
+
return (
|
|
126
|
+
<AlertDialogPrimitive.Action
|
|
127
|
+
className={cn(buttonVariants(), className)}
|
|
128
|
+
{...props}
|
|
129
|
+
/>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function AlertDialogCancel({
|
|
134
|
+
className,
|
|
135
|
+
...props
|
|
136
|
+
}: React.ComponentProps<typeof AlertDialogPrimitive.Cancel>) {
|
|
137
|
+
return (
|
|
138
|
+
<AlertDialogPrimitive.Cancel
|
|
139
|
+
className={cn(buttonVariants({ variant: 'outline' }), className)}
|
|
140
|
+
{...props}
|
|
141
|
+
/>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
AlertDialog,
|
|
147
|
+
AlertDialogPortal,
|
|
148
|
+
AlertDialogOverlay,
|
|
149
|
+
AlertDialogTrigger,
|
|
150
|
+
AlertDialogContent,
|
|
151
|
+
AlertDialogHeader,
|
|
152
|
+
AlertDialogFooter,
|
|
153
|
+
AlertDialogTitle,
|
|
154
|
+
AlertDialogDescription,
|
|
155
|
+
AlertDialogAction,
|
|
156
|
+
AlertDialogCancel,
|
|
157
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
3
|
+
|
|
4
|
+
import { cn } from '@openui-xio/ui/lib/utils';
|
|
5
|
+
|
|
6
|
+
const alertVariants = cva(
|
|
7
|
+
'relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default: 'bg-card text-card-foreground',
|
|
12
|
+
destructive:
|
|
13
|
+
'bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 [&>svg]:text-current',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
defaultVariants: {
|
|
17
|
+
variant: 'default',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
function Alert({
|
|
23
|
+
className,
|
|
24
|
+
variant,
|
|
25
|
+
...props
|
|
26
|
+
}: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {
|
|
27
|
+
return (
|
|
28
|
+
<div
|
|
29
|
+
data-slot="alert"
|
|
30
|
+
role="alert"
|
|
31
|
+
className={cn(alertVariants({ variant }), className)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {
|
|
38
|
+
return (
|
|
39
|
+
<div
|
|
40
|
+
data-slot="alert-title"
|
|
41
|
+
className={cn(
|
|
42
|
+
'col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight',
|
|
43
|
+
className,
|
|
44
|
+
)}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function AlertDescription({
|
|
51
|
+
className,
|
|
52
|
+
...props
|
|
53
|
+
}: React.ComponentProps<'div'>) {
|
|
54
|
+
return (
|
|
55
|
+
<div
|
|
56
|
+
data-slot="alert-description"
|
|
57
|
+
className={cn(
|
|
58
|
+
'col-start-2 grid justify-items-start gap-1 text-muted-foreground text-sm [&_p]:leading-relaxed',
|
|
59
|
+
className,
|
|
60
|
+
)}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { Alert, AlertTitle, AlertDescription };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
|
|
4
|
+
|
|
5
|
+
function AspectRatio({
|
|
6
|
+
...props
|
|
7
|
+
}: React.ComponentProps<typeof AspectRatioPrimitive.Root>) {
|
|
8
|
+
return <AspectRatioPrimitive.Root data-slot="aspect-ratio" {...props} />;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { AspectRatio };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
5
|
+
|
|
6
|
+
import { cn } from '@openui-xio/ui/lib/utils';
|
|
7
|
+
|
|
8
|
+
function Avatar({
|
|
9
|
+
className,
|
|
10
|
+
...props
|
|
11
|
+
}: React.ComponentProps<typeof AvatarPrimitive.Root>) {
|
|
12
|
+
return (
|
|
13
|
+
<AvatarPrimitive.Root
|
|
14
|
+
data-slot="avatar"
|
|
15
|
+
className={cn(
|
|
16
|
+
'relative flex size-8 shrink-0 overflow-hidden rounded-full',
|
|
17
|
+
className,
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function AvatarImage({
|
|
25
|
+
className,
|
|
26
|
+
...props
|
|
27
|
+
}: React.ComponentProps<typeof AvatarPrimitive.Image>) {
|
|
28
|
+
return (
|
|
29
|
+
<AvatarPrimitive.Image
|
|
30
|
+
data-slot="avatar-image"
|
|
31
|
+
className={cn('aspect-square size-full', className)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function AvatarFallback({
|
|
38
|
+
className,
|
|
39
|
+
...props
|
|
40
|
+
}: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
|
|
41
|
+
return (
|
|
42
|
+
<AvatarPrimitive.Fallback
|
|
43
|
+
data-slot="avatar-fallback"
|
|
44
|
+
className={cn(
|
|
45
|
+
'flex size-full items-center justify-center rounded-full bg-muted',
|
|
46
|
+
className,
|
|
47
|
+
)}
|
|
48
|
+
{...props}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { Avatar, AvatarImage, AvatarFallback };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
4
|
+
|
|
5
|
+
import { cn } from '@openui-xio/ui/lib/utils';
|
|
6
|
+
|
|
7
|
+
const badgeVariants = cva(
|
|
8
|
+
'inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden whitespace-nowrap rounded-md border px-2 py-0.5 font-medium text-xs transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3',
|
|
9
|
+
{
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default:
|
|
13
|
+
'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
|
|
14
|
+
secondary:
|
|
15
|
+
'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
|
|
16
|
+
destructive:
|
|
17
|
+
'border-transparent bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90',
|
|
18
|
+
outline:
|
|
19
|
+
'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
variant: 'default',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
function Badge({
|
|
29
|
+
className,
|
|
30
|
+
variant,
|
|
31
|
+
asChild = false,
|
|
32
|
+
...props
|
|
33
|
+
}: React.ComponentProps<'span'> &
|
|
34
|
+
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
|
|
35
|
+
const Comp = asChild ? Slot : 'span';
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<Comp
|
|
39
|
+
data-slot="badge"
|
|
40
|
+
className={cn(badgeVariants({ variant }), className)}
|
|
41
|
+
{...props}
|
|
42
|
+
/>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { Badge, badgeVariants };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import { ChevronRight, MoreHorizontal } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
import { cn } from '@openui-xio/ui/lib/utils';
|
|
6
|
+
|
|
7
|
+
function Breadcrumb({ ...props }: React.ComponentProps<'nav'>) {
|
|
8
|
+
return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {
|
|
12
|
+
return (
|
|
13
|
+
<ol
|
|
14
|
+
data-slot="breadcrumb-list"
|
|
15
|
+
className={cn(
|
|
16
|
+
'flex flex-wrap items-center gap-1.5 break-words text-muted-foreground text-sm sm:gap-2.5',
|
|
17
|
+
className,
|
|
18
|
+
)}
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {
|
|
25
|
+
return (
|
|
26
|
+
<li
|
|
27
|
+
data-slot="breadcrumb-item"
|
|
28
|
+
className={cn('inline-flex items-center gap-1.5', className)}
|
|
29
|
+
{...props}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function BreadcrumbLink({
|
|
35
|
+
asChild,
|
|
36
|
+
className,
|
|
37
|
+
...props
|
|
38
|
+
}: React.ComponentProps<'a'> & {
|
|
39
|
+
asChild?: boolean;
|
|
40
|
+
}) {
|
|
41
|
+
const Comp = asChild ? Slot : 'a';
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<Comp
|
|
45
|
+
data-slot="breadcrumb-link"
|
|
46
|
+
className={cn('transition-colors hover:text-foreground', className)}
|
|
47
|
+
{...props}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {
|
|
53
|
+
return (
|
|
54
|
+
<span
|
|
55
|
+
data-slot="breadcrumb-page"
|
|
56
|
+
role="link"
|
|
57
|
+
aria-disabled="true"
|
|
58
|
+
aria-current="page"
|
|
59
|
+
className={cn('font-normal text-foreground', className)}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function BreadcrumbSeparator({
|
|
66
|
+
children,
|
|
67
|
+
className,
|
|
68
|
+
...props
|
|
69
|
+
}: React.ComponentProps<'li'>) {
|
|
70
|
+
return (
|
|
71
|
+
<li
|
|
72
|
+
data-slot="breadcrumb-separator"
|
|
73
|
+
role="presentation"
|
|
74
|
+
aria-hidden="true"
|
|
75
|
+
className={cn('[&>svg]:size-3.5', className)}
|
|
76
|
+
{...props}
|
|
77
|
+
>
|
|
78
|
+
{children ?? <ChevronRight />}
|
|
79
|
+
</li>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function BreadcrumbEllipsis({
|
|
84
|
+
className,
|
|
85
|
+
...props
|
|
86
|
+
}: React.ComponentProps<'span'>) {
|
|
87
|
+
return (
|
|
88
|
+
<span
|
|
89
|
+
data-slot="breadcrumb-ellipsis"
|
|
90
|
+
role="presentation"
|
|
91
|
+
aria-hidden="true"
|
|
92
|
+
className={cn('flex size-9 items-center justify-center', className)}
|
|
93
|
+
{...props}
|
|
94
|
+
>
|
|
95
|
+
<MoreHorizontal className="size-4" />
|
|
96
|
+
<span className="sr-only">More</span>
|
|
97
|
+
</span>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export {
|
|
102
|
+
Breadcrumb,
|
|
103
|
+
BreadcrumbList,
|
|
104
|
+
BreadcrumbItem,
|
|
105
|
+
BreadcrumbLink,
|
|
106
|
+
BreadcrumbPage,
|
|
107
|
+
BreadcrumbSeparator,
|
|
108
|
+
BreadcrumbEllipsis,
|
|
109
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
2
|
+
import { cn } from '../lib/utils.js';
|
|
3
|
+
|
|
4
|
+
export const buttonVariants = cva(
|
|
5
|
+
cn(
|
|
6
|
+
'relative flex flex-row items-center justify-center gap-2 font-normal disabled:opacity-50',
|
|
7
|
+
),
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
primary:
|
|
12
|
+
'glass-body glass-body-interactive glass-body-motion enabled:glass-body-motion-interactive bg-primary text-primary-foreground',
|
|
13
|
+
secondary:
|
|
14
|
+
'glass-body glass-body-interactive glass-body-motion enabled:glass-body-motion-interactive bg-muted text-foreground',
|
|
15
|
+
ghost: 'bg-transparent text-foreground',
|
|
16
|
+
},
|
|
17
|
+
size: {
|
|
18
|
+
sm: 'h-8 rounded-xl px-2 py-1 text-sm',
|
|
19
|
+
md: 'h-10 rounded-xl px-4 py-2 text-sm',
|
|
20
|
+
lg: 'h-12 rounded-xl px-6 py-3 text-base',
|
|
21
|
+
xl: 'h-14 rounded-xl px-8 py-4 text-lg',
|
|
22
|
+
'icon-sm': 'size-8 rounded-full',
|
|
23
|
+
'icon-md': 'size-10 rounded-full',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
|
|
30
|
+
VariantProps<typeof buttonVariants>;
|
|
31
|
+
|
|
32
|
+
export function Button({
|
|
33
|
+
variant = 'primary',
|
|
34
|
+
size = 'md',
|
|
35
|
+
className,
|
|
36
|
+
type = 'button',
|
|
37
|
+
...props
|
|
38
|
+
}: ButtonProps) {
|
|
39
|
+
return (
|
|
40
|
+
<button
|
|
41
|
+
className={cn(buttonVariants({ variant, size }), className)}
|
|
42
|
+
type={type}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|