@quarklab/rad-ui 0.3.1 → 0.3.3

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.
@@ -1,291 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { cva, type VariantProps } from "class-variance-authority";
5
-
6
- import { cn } from "../lib/utils";
7
- import { Label } from "./label";
8
- import { Separator } from "./separator";
9
-
10
- // ---------------------------------------------------------------------------
11
- // FieldSet
12
- // ---------------------------------------------------------------------------
13
-
14
- const FieldSet = React.forwardRef<
15
- HTMLFieldSetElement,
16
- React.FieldsetHTMLAttributes<HTMLFieldSetElement>
17
- >(({ className, ...props }, ref) => (
18
- <fieldset
19
- ref={ref}
20
- className={cn(
21
- "space-y-6 border-none p-0 [&>*+[data-slot=field-group]]:pt-4",
22
- className
23
- )}
24
- {...props}
25
- />
26
- ));
27
- FieldSet.displayName = "FieldSet";
28
-
29
- // ---------------------------------------------------------------------------
30
- // FieldLegend
31
- // ---------------------------------------------------------------------------
32
-
33
- interface FieldLegendProps extends React.HTMLAttributes<HTMLLegendElement> {
34
- variant?: "legend" | "label";
35
- }
36
-
37
- const FieldLegend = React.forwardRef<HTMLLegendElement, FieldLegendProps>(
38
- ({ className, variant = "legend", ...props }, ref) => (
39
- <legend
40
- ref={ref}
41
- className={cn(
42
- variant === "legend"
43
- ? "text-base font-semibold leading-none"
44
- : "text-sm font-medium leading-none",
45
- className
46
- )}
47
- {...props}
48
- />
49
- )
50
- );
51
- FieldLegend.displayName = "FieldLegend";
52
-
53
- // ---------------------------------------------------------------------------
54
- // FieldGroup
55
- // ---------------------------------------------------------------------------
56
-
57
- const FieldGroup = React.forwardRef<
58
- HTMLDivElement,
59
- React.HTMLAttributes<HTMLDivElement>
60
- >(({ className, ...props }, ref) => (
61
- <div
62
- ref={ref}
63
- data-slot="field-group"
64
- className={cn("@container/field-group flex flex-col gap-4", className)}
65
- {...props}
66
- />
67
- ));
68
- FieldGroup.displayName = "FieldGroup";
69
-
70
- // ---------------------------------------------------------------------------
71
- // Field
72
- // ---------------------------------------------------------------------------
73
-
74
- const fieldVariants = cva(
75
- "group/field flex w-full gap-3 data-[invalid=true]:text-destructive",
76
- {
77
- variants: {
78
- orientation: {
79
- vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
80
- horizontal: [
81
- "flex-row items-center",
82
- "[&>[data-slot=field-label]]:flex-auto",
83
- "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
84
- ],
85
- responsive: [
86
- "flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto",
87
- "@md/field-group:[&>[data-slot=field-label]]:flex-auto",
88
- "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
89
- ],
90
- },
91
- },
92
- defaultVariants: {
93
- orientation: "vertical",
94
- },
95
- }
96
- );
97
-
98
- export interface FieldProps
99
- extends
100
- React.HTMLAttributes<HTMLDivElement>,
101
- VariantProps<typeof fieldVariants> {}
102
-
103
- const Field = React.forwardRef<HTMLDivElement, FieldProps>(
104
- ({ className, orientation = "vertical", ...props }, ref) => (
105
- <div
106
- ref={ref}
107
- role="group"
108
- data-slot="field"
109
- className={cn(fieldVariants({ orientation }), className)}
110
- {...props}
111
- />
112
- )
113
- );
114
- Field.displayName = "Field";
115
-
116
- // ---------------------------------------------------------------------------
117
- // FieldContent
118
- // ---------------------------------------------------------------------------
119
-
120
- const FieldContent = React.forwardRef<
121
- HTMLDivElement,
122
- React.HTMLAttributes<HTMLDivElement>
123
- >(({ className, ...props }, ref) => (
124
- <div
125
- ref={ref}
126
- data-slot="field-content"
127
- className={cn("flex flex-col gap-1", className)}
128
- {...props}
129
- />
130
- ));
131
- FieldContent.displayName = "FieldContent";
132
-
133
- // ---------------------------------------------------------------------------
134
- // FieldLabel
135
- // ---------------------------------------------------------------------------
136
-
137
- const FieldLabel = React.forwardRef<
138
- React.ElementRef<typeof Label>,
139
- React.ComponentPropsWithoutRef<typeof Label>
140
- >(({ className, ...props }, ref) => (
141
- <Label
142
- ref={ref}
143
- data-slot="field-label"
144
- className={cn(
145
- "group-data-[invalid=true]/field:text-destructive",
146
- className
147
- )}
148
- {...props}
149
- />
150
- ));
151
- FieldLabel.displayName = "FieldLabel";
152
-
153
- // ---------------------------------------------------------------------------
154
- // FieldTitle
155
- // ---------------------------------------------------------------------------
156
-
157
- const FieldTitle = React.forwardRef<
158
- HTMLDivElement,
159
- React.HTMLAttributes<HTMLDivElement>
160
- >(({ className, ...props }, ref) => (
161
- <div
162
- ref={ref}
163
- data-slot="field-title"
164
- className={cn(
165
- "text-sm font-medium leading-none group-data-[invalid=true]/field:text-destructive",
166
- className
167
- )}
168
- {...props}
169
- />
170
- ));
171
- FieldTitle.displayName = "FieldTitle";
172
-
173
- // ---------------------------------------------------------------------------
174
- // FieldDescription
175
- // ---------------------------------------------------------------------------
176
-
177
- const FieldDescription = React.forwardRef<
178
- HTMLParagraphElement,
179
- React.HTMLAttributes<HTMLParagraphElement>
180
- >(({ className, ...props }, ref) => (
181
- <p
182
- ref={ref}
183
- data-slot="field-description"
184
- className={cn("text-sm text-muted-foreground text-pretty", className)}
185
- {...props}
186
- />
187
- ));
188
- FieldDescription.displayName = "FieldDescription";
189
-
190
- // ---------------------------------------------------------------------------
191
- // FieldSeparator
192
- // ---------------------------------------------------------------------------
193
-
194
- interface FieldSeparatorProps extends React.HTMLAttributes<HTMLDivElement> {
195
- children?: React.ReactNode;
196
- }
197
-
198
- const FieldSeparator = React.forwardRef<HTMLDivElement, FieldSeparatorProps>(
199
- ({ children, className, ...props }, ref) => (
200
- <div
201
- ref={ref}
202
- data-slot="field-separator"
203
- className={cn("flex items-center gap-3", className)}
204
- {...props}
205
- >
206
- <Separator className="flex-1" />
207
- {children && (
208
- <span className="text-xs text-muted-foreground font-medium">
209
- {children}
210
- </span>
211
- )}
212
- <Separator className={cn("flex-1", !children && "hidden")} />
213
- </div>
214
- )
215
- );
216
- FieldSeparator.displayName = "FieldSeparator";
217
-
218
- // ---------------------------------------------------------------------------
219
- // FieldError
220
- // ---------------------------------------------------------------------------
221
-
222
- interface FieldErrorProps extends React.HTMLAttributes<HTMLDivElement> {
223
- errors?: Array<{ message?: string } | undefined>;
224
- }
225
-
226
- const FieldError = React.forwardRef<HTMLDivElement, FieldErrorProps>(
227
- ({ className, children, errors, ...props }, ref) => {
228
- const content = React.useMemo(() => {
229
- if (children) {
230
- return children;
231
- }
232
-
233
- if (!errors?.length) {
234
- return null;
235
- }
236
-
237
- const uniqueErrors = [
238
- ...new Map(errors.map((error) => [error?.message, error])).values(),
239
- ];
240
-
241
- if (uniqueErrors?.length === 1) {
242
- return uniqueErrors[0]?.message;
243
- }
244
-
245
- return (
246
- <ul className="list-disc list-inside space-y-1">
247
- {uniqueErrors.map(
248
- (error, index) =>
249
- error?.message && <li key={index}>{error.message}</li>
250
- )}
251
- </ul>
252
- );
253
- }, [children, errors]);
254
-
255
- if (!content) {
256
- return null;
257
- }
258
-
259
- return (
260
- <div
261
- ref={ref}
262
- data-slot="field-error"
263
- role="alert"
264
- className={cn("text-sm text-destructive", className)}
265
- {...props}
266
- >
267
- {content}
268
- </div>
269
- );
270
- }
271
- );
272
- FieldError.displayName = "FieldError";
273
-
274
- // ---------------------------------------------------------------------------
275
- // Exports
276
- // ---------------------------------------------------------------------------
277
-
278
- export {
279
- Field,
280
- fieldVariants,
281
- FieldContent,
282
- FieldDescription,
283
- FieldError,
284
- FieldGroup,
285
- FieldLabel,
286
- FieldLegend,
287
- FieldSeparator,
288
- FieldSet,
289
- FieldTitle,
290
- };
291
- export type { FieldLegendProps, FieldSeparatorProps, FieldErrorProps };