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