@rachelallyson/hero-hook-form 1.0.0 → 1.0.1

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,1297 +0,0 @@
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
- ConfigurableForm: () => ConfigurableForm,
35
- DateField: () => DateField,
36
- FileField: () => FileField,
37
- FormField: () => FormField,
38
- FormProvider: () => FormProvider,
39
- HeroHookFormProvider: () => HeroHookFormProvider,
40
- InputField: () => InputField,
41
- RadioGroupField: () => RadioGroupField,
42
- SelectField: () => SelectField,
43
- SliderField: () => SliderField,
44
- SubmitButton: () => SubmitButton,
45
- SwitchField: () => SwitchField,
46
- TextareaField: () => TextareaField,
47
- ZodForm: () => ZodForm,
48
- applyServerErrors: () => applyServerErrors,
49
- useFormHelper: () => useFormHelper,
50
- useHeroHookFormDefaults: () => useHeroHookFormDefaults,
51
- useZodForm: () => useZodForm
52
- });
53
- module.exports = __toCommonJS(index_exports);
54
-
55
- // src/components/Form.tsx
56
- var import_react14 = __toESM(require("react"), 1);
57
- var import_react15 = require("@heroui/react");
58
-
59
- // src/hooks/useFormHelper.ts
60
- var import_react = require("react");
61
- var import_react_hook_form = require("react-hook-form");
62
- function useFormHelper({
63
- defaultValues,
64
- methods,
65
- onError,
66
- onSubmit,
67
- onSuccess
68
- }) {
69
- const [submissionState, setSubmissionState] = (0, import_react.useState)({
70
- isSubmitted: false,
71
- isSubmitting: false,
72
- isSuccess: false
73
- });
74
- const form = methods ?? (0, import_react_hook_form.useForm)({ defaultValues });
75
- const handleSubmit = async () => {
76
- setSubmissionState((prev) => ({
77
- ...prev,
78
- error: void 0,
79
- isSubmitting: true
80
- }));
81
- try {
82
- await form.handleSubmit(async (formData) => {
83
- await onSubmit(formData);
84
- })();
85
- setSubmissionState({
86
- isSubmitted: true,
87
- isSubmitting: false,
88
- isSuccess: true
89
- });
90
- onSuccess?.(form.getValues());
91
- } catch (error) {
92
- const errorMessage = error instanceof Error ? error.message : "An error occurred";
93
- setSubmissionState({
94
- error: errorMessage,
95
- isSubmitted: true,
96
- isSubmitting: false,
97
- isSuccess: false
98
- });
99
- onError?.({
100
- message: errorMessage
101
- });
102
- }
103
- };
104
- const resetForm = () => {
105
- form.reset();
106
- setSubmissionState({
107
- isSubmitted: false,
108
- isSubmitting: false,
109
- isSuccess: false
110
- });
111
- };
112
- return {
113
- error: submissionState.error,
114
- form,
115
- handleSubmit,
116
- isSubmitted: submissionState.isSubmitted,
117
- isSubmitting: submissionState.isSubmitting,
118
- isSuccess: submissionState.isSuccess,
119
- resetForm,
120
- submissionState
121
- };
122
- }
123
-
124
- // src/components/FormField.tsx
125
- var import_react13 = __toESM(require("react"), 1);
126
-
127
- // src/fields/CheckboxField.tsx
128
- var import_react4 = __toESM(require("react"), 1);
129
- var import_react_hook_form2 = require("react-hook-form");
130
-
131
- // src/providers/ConfigProvider.tsx
132
- var import_react2 = __toESM(require("react"), 1);
133
- var DefaultsContext = (0, import_react2.createContext)(null);
134
- function HeroHookFormProvider(props) {
135
- const value = (0, import_react2.useMemo)(() => props.defaults ?? {}, [props.defaults]);
136
- return /* @__PURE__ */ import_react2.default.createElement(DefaultsContext.Provider, { value }, props.children);
137
- }
138
- function useHeroHookFormDefaults() {
139
- const cfg = (0, import_react2.useContext)(DefaultsContext) ?? {};
140
- const common = cfg.common ?? {};
141
- const commonInput = {
142
- ...common.color !== void 0 ? { color: common.color } : {},
143
- ...common.size !== void 0 ? { size: common.size } : {},
144
- ...common.variant !== void 0 ? { variant: common.variant } : {},
145
- ...common.radius !== void 0 ? { radius: common.radius } : {},
146
- ...common.labelPlacement !== void 0 ? {
147
- labelPlacement: common.labelPlacement
148
- } : {}
149
- };
150
- const commonTextarea = {
151
- ...common.color !== void 0 ? { color: common.color } : {},
152
- ...common.size !== void 0 ? { size: common.size } : {},
153
- ...common.variant !== void 0 ? { variant: common.variant } : {},
154
- ...common.radius !== void 0 ? { radius: common.radius } : {},
155
- ...common.labelPlacement !== void 0 ? {
156
- labelPlacement: common.labelPlacement
157
- } : {}
158
- };
159
- const commonSelect = {
160
- ...common.color !== void 0 ? { color: common.color } : {},
161
- ...common.size !== void 0 ? { size: common.size } : {},
162
- ...common.variant !== void 0 ? { variant: common.variant } : {},
163
- ...common.radius !== void 0 ? { radius: common.radius } : {},
164
- ...common.labelPlacement !== void 0 ? {
165
- labelPlacement: common.labelPlacement
166
- } : {}
167
- };
168
- const commonCheckbox = {
169
- ...common.color !== void 0 ? {
170
- color: common.color
171
- } : {},
172
- ...common.size !== void 0 ? { size: common.size } : {}
173
- };
174
- const commonRadioGroup = {
175
- ...common.color !== void 0 ? {
176
- color: common.color
177
- } : {},
178
- ...common.size !== void 0 ? { size: common.size } : {}
179
- };
180
- const commonDateInput = {
181
- ...common.color !== void 0 ? {
182
- color: common.color
183
- } : {},
184
- ...common.size !== void 0 ? { size: common.size } : {},
185
- ...common.variant !== void 0 ? {
186
- variant: common.variant
187
- } : {},
188
- ...common.radius !== void 0 ? {
189
- radius: common.radius
190
- } : {}
191
- };
192
- const commonSlider = {
193
- ...common.color !== void 0 ? { color: common.color } : {},
194
- ...common.size !== void 0 ? { size: common.size } : {}
195
- };
196
- const commonSwitch = {
197
- ...common.color !== void 0 ? { color: common.color } : {},
198
- ...common.size !== void 0 ? { size: common.size } : {}
199
- };
200
- const commonButton = {
201
- ...common.color !== void 0 ? { color: common.color } : {},
202
- ...common.size !== void 0 ? { size: common.size } : {}
203
- };
204
- return {
205
- checkbox: { ...commonCheckbox, ...cfg.checkbox ?? {} },
206
- dateInput: { ...commonDateInput, ...cfg.dateInput ?? {} },
207
- input: { ...commonInput, ...cfg.input ?? {} },
208
- radioGroup: { ...commonRadioGroup, ...cfg.radioGroup ?? {} },
209
- select: { ...commonSelect, ...cfg.select ?? {} },
210
- slider: { ...commonSlider, ...cfg.slider ?? {} },
211
- submitButton: { ...commonButton, ...cfg.submitButton ?? {} },
212
- switch: { ...commonSwitch, ...cfg.switch ?? {} },
213
- textarea: { ...commonTextarea, ...cfg.textarea ?? {} }
214
- };
215
- }
216
-
217
- // src/ui/react.ts
218
- var import_react3 = require("@heroui/react");
219
-
220
- // src/fields/CheckboxField.tsx
221
- function CheckboxField(props) {
222
- const {
223
- checkboxProps,
224
- className,
225
- control,
226
- description,
227
- isDisabled,
228
- label,
229
- name,
230
- rules
231
- } = props;
232
- const defaults = useHeroHookFormDefaults();
233
- return /* @__PURE__ */ import_react4.default.createElement(
234
- import_react_hook_form2.Controller,
235
- {
236
- control,
237
- name,
238
- render: ({ field, fieldState }) => /* @__PURE__ */ import_react4.default.createElement("div", { className }, /* @__PURE__ */ import_react4.default.createElement(
239
- import_react3.Checkbox,
240
- {
241
- ...defaults.checkbox,
242
- ...checkboxProps,
243
- isDisabled,
244
- isInvalid: Boolean(fieldState.error),
245
- isSelected: Boolean(field.value),
246
- onBlur: field.onBlur,
247
- onValueChange: (val) => field.onChange(val)
248
- },
249
- label
250
- ), description ? /* @__PURE__ */ import_react4.default.createElement("p", { className: "text-small text-default-400" }, description) : null, fieldState.error?.message ? /* @__PURE__ */ import_react4.default.createElement("p", { className: "text-tiny text-danger mt-1" }, fieldState.error.message) : null),
251
- rules
252
- }
253
- );
254
- }
255
-
256
- // src/fields/DateField.tsx
257
- var import_react5 = __toESM(require("react"), 1);
258
- var import_react_hook_form3 = require("react-hook-form");
259
- function CoercedDateInput(props) {
260
- const { dateProps, description, disabled, errorMessage, field, label } = props;
261
- const defaults = useHeroHookFormDefaults();
262
- return /* @__PURE__ */ import_react5.default.createElement(
263
- import_react3.DateInput,
264
- {
265
- ...defaults.dateInput,
266
- ...dateProps,
267
- description,
268
- errorMessage,
269
- isDisabled: disabled,
270
- isInvalid: Boolean(errorMessage),
271
- label,
272
- value: field.value ?? null,
273
- onBlur: field.onBlur,
274
- onChange: field.onChange
275
- }
276
- );
277
- }
278
- function DateField(props) {
279
- const {
280
- className,
281
- control,
282
- dateProps,
283
- description,
284
- isDisabled,
285
- label,
286
- name,
287
- rules,
288
- transform
289
- } = props;
290
- return /* @__PURE__ */ import_react5.default.createElement(
291
- import_react_hook_form3.Controller,
292
- {
293
- control,
294
- name,
295
- render: ({ field, fieldState }) => /* @__PURE__ */ import_react5.default.createElement("div", { className }, /* @__PURE__ */ import_react5.default.createElement(
296
- CoercedDateInput,
297
- {
298
- dateProps,
299
- description,
300
- disabled: isDisabled,
301
- errorMessage: fieldState.error?.message,
302
- field: {
303
- ...field,
304
- onChange: (value) => field.onChange(transform ? transform(value) : value)
305
- },
306
- label
307
- }
308
- )),
309
- rules
310
- }
311
- );
312
- }
313
-
314
- // src/fields/FileField.tsx
315
- var import_react6 = __toESM(require("react"), 1);
316
- var import_react_hook_form4 = require("react-hook-form");
317
- function CoercedFileInput(props) {
318
- const {
319
- accept,
320
- description,
321
- disabled,
322
- errorMessage,
323
- field,
324
- fileProps,
325
- label,
326
- multiple
327
- } = props;
328
- const defaults = useHeroHookFormDefaults();
329
- return /* @__PURE__ */ import_react6.default.createElement(
330
- import_react3.Input,
331
- {
332
- ...defaults.input,
333
- ...fileProps,
334
- accept,
335
- description,
336
- errorMessage,
337
- isDisabled: disabled,
338
- isInvalid: Boolean(errorMessage),
339
- label,
340
- multiple,
341
- type: "file",
342
- value: field.value ? "" : "",
343
- onBlur: field.onBlur,
344
- onChange: (e2) => {
345
- const target = e2.target;
346
- field.onChange(target.files);
347
- }
348
- }
349
- );
350
- }
351
- function FileField(props) {
352
- const {
353
- accept,
354
- className,
355
- control,
356
- description,
357
- fileProps,
358
- isDisabled,
359
- label,
360
- multiple = false,
361
- name,
362
- rules,
363
- transform
364
- } = props;
365
- return /* @__PURE__ */ import_react6.default.createElement(
366
- import_react_hook_form4.Controller,
367
- {
368
- control,
369
- name,
370
- render: ({ field, fieldState }) => /* @__PURE__ */ import_react6.default.createElement("div", { className }, /* @__PURE__ */ import_react6.default.createElement(
371
- CoercedFileInput,
372
- {
373
- accept,
374
- description,
375
- disabled: isDisabled,
376
- errorMessage: fieldState.error?.message,
377
- field: {
378
- ...field,
379
- onChange: (value) => field.onChange(transform ? transform(value) : value)
380
- },
381
- fileProps,
382
- label,
383
- multiple
384
- }
385
- )),
386
- rules
387
- }
388
- );
389
- }
390
-
391
- // src/fields/InputField.tsx
392
- var import_react7 = __toESM(require("react"), 1);
393
- var import_react_hook_form5 = require("react-hook-form");
394
- function CoercedInput(props) {
395
- const { description, disabled, errorMessage, field, inputProps, label } = props;
396
- const defaults = useHeroHookFormDefaults();
397
- return /* @__PURE__ */ import_react7.default.createElement(
398
- import_react3.Input,
399
- {
400
- ...defaults.input,
401
- ...inputProps,
402
- description,
403
- errorMessage,
404
- isDisabled: disabled,
405
- isInvalid: Boolean(errorMessage),
406
- label,
407
- value: field.value ?? "",
408
- onBlur: field.onBlur,
409
- onValueChange: field.onChange
410
- }
411
- );
412
- }
413
- function InputField(props) {
414
- const {
415
- className,
416
- control,
417
- description,
418
- inputProps,
419
- isDisabled,
420
- label,
421
- name,
422
- rules,
423
- transform
424
- } = props;
425
- return /* @__PURE__ */ import_react7.default.createElement(
426
- import_react_hook_form5.Controller,
427
- {
428
- control,
429
- name,
430
- render: ({ field, fieldState }) => /* @__PURE__ */ import_react7.default.createElement("div", { className }, /* @__PURE__ */ import_react7.default.createElement(
431
- CoercedInput,
432
- {
433
- description,
434
- disabled: isDisabled,
435
- errorMessage: fieldState.error?.message,
436
- field: {
437
- ...field,
438
- onChange: (value) => {
439
- if (inputProps?.type === "number") {
440
- const numValue = value === "" ? void 0 : Number(value);
441
- field.onChange(
442
- transform ? transform(String(numValue)) : numValue
443
- );
444
- } else {
445
- field.onChange(transform ? transform(value) : value);
446
- }
447
- }
448
- },
449
- inputProps,
450
- label
451
- }
452
- )),
453
- rules
454
- }
455
- );
456
- }
457
-
458
- // src/fields/RadioGroupField.tsx
459
- var import_react8 = __toESM(require("react"), 1);
460
- var import_react_hook_form6 = require("react-hook-form");
461
- function RadioGroupField(props) {
462
- const {
463
- className,
464
- control,
465
- description,
466
- isDisabled,
467
- label,
468
- name,
469
- options,
470
- radioGroupProps,
471
- rules
472
- } = props;
473
- const defaults = useHeroHookFormDefaults();
474
- return /* @__PURE__ */ import_react8.default.createElement(
475
- import_react_hook_form6.Controller,
476
- {
477
- control,
478
- name,
479
- render: ({ field, fieldState }) => /* @__PURE__ */ import_react8.default.createElement("div", { className }, /* @__PURE__ */ import_react8.default.createElement(
480
- import_react3.RadioGroup,
481
- {
482
- ...defaults.radioGroup,
483
- ...radioGroupProps,
484
- description,
485
- isDisabled,
486
- isInvalid: Boolean(fieldState.error),
487
- label,
488
- value: String(field.value ?? ""),
489
- onBlur: field.onBlur,
490
- onValueChange: (val) => field.onChange(val)
491
- },
492
- options.map((opt) => /* @__PURE__ */ import_react8.default.createElement(
493
- import_react3.Radio,
494
- {
495
- key: String(opt.value),
496
- isDisabled: opt.disabled,
497
- value: String(opt.value)
498
- },
499
- opt.label
500
- ))
501
- ), fieldState.error?.message ? /* @__PURE__ */ import_react8.default.createElement("p", { className: "text-tiny text-danger mt-1" }, fieldState.error.message) : null),
502
- rules
503
- }
504
- );
505
- }
506
-
507
- // src/fields/SelectField.tsx
508
- var import_react9 = __toESM(require("react"), 1);
509
- var import_react_hook_form7 = require("react-hook-form");
510
- function SelectField(props) {
511
- const {
512
- className,
513
- control,
514
- description,
515
- isDisabled,
516
- label,
517
- name,
518
- options,
519
- placeholder,
520
- rules,
521
- selectProps
522
- } = props;
523
- const defaults = useHeroHookFormDefaults();
524
- return /* @__PURE__ */ import_react9.default.createElement(
525
- import_react_hook_form7.Controller,
526
- {
527
- control,
528
- name,
529
- render: ({ field, fieldState }) => {
530
- const selectedKey = field.value;
531
- return /* @__PURE__ */ import_react9.default.createElement("div", { className }, /* @__PURE__ */ import_react9.default.createElement(
532
- import_react3.Select,
533
- {
534
- ...defaults.select,
535
- ...selectProps,
536
- description,
537
- errorMessage: fieldState.error?.message,
538
- isDisabled,
539
- isInvalid: Boolean(fieldState.error),
540
- label,
541
- placeholder,
542
- selectedKeys: selectedKey != null ? /* @__PURE__ */ new Set([String(selectedKey)]) : /* @__PURE__ */ new Set(),
543
- onSelectionChange: (keys) => {
544
- const keyArray = Array.from(keys);
545
- const next = keyArray[0] ?? "";
546
- field.onChange(next);
547
- }
548
- },
549
- options.map((opt) => /* @__PURE__ */ import_react9.default.createElement(
550
- import_react3.SelectItem,
551
- {
552
- key: String(opt.value),
553
- isDisabled: opt.disabled,
554
- textValue: String(opt.value)
555
- },
556
- opt.label
557
- ))
558
- ));
559
- },
560
- rules
561
- }
562
- );
563
- }
564
-
565
- // src/fields/SliderField.tsx
566
- var import_react10 = __toESM(require("react"), 1);
567
- var import_react_hook_form8 = require("react-hook-form");
568
- function CoercedSlider(props) {
569
- const { description, disabled, errorMessage, field, label, sliderProps } = props;
570
- const defaults = useHeroHookFormDefaults();
571
- return /* @__PURE__ */ import_react10.default.createElement(
572
- import_react3.Slider,
573
- {
574
- ...defaults.slider,
575
- ...sliderProps,
576
- description,
577
- errorMessage,
578
- isDisabled: disabled,
579
- isInvalid: Boolean(errorMessage),
580
- label,
581
- value: field.value ?? 0,
582
- onBlur: field.onBlur,
583
- onValueChange: field.onChange
584
- }
585
- );
586
- }
587
- function SliderField(props) {
588
- const {
589
- className,
590
- control,
591
- description,
592
- isDisabled,
593
- label,
594
- name,
595
- rules,
596
- sliderProps,
597
- transform
598
- } = props;
599
- return /* @__PURE__ */ import_react10.default.createElement(
600
- import_react_hook_form8.Controller,
601
- {
602
- control,
603
- name,
604
- render: ({ field, fieldState }) => /* @__PURE__ */ import_react10.default.createElement("div", { className }, /* @__PURE__ */ import_react10.default.createElement(
605
- CoercedSlider,
606
- {
607
- description,
608
- disabled: isDisabled,
609
- errorMessage: fieldState.error?.message,
610
- field: {
611
- ...field,
612
- onChange: (value) => field.onChange(transform ? transform(value) : value)
613
- },
614
- label,
615
- sliderProps
616
- }
617
- )),
618
- rules
619
- }
620
- );
621
- }
622
-
623
- // src/fields/SwitchField.tsx
624
- var import_react11 = __toESM(require("react"), 1);
625
- var import_react_hook_form9 = require("react-hook-form");
626
- function SwitchField(props) {
627
- const {
628
- className,
629
- control,
630
- description,
631
- isDisabled,
632
- label,
633
- name,
634
- rules,
635
- switchProps
636
- } = props;
637
- const defaults = useHeroHookFormDefaults();
638
- return /* @__PURE__ */ import_react11.default.createElement(
639
- import_react_hook_form9.Controller,
640
- {
641
- control,
642
- name,
643
- render: ({ field, fieldState }) => /* @__PURE__ */ import_react11.default.createElement("div", { className }, /* @__PURE__ */ import_react11.default.createElement(
644
- import_react3.Switch,
645
- {
646
- ...defaults.switch,
647
- ...switchProps,
648
- isDisabled,
649
- isSelected: Boolean(field.value),
650
- onBlur: field.onBlur,
651
- onValueChange: (val) => field.onChange(val)
652
- },
653
- label
654
- ), description ? /* @__PURE__ */ import_react11.default.createElement("p", { className: "text-small text-default-400" }, description) : null, fieldState.error?.message ? /* @__PURE__ */ import_react11.default.createElement("p", { className: "text-tiny text-danger mt-1" }, fieldState.error.message) : null),
655
- rules
656
- }
657
- );
658
- }
659
-
660
- // src/fields/TextareaField.tsx
661
- var import_react12 = __toESM(require("react"), 1);
662
- var import_react_hook_form10 = require("react-hook-form");
663
- function TextareaField(props) {
664
- const {
665
- className,
666
- control,
667
- description,
668
- isDisabled,
669
- label,
670
- name,
671
- rules,
672
- textareaProps
673
- } = props;
674
- const defaults = useHeroHookFormDefaults();
675
- return /* @__PURE__ */ import_react12.default.createElement(
676
- import_react_hook_form10.Controller,
677
- {
678
- control,
679
- name,
680
- render: ({ field, fieldState }) => /* @__PURE__ */ import_react12.default.createElement("div", { className }, /* @__PURE__ */ import_react12.default.createElement(
681
- import_react3.Textarea,
682
- {
683
- ...defaults.textarea,
684
- ...textareaProps,
685
- description,
686
- errorMessage: fieldState.error?.message,
687
- isDisabled,
688
- isInvalid: Boolean(fieldState.error),
689
- label,
690
- value: field.value ?? "",
691
- onBlur: field.onBlur,
692
- onValueChange: field.onChange
693
- }
694
- )),
695
- rules
696
- }
697
- );
698
- }
699
-
700
- // src/components/FormField.tsx
701
- function FormField({
702
- config,
703
- form,
704
- submissionState
705
- }) {
706
- const { control } = form;
707
- const baseProps = {
708
- className: config.className,
709
- description: config.description,
710
- isDisabled: config.isDisabled ?? submissionState.isSubmitting,
711
- label: config.label,
712
- name: config.name,
713
- rules: config.rules
714
- };
715
- switch (config.type) {
716
- case "input":
717
- return /* @__PURE__ */ import_react13.default.createElement(
718
- InputField,
719
- {
720
- ...baseProps,
721
- control,
722
- defaultValue: config.defaultValue,
723
- inputProps: config.inputProps
724
- }
725
- );
726
- case "textarea":
727
- return /* @__PURE__ */ import_react13.default.createElement(
728
- TextareaField,
729
- {
730
- ...baseProps,
731
- control,
732
- defaultValue: config.defaultValue,
733
- textareaProps: config.textareaProps
734
- }
735
- );
736
- case "select":
737
- return /* @__PURE__ */ import_react13.default.createElement(
738
- SelectField,
739
- {
740
- ...baseProps,
741
- control,
742
- defaultValue: config.defaultValue,
743
- options: (config.options ?? []).map((opt) => ({
744
- label: opt.label,
745
- value: String(opt.value)
746
- })),
747
- selectProps: config.selectProps
748
- }
749
- );
750
- case "checkbox":
751
- return /* @__PURE__ */ import_react13.default.createElement(
752
- CheckboxField,
753
- {
754
- ...baseProps,
755
- checkboxProps: config.checkboxProps,
756
- control,
757
- defaultValue: config.defaultValue
758
- }
759
- );
760
- case "radio":
761
- return /* @__PURE__ */ import_react13.default.createElement(
762
- RadioGroupField,
763
- {
764
- ...baseProps,
765
- control,
766
- defaultValue: config.defaultValue,
767
- options: (config.radioOptions ?? []).map((opt) => ({
768
- label: opt.label,
769
- value: String(opt.value)
770
- })),
771
- radioGroupProps: config.radioProps
772
- }
773
- );
774
- case "switch":
775
- return /* @__PURE__ */ import_react13.default.createElement(
776
- SwitchField,
777
- {
778
- ...baseProps,
779
- control,
780
- defaultValue: config.defaultValue,
781
- switchProps: config.switchProps
782
- }
783
- );
784
- case "slider":
785
- return /* @__PURE__ */ import_react13.default.createElement(
786
- SliderField,
787
- {
788
- ...baseProps,
789
- control,
790
- defaultValue: config.defaultValue,
791
- sliderProps: config.sliderProps
792
- }
793
- );
794
- case "date":
795
- return /* @__PURE__ */ import_react13.default.createElement(
796
- DateField,
797
- {
798
- ...baseProps,
799
- control,
800
- dateProps: config.dateProps,
801
- defaultValue: config.defaultValue
802
- }
803
- );
804
- case "file":
805
- return /* @__PURE__ */ import_react13.default.createElement(
806
- FileField,
807
- {
808
- ...baseProps,
809
- accept: config.accept,
810
- control,
811
- defaultValue: config.defaultValue,
812
- fileProps: config.fileProps,
813
- multiple: config.multiple
814
- }
815
- );
816
- default: {
817
- const fieldType = config.type;
818
- console.warn(`Unknown field type: ${fieldType}`);
819
- return null;
820
- }
821
- }
822
- }
823
-
824
- // src/components/Form.tsx
825
- function ConfigurableForm({
826
- className,
827
- columns = 1,
828
- defaultValues,
829
- fields,
830
- layout = "vertical",
831
- onError,
832
- onSubmit,
833
- onSuccess,
834
- resetButtonText = "Reset",
835
- showResetButton = false,
836
- spacing = "4",
837
- submitButtonProps = {},
838
- submitButtonText = "Submit",
839
- subtitle,
840
- title
841
- }) {
842
- const {
843
- error,
844
- form,
845
- handleSubmit,
846
- isSubmitted,
847
- isSubmitting,
848
- isSuccess,
849
- resetForm,
850
- submissionState
851
- } = useFormHelper({
852
- defaultValues,
853
- onError,
854
- onSubmit,
855
- onSuccess
856
- });
857
- const renderFields = () => {
858
- if (layout === "grid") {
859
- return /* @__PURE__ */ import_react14.default.createElement(
860
- "div",
861
- {
862
- className: `grid gap-${spacing} ${columns === 1 ? "grid-cols-1" : columns === 2 ? "grid-cols-1 md:grid-cols-2" : "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"}`
863
- },
864
- fields.map((field) => /* @__PURE__ */ import_react14.default.createElement(
865
- FormField,
866
- {
867
- key: field.name,
868
- config: field,
869
- form,
870
- submissionState
871
- }
872
- ))
873
- );
874
- }
875
- if (layout === "horizontal") {
876
- return /* @__PURE__ */ import_react14.default.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, fields.map((field) => /* @__PURE__ */ import_react14.default.createElement(
877
- FormField,
878
- {
879
- key: field.name,
880
- config: field,
881
- form,
882
- submissionState
883
- }
884
- )));
885
- }
886
- return /* @__PURE__ */ import_react14.default.createElement("div", { className: `space-y-${spacing}` }, fields.map((field) => /* @__PURE__ */ import_react14.default.createElement(
887
- FormField,
888
- {
889
- key: field.name,
890
- config: field,
891
- form,
892
- submissionState
893
- }
894
- )));
895
- };
896
- const handleFormSubmit = (e2) => {
897
- e2.preventDefault();
898
- void handleSubmit();
899
- };
900
- return /* @__PURE__ */ import_react14.default.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, title && /* @__PURE__ */ import_react14.default.createElement("div", { className: "mb-6" }, /* @__PURE__ */ import_react14.default.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)), isSubmitted && isSuccess && /* @__PURE__ */ import_react14.default.createElement(
901
- "div",
902
- {
903
- className: "mb-6 p-4 bg-success-50 border border-success-200 rounded-lg",
904
- "data-testid": "success-message"
905
- },
906
- /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-success-800 font-medium" }, "Success!"),
907
- /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-success-700 text-sm mt-1" }, "Your request has been processed successfully.")
908
- ), error && /* @__PURE__ */ import_react14.default.createElement(
909
- "div",
910
- {
911
- className: "mb-6 p-4 bg-danger-50 border border-danger-200 rounded-lg",
912
- "data-testid": "error-message"
913
- },
914
- /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-danger-800 font-medium" }, "Error"),
915
- /* @__PURE__ */ import_react14.default.createElement("p", { className: "text-danger-700 text-sm mt-1" }, error)
916
- ), renderFields(), /* @__PURE__ */ import_react14.default.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ import_react14.default.createElement(
917
- import_react15.Button,
918
- {
919
- color: "primary",
920
- isDisabled: isSubmitting,
921
- isLoading: isSubmitting,
922
- type: "submit",
923
- ...submitButtonProps
924
- },
925
- submitButtonText
926
- ), showResetButton && /* @__PURE__ */ import_react14.default.createElement(
927
- import_react15.Button,
928
- {
929
- isDisabled: isSubmitting,
930
- type: "button",
931
- variant: "bordered",
932
- onPress: resetForm
933
- },
934
- resetButtonText
935
- )));
936
- }
937
-
938
- // src/providers/FormProvider.tsx
939
- var import_react16 = __toESM(require("react"), 1);
940
- var import_react_hook_form11 = require("react-hook-form");
941
- function FormProvider(props) {
942
- return /* @__PURE__ */ import_react16.default.createElement(import_react_hook_form11.FormProvider, { ...props.methods }, /* @__PURE__ */ import_react16.default.createElement(
943
- "form",
944
- {
945
- className: props.className,
946
- id: props.id,
947
- noValidate: props.noValidate,
948
- onSubmit: (event) => void props.methods.handleSubmit(props.onSubmit)(event)
949
- },
950
- props.children
951
- ));
952
- }
953
-
954
- // src/submit/SubmitButton.tsx
955
- var import_react17 = __toESM(require("react"), 1);
956
- var import_react_hook_form12 = require("react-hook-form");
957
- function SubmitButton(props) {
958
- const ctx = (0, import_react_hook_form12.useFormContext)();
959
- const loading = props.isLoading ?? ctx.formState.isSubmitting;
960
- const isDisabledFromProps = props.buttonProps?.isDisabled ?? false;
961
- const isDisabled = Boolean(isDisabledFromProps) || Boolean(loading);
962
- const defaults = useHeroHookFormDefaults();
963
- return /* @__PURE__ */ import_react17.default.createElement(
964
- import_react3.Button,
965
- {
966
- type: "submit",
967
- ...defaults.submitButton,
968
- ...props.buttonProps,
969
- isDisabled
970
- },
971
- loading ? /* @__PURE__ */ import_react17.default.createElement("span", { className: "inline-flex items-center gap-2" }, /* @__PURE__ */ import_react17.default.createElement(import_react3.Spinner, { size: "sm" }), "Submitting\u2026") : props.children
972
- );
973
- }
974
-
975
- // src/utils/applyServerErrors.ts
976
- function applyServerErrors(setError, serverError) {
977
- if (!serverError.fieldErrors?.length) return;
978
- for (const err of serverError.fieldErrors) {
979
- setError(err.path, { message: err.message, type: err.type });
980
- }
981
- }
982
-
983
- // src/components/ZodForm.tsx
984
- var import_react18 = __toESM(require("react"), 1);
985
- var import_react19 = require("@heroui/react");
986
-
987
- // node_modules/@hookform/resolvers/dist/resolvers.mjs
988
- var import_react_hook_form13 = require("react-hook-form");
989
- var r = (t3, r2, o3) => {
990
- if (t3 && "reportValidity" in t3) {
991
- const s3 = (0, import_react_hook_form13.get)(o3, r2);
992
- t3.setCustomValidity(s3 && s3.message || ""), t3.reportValidity();
993
- }
994
- };
995
- var o = (e2, t3) => {
996
- for (const o3 in t3.fields) {
997
- const s3 = t3.fields[o3];
998
- s3 && s3.ref && "reportValidity" in s3.ref ? r(s3.ref, o3, e2) : s3 && s3.refs && s3.refs.forEach((t4) => r(t4, o3, e2));
999
- }
1000
- };
1001
- var s = (r2, s3) => {
1002
- s3.shouldUseNativeValidation && o(r2, s3);
1003
- const n3 = {};
1004
- for (const o3 in r2) {
1005
- const f = (0, import_react_hook_form13.get)(s3.fields, o3), c = Object.assign(r2[o3] || {}, { ref: f && f.ref });
1006
- if (i(s3.names || Object.keys(r2), o3)) {
1007
- const r3 = Object.assign({}, (0, import_react_hook_form13.get)(n3, o3));
1008
- (0, import_react_hook_form13.set)(r3, "root", c), (0, import_react_hook_form13.set)(n3, o3, r3);
1009
- } else (0, import_react_hook_form13.set)(n3, o3, c);
1010
- }
1011
- return n3;
1012
- };
1013
- var i = (e2, t3) => {
1014
- const r2 = n(t3);
1015
- return e2.some((e3) => n(e3).match(`^${r2}\\.\\d+`));
1016
- };
1017
- function n(e2) {
1018
- return e2.replace(/\]|\[/g, "");
1019
- }
1020
-
1021
- // node_modules/@hookform/resolvers/zod/dist/zod.mjs
1022
- var import_react_hook_form14 = require("react-hook-form");
1023
- var n2 = __toESM(require("zod/v4/core"), 1);
1024
- function t2(r2, e2) {
1025
- try {
1026
- var o3 = r2();
1027
- } catch (r3) {
1028
- return e2(r3);
1029
- }
1030
- return o3 && o3.then ? o3.then(void 0, e2) : o3;
1031
- }
1032
- function s2(r2, e2) {
1033
- for (var n3 = {}; r2.length; ) {
1034
- var t3 = r2[0], s3 = t3.code, i3 = t3.message, a2 = t3.path.join(".");
1035
- if (!n3[a2]) if ("unionErrors" in t3) {
1036
- var u = t3.unionErrors[0].errors[0];
1037
- n3[a2] = { message: u.message, type: u.code };
1038
- } else n3[a2] = { message: i3, type: s3 };
1039
- if ("unionErrors" in t3 && t3.unionErrors.forEach(function(e3) {
1040
- return e3.errors.forEach(function(e4) {
1041
- return r2.push(e4);
1042
- });
1043
- }), e2) {
1044
- var c = n3[a2].types, f = c && c[t3.code];
1045
- n3[a2] = (0, import_react_hook_form14.appendErrors)(a2, e2, n3, s3, f ? [].concat(f, t3.message) : t3.message);
1046
- }
1047
- r2.shift();
1048
- }
1049
- return n3;
1050
- }
1051
- function i2(r2, e2) {
1052
- for (var n3 = {}; r2.length; ) {
1053
- var t3 = r2[0], s3 = t3.code, i3 = t3.message, a2 = t3.path.join(".");
1054
- if (!n3[a2]) if ("invalid_union" === t3.code && t3.errors.length > 0) {
1055
- var u = t3.errors[0][0];
1056
- n3[a2] = { message: u.message, type: u.code };
1057
- } else n3[a2] = { message: i3, type: s3 };
1058
- if ("invalid_union" === t3.code && t3.errors.forEach(function(e3) {
1059
- return e3.forEach(function(e4) {
1060
- return r2.push(e4);
1061
- });
1062
- }), e2) {
1063
- var c = n3[a2].types, f = c && c[t3.code];
1064
- n3[a2] = (0, import_react_hook_form14.appendErrors)(a2, e2, n3, s3, f ? [].concat(f, t3.message) : t3.message);
1065
- }
1066
- r2.shift();
1067
- }
1068
- return n3;
1069
- }
1070
- function a(o3, a2, u) {
1071
- if (void 0 === u && (u = {}), (function(r2) {
1072
- return "_def" in r2 && "object" == typeof r2._def && "typeName" in r2._def;
1073
- })(o3)) return function(n3, i3, c) {
1074
- try {
1075
- return Promise.resolve(t2(function() {
1076
- return Promise.resolve(o3["sync" === u.mode ? "parse" : "parseAsync"](n3, a2)).then(function(e2) {
1077
- return c.shouldUseNativeValidation && o({}, c), { errors: {}, values: u.raw ? Object.assign({}, n3) : e2 };
1078
- });
1079
- }, function(r2) {
1080
- if ((function(r3) {
1081
- return Array.isArray(null == r3 ? void 0 : r3.issues);
1082
- })(r2)) return { values: {}, errors: s(s2(r2.errors, !c.shouldUseNativeValidation && "all" === c.criteriaMode), c) };
1083
- throw r2;
1084
- }));
1085
- } catch (r2) {
1086
- return Promise.reject(r2);
1087
- }
1088
- };
1089
- if ((function(r2) {
1090
- return "_zod" in r2 && "object" == typeof r2._zod;
1091
- })(o3)) return function(s3, c, f) {
1092
- try {
1093
- return Promise.resolve(t2(function() {
1094
- return Promise.resolve(("sync" === u.mode ? n2.parse : n2.parseAsync)(o3, s3, a2)).then(function(e2) {
1095
- return f.shouldUseNativeValidation && o({}, f), { errors: {}, values: u.raw ? Object.assign({}, s3) : e2 };
1096
- });
1097
- }, function(r2) {
1098
- if ((function(r3) {
1099
- return r3 instanceof n2.$ZodError;
1100
- })(r2)) return { values: {}, errors: s(i2(r2.issues, !f.shouldUseNativeValidation && "all" === f.criteriaMode), f) };
1101
- throw r2;
1102
- }));
1103
- } catch (r2) {
1104
- return Promise.reject(r2);
1105
- }
1106
- };
1107
- throw new Error("Invalid input: not a Zod schema");
1108
- }
1109
-
1110
- // src/zod-integration.ts
1111
- var import_react_hook_form15 = require("react-hook-form");
1112
- function useZodForm(config) {
1113
- if (!config.resolver && config.schema) {
1114
- const resolver = a(config.schema);
1115
- config.resolver = resolver;
1116
- }
1117
- const formConfig = {
1118
- ...config
1119
- };
1120
- return (0, import_react_hook_form15.useForm)(formConfig);
1121
- }
1122
-
1123
- // src/components/ZodForm.tsx
1124
- function ZodForm({
1125
- className,
1126
- columns = 1,
1127
- config,
1128
- layout = "vertical",
1129
- onError,
1130
- onSubmit,
1131
- onSuccess,
1132
- resetButtonText = "Reset",
1133
- showResetButton = false,
1134
- spacing = "4",
1135
- submitButtonProps = {},
1136
- submitButtonText = "Submit",
1137
- subtitle,
1138
- title
1139
- }) {
1140
- const form = useZodForm(config);
1141
- const [submissionState, setSubmissionState] = import_react18.default.useState({
1142
- error: void 0,
1143
- isSubmitted: false,
1144
- isSubmitting: false,
1145
- isSuccess: false
1146
- });
1147
- const handleSubmit = async () => {
1148
- setSubmissionState((prev) => ({
1149
- ...prev,
1150
- error: void 0,
1151
- isSubmitting: true
1152
- }));
1153
- const isValid = await form.trigger();
1154
- if (!isValid) {
1155
- setSubmissionState({
1156
- error: "Please fix the validation errors above",
1157
- isSubmitted: true,
1158
- isSubmitting: false,
1159
- isSuccess: false
1160
- });
1161
- return;
1162
- }
1163
- try {
1164
- await form.handleSubmit(async (formData) => {
1165
- await onSubmit(formData);
1166
- })();
1167
- setSubmissionState({
1168
- error: void 0,
1169
- isSubmitted: true,
1170
- isSubmitting: false,
1171
- isSuccess: true
1172
- });
1173
- onSuccess?.(form.getValues());
1174
- } catch (error) {
1175
- const errorMessage = error instanceof Error ? error.message : "An error occurred";
1176
- setSubmissionState({
1177
- error: errorMessage,
1178
- isSubmitted: true,
1179
- isSubmitting: false,
1180
- isSuccess: false
1181
- });
1182
- onError?.({
1183
- message: errorMessage
1184
- });
1185
- }
1186
- };
1187
- const resetForm = () => {
1188
- form.reset();
1189
- setSubmissionState({
1190
- error: void 0,
1191
- isSubmitted: false,
1192
- isSubmitting: false,
1193
- isSuccess: false
1194
- });
1195
- };
1196
- const renderFields = () => {
1197
- if (layout === "grid") {
1198
- return /* @__PURE__ */ import_react18.default.createElement(
1199
- "div",
1200
- {
1201
- className: `grid gap-${spacing} ${columns === 1 ? "grid-cols-1" : columns === 2 ? "grid-cols-1 md:grid-cols-2" : "grid-cols-1 md:grid-cols-2 lg:grid-cols-3"}`
1202
- },
1203
- config.fields.map((field) => /* @__PURE__ */ import_react18.default.createElement(
1204
- FormField,
1205
- {
1206
- key: field.name,
1207
- config: field,
1208
- form,
1209
- submissionState
1210
- }
1211
- ))
1212
- );
1213
- }
1214
- if (layout === "horizontal") {
1215
- return /* @__PURE__ */ import_react18.default.createElement("div", { className: `grid gap-${spacing} grid-cols-1 md:grid-cols-2` }, config.fields.map((field) => /* @__PURE__ */ import_react18.default.createElement(
1216
- FormField,
1217
- {
1218
- key: field.name,
1219
- config: field,
1220
- form,
1221
- submissionState
1222
- }
1223
- )));
1224
- }
1225
- return /* @__PURE__ */ import_react18.default.createElement("div", { className: `space-y-${spacing}` }, config.fields.map((field) => /* @__PURE__ */ import_react18.default.createElement(
1226
- FormField,
1227
- {
1228
- key: field.name,
1229
- config: field,
1230
- form,
1231
- submissionState
1232
- }
1233
- )));
1234
- };
1235
- const handleFormSubmit = (e2) => {
1236
- e2.preventDefault();
1237
- void handleSubmit();
1238
- };
1239
- return /* @__PURE__ */ import_react18.default.createElement("form", { className, role: "form", onSubmit: handleFormSubmit }, title && /* @__PURE__ */ import_react18.default.createElement("div", { className: "mb-6" }, /* @__PURE__ */ import_react18.default.createElement("h2", { className: "text-xl font-semibold text-foreground mb-2" }, title), subtitle && /* @__PURE__ */ import_react18.default.createElement("p", { className: "text-sm text-muted-foreground" }, subtitle)), submissionState.isSubmitted && submissionState.isSuccess && /* @__PURE__ */ import_react18.default.createElement(
1240
- "div",
1241
- {
1242
- className: "mb-6 p-4 bg-success-50 border border-success-200 rounded-lg",
1243
- "data-testid": "success-message"
1244
- },
1245
- /* @__PURE__ */ import_react18.default.createElement("p", { className: "text-success-800 font-medium" }, "Success!"),
1246
- /* @__PURE__ */ import_react18.default.createElement("p", { className: "text-success-700 text-sm mt-1" }, "Your request has been processed successfully.")
1247
- ), submissionState.error && /* @__PURE__ */ import_react18.default.createElement(
1248
- "div",
1249
- {
1250
- className: "mb-6 p-4 bg-danger-50 border border-danger-200 rounded-lg",
1251
- "data-testid": "error-message"
1252
- },
1253
- /* @__PURE__ */ import_react18.default.createElement("p", { className: "text-danger-800 font-medium" }, "Error"),
1254
- /* @__PURE__ */ import_react18.default.createElement("p", { className: "text-danger-700 text-sm mt-1" }, submissionState.error)
1255
- ), renderFields(), /* @__PURE__ */ import_react18.default.createElement("div", { className: "mt-6 flex gap-3 justify-end" }, /* @__PURE__ */ import_react18.default.createElement(
1256
- import_react19.Button,
1257
- {
1258
- color: "primary",
1259
- isDisabled: submissionState.isSubmitting,
1260
- isLoading: submissionState.isSubmitting,
1261
- type: "submit",
1262
- ...submitButtonProps
1263
- },
1264
- submitButtonText
1265
- ), showResetButton && /* @__PURE__ */ import_react18.default.createElement(
1266
- import_react19.Button,
1267
- {
1268
- isDisabled: submissionState.isSubmitting,
1269
- type: "button",
1270
- variant: "bordered",
1271
- onPress: resetForm
1272
- },
1273
- resetButtonText
1274
- )));
1275
- }
1276
- // Annotate the CommonJS export names for ESM import in node:
1277
- 0 && (module.exports = {
1278
- CheckboxField,
1279
- ConfigurableForm,
1280
- DateField,
1281
- FileField,
1282
- FormField,
1283
- FormProvider,
1284
- HeroHookFormProvider,
1285
- InputField,
1286
- RadioGroupField,
1287
- SelectField,
1288
- SliderField,
1289
- SubmitButton,
1290
- SwitchField,
1291
- TextareaField,
1292
- ZodForm,
1293
- applyServerErrors,
1294
- useFormHelper,
1295
- useHeroHookFormDefaults,
1296
- useZodForm
1297
- });