@hobenakicoffee/libraries 1.27.0 → 1.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -39
- package/src/nuqs/common.ts +12 -0
- package/src/nuqs/index.ts +2 -0
- package/src/nuqs/transactions.ts +31 -0
- package/src/types/supabase.ts +30 -0
- package/src/components/ui/alert-dialog.tsx +0 -196
- package/src/components/ui/alert.tsx +0 -76
- package/src/components/ui/avatar.tsx +0 -110
- package/src/components/ui/badge.tsx +0 -49
- package/src/components/ui/breadcrumb.tsx +0 -122
- package/src/components/ui/button-group.tsx +0 -82
- package/src/components/ui/card.tsx +0 -100
- package/src/components/ui/chart.tsx +0 -364
- package/src/components/ui/checkbox.tsx +0 -30
- package/src/components/ui/dialog.tsx +0 -162
- package/src/components/ui/drawer.tsx +0 -126
- package/src/components/ui/dropdown-menu.tsx +0 -267
- package/src/components/ui/empty-minimal.tsx +0 -20
- package/src/components/ui/empty.tsx +0 -101
- package/src/components/ui/field.tsx +0 -235
- package/src/components/ui/input-group.tsx +0 -170
- package/src/components/ui/input-otp.tsx +0 -84
- package/src/components/ui/input.tsx +0 -37
- package/src/components/ui/item.tsx +0 -196
- package/src/components/ui/label.tsx +0 -19
- package/src/components/ui/popover.tsx +0 -87
- package/src/components/ui/radio-group.tsx +0 -47
- package/src/components/ui/select.tsx +0 -205
- package/src/components/ui/separator.tsx +0 -26
- package/src/components/ui/sheet.tsx +0 -141
- package/src/components/ui/sidebar.tsx +0 -699
- package/src/components/ui/skeleton.tsx +0 -13
- package/src/components/ui/sonner.tsx +0 -74
- package/src/components/ui/table.tsx +0 -114
- package/src/components/ui/tabs.tsx +0 -88
- package/src/components/ui/textarea.tsx +0 -35
- package/src/components/ui/toggle-group.tsx +0 -91
- package/src/components/ui/toggle.tsx +0 -44
- package/src/components/ui/tooltip.tsx +0 -59
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
|
-
import { useMemo } from "react";
|
|
3
|
-
import { Label } from "@/components/ui/label";
|
|
4
|
-
import { Separator } from "@/components/ui/separator";
|
|
5
|
-
import { cn } from "@/lib/utils";
|
|
6
|
-
|
|
7
|
-
function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
|
|
8
|
-
return (
|
|
9
|
-
<fieldset
|
|
10
|
-
className={cn(
|
|
11
|
-
"flex flex-col gap-6 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
|
|
12
|
-
className
|
|
13
|
-
)}
|
|
14
|
-
data-slot="field-set"
|
|
15
|
-
{...props}
|
|
16
|
-
/>
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function FieldLegend({
|
|
21
|
-
className,
|
|
22
|
-
variant = "legend",
|
|
23
|
-
...props
|
|
24
|
-
}: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
|
|
25
|
-
return (
|
|
26
|
-
<legend
|
|
27
|
-
className={cn(
|
|
28
|
-
"mb-3 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base",
|
|
29
|
-
className
|
|
30
|
-
)}
|
|
31
|
-
data-slot="field-legend"
|
|
32
|
-
data-variant={variant}
|
|
33
|
-
{...props}
|
|
34
|
-
/>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
|
|
39
|
-
return (
|
|
40
|
-
<div
|
|
41
|
-
className={cn(
|
|
42
|
-
"group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4",
|
|
43
|
-
className
|
|
44
|
-
)}
|
|
45
|
-
data-slot="field-group"
|
|
46
|
-
{...props}
|
|
47
|
-
/>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const fieldVariants = cva(
|
|
52
|
-
"group/field flex w-full gap-3 data-[invalid=true]:text-destructive",
|
|
53
|
-
{
|
|
54
|
-
variants: {
|
|
55
|
-
orientation: {
|
|
56
|
-
vertical: "flex-col [&>*]:w-full [&>.sr-only]:w-auto",
|
|
57
|
-
horizontal:
|
|
58
|
-
"flex-row items-center has-[>[data-slot=field-content]]:items-start [&>[data-slot=field-label]]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
|
|
59
|
-
responsive:
|
|
60
|
-
"@md/field-group:flex-row flex-col @md/field-group:items-center @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:[&>*]:w-auto [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:[&>[data-slot=field-label]]:flex-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
|
|
61
|
-
},
|
|
62
|
-
},
|
|
63
|
-
defaultVariants: {
|
|
64
|
-
orientation: "vertical",
|
|
65
|
-
},
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
function Field({
|
|
70
|
-
className,
|
|
71
|
-
orientation = "vertical",
|
|
72
|
-
...props
|
|
73
|
-
}: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
|
|
74
|
-
return (
|
|
75
|
-
<div
|
|
76
|
-
className={cn(fieldVariants({ orientation }), className)}
|
|
77
|
-
data-orientation={orientation}
|
|
78
|
-
data-slot="field"
|
|
79
|
-
role="group"
|
|
80
|
-
{...props}
|
|
81
|
-
/>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
86
|
-
return (
|
|
87
|
-
<div
|
|
88
|
-
className={cn(
|
|
89
|
-
"group/field-content flex flex-1 flex-col gap-1 leading-snug",
|
|
90
|
-
className
|
|
91
|
-
)}
|
|
92
|
-
data-slot="field-content"
|
|
93
|
-
{...props}
|
|
94
|
-
/>
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function FieldLabel({
|
|
99
|
-
className,
|
|
100
|
-
...props
|
|
101
|
-
}: React.ComponentProps<typeof Label>) {
|
|
102
|
-
return (
|
|
103
|
-
<Label
|
|
104
|
-
className={cn(
|
|
105
|
-
"group/field-label peer/field-label flex w-fit gap-2 leading-snug has-[>[data-slot=field]]:rounded-xl has-[>[data-slot=field]]:border-2 has-data-checked:border-primary has-data-checked:bg-primary/5 *:data-[slot=field]:p-4 group-data-[disabled=true]/field:opacity-50 dark:has-data-checked:bg-primary/10",
|
|
106
|
-
"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col",
|
|
107
|
-
className
|
|
108
|
-
)}
|
|
109
|
-
data-slot="field-label"
|
|
110
|
-
{...props}
|
|
111
|
-
/>
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
116
|
-
return (
|
|
117
|
-
<div
|
|
118
|
-
className={cn(
|
|
119
|
-
"flex w-fit items-center gap-2 font-medium text-sm leading-snug group-data-[disabled=true]/field:opacity-50",
|
|
120
|
-
className
|
|
121
|
-
)}
|
|
122
|
-
data-slot="field-label"
|
|
123
|
-
{...props}
|
|
124
|
-
/>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
|
|
129
|
-
return (
|
|
130
|
-
<p
|
|
131
|
-
className={cn(
|
|
132
|
-
"text-left font-normal text-muted-foreground text-sm leading-normal group-has-data-[orientation=horizontal]/field:text-balance [[data-variant=legend]+&]:-mt-1.5",
|
|
133
|
-
"nth-last-2:-mt-1 last:mt-0",
|
|
134
|
-
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
|
|
135
|
-
className
|
|
136
|
-
)}
|
|
137
|
-
data-slot="field-description"
|
|
138
|
-
{...props}
|
|
139
|
-
/>
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function FieldSeparator({
|
|
144
|
-
children,
|
|
145
|
-
className,
|
|
146
|
-
...props
|
|
147
|
-
}: React.ComponentProps<"div"> & {
|
|
148
|
-
children?: React.ReactNode;
|
|
149
|
-
}) {
|
|
150
|
-
return (
|
|
151
|
-
<div
|
|
152
|
-
className={cn(
|
|
153
|
-
"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
|
|
154
|
-
className
|
|
155
|
-
)}
|
|
156
|
-
data-content={!!children}
|
|
157
|
-
data-slot="field-separator"
|
|
158
|
-
{...props}
|
|
159
|
-
>
|
|
160
|
-
<Separator className="absolute inset-0 top-1/2" />
|
|
161
|
-
{children && (
|
|
162
|
-
<span
|
|
163
|
-
className="relative mx-auto block w-fit bg-background px-2 text-muted-foreground"
|
|
164
|
-
data-slot="field-separator-content"
|
|
165
|
-
>
|
|
166
|
-
{children}
|
|
167
|
-
</span>
|
|
168
|
-
)}
|
|
169
|
-
</div>
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
function FieldError({
|
|
174
|
-
className,
|
|
175
|
-
children,
|
|
176
|
-
errors,
|
|
177
|
-
...props
|
|
178
|
-
}: React.ComponentProps<"div"> & {
|
|
179
|
-
errors?: Array<{ message?: string } | undefined>;
|
|
180
|
-
}) {
|
|
181
|
-
const content = useMemo(() => {
|
|
182
|
-
if (children) {
|
|
183
|
-
return children;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (!errors?.length) {
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const uniqueErrors = [
|
|
191
|
-
...new Map(errors.map((error) => [error?.message, error])).values(),
|
|
192
|
-
];
|
|
193
|
-
|
|
194
|
-
if (uniqueErrors?.length === 1) {
|
|
195
|
-
return uniqueErrors[0]?.message;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return (
|
|
199
|
-
<ul className="ml-4 flex list-disc flex-col gap-1">
|
|
200
|
-
{uniqueErrors.map(
|
|
201
|
-
(error, index) =>
|
|
202
|
-
error?.message && <li key={index}>{error.message}</li>
|
|
203
|
-
)}
|
|
204
|
-
</ul>
|
|
205
|
-
);
|
|
206
|
-
}, [children, errors]);
|
|
207
|
-
|
|
208
|
-
if (!content) {
|
|
209
|
-
return null;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return (
|
|
213
|
-
<div
|
|
214
|
-
className={cn("font-normal text-destructive text-sm", className)}
|
|
215
|
-
data-slot="field-error"
|
|
216
|
-
role="alert"
|
|
217
|
-
{...props}
|
|
218
|
-
>
|
|
219
|
-
{content}
|
|
220
|
-
</div>
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
export {
|
|
225
|
-
Field,
|
|
226
|
-
FieldLabel,
|
|
227
|
-
FieldDescription,
|
|
228
|
-
FieldError,
|
|
229
|
-
FieldGroup,
|
|
230
|
-
FieldLegend,
|
|
231
|
-
FieldSeparator,
|
|
232
|
-
FieldSet,
|
|
233
|
-
FieldContent,
|
|
234
|
-
FieldTitle,
|
|
235
|
-
};
|
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
|
-
import type * as React from "react";
|
|
3
|
-
import { Button } from "@/components/ui/button";
|
|
4
|
-
import { Input } from "@/components/ui/input";
|
|
5
|
-
import { Textarea } from "@/components/ui/textarea";
|
|
6
|
-
import { cn } from "@/lib/utils";
|
|
7
|
-
|
|
8
|
-
const inputGroupVariants = cva(
|
|
9
|
-
"group/input-group relative flex h-12 w-full min-w-0 items-center gap-1.5 overflow-hidden rounded-xl border border-input outline-none transition-colors has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-start]]:h-auto has-[>textarea]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:flex-col has-[textarea]:rounded-xl has-data-[align=block-end]:rounded-2xl has-data-[align=block-start]:rounded-2xl has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot=input-group-control]:focus-visible]:ring has-[[data-slot][aria-invalid=true]]:ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring has-[[data-slot][aria-invalid=true]]:ring-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-start]]:[&>input]:pl-1.5 [[data-slot=combobox-content]_&]:focus-within:border-inherit [[data-slot=combobox-content]_&]:focus-within:ring-0",
|
|
10
|
-
{
|
|
11
|
-
variants: {
|
|
12
|
-
variant: {
|
|
13
|
-
default: "bg-input/30",
|
|
14
|
-
inverted: "bg-background",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
defaultVariants: {
|
|
18
|
-
variant: "default",
|
|
19
|
-
},
|
|
20
|
-
}
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
function InputGroup({
|
|
24
|
-
className,
|
|
25
|
-
variant = "default",
|
|
26
|
-
...props
|
|
27
|
-
}: React.ComponentProps<"div"> & VariantProps<typeof inputGroupVariants>) {
|
|
28
|
-
return (
|
|
29
|
-
<div
|
|
30
|
-
className={cn(inputGroupVariants({ variant, className }))}
|
|
31
|
-
data-slot="input-group"
|
|
32
|
-
role="group"
|
|
33
|
-
{...props}
|
|
34
|
-
/>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const inputGroupAddonVariants = cva(
|
|
39
|
-
"flex h-auto cursor-text select-none items-center justify-center gap-2 py-2 font-medium text-muted-foreground text-sm **:data-[slot=kbd]:rounded-xl **:data-[slot=kbd]:bg-muted-foreground/10 **:data-[slot=kbd]:px-1.5 group-data-[disabled=true]/input-group:opacity-50 [&>svg:not([class*='size-'])]:size-4",
|
|
40
|
-
{
|
|
41
|
-
variants: {
|
|
42
|
-
align: {
|
|
43
|
-
"inline-start":
|
|
44
|
-
"order-first pl-3 has-[>button]:ml-[-0.25rem] has-[>kbd]:ml-[-0.15rem]",
|
|
45
|
-
"inline-end":
|
|
46
|
-
"order-last pr-3 has-[>button]:mr-[-0.25rem] has-[>kbd]:mr-[-0.15rem]",
|
|
47
|
-
"block-start":
|
|
48
|
-
"order-first w-full justify-start px-3 pt-3 group-has-[>input]/input-group:pt-3 [.border-b]:pb-3",
|
|
49
|
-
"block-end":
|
|
50
|
-
"order-last w-full justify-start px-3 pb-3 group-has-[>input]/input-group:pb-3 [.border-t]:pt-3",
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
defaultVariants: {
|
|
54
|
-
align: "inline-start",
|
|
55
|
-
},
|
|
56
|
-
}
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
function InputGroupAddon({
|
|
60
|
-
className,
|
|
61
|
-
align = "inline-start",
|
|
62
|
-
...props
|
|
63
|
-
}: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
|
|
64
|
-
return (
|
|
65
|
-
<div
|
|
66
|
-
className={cn(inputGroupAddonVariants({ align }), className)}
|
|
67
|
-
data-align={align}
|
|
68
|
-
data-slot="input-group-addon"
|
|
69
|
-
onClick={(e) => {
|
|
70
|
-
if ((e.target as HTMLElement).closest("button")) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
e.currentTarget.parentElement?.querySelector("input")?.focus();
|
|
74
|
-
}}
|
|
75
|
-
role="group"
|
|
76
|
-
{...props}
|
|
77
|
-
/>
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const inputGroupButtonVariants = cva(
|
|
82
|
-
"flex items-center gap-2 rounded-xl text-sm shadow-none",
|
|
83
|
-
{
|
|
84
|
-
variants: {
|
|
85
|
-
size: {
|
|
86
|
-
xs: "h-6 gap-1 px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
|
|
87
|
-
sm: "",
|
|
88
|
-
"icon-xs": "size-6 p-0 has-[>svg]:p-0",
|
|
89
|
-
"icon-sm": "size-8 p-0 has-[>svg]:p-0",
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
defaultVariants: {
|
|
93
|
-
size: "xs",
|
|
94
|
-
},
|
|
95
|
-
}
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
function InputGroupButton({
|
|
99
|
-
className,
|
|
100
|
-
type = "button",
|
|
101
|
-
variant = "ghost",
|
|
102
|
-
size = "xs",
|
|
103
|
-
...props
|
|
104
|
-
}: Omit<React.ComponentProps<typeof Button>, "size" | "type"> &
|
|
105
|
-
VariantProps<typeof inputGroupButtonVariants> & {
|
|
106
|
-
type?: "button" | "submit" | "reset";
|
|
107
|
-
}) {
|
|
108
|
-
return (
|
|
109
|
-
<Button
|
|
110
|
-
className={cn(inputGroupButtonVariants({ size }), className)}
|
|
111
|
-
data-size={size}
|
|
112
|
-
type={type}
|
|
113
|
-
variant={variant}
|
|
114
|
-
{...props}
|
|
115
|
-
/>
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
|
|
120
|
-
return (
|
|
121
|
-
<span
|
|
122
|
-
className={cn(
|
|
123
|
-
"flex items-center gap-2 text-muted-foreground text-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none",
|
|
124
|
-
className
|
|
125
|
-
)}
|
|
126
|
-
{...props}
|
|
127
|
-
/>
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function InputGroupInput({
|
|
132
|
-
className,
|
|
133
|
-
...props
|
|
134
|
-
}: React.ComponentProps<"input">) {
|
|
135
|
-
return (
|
|
136
|
-
<Input
|
|
137
|
-
className={cn(
|
|
138
|
-
"flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",
|
|
139
|
-
className
|
|
140
|
-
)}
|
|
141
|
-
data-slot="input-group-control"
|
|
142
|
-
{...props}
|
|
143
|
-
/>
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function InputGroupTextarea({
|
|
148
|
-
className,
|
|
149
|
-
...props
|
|
150
|
-
}: React.ComponentProps<"textarea">) {
|
|
151
|
-
return (
|
|
152
|
-
<Textarea
|
|
153
|
-
className={cn(
|
|
154
|
-
"flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent",
|
|
155
|
-
className
|
|
156
|
-
)}
|
|
157
|
-
data-slot="input-group-control"
|
|
158
|
-
{...props}
|
|
159
|
-
/>
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export {
|
|
164
|
-
InputGroup,
|
|
165
|
-
InputGroupAddon,
|
|
166
|
-
InputGroupButton,
|
|
167
|
-
InputGroupText,
|
|
168
|
-
InputGroupInput,
|
|
169
|
-
InputGroupTextarea,
|
|
170
|
-
};
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { MinusSignIcon } from "@hugeicons/core-free-icons";
|
|
2
|
-
import { HugeiconsIcon } from "@hugeicons/react";
|
|
3
|
-
import { OTPInput, OTPInputContext } from "input-otp";
|
|
4
|
-
import { type ComponentProps, useContext } from "react";
|
|
5
|
-
import { cn } from "@/lib/utils";
|
|
6
|
-
|
|
7
|
-
function InputOTP({
|
|
8
|
-
className,
|
|
9
|
-
containerClassName,
|
|
10
|
-
...props
|
|
11
|
-
}: ComponentProps<typeof OTPInput> & {
|
|
12
|
-
containerClassName?: string;
|
|
13
|
-
}) {
|
|
14
|
-
return (
|
|
15
|
-
<OTPInput
|
|
16
|
-
className={cn("disabled:cursor-not-allowed", className)}
|
|
17
|
-
containerClassName={cn(
|
|
18
|
-
"cn-input-otp flex items-center has-disabled:opacity-50",
|
|
19
|
-
containerClassName
|
|
20
|
-
)}
|
|
21
|
-
data-slot="input-otp"
|
|
22
|
-
spellCheck={false}
|
|
23
|
-
{...props}
|
|
24
|
-
/>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function InputOTPGroup({ className, ...props }: ComponentProps<"div">) {
|
|
29
|
-
return (
|
|
30
|
-
<div
|
|
31
|
-
className={cn(
|
|
32
|
-
"flex items-center rounded-xl has-aria-invalid:border-destructive has-aria-invalid:ring has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40",
|
|
33
|
-
className
|
|
34
|
-
)}
|
|
35
|
-
data-slot="input-otp-group"
|
|
36
|
-
{...props}
|
|
37
|
-
/>
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function InputOTPSlot({
|
|
42
|
-
index,
|
|
43
|
-
className,
|
|
44
|
-
...props
|
|
45
|
-
}: ComponentProps<"div"> & {
|
|
46
|
-
index: number;
|
|
47
|
-
}) {
|
|
48
|
-
const inputOTPContext = useContext(OTPInputContext);
|
|
49
|
-
const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};
|
|
50
|
-
|
|
51
|
-
return (
|
|
52
|
-
<div
|
|
53
|
-
className={cn(
|
|
54
|
-
"relative flex size-9 items-center justify-center border-input border-y border-r bg-input/10 text-foreground text-sm outline-none transition-all first:rounded-l-xl first:border-l last:rounded-r-xl aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:border-l data-[active=true]:ring data-[active=true]:ring-ring data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 sm:size-10 dark:data-[active=true]:aria-invalid:ring-destructive/40",
|
|
55
|
-
className
|
|
56
|
-
)}
|
|
57
|
-
data-active={isActive}
|
|
58
|
-
data-slot="input-otp-slot"
|
|
59
|
-
{...props}
|
|
60
|
-
>
|
|
61
|
-
{char}
|
|
62
|
-
{hasFakeCaret && (
|
|
63
|
-
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
|
|
64
|
-
<div className="h-4 w-px animate-caret-blink bg-foreground duration-1000" />
|
|
65
|
-
</div>
|
|
66
|
-
)}
|
|
67
|
-
</div>
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function InputOTPSeparator({ ...props }: ComponentProps<"div">) {
|
|
72
|
-
return (
|
|
73
|
-
<div
|
|
74
|
-
className="flex items-center [&_svg:not([class*='size-'])]:size-4"
|
|
75
|
-
data-slot="input-otp-separator"
|
|
76
|
-
role="separator"
|
|
77
|
-
{...props}
|
|
78
|
-
>
|
|
79
|
-
<HugeiconsIcon icon={MinusSignIcon} strokeWidth={2} />
|
|
80
|
-
</div>
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
|
-
import type * as React from "react";
|
|
3
|
-
import { cn } from "@/lib/utils";
|
|
4
|
-
|
|
5
|
-
const inputVariants = cva(
|
|
6
|
-
"h-12 w-full min-w-0 rounded-xl border border-input px-3 py-1 text-base text-foreground outline-none transition-colors file:inline-flex file:h-7 file:border-0 file:bg-transparent file:font-medium file:text-foreground file:text-sm placeholder:text-muted-foreground/80 focus-visible:border-ring focus-visible:ring focus-visible:ring-ring disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring aria-invalid:ring-destructive md:text-sm dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive",
|
|
7
|
-
{
|
|
8
|
-
variants: {
|
|
9
|
-
variant: {
|
|
10
|
-
default: "bg-input/30",
|
|
11
|
-
inverted: "bg-background",
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
defaultVariants: {
|
|
15
|
-
variant: "default",
|
|
16
|
-
},
|
|
17
|
-
}
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
function Input({
|
|
21
|
-
className,
|
|
22
|
-
variant = "default",
|
|
23
|
-
type,
|
|
24
|
-
...props
|
|
25
|
-
}: React.ComponentProps<"input"> & VariantProps<typeof inputVariants>) {
|
|
26
|
-
return (
|
|
27
|
-
<input
|
|
28
|
-
className={cn(inputVariants({ variant, className }))}
|
|
29
|
-
data-slot="input"
|
|
30
|
-
data-variant={variant}
|
|
31
|
-
type={type}
|
|
32
|
-
{...props}
|
|
33
|
-
/>
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export { Input, inputVariants };
|