@liam-michel/simple-form 0.1.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/dist/index.js ADDED
@@ -0,0 +1,714 @@
1
+ // src/SimpleForm.tsx
2
+ import { useForm, FormProvider } from "react-hook-form";
3
+ import { zodResolver } from "@hookform/resolvers/zod";
4
+ import "zod";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ function SimpleForm({
7
+ children,
8
+ schema,
9
+ onSubmit,
10
+ defaultValues,
11
+ form: externalForm,
12
+ submitLabel,
13
+ hideSubmit,
14
+ renderSubmit,
15
+ renderError
16
+ }) {
17
+ const internalForm = useForm({
18
+ resolver: zodResolver(schema),
19
+ defaultValues
20
+ });
21
+ const form = externalForm ?? internalForm;
22
+ const handleSubmit = form.handleSubmit(async (data) => {
23
+ try {
24
+ await onSubmit(data);
25
+ } catch (err) {
26
+ const fieldErrors = err?.data?.fieldErrors;
27
+ if (fieldErrors) {
28
+ Object.entries(fieldErrors).forEach(([field, message]) => {
29
+ form.setError(field, { message });
30
+ });
31
+ } else {
32
+ form.setError("root", {
33
+ message: err?.data?.message ?? err?.message ?? "Something went wrong"
34
+ });
35
+ }
36
+ }
37
+ });
38
+ return /* @__PURE__ */ jsx(FormProvider, { ...form, children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
39
+ typeof children === "function" ? children(form) : children,
40
+ form.formState.errors.root && (renderError ? renderError(form.formState.errors.root.message) : /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-destructive", children: form.formState.errors.root.message })),
41
+ renderSubmit ? renderSubmit({
42
+ isSubmitting: form.formState.isSubmitting,
43
+ reset: form.reset
44
+ }) : !hideSubmit && /* @__PURE__ */ jsx(
45
+ "button",
46
+ {
47
+ type: "submit",
48
+ disabled: form.formState.isSubmitting,
49
+ className: "inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow transition-colors hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-50",
50
+ children: form.formState.isSubmitting ? "Submitting..." : submitLabel ?? "Submit"
51
+ }
52
+ )
53
+ ] }) });
54
+ }
55
+
56
+ // src/createForm.tsx
57
+ import "zod";
58
+
59
+ // src/fields/TextField.tsx
60
+ import "react";
61
+ import { Controller, useFormContext } from "react-hook-form";
62
+ import "zod";
63
+
64
+ // src/utils/cn.ts
65
+ import { clsx } from "clsx";
66
+ import { twMerge } from "tailwind-merge";
67
+ function cn(...inputs) {
68
+ return twMerge(clsx(inputs));
69
+ }
70
+
71
+ // src/fields/TextField.tsx
72
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
73
+ function TextField({
74
+ name,
75
+ label,
76
+ placeholder,
77
+ disabled,
78
+ description,
79
+ className,
80
+ form,
81
+ type = "text",
82
+ showReset
83
+ }) {
84
+ const contextForm = useFormContext();
85
+ const actualForm = form || contextForm;
86
+ return /* @__PURE__ */ jsx2(
87
+ Controller,
88
+ {
89
+ control: actualForm.control,
90
+ name,
91
+ render: ({ field, fieldState }) => /* @__PURE__ */ jsxs2("div", { className: cn("space-y-2", className), children: [
92
+ /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-between", children: [
93
+ /* @__PURE__ */ jsx2(
94
+ "label",
95
+ {
96
+ htmlFor: name,
97
+ className: "text-sm font-medium leading-none",
98
+ children: label
99
+ }
100
+ ),
101
+ showReset && /* @__PURE__ */ jsx2(
102
+ "button",
103
+ {
104
+ type: "button",
105
+ onClick: () => actualForm.resetField(name),
106
+ className: "text-xs text-muted-foreground hover:text-foreground",
107
+ children: "Reset"
108
+ }
109
+ )
110
+ ] }),
111
+ /* @__PURE__ */ jsx2(
112
+ "input",
113
+ {
114
+ ...field,
115
+ id: name,
116
+ value: field.value ?? "",
117
+ placeholder,
118
+ disabled,
119
+ type,
120
+ className: "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
121
+ }
122
+ ),
123
+ description && /* @__PURE__ */ jsx2("p", { className: "text-sm text-muted-foreground", children: description }),
124
+ fieldState.error && /* @__PURE__ */ jsx2("p", { className: "text-sm font-medium text-destructive", children: fieldState.error.message })
125
+ ] })
126
+ }
127
+ );
128
+ }
129
+
130
+ // src/fields/TextAreaField.tsx
131
+ import "react";
132
+ import { Controller as Controller2, useFormContext as useFormContext2 } from "react-hook-form";
133
+ import "zod";
134
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
135
+ function TextAreaField({
136
+ name,
137
+ label,
138
+ placeholder,
139
+ disabled,
140
+ description,
141
+ className,
142
+ form,
143
+ showReset
144
+ }) {
145
+ const contextForm = useFormContext2();
146
+ const actualForm = form || contextForm;
147
+ return /* @__PURE__ */ jsx3(
148
+ Controller2,
149
+ {
150
+ control: actualForm.control,
151
+ name,
152
+ render: ({ field, fieldState }) => /* @__PURE__ */ jsxs3("div", { className: cn("space-y-2", className), children: [
153
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between", children: [
154
+ /* @__PURE__ */ jsx3("label", { htmlFor: name, className: "text-sm font-medium leading-none", children: label }),
155
+ showReset && /* @__PURE__ */ jsx3(
156
+ "button",
157
+ {
158
+ type: "button",
159
+ onClick: () => actualForm.resetField(name),
160
+ className: "text-xs text-muted-foreground hover:text-foreground",
161
+ children: "Reset"
162
+ }
163
+ )
164
+ ] }),
165
+ /* @__PURE__ */ jsx3(
166
+ "textarea",
167
+ {
168
+ ...field,
169
+ id: name,
170
+ value: field.value ?? "",
171
+ placeholder,
172
+ disabled,
173
+ className: "flex min-h-[75px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
174
+ }
175
+ ),
176
+ description && /* @__PURE__ */ jsx3("p", { className: "text-sm text-muted-foreground", children: description }),
177
+ fieldState.error && /* @__PURE__ */ jsx3("p", { className: "text-sm font-medium text-destructive", children: fieldState.error.message })
178
+ ] })
179
+ }
180
+ );
181
+ }
182
+
183
+ // src/fields/NumberField.tsx
184
+ import "react";
185
+ import { Controller as Controller3, useFormContext as useFormContext3 } from "react-hook-form";
186
+ import "zod";
187
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
188
+ function NumberField({
189
+ name,
190
+ label,
191
+ placeholder,
192
+ disabled,
193
+ description,
194
+ className,
195
+ form,
196
+ showReset
197
+ }) {
198
+ const contextForm = useFormContext3();
199
+ const actualForm = form || contextForm;
200
+ return /* @__PURE__ */ jsx4(
201
+ Controller3,
202
+ {
203
+ control: actualForm.control,
204
+ name,
205
+ render: ({ field, fieldState }) => /* @__PURE__ */ jsxs4("div", { className: cn("space-y-2", className), children: [
206
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between", children: [
207
+ /* @__PURE__ */ jsx4("label", { htmlFor: name, className: "text-sm font-medium leading-none", children: label }),
208
+ showReset && /* @__PURE__ */ jsx4(
209
+ "button",
210
+ {
211
+ type: "button",
212
+ onClick: () => actualForm.resetField(name),
213
+ className: "text-xs text-muted-foreground hover:text-foreground",
214
+ children: "Reset"
215
+ }
216
+ )
217
+ ] }),
218
+ /* @__PURE__ */ jsx4(
219
+ "input",
220
+ {
221
+ ...field,
222
+ id: name,
223
+ value: field.value ?? "",
224
+ placeholder,
225
+ disabled,
226
+ type: "number",
227
+ onChange: (e) => {
228
+ const value = e.target.value;
229
+ field.onChange(value === "" ? void 0 : Number(value));
230
+ },
231
+ className: "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
232
+ }
233
+ ),
234
+ description && /* @__PURE__ */ jsx4("p", { className: "text-sm text-muted-foreground", children: description }),
235
+ fieldState.error && /* @__PURE__ */ jsx4("p", { className: "text-sm font-medium text-destructive", children: fieldState.error.message })
236
+ ] })
237
+ }
238
+ );
239
+ }
240
+
241
+ // src/fields/SelectField.tsx
242
+ import "react";
243
+ import { Controller as Controller4, useFormContext as useFormContext4 } from "react-hook-form";
244
+ import "zod";
245
+ import * as SelectPrimitive from "@radix-ui/react-select";
246
+ import { Check, ChevronDown } from "lucide-react";
247
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
248
+ function SelectField({
249
+ name,
250
+ label,
251
+ placeholder,
252
+ disabled,
253
+ description,
254
+ className,
255
+ form,
256
+ options,
257
+ showReset
258
+ }) {
259
+ const contextForm = useFormContext4();
260
+ const actualForm = form || contextForm;
261
+ return /* @__PURE__ */ jsx5(
262
+ Controller4,
263
+ {
264
+ control: actualForm.control,
265
+ name,
266
+ render: ({ field, fieldState }) => /* @__PURE__ */ jsxs5("div", { className: cn("space-y-2", className), children: [
267
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between", children: [
268
+ /* @__PURE__ */ jsx5("label", { htmlFor: name, className: "text-sm font-medium leading-none", children: label }),
269
+ showReset && /* @__PURE__ */ jsx5(
270
+ "button",
271
+ {
272
+ type: "button",
273
+ onClick: () => actualForm.resetField(name),
274
+ className: "text-xs text-muted-foreground hover:text-foreground",
275
+ children: "Reset"
276
+ }
277
+ )
278
+ ] }),
279
+ /* @__PURE__ */ jsxs5(
280
+ SelectPrimitive.Root,
281
+ {
282
+ onValueChange: field.onChange,
283
+ value: String(field.value || ""),
284
+ disabled,
285
+ children: [
286
+ /* @__PURE__ */ jsxs5(SelectPrimitive.Trigger, { className: "flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50", children: [
287
+ /* @__PURE__ */ jsx5(
288
+ SelectPrimitive.Value,
289
+ {
290
+ placeholder: placeholder ?? "Select an option"
291
+ }
292
+ ),
293
+ /* @__PURE__ */ jsx5(SelectPrimitive.Icon, { children: /* @__PURE__ */ jsx5(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
294
+ ] }),
295
+ /* @__PURE__ */ jsx5(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx5(SelectPrimitive.Content, { className: "relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md", children: /* @__PURE__ */ jsx5(SelectPrimitive.Viewport, { className: "p-1", children: options.map((option) => /* @__PURE__ */ jsxs5(
296
+ SelectPrimitive.Item,
297
+ {
298
+ value: String(option.value),
299
+ className: "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
300
+ children: [
301
+ /* @__PURE__ */ jsx5("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx5(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx5(Check, { className: "h-4 w-4" }) }) }),
302
+ /* @__PURE__ */ jsx5(SelectPrimitive.ItemText, { children: option.label })
303
+ ]
304
+ },
305
+ String(option.value)
306
+ )) }) }) })
307
+ ]
308
+ }
309
+ ),
310
+ description && /* @__PURE__ */ jsx5("p", { className: "text-sm text-muted-foreground", children: description }),
311
+ fieldState.error && /* @__PURE__ */ jsx5("p", { className: "text-sm font-medium text-destructive", children: fieldState.error.message })
312
+ ] })
313
+ }
314
+ );
315
+ }
316
+
317
+ // src/fields/CheckboxField.tsx
318
+ import "react";
319
+ import { Controller as Controller5, useFormContext as useFormContext5 } from "react-hook-form";
320
+ import "zod";
321
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
322
+ import { Check as Check2 } from "lucide-react";
323
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
324
+ function CheckboxField({
325
+ name,
326
+ label,
327
+ disabled,
328
+ description,
329
+ className,
330
+ form
331
+ }) {
332
+ const contextForm = useFormContext5();
333
+ const actualForm = form || contextForm;
334
+ return /* @__PURE__ */ jsx6(
335
+ Controller5,
336
+ {
337
+ control: actualForm.control,
338
+ name,
339
+ render: ({ field, fieldState }) => /* @__PURE__ */ jsxs6("div", { className: cn("space-y-2", className), children: [
340
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3", children: [
341
+ /* @__PURE__ */ jsx6(
342
+ CheckboxPrimitive.Root,
343
+ {
344
+ id: name,
345
+ checked: !!field.value,
346
+ onCheckedChange: (checked) => field.onChange(checked),
347
+ disabled,
348
+ className: "h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
349
+ children: /* @__PURE__ */ jsx6(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: /* @__PURE__ */ jsx6(Check2, { className: "h-3 w-3" }) })
350
+ }
351
+ ),
352
+ /* @__PURE__ */ jsx6("label", { htmlFor: name, className: "text-sm font-medium leading-none", children: label })
353
+ ] }),
354
+ description && /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground", children: description }),
355
+ fieldState.error && /* @__PURE__ */ jsx6("p", { className: "text-sm font-medium text-destructive", children: fieldState.error.message })
356
+ ] })
357
+ }
358
+ );
359
+ }
360
+
361
+ // src/fields/DateField.tsx
362
+ import "react";
363
+ import { Controller as Controller6, useFormContext as useFormContext6 } from "react-hook-form";
364
+ import "zod";
365
+ import { DayPicker } from "react-day-picker";
366
+ import * as PopoverPrimitive from "@radix-ui/react-popover";
367
+ import { format } from "date-fns";
368
+ import { CalendarIcon } from "lucide-react";
369
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
370
+ function DateField({
371
+ name,
372
+ label,
373
+ description,
374
+ className,
375
+ form,
376
+ showReset
377
+ }) {
378
+ const contextForm = useFormContext6();
379
+ const actualForm = form || contextForm;
380
+ return /* @__PURE__ */ jsx7(
381
+ Controller6,
382
+ {
383
+ control: actualForm.control,
384
+ name,
385
+ render: ({ field, fieldState }) => {
386
+ const date = field.value ? new Date(field.value) : void 0;
387
+ return /* @__PURE__ */ jsxs7("div", { className: cn("space-y-2", className), children: [
388
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between", children: [
389
+ /* @__PURE__ */ jsx7("label", { htmlFor: name, className: "text-sm font-medium leading-none", children: label }),
390
+ showReset && /* @__PURE__ */ jsx7(
391
+ "button",
392
+ {
393
+ type: "button",
394
+ onClick: () => actualForm.resetField(name),
395
+ className: "text-xs text-muted-foreground hover:text-foreground",
396
+ children: "Reset"
397
+ }
398
+ )
399
+ ] }),
400
+ /* @__PURE__ */ jsxs7(PopoverPrimitive.Root, { children: [
401
+ /* @__PURE__ */ jsx7(PopoverPrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs7(
402
+ "button",
403
+ {
404
+ type: "button",
405
+ className: cn(
406
+ "flex h-9 w-full items-center justify-start gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
407
+ !date && "text-muted-foreground"
408
+ ),
409
+ children: [
410
+ /* @__PURE__ */ jsx7(CalendarIcon, { className: "h-4 w-4" }),
411
+ date ? format(date, "PPP") : "Pick a date"
412
+ ]
413
+ }
414
+ ) }),
415
+ /* @__PURE__ */ jsx7(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx7(
416
+ PopoverPrimitive.Content,
417
+ {
418
+ align: "start",
419
+ className: "z-50 rounded-md border bg-popover p-0 text-popover-foreground shadow-md outline-none",
420
+ children: /* @__PURE__ */ jsx7(
421
+ DayPicker,
422
+ {
423
+ mode: "single",
424
+ selected: date,
425
+ onSelect: (d) => field.onChange(d),
426
+ className: "p-3"
427
+ }
428
+ )
429
+ }
430
+ ) })
431
+ ] }),
432
+ description && /* @__PURE__ */ jsx7("p", { className: "text-sm text-muted-foreground", children: description }),
433
+ fieldState.error && /* @__PURE__ */ jsx7("p", { className: "text-sm font-medium text-destructive", children: fieldState.error.message })
434
+ ] });
435
+ }
436
+ }
437
+ );
438
+ }
439
+
440
+ // src/fields/SliderField.tsx
441
+ import "react";
442
+ import { Controller as Controller7, useFormContext as useFormContext7 } from "react-hook-form";
443
+ import "zod";
444
+ import * as SliderPrimitive from "@radix-ui/react-slider";
445
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
446
+ function SliderField({
447
+ name,
448
+ label,
449
+ description,
450
+ disabled,
451
+ className,
452
+ form,
453
+ min = 0,
454
+ max = 100,
455
+ step = 1,
456
+ showReset
457
+ }) {
458
+ const contextForm = useFormContext7();
459
+ const actualForm = form || contextForm;
460
+ return /* @__PURE__ */ jsx8(
461
+ Controller7,
462
+ {
463
+ control: actualForm.control,
464
+ name,
465
+ render: ({ field, fieldState }) => {
466
+ const value = field.value !== void 0 ? field.value : min;
467
+ return /* @__PURE__ */ jsxs8("div", { className: cn("space-y-2", className), children: [
468
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between", children: [
469
+ /* @__PURE__ */ jsx8("label", { htmlFor: name, className: "text-sm font-medium leading-none", children: label }),
470
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
471
+ /* @__PURE__ */ jsx8("span", { className: "text-sm text-muted-foreground", children: value }),
472
+ showReset && /* @__PURE__ */ jsx8(
473
+ "button",
474
+ {
475
+ type: "button",
476
+ onClick: () => actualForm.resetField(name),
477
+ className: "text-xs text-muted-foreground hover:text-foreground",
478
+ children: "Reset"
479
+ }
480
+ )
481
+ ] })
482
+ ] }),
483
+ /* @__PURE__ */ jsxs8(
484
+ SliderPrimitive.Root,
485
+ {
486
+ value: [value],
487
+ onValueChange: ([val]) => field.onChange(val),
488
+ min,
489
+ max,
490
+ step,
491
+ disabled,
492
+ className: "relative flex w-full touch-none select-none items-center",
493
+ children: [
494
+ /* @__PURE__ */ jsx8(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20", children: /* @__PURE__ */ jsx8(SliderPrimitive.Range, { className: "absolute h-full bg-primary" }) }),
495
+ /* @__PURE__ */ jsx8(SliderPrimitive.Thumb, { className: "block h-4 w-4 rounded-full border border-primary/50 bg-background shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50" })
496
+ ]
497
+ }
498
+ ),
499
+ description && /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: description }),
500
+ fieldState.error && /* @__PURE__ */ jsx8("p", { className: "text-sm font-medium text-destructive", children: fieldState.error.message })
501
+ ] });
502
+ }
503
+ }
504
+ );
505
+ }
506
+
507
+ // src/fields/MultiSelectField.tsx
508
+ import "react";
509
+ import { Controller as Controller8, useFormContext as useFormContext8 } from "react-hook-form";
510
+ import "zod";
511
+ import * as PopoverPrimitive2 from "@radix-ui/react-popover";
512
+ import { Command } from "cmdk";
513
+ import { Check as Check3, ChevronsUpDown, X } from "lucide-react";
514
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
515
+ function MultiSelectField({
516
+ name,
517
+ label,
518
+ description,
519
+ disabled,
520
+ form,
521
+ className,
522
+ options,
523
+ placeholder = "Select options...",
524
+ showReset
525
+ }) {
526
+ const contextForm = useFormContext8();
527
+ const actualForm = form || contextForm;
528
+ return /* @__PURE__ */ jsx9(
529
+ Controller8,
530
+ {
531
+ control: actualForm.control,
532
+ name,
533
+ render: ({ field, fieldState }) => {
534
+ const selected = Array.isArray(field.value) ? field.value : [];
535
+ const toggle = (val) => {
536
+ const next = selected.includes(val) ? selected.filter((v) => v !== val) : [...selected, val];
537
+ field.onChange(next);
538
+ };
539
+ return /* @__PURE__ */ jsxs9("div", { className: cn("space-y-2", className), children: [
540
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between", children: [
541
+ /* @__PURE__ */ jsx9("label", { className: "text-sm font-medium leading-none", children: label }),
542
+ showReset && /* @__PURE__ */ jsx9(
543
+ "button",
544
+ {
545
+ type: "button",
546
+ onClick: () => actualForm.resetField(name),
547
+ className: "text-xs text-muted-foreground hover:text-foreground",
548
+ children: "Reset"
549
+ }
550
+ )
551
+ ] }),
552
+ /* @__PURE__ */ jsxs9(PopoverPrimitive2.Root, { children: [
553
+ /* @__PURE__ */ jsx9(PopoverPrimitive2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs9(
554
+ "button",
555
+ {
556
+ type: "button",
557
+ role: "combobox",
558
+ disabled,
559
+ className: cn(
560
+ "flex min-h-9 w-full flex-wrap items-center justify-between gap-1 rounded-md border border-input bg-transparent px-3 py-1.5 text-sm shadow-sm focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
561
+ !selected.length && "text-muted-foreground"
562
+ ),
563
+ children: [
564
+ /* @__PURE__ */ jsx9("div", { className: "flex flex-wrap gap-1", children: selected.length ? selected.map((val) => /* @__PURE__ */ jsxs9(
565
+ "span",
566
+ {
567
+ className: "inline-flex items-center gap-1 rounded-md border bg-secondary px-1.5 py-0.5 text-xs text-secondary-foreground",
568
+ children: [
569
+ options.find((o) => o.value === val)?.label ?? val,
570
+ /* @__PURE__ */ jsx9(
571
+ "span",
572
+ {
573
+ onClick: (e) => {
574
+ e.stopPropagation();
575
+ toggle(val);
576
+ },
577
+ className: "cursor-pointer",
578
+ children: /* @__PURE__ */ jsx9(X, { className: "h-3 w-3" })
579
+ }
580
+ )
581
+ ]
582
+ },
583
+ val
584
+ )) : placeholder }),
585
+ /* @__PURE__ */ jsx9(ChevronsUpDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
586
+ ]
587
+ }
588
+ ) }),
589
+ /* @__PURE__ */ jsx9(PopoverPrimitive2.Portal, { children: /* @__PURE__ */ jsx9(
590
+ PopoverPrimitive2.Content,
591
+ {
592
+ align: "start",
593
+ className: "z-50 min-w-[200px] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md outline-none",
594
+ children: /* @__PURE__ */ jsxs9(Command, { children: [
595
+ /* @__PURE__ */ jsx9("div", { className: "flex items-center border-b px-3", children: /* @__PURE__ */ jsx9(
596
+ Command.Input,
597
+ {
598
+ placeholder: "Search...",
599
+ className: "flex h-9 w-full bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground"
600
+ }
601
+ ) }),
602
+ /* @__PURE__ */ jsxs9(Command.List, { className: "max-h-[200px] overflow-y-auto p-1", children: [
603
+ /* @__PURE__ */ jsx9(Command.Empty, { className: "py-6 text-center text-sm", children: "No options found." }),
604
+ /* @__PURE__ */ jsx9(Command.Group, { children: options.map((option) => /* @__PURE__ */ jsxs9(
605
+ Command.Item,
606
+ {
607
+ value: option.value,
608
+ onSelect: () => toggle(option.value),
609
+ className: "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:text-accent-foreground",
610
+ children: [
611
+ /* @__PURE__ */ jsx9(
612
+ Check3,
613
+ {
614
+ className: cn(
615
+ "mr-2 h-4 w-4",
616
+ selected.includes(option.value) ? "opacity-100" : "opacity-0"
617
+ )
618
+ }
619
+ ),
620
+ option.label
621
+ ]
622
+ },
623
+ option.value
624
+ )) })
625
+ ] })
626
+ ] })
627
+ }
628
+ ) })
629
+ ] }),
630
+ description && /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground", children: description }),
631
+ fieldState.error && /* @__PURE__ */ jsx9("p", { className: "text-sm font-medium text-destructive", children: fieldState.error.message })
632
+ ] });
633
+ }
634
+ }
635
+ );
636
+ }
637
+
638
+ // src/createForm.tsx
639
+ import { jsx as jsx10 } from "react/jsx-runtime";
640
+ function createForm(schema) {
641
+ const Form = ({
642
+ children,
643
+ onSubmit,
644
+ defaultValues,
645
+ components
646
+ }) => /* @__PURE__ */ jsx10(
647
+ SimpleForm,
648
+ {
649
+ schema,
650
+ onSubmit,
651
+ defaultValues,
652
+ components,
653
+ children
654
+ }
655
+ );
656
+ Form.displayName = "Form";
657
+ const SchemaTextField = (props) => /* @__PURE__ */ jsx10(TextField, { ...props });
658
+ SchemaTextField.displayName = "TextField";
659
+ const SchemaPasswordField = (props) => /* @__PURE__ */ jsx10(TextField, { ...props });
660
+ SchemaPasswordField.displayName = "PasswordField";
661
+ const SchemaTextAreaField = (props) => /* @__PURE__ */ jsx10(TextAreaField, { ...props });
662
+ SchemaTextAreaField.displayName = "TextAreaField";
663
+ const SchemaNumberField = (props) => /* @__PURE__ */ jsx10(NumberField, { ...props });
664
+ SchemaNumberField.displayName = "NumberField";
665
+ const SchemaSelectField = (props) => /* @__PURE__ */ jsx10(SelectField, { ...props });
666
+ SchemaSelectField.displayName = "SelectField";
667
+ const SchemaCheckboxField = (props) => /* @__PURE__ */ jsx10(CheckboxField, { ...props });
668
+ SchemaCheckboxField.displayName = "CheckboxField";
669
+ const SchemaDateField = (props) => /* @__PURE__ */ jsx10(DateField, { ...props });
670
+ SchemaDateField.displayName = "DateField";
671
+ const SchemaSliderField = (props) => /* @__PURE__ */ jsx10(SliderField, { ...props });
672
+ SchemaSliderField.displayName = "SliderField";
673
+ const SchemaMultiSelectField = (props) => /* @__PURE__ */ jsx10(MultiSelectField, { ...props });
674
+ SchemaMultiSelectField.displayName = "MultiSelectField";
675
+ return {
676
+ Form,
677
+ TextField: SchemaTextField,
678
+ PasswordField: SchemaPasswordField,
679
+ TextAreaField: SchemaTextAreaField,
680
+ NumberField: SchemaNumberField,
681
+ SelectField: SchemaSelectField,
682
+ CheckboxField: SchemaCheckboxField,
683
+ DateField: SchemaDateField,
684
+ SliderField: SchemaSliderField,
685
+ MultiSelectField: SchemaMultiSelectField
686
+ };
687
+ }
688
+
689
+ // src/hooks/useSimpleForm.ts
690
+ import { useForm as useForm2 } from "react-hook-form";
691
+ import { zodResolver as zodResolver2 } from "@hookform/resolvers/zod";
692
+ function useSimpleForm({
693
+ schema,
694
+ defaultValues
695
+ }) {
696
+ return useForm2({
697
+ resolver: zodResolver2(schema),
698
+ defaultValues
699
+ });
700
+ }
701
+ export {
702
+ CheckboxField,
703
+ DateField,
704
+ MultiSelectField,
705
+ NumberField,
706
+ SelectField,
707
+ SimpleForm,
708
+ SliderField,
709
+ TextAreaField,
710
+ TextField,
711
+ createForm,
712
+ useSimpleForm
713
+ };
714
+ //# sourceMappingURL=index.js.map