@arturton/react-form-constructor 0.1.5 → 0.2.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.mjs CHANGED
@@ -1,8 +1,324 @@
1
1
  // src/JsonMethod/FormLayout.tsx
2
- import { useForm } from "react-hook-form";
2
+ import { useForm, Controller } from "react-hook-form";
3
+ import { PatternFormat } from "react-number-format";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ function FieldRenderer({
6
+ field,
7
+ register,
8
+ control,
9
+ errors,
10
+ globalClasses
11
+ }) {
12
+ const fieldName = String(field.key);
13
+ const error = errors[fieldName];
14
+ const errorMessage = error?.message;
15
+ const hasError = !!error;
16
+ const labelFieldClassName = field.labelClass || globalClasses.label;
17
+ const inputFieldClassName = `${field.inputClass || globalClasses.input || ""} ${hasError ? field.classNameError || "" : ""}`.trim();
18
+ const errorFieldClassName = field.errorClass || globalClasses.error;
19
+ if (field.render) {
20
+ return field.render({
21
+ register,
22
+ control,
23
+ errors,
24
+ field
25
+ });
26
+ }
27
+ const renderField = () => {
28
+ switch (field.type) {
29
+ // Text inputs
30
+ case "text":
31
+ case "email":
32
+ case "password":
33
+ return /* @__PURE__ */ jsx(
34
+ "input",
35
+ {
36
+ ...register(fieldName, {
37
+ required: field.required,
38
+ minLength: field.minLength,
39
+ maxLength: field.maxLength,
40
+ pattern: field.pattern,
41
+ validate: field.validate
42
+ }),
43
+ type: field.type,
44
+ placeholder: field.placeholder,
45
+ className: inputFieldClassName,
46
+ disabled: field.disabled
47
+ }
48
+ );
49
+ // Number input
50
+ case "number":
51
+ return /* @__PURE__ */ jsx(
52
+ "input",
53
+ {
54
+ ...register(fieldName, {
55
+ required: field.required,
56
+ minLength: field.minLength,
57
+ maxLength: field.maxLength,
58
+ validate: field.validate
59
+ }),
60
+ type: "number",
61
+ min: field.min,
62
+ max: field.max,
63
+ step: field.step || 1,
64
+ placeholder: field.placeholder,
65
+ className: inputFieldClassName,
66
+ disabled: field.disabled
67
+ }
68
+ );
69
+ // Date input
70
+ case "date":
71
+ return /* @__PURE__ */ jsx(
72
+ "input",
73
+ {
74
+ ...register(fieldName, {
75
+ required: field.required,
76
+ validate: field.validate
77
+ }),
78
+ type: "date",
79
+ className: inputFieldClassName,
80
+ disabled: field.disabled
81
+ }
82
+ );
83
+ // Textarea
84
+ case "textarea":
85
+ return /* @__PURE__ */ jsx(
86
+ "textarea",
87
+ {
88
+ ...register(fieldName, {
89
+ required: field.required,
90
+ minLength: field.minLength,
91
+ maxLength: field.maxLength,
92
+ validate: field.validate
93
+ }),
94
+ placeholder: field.placeholder,
95
+ className: inputFieldClassName,
96
+ disabled: field.disabled,
97
+ rows: field.rows || 4
98
+ }
99
+ );
100
+ // Select
101
+ case "select":
102
+ return /* @__PURE__ */ jsxs(
103
+ "select",
104
+ {
105
+ ...register(fieldName, {
106
+ required: field.required,
107
+ validate: field.validate
108
+ }),
109
+ className: inputFieldClassName,
110
+ disabled: field.disabled,
111
+ multiple: field.multiple,
112
+ children: [
113
+ field.placeholder && /* @__PURE__ */ jsx("option", { value: "", children: field.placeholder }),
114
+ field.options?.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
115
+ ]
116
+ }
117
+ );
118
+ // Masked input
119
+ case "mask":
120
+ return field.maska ? /* @__PURE__ */ jsx(
121
+ Controller,
122
+ {
123
+ name: fieldName,
124
+ control,
125
+ rules: {
126
+ required: field.maska.required || field.required,
127
+ minLength: field.minLength,
128
+ maxLength: field.maxLength,
129
+ validate: field.validate
130
+ },
131
+ render: ({ field: fieldProps }) => /* @__PURE__ */ jsx(
132
+ PatternFormat,
133
+ {
134
+ ...fieldProps,
135
+ format: field.maska.format,
136
+ mask: field.maska.mask,
137
+ placeholder: field.placeholder,
138
+ className: inputFieldClassName,
139
+ disabled: field.disabled
140
+ }
141
+ )
142
+ }
143
+ ) : null;
144
+ // File input
145
+ case "file":
146
+ return /* @__PURE__ */ jsx(
147
+ "input",
148
+ {
149
+ ...register(fieldName, {
150
+ required: field.required,
151
+ validate: field.validate
152
+ }),
153
+ type: "file",
154
+ accept: field.accept,
155
+ className: inputFieldClassName,
156
+ disabled: field.disabled,
157
+ multiple: field.multiple
158
+ }
159
+ );
160
+ // Checkbox
161
+ case "checkbox":
162
+ return /* @__PURE__ */ jsxs("div", { className: field.containerClass, children: [
163
+ /* @__PURE__ */ jsx(
164
+ "input",
165
+ {
166
+ ...register(fieldName, {
167
+ required: field.required,
168
+ validate: field.validate
169
+ }),
170
+ type: "checkbox",
171
+ id: fieldName,
172
+ className: inputFieldClassName,
173
+ disabled: field.disabled,
174
+ defaultChecked: field.defaultChecked
175
+ }
176
+ ),
177
+ field.label && /* @__PURE__ */ jsx("label", { htmlFor: fieldName, className: labelFieldClassName, children: field.label })
178
+ ] });
179
+ // Radio buttons
180
+ case "radio":
181
+ return /* @__PURE__ */ jsx("div", { className: field.containerClass, children: field.radioOptions?.map((option) => /* @__PURE__ */ jsxs("label", { className: labelFieldClassName, children: [
182
+ /* @__PURE__ */ jsx(
183
+ "input",
184
+ {
185
+ ...register(fieldName, {
186
+ required: field.required,
187
+ validate: field.validate
188
+ }),
189
+ type: "radio",
190
+ value: option.value,
191
+ className: inputFieldClassName,
192
+ disabled: field.disabled,
193
+ defaultChecked: field.defaultChecked
194
+ }
195
+ ),
196
+ option.label
197
+ ] }, option.value)) });
198
+ // Range/Slider
199
+ case "range":
200
+ return /* @__PURE__ */ jsxs("div", { className: field.containerClass, children: [
201
+ /* @__PURE__ */ jsx(
202
+ "input",
203
+ {
204
+ ...register(fieldName, {
205
+ required: field.required,
206
+ validate: field.validate
207
+ }),
208
+ type: "range",
209
+ min: field.min || 0,
210
+ max: field.max || 100,
211
+ step: field.step || 1,
212
+ className: inputFieldClassName,
213
+ disabled: field.disabled
214
+ }
215
+ ),
216
+ field.showValue && /* @__PURE__ */ jsx("span", { children: errors[fieldName]?.message || "Value" })
217
+ ] });
218
+ default:
219
+ return /* @__PURE__ */ jsx(
220
+ "input",
221
+ {
222
+ ...register(fieldName, {
223
+ required: field.required,
224
+ minLength: field.minLength,
225
+ maxLength: field.maxLength,
226
+ pattern: field.pattern,
227
+ validate: field.validate
228
+ }),
229
+ type: "text",
230
+ placeholder: field.placeholder,
231
+ className: inputFieldClassName,
232
+ disabled: field.disabled
233
+ }
234
+ );
235
+ }
236
+ };
237
+ return renderField();
238
+ }
239
+ function FormLayout({
240
+ formData,
241
+ funSubmit,
242
+ defaultValues,
243
+ onError,
244
+ formClass,
245
+ containerClass,
246
+ buttonClass,
247
+ buttonName = "Submit",
248
+ labelClass,
249
+ inputClass,
250
+ errorClass,
251
+ submitButtonProps,
252
+ disabledOnError = false
253
+ }) {
254
+ const {
255
+ register,
256
+ handleSubmit,
257
+ control,
258
+ formState: { errors }
259
+ } = useForm({
260
+ mode: "onChange",
261
+ defaultValues
262
+ });
263
+ const onSubmit = (data) => {
264
+ funSubmit(data);
265
+ };
266
+ const onSubmitError = (formErrors) => {
267
+ onError?.(formErrors);
268
+ };
269
+ const globalClasses = {
270
+ label: labelClass,
271
+ input: inputClass,
272
+ error: errorClass
273
+ };
274
+ const hasErrors = Object.keys(errors).length > 0;
275
+ return /* @__PURE__ */ jsxs(
276
+ "form",
277
+ {
278
+ onSubmit: handleSubmit(onSubmit, onSubmitError),
279
+ className: formClass,
280
+ children: [
281
+ /* @__PURE__ */ jsx("div", { className: containerClass, children: formData.map((field) => /* @__PURE__ */ jsxs("div", { className: field.containerClass, children: [
282
+ field.type !== "checkbox" && field.label && /* @__PURE__ */ jsxs(
283
+ "label",
284
+ {
285
+ htmlFor: String(field.key),
286
+ className: field.labelClass || globalClasses.label,
287
+ children: [
288
+ field.label,
289
+ field.required && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
290
+ ]
291
+ }
292
+ ),
293
+ /* @__PURE__ */ jsx(
294
+ FieldRenderer,
295
+ {
296
+ field,
297
+ register,
298
+ control,
299
+ errors,
300
+ globalClasses
301
+ }
302
+ ),
303
+ errors[String(field.key)] && /* @__PURE__ */ jsx("span", { className: field.errorClass || globalClasses.error, children: errors[String(field.key)]?.message })
304
+ ] }, String(field.key))) }),
305
+ /* @__PURE__ */ jsx(
306
+ "button",
307
+ {
308
+ type: "submit",
309
+ className: buttonClass,
310
+ disabled: disabledOnError && hasErrors,
311
+ ...submitButtonProps,
312
+ children: buttonName
313
+ }
314
+ )
315
+ ]
316
+ }
317
+ );
318
+ }
3
319
 
4
320
  // src/InputForm/layouts/mainLayout.tsx
5
- import { jsx, jsxs } from "react/jsx-runtime";
321
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
6
322
  function MainLayout({
7
323
  children,
8
324
  label,
@@ -12,22 +328,22 @@ function MainLayout({
12
328
  labelClass,
13
329
  errorClass
14
330
  }) {
15
- return /* @__PURE__ */ jsxs("div", { children: [
16
- label && /* @__PURE__ */ jsxs("label", { className: labelClass, children: [
331
+ return /* @__PURE__ */ jsxs2("div", { children: [
332
+ label && /* @__PURE__ */ jsxs2("label", { className: labelClass, children: [
17
333
  label,
18
334
  " ",
19
- required ? /* @__PURE__ */ jsx("span", { children: "*" }) : null
335
+ required ? /* @__PURE__ */ jsx2("span", { children: "*" }) : null
20
336
  ] }),
21
337
  children,
22
- error?.[name] && /* @__PURE__ */ jsx("span", { className: errorClass, children: error?.[name]?.message })
338
+ error?.[name] && /* @__PURE__ */ jsx2("span", { className: errorClass, children: error?.[name]?.message })
23
339
  ] });
24
340
  }
25
341
  var mainLayout_default = MainLayout;
26
342
 
27
343
  // src/InputForm/components/MaskedField.tsx
28
- import { Controller } from "react-hook-form";
29
- import { PatternFormat } from "react-number-format";
30
- import { jsx as jsx2 } from "react/jsx-runtime";
344
+ import { Controller as Controller2 } from "react-hook-form";
345
+ import { PatternFormat as PatternFormat2 } from "react-number-format";
346
+ import { jsx as jsx3 } from "react/jsx-runtime";
31
347
  function MaskedField({
32
348
  placeholder,
33
349
  name,
@@ -35,14 +351,14 @@ function MaskedField({
35
351
  maska,
36
352
  inputClass
37
353
  }) {
38
- return /* @__PURE__ */ jsx2(
39
- Controller,
354
+ return /* @__PURE__ */ jsx3(
355
+ Controller2,
40
356
  {
41
357
  name: name || "",
42
358
  control,
43
359
  rules: { required: maska.required },
44
- render: ({ field }) => /* @__PURE__ */ jsx2(
45
- PatternFormat,
360
+ render: ({ field }) => /* @__PURE__ */ jsx3(
361
+ PatternFormat2,
46
362
  {
47
363
  ...field,
48
364
  format: maska.format,
@@ -57,7 +373,7 @@ function MaskedField({
57
373
  var MaskedField_default = MaskedField;
58
374
 
59
375
  // src/InputForm/components/InputField.tsx
60
- import { jsx as jsx3 } from "react/jsx-runtime";
376
+ import { jsx as jsx4 } from "react/jsx-runtime";
61
377
  function InputField({
62
378
  register,
63
379
  type,
@@ -65,7 +381,7 @@ function InputField({
65
381
  inputClass,
66
382
  name
67
383
  }) {
68
- return /* @__PURE__ */ jsx3(
384
+ return /* @__PURE__ */ jsx4(
69
385
  "input",
70
386
  {
71
387
  id: name,
@@ -79,7 +395,7 @@ function InputField({
79
395
  var InputField_default = InputField;
80
396
 
81
397
  // src/InputForm/InputForm.tsx
82
- import { jsx as jsx4 } from "react/jsx-runtime";
398
+ import { jsx as jsx5 } from "react/jsx-runtime";
83
399
  function InputForm({
84
400
  register,
85
401
  type,
@@ -96,7 +412,7 @@ function InputForm({
96
412
  }) {
97
413
  const renderChildren = () => {
98
414
  if (maska) {
99
- return /* @__PURE__ */ jsx4(
415
+ return /* @__PURE__ */ jsx5(
100
416
  MaskedField_default,
101
417
  {
102
418
  name,
@@ -107,7 +423,7 @@ function InputForm({
107
423
  }
108
424
  );
109
425
  } else {
110
- return /* @__PURE__ */ jsx4(
426
+ return /* @__PURE__ */ jsx5(
111
427
  InputField_default,
112
428
  {
113
429
  name,
@@ -119,7 +435,7 @@ function InputForm({
119
435
  );
120
436
  }
121
437
  };
122
- return /* @__PURE__ */ jsx4(
438
+ return /* @__PURE__ */ jsx5(
123
439
  mainLayout_default,
124
440
  {
125
441
  label,
@@ -134,53 +450,6 @@ function InputForm({
134
450
  }
135
451
  var InputForm_default = InputForm;
136
452
 
137
- // src/JsonMethod/FormLayout.tsx
138
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
139
- function FormLayout({
140
- formData,
141
- funSubmit,
142
- formClass,
143
- buttonClass,
144
- buttonName
145
- }) {
146
- const {
147
- control,
148
- register,
149
- handleSubmit,
150
- formState: { errors }
151
- } = useForm();
152
- const onSubmit = (data) => {
153
- funSubmit(data);
154
- };
155
- return /* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit(onSubmit), className: formClass, children: [
156
- formData.map((item) => /* @__PURE__ */ jsx5(
157
- InputForm_default,
158
- {
159
- type: item.type,
160
- placeholder: item.placeholder,
161
- error: errors,
162
- name: String(item.key),
163
- label: item.label,
164
- control,
165
- maska: item.maska,
166
- register: register(item.key, {
167
- required: item.required,
168
- minLength: item.minLength,
169
- maxLength: item.maxLength,
170
- pattern: item.pattern,
171
- validate: item.validate
172
- }),
173
- required: item.required,
174
- inputClass: item.inputClass,
175
- errorClass: item.errorClass,
176
- labelClass: item.labelClass
177
- },
178
- String(item.key)
179
- )),
180
- /* @__PURE__ */ jsx5("button", { type: "submit", className: buttonClass, children: buttonName || "Submit" })
181
- ] });
182
- }
183
-
184
453
  // src/ProviderMethod/layouts/FormProvider.tsx
185
454
  import { useForm as useForm2, useWatch } from "react-hook-form";
186
455
 
@@ -429,8 +698,8 @@ function FormTextarea({
429
698
  var FormTextarea_default = FormTextarea;
430
699
 
431
700
  // src/ProviderMethod/components/FormMaskedInput.tsx
432
- import { Controller as Controller2 } from "react-hook-form";
433
- import { PatternFormat as PatternFormat2 } from "react-number-format";
701
+ import { Controller as Controller3 } from "react-hook-form";
702
+ import { PatternFormat as PatternFormat3 } from "react-number-format";
434
703
  import { jsx as jsx11 } from "react/jsx-runtime";
435
704
  function FormMaskedInput({
436
705
  placeholder,
@@ -444,7 +713,7 @@ function FormMaskedInput({
444
713
  return null;
445
714
  }
446
715
  return /* @__PURE__ */ jsx11(
447
- Controller2,
716
+ Controller3,
448
717
  {
449
718
  name: name || "",
450
719
  control,
@@ -456,7 +725,7 @@ function FormMaskedInput({
456
725
  validate
457
726
  },
458
727
  render: ({ field }) => /* @__PURE__ */ jsx11(
459
- PatternFormat2,
728
+ PatternFormat3,
460
729
  {
461
730
  ...field,
462
731
  format: maska.format,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arturton/react-form-constructor",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "Flexible form constructor with React Hook Form integration",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -45,8 +45,5 @@
45
45
  "devDependencies": {
46
46
  "@types/react": "^19.2.10",
47
47
  "react-number-format": "^5.4.4"
48
- },
49
- "dependencies": {
50
- "zod": "^3.22.0"
51
48
  }
52
49
  }