mui-custom-form 1.1.8 → 1.1.9

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.
Files changed (33) hide show
  1. package/README.md +23 -237
  2. package/dist/CustomForm.d.ts +1 -0
  3. package/dist/CustomForm.js +29 -89
  4. package/dist/components/fields/CheckboxGroupField.d.ts +9 -0
  5. package/dist/components/fields/CheckboxGroupField.js +23 -0
  6. package/dist/components/fields/CheckboxGroupField.js.map +1 -0
  7. package/dist/components/fields/CustomField.d.ts +9 -0
  8. package/dist/components/fields/CustomField.js +12 -0
  9. package/dist/components/fields/CustomField.js.map +1 -0
  10. package/dist/components/fields/DateField.d.ts +9 -0
  11. package/dist/components/fields/DateField.js +9 -0
  12. package/dist/components/fields/DateField.js.map +1 -0
  13. package/dist/components/fields/FileField.d.ts +9 -0
  14. package/dist/components/fields/FileField.js +44 -0
  15. package/dist/components/fields/FileField.js.map +1 -0
  16. package/dist/components/fields/RadioGroupField.d.ts +9 -0
  17. package/dist/components/fields/RadioGroupField.js +11 -0
  18. package/dist/components/fields/RadioGroupField.js.map +1 -0
  19. package/dist/components/fields/SelectField.d.ts +9 -0
  20. package/dist/components/fields/SelectField.js +11 -0
  21. package/dist/components/fields/SelectField.js.map +1 -0
  22. package/dist/components/fields/SwitchField.d.ts +9 -0
  23. package/dist/components/fields/SwitchField.js +8 -0
  24. package/dist/components/fields/SwitchField.js.map +1 -0
  25. package/dist/components/fields/TextField.d.ts +9 -0
  26. package/dist/components/fields/TextField.js +14 -0
  27. package/dist/components/fields/TextField.js.map +1 -0
  28. package/dist/components/fields/TextareaField.d.ts +9 -0
  29. package/dist/components/fields/TextareaField.js +8 -0
  30. package/dist/components/fields/TextareaField.js.map +1 -0
  31. package/dist/types.d.ts +41 -26
  32. package/dist/types.js +1 -2
  33. package/package.json +9 -8
package/README.md CHANGED
@@ -63,44 +63,34 @@ npm install mui-custom-form
63
63
  | `span` | Grid span for the field (1-12). | **No** |
64
64
  | `component` | Custom React component for the field. | *Conditional* |
65
65
 
66
- > **Notes**:
66
+ > **Notes**:
67
67
  > - The `list` prop is **required** when the `type` is `single-select`, `multi-select`, `checkbox-group`, or `radio-group`.
68
68
  > - The `component` prop is **required** when the `type` is `custom`.
69
+ > - The `fileInputComponent` prop is **optional** when the `type` is `file`. It allows you to provide a custom React component or element to serve as the clickable area for the file input. If not provided, a default clickable area will be rendered.
69
70
 
70
- ### 🧩 Custom Components
71
-
72
- To integrate custom components into your forms, ensure they adhere to the `CustomComponentProps` interface, which requires `value` and `onChange` props.
73
-
74
- ```typescript
75
- export interface CustomComponentProps {
76
- value: any;
77
- onChange: (value: any) => void;
78
- [key: string]: any; // Allow additional props
79
- }
80
- ```
81
-
82
- **Example of a Custom Component:**
71
+ **Example of `fileInputComponent` usage:**
83
72
 
84
73
  ```tsx
85
- // CustomComponents.tsx
86
- import React from "react";
87
- import { TextField } from "@mui/material";
88
- import { CustomComponentProps } from "./types";
89
-
90
- export const CustomTextComponent: React.FC<CustomComponentProps> = ({
91
- value,
92
- onChange,
93
- placeholder,
94
- }) => {
95
- return (
96
- <TextField
97
- value={value || ""}
98
- onChange={(e) => onChange(e.target.value)}
99
- placeholder={placeholder}
100
- fullWidth
101
- />
102
- );
103
- };
74
+ import { Button } from "@mui/material";
75
+ import CloudUploadIcon from "@mui/icons-material/CloudUpload";
76
+
77
+ // ... inside your fieldsGroups configuration
78
+ {
79
+ label: "Upload Document",
80
+ name: "document",
81
+ type: "file",
82
+ fileInputComponent: (
83
+ <Button
84
+ variant="contained"
85
+ component="span" // Important: This makes the Button act as a span, allowing the hidden input to be clicked
86
+ startIcon={<CloudUploadIcon />}
87
+ >
88
+ Upload File
89
+ </Button>
90
+ ),
91
+ required: false,
92
+ span: 6,
93
+ }
104
94
  ```
105
95
 
106
96
  ## 📖 Examples
@@ -278,210 +268,6 @@ const FormWithZod = () => {
278
268
  export default FormWithZod;
279
269
  ```
280
270
 
281
- ### Comprehensive Example with All Field Types
282
-
283
- An extensive example showcasing all supported field types, customizable input props, and custom components.
284
-
285
- ```tsx
286
- // ComprehensiveForm.tsx
287
- import React from "react";
288
- import { useForm } from "react-hook-form";
289
- import { zodResolver } from "@hookform/resolvers/zod";
290
- import { z } from "zod";
291
- import { Container, Typography, ButtonProps } from "@mui/material";
292
- import { CustomForm } from "mui-custom-form";
293
- import { IFieldGroup } from "mui-custom-form/types";
294
- import {
295
- CustomTextComponent,
296
- DateRangePickerComponent,
297
- } from "./CustomComponents"; // Ensure correct import path
298
-
299
- const GENDERS = ["Male", "Female", "Other"] as const;
300
- const HOBBIES = ["Coding", "Collections", "Hiking"] as const;
301
-
302
- const Fields = z.object({
303
- username: z.string().min(1, "Username is required"),
304
- password: z.string().min(6, "Password must be at least 6 characters"),
305
- bio: z.string().optional(),
306
- subscribe: z.boolean().optional(),
307
- age: z
308
- .number({
309
- required_error: "Age is required",
310
- invalid_type_error: "Age must be a number",
311
- })
312
- .min(16, "Minimum age is 16")
313
- .max(80, "Maximum age is 80"),
314
- gender: z.enum(GENDERS, { required_error: "Gender is required" }),
315
- hobbies: z
316
- .array(z.enum(HOBBIES), { required_error: "Hobbies are required" })
317
- .nonempty("Please choose at least one hobby"),
318
- birthDate: z.date({ required_error: "Birthdate is required" }),
319
- file: z.instanceof(File).optional(),
320
- customField: z.string().optional(),
321
- eventDates: z
322
- .tuple([z.date().nullable(), z.date().nullable()])
323
- .optional(),
324
- });
325
-
326
- type FieldTypes = z.infer<typeof Fields>;
327
-
328
- const ComprehensiveForm = () => {
329
- const formControl = useForm<FieldTypes>({
330
- resolver: zodResolver(Fields),
331
- defaultValues: {
332
- subscribe: false,
333
- hobbies: [],
334
- eventDates: [null, null],
335
- },
336
- });
337
-
338
- const fieldsGroups: IFieldGroup<FieldTypes> = [
339
- [
340
- {
341
- label: "Username",
342
- name: "username",
343
- type: "text",
344
- required: true,
345
- otherProps: { placeholder: "Enter your username" },
346
- span: 6,
347
- },
348
- {
349
- label: "Password",
350
- name: "password",
351
- type: "password",
352
- required: true,
353
- otherProps: { placeholder: "Enter your password" },
354
- span: 6,
355
- },
356
- ],
357
- [
358
- {
359
- label: "Bio",
360
- name: "bio",
361
- type: "textarea",
362
- required: false,
363
- otherProps: { rows: 5, placeholder: "Tell us about yourself" },
364
- span: 12,
365
- },
366
- ],
367
- [
368
- {
369
- label: "Subscribe to Newsletter",
370
- name: "subscribe",
371
- type: "switch",
372
- required: false,
373
- otherProps: { color: "primary" },
374
- span: 6,
375
- },
376
- ],
377
- [
378
- {
379
- label: "Age",
380
- name: "age",
381
- type: "number",
382
- required: true,
383
- otherProps: { min: 16, max: 80 },
384
- span: 6,
385
- },
386
- {
387
- label: "Gender",
388
- name: "gender",
389
- type: "radio-group",
390
- list: GENDERS.map((gender) => ({
391
- label: gender,
392
- value: gender,
393
- })),
394
- required: true,
395
- otherProps: { row: true },
396
- span: 6,
397
- },
398
- ],
399
- [
400
- {
401
- label: "Hobbies",
402
- name: "hobbies",
403
- type: "checkbox-group",
404
- list: HOBBIES.map((hobby) => ({ label: hobby, value: hobby })),
405
- required: true,
406
- span: 6,
407
- },
408
- {
409
- label: "Birthdate",
410
- name: "birthDate",
411
- type: "date",
412
- required: true,
413
- span: 6,
414
- },
415
- ],
416
- [
417
- {
418
- label: "Event Dates",
419
- name: "eventDates",
420
- type: "custom",
421
- component: DateRangePickerComponent,
422
- required: false,
423
- span: 6,
424
- },
425
- {
426
- label: "Upload Image",
427
- name: "file",
428
- type: "file",
429
- required: false,
430
- span: 6,
431
- },
432
- ],
433
- [
434
- {
435
- label: "Custom Text Field",
436
- name: "customField",
437
- type: "custom",
438
- component: CustomTextComponent,
439
- required: false,
440
- otherProps: { placeholder: "Custom input here" },
441
- span: 12,
442
- },
443
- ],
444
- ];
445
-
446
- const onSubmit = (data: FieldTypes) => {
447
- console.log({ success: data });
448
- };
449
-
450
- const submitError = (errors: any) => {
451
- console.log({ errors });
452
- };
453
-
454
- const submitButtonProps: ButtonProps = {
455
- variant: "contained",
456
- color: "primary",
457
- };
458
-
459
- const resetButtonProps: ButtonProps = {
460
- variant: "outlined",
461
- color: "secondary",
462
- };
463
-
464
- return (
465
- <Container maxWidth="md" sx={{ mt: 4, mb: 4 }}>
466
- <Typography variant="h4" gutterBottom>
467
- Comprehensive Form
468
- </Typography>
469
- <CustomForm
470
- fieldsGroups={fieldsGroups}
471
- onSubmit={[onSubmit, submitError]}
472
- formControl={formControl}
473
- submitButton={submitButtonProps}
474
- resetButton={resetButtonProps}
475
- actionButtonsPlacement="flex-end"
476
- otherProps={{ spacing: 2 }}
477
- />
478
- </Container>
479
- );
480
- };
481
-
482
- export default ComprehensiveForm;
483
- ```
484
-
485
271
  ## 🤝 Contribution
486
272
 
487
273
  Your contributions are always welcome! Whether it's reporting bugs, suggesting features, or submitting pull requests, we appreciate your support in making `CustomForm` better for everyone.
@@ -2,3 +2,4 @@ import React from "react";
2
2
  import { FieldValues } from "react-hook-form";
3
3
  import { ICustomForm } from "./types";
4
4
  export declare const CustomForm: <T extends FieldValues>({ fieldsGroups, onSubmit, formControl, submitButton, resetButton, actionButtonsPlacement, layout, otherProps, }: ICustomForm<T>) => React.JSX.Element;
5
+ export default CustomForm;
@@ -1,100 +1,40 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CustomForm = void 0;
7
- // CustomForm.tsx
8
- const material_1 = require("@mui/material");
9
- const x_date_pickers_1 = require("@mui/x-date-pickers");
10
- const react_1 = __importDefault(require("react"));
11
- const react_hook_form_1 = require("react-hook-form");
12
- const CustomForm = ({ fieldsGroups, onSubmit, formControl, submitButton = true, resetButton, actionButtonsPlacement, layout, otherProps, }) => {
13
- const { control, setValue, reset } = formControl;
1
+ import { Button, Grid, Stack } from "@mui/material";
2
+ import React from "react";
3
+ // Import modularized field components
4
+ import { TextField } from "./components/fields/TextField";
5
+ import { TextareaField } from "./components/fields/TextareaField";
6
+ import { SelectField } from "./components/fields/SelectField";
7
+ import { DateField } from "./components/fields/DateField";
8
+ import { FileField } from "./components/fields/FileField";
9
+ import { SwitchField } from "./components/fields/SwitchField";
10
+ import { CheckboxGroupField } from "./components/fields/CheckboxGroupField";
11
+ import { RadioGroupField } from "./components/fields/RadioGroupField";
12
+ import { CustomField as CustomComponentField } from "./components/fields/CustomField";
13
+ export const CustomForm = ({ fieldsGroups, onSubmit, formControl, submitButton = true, resetButton, actionButtonsPlacement, layout, otherProps, }) => {
14
+ const { control, reset } = formControl;
14
15
  const renderField = (field) => {
15
16
  switch (field.type) {
16
17
  case "text":
17
18
  case "number":
18
19
  case "password":
19
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (react_1.default.createElement(material_1.TextField, Object.assign({}, controlField, { value: controlField.value || "" }, field.otherProps, { label: field.label, type: field.type, fullWidth: true, required: field.required, error: !!error, helperText: error === null || error === void 0 ? void 0 : error.message, onChange: (e) => {
20
- if (!e.target.value)
21
- return controlField.onChange(undefined);
22
- controlField.onChange(field.type === "number"
23
- ? parseFloat(e.target.value)
24
- : e.target.value);
25
- } }))) }));
20
+ return React.createElement(TextField, { field: field, formControl: formControl });
26
21
  case "textarea":
27
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => {
28
- var _a;
29
- return (react_1.default.createElement(material_1.TextField, Object.assign({}, controlField, { value: controlField.value || "" }, field.otherProps, { label: field.label, type: "text", fullWidth: true, required: field.required, multiline: true, rows: ((_a = field.otherProps) === null || _a === void 0 ? void 0 : _a.rows) || 4, error: !!error, helperText: error === null || error === void 0 ? void 0 : error.message, onChange: controlField.onChange })));
30
- } }));
22
+ return React.createElement(TextareaField, { field: field, formControl: formControl });
31
23
  case "single-select":
32
24
  case "multi-select":
33
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => {
34
- var _a;
35
- return (react_1.default.createElement(material_1.FormControl, { fullWidth: true, error: !!error },
36
- react_1.default.createElement(material_1.InputLabel, { required: field.required }, field.label),
37
- react_1.default.createElement(material_1.Select, Object.assign({ label: field.label }, controlField, { value: controlField.value ||
38
- (field.type === "multi-select" ? [] : "") }, field.otherProps, { multiple: field.type === "multi-select" }), (_a = field.list) === null || _a === void 0 ? void 0 : _a.map((item) => (react_1.default.createElement(material_1.MenuItem, { key: item.value, value: item.value }, item.label)))),
39
- error && react_1.default.createElement(material_1.FormHelperText, null, error.message)));
40
- } }));
25
+ return React.createElement(SelectField, { field: field, formControl: formControl });
41
26
  case "date":
42
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (react_1.default.createElement(x_date_pickers_1.DatePicker, Object.assign({}, controlField, { value: controlField.value || null }, field.otherProps, { label: field.label, onChange: (date) => controlField.onChange(date), renderInput: (params) => (react_1.default.createElement(material_1.TextField, Object.assign({}, params, { required: field.required, error: !!error, helperText: error === null || error === void 0 ? void 0 : error.message, fullWidth: true }))) }))) }));
27
+ return React.createElement(DateField, { field: field, formControl: formControl });
43
28
  case "file":
44
- const Component = field.component;
45
- return (react_1.default.createElement(material_1.FormControl, { fullWidth: true, error: !!field.required },
46
- react_1.default.createElement(material_1.FormLabel, { component: "legend", required: field.required }, field.label),
47
- react_1.default.createElement(react_1.default.Fragment, null,
48
- react_1.default.createElement(material_1.Box, Object.assign({ component: "label" }, field.otherProps),
49
- Component && react_1.default.createElement(Component, null),
50
- react_1.default.createElement("input", { type: "file", hidden: true, onChange: (e) => {
51
- const fileValue = e.target.files && e.target.files.length > 0
52
- ? e.target.files
53
- : undefined;
54
- setValue(field.name, fileValue);
55
- } })))));
29
+ return React.createElement(FileField, { field: field, formControl: formControl });
56
30
  case "switch":
57
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Switch, Object.assign({}, controlField, { checked: !!controlField.value, onChange: (e) => controlField.onChange(e.target.checked) }, field.otherProps)), label: field.label })) }));
31
+ return React.createElement(SwitchField, { field: field, formControl: formControl });
58
32
  case "checkbox-group":
59
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => {
60
- var _a;
61
- return (react_1.default.createElement(material_1.FormControl, { component: "fieldset", error: !!error },
62
- react_1.default.createElement(material_1.FormLabel, { component: "legend", required: field.required }, field.label),
63
- react_1.default.createElement(material_1.Stack, { direction: "row", spacing: 2 }, (_a = field.list) === null || _a === void 0 ? void 0 : _a.map((option) => {
64
- var _a;
65
- return (react_1.default.createElement(material_1.FormControlLabel, { key: option.value, control: react_1.default.createElement(material_1.Checkbox, Object.assign({ checked: ((_a = controlField.value) === null || _a === void 0 ? void 0 : _a.includes(option.value)) || false, onChange: (e) => {
66
- const checked = e.target.checked;
67
- const value = option.value;
68
- if (checked) {
69
- controlField.onChange([
70
- ...(controlField.value || []),
71
- value,
72
- ]);
73
- }
74
- else {
75
- controlField.onChange((controlField.value || []).filter((v) => v !== value));
76
- }
77
- } }, field.otherProps)), label: option.label }));
78
- })),
79
- error && react_1.default.createElement(material_1.FormHelperText, null, error.message)));
80
- } }));
33
+ return React.createElement(CheckboxGroupField, { field: field, formControl: formControl });
81
34
  case "radio-group":
82
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => {
83
- var _a, _b;
84
- return (react_1.default.createElement(material_1.FormControl, { component: "fieldset", error: !!error },
85
- react_1.default.createElement(material_1.FormLabel, { component: "legend", required: field.required }, field.label),
86
- react_1.default.createElement(material_1.RadioGroup, Object.assign({}, controlField, { value: controlField.value || "", onChange: (e) => controlField.onChange(e.target.value), row: ((_a = field.otherProps) === null || _a === void 0 ? void 0 : _a.row) || false }), (_b = field.list) === null || _b === void 0 ? void 0 : _b.map((option) => (react_1.default.createElement(material_1.FormControlLabel, { key: option.value, value: option.value, control: react_1.default.createElement(material_1.Radio, Object.assign({}, field.otherProps)), label: option.label })))),
87
- error && react_1.default.createElement(material_1.FormHelperText, null, error.message)));
88
- } }));
35
+ return React.createElement(RadioGroupField, { field: field, formControl: formControl });
89
36
  case "custom":
90
- if (field.component) {
91
- const CustomComponent = field.component;
92
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (react_1.default.createElement(material_1.FormControl, { fullWidth: true, error: !!error },
93
- react_1.default.createElement(material_1.FormLabel, { component: "legend", required: field.required }, field.label),
94
- react_1.default.createElement(CustomComponent, Object.assign({ value: controlField.value, onChange: controlField.onChange }, field.otherProps)),
95
- error && react_1.default.createElement(material_1.FormHelperText, null, error.message))) }));
96
- }
97
- return null;
37
+ return React.createElement(CustomComponentField, { field: field, formControl: formControl });
98
38
  default:
99
39
  return null;
100
40
  }
@@ -109,18 +49,18 @@ const CustomForm = ({ fieldsGroups, onSubmit, formControl, submitButton = true,
109
49
  const calculatedSpan = autoSpanFields > 0 ? Math.floor(remainingSpan / autoSpanFields) : 12;
110
50
  return { calculatedSpan, autoSpanFields };
111
51
  };
112
- return (react_1.default.createElement(material_1.Stack, Object.assign({ component: "form", onSubmit: formControl.handleSubmit(onSubmit[0], onSubmit[1]), noValidate: true, direction: layout }, otherProps, { spacing: 3 }),
52
+ return (React.createElement(Stack, { component: "form", onSubmit: formControl.handleSubmit(onSubmit[0], onSubmit[1]), noValidate: true, direction: layout, ...otherProps, spacing: 3 },
113
53
  fieldsGroups.map((fields, rowIndex) => {
114
54
  const { calculatedSpan, autoSpanFields } = calculateSpan(fields);
115
- return (react_1.default.createElement(material_1.Grid, { container: true, key: rowIndex, spacing: 2 }, fields.map((field, fieldIndex) => (react_1.default.createElement(material_1.Grid, { key: fieldIndex, size: field.span
55
+ return (React.createElement(Grid, { container: true, key: rowIndex, spacing: 2 }, fields.map((field, fieldIndex) => (React.createElement(Grid, { key: fieldIndex, size: field.span
116
56
  ? field.span
117
57
  : autoSpanFields > 0
118
58
  ? calculatedSpan
119
59
  : 12 }, renderField(field))))));
120
60
  }),
121
- react_1.default.createElement(material_1.Stack, { direction: "row", justifyContent: actionButtonsPlacement || "flex-end", spacing: 2 },
122
- resetButton && (react_1.default.createElement(material_1.Button, Object.assign({ type: "reset", variant: "contained", onClick: () => reset() }, resetButtonProps), "Reset")),
123
- submitButton && (react_1.default.createElement(material_1.Button, Object.assign({ type: "submit", variant: "contained" }, submitButtonProps), "Submit")))));
61
+ React.createElement(Stack, { direction: "row", justifyContent: actionButtonsPlacement || "flex-end", spacing: 2 },
62
+ resetButton && (React.createElement(Button, { type: "reset", variant: "contained", onClick: () => reset(), ...resetButtonProps }, "Reset")),
63
+ submitButton && (React.createElement(Button, { type: "submit", variant: "contained", ...submitButtonProps }, "Submit")))));
124
64
  };
125
- exports.CustomForm = CustomForm;
65
+ export default CustomForm;
126
66
  //# sourceMappingURL=CustomForm.js.map
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
3
+ import { ICheckboxGroupField } from "../../types";
4
+ interface CheckboxGroupFieldProps<T extends FieldValues> {
5
+ field: ICheckboxGroupField<Path<T>>;
6
+ formControl: UseFormReturn<T>;
7
+ }
8
+ export declare const CheckboxGroupField: <T extends FieldValues>({ field, formControl, }: CheckboxGroupFieldProps<T>) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,23 @@
1
+ import { Checkbox, FormControl, FormControlLabel, FormHelperText, FormLabel, Stack, } from "@mui/material";
2
+ import React from "react";
3
+ import { Controller } from "react-hook-form";
4
+ export const CheckboxGroupField = ({ field, formControl, }) => {
5
+ const { control } = formControl;
6
+ return (React.createElement(Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (React.createElement(FormControl, { component: "fieldset", error: !!error },
7
+ React.createElement(FormLabel, { component: "legend", required: field.required }, field.label),
8
+ React.createElement(Stack, { direction: "row", spacing: 2 }, field.list?.map((option) => (React.createElement(FormControlLabel, { key: option.value, control: React.createElement(Checkbox, { checked: controlField.value?.includes(option.value) || false, onChange: (e) => {
9
+ const checked = e.target.checked;
10
+ const value = option.value;
11
+ if (checked) {
12
+ controlField.onChange([
13
+ ...(controlField.value || []),
14
+ value,
15
+ ]);
16
+ }
17
+ else {
18
+ controlField.onChange((controlField.value || []).filter((v) => v !== value));
19
+ }
20
+ }, ...field.otherProps }), label: option.label })))),
21
+ error && React.createElement(FormHelperText, null, error.message))) }));
22
+ };
23
+ //# sourceMappingURL=CheckboxGroupField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CheckboxGroupField.js","sourceRoot":"","sources":["../../../src/components/fields/CheckboxGroupField.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,SAAS,EACT,KAAK,GACN,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAoC,MAAM,iBAAiB,CAAA;AAQ9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAwB,EACxD,KAAK,EACL,WAAW,GACgB,EAAE,EAAE;IAC/B,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;IAE/B,OAAO,CACL,oBAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,IAAe,EAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EACnC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAC1D,oBAAC,WAAW,IAAC,SAAS,EAAC,UAAU,EAAC,KAAK,EAAE,CAAC,CAAC,KAAK;YAC9C,oBAAC,SAAS,IAAC,SAAS,EAAC,QAAQ,EAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IACnD,KAAK,CAAC,KAAK,CACF;YACZ,oBAAC,KAAK,IAAC,SAAS,EAAC,KAAK,EAAC,OAAO,EAAE,CAAC,IAC9B,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC3B,oBAAC,gBAAgB,IACf,GAAG,EAAE,MAAM,CAAC,KAAK,EACjB,OAAO,EACL,oBAAC,QAAQ,IACP,OAAO,EACL,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,EAErD,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;wBACd,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAA;wBAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAA;wBAC1B,IAAI,OAAO,EAAE,CAAC;4BACZ,YAAY,CAAC,QAAQ,CAAC;gCACpB,GAAG,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC;gCAC7B,KAAK;6BACN,CAAC,CAAA;wBACJ,CAAC;6BAAM,CAAC;4BACN,YAAY,CAAC,QAAQ,CACnB,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CAC/B,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CACxB,CACF,CAAA;wBACH,CAAC;oBACH,CAAC,KACG,KAAK,CAAC,UAAU,GACpB,EAEJ,KAAK,EAAE,MAAM,CAAC,KAAK,GACnB,CACH,CAAC,CACI;YACP,KAAK,IAAI,oBAAC,cAAc,QAAE,KAAK,CAAC,OAAO,CAAkB,CAC9C,CACf,GACD,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
3
+ import { ICustomComponentField } from "../../types";
4
+ interface CustomFieldProps<T extends FieldValues> {
5
+ field: ICustomComponentField<Path<T>>;
6
+ formControl: UseFormReturn<T>;
7
+ }
8
+ export declare const CustomField: <T extends FieldValues>({ field, formControl, }: CustomFieldProps<T>) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,12 @@
1
+ import { FormControl, FormHelperText, FormLabel } from "@mui/material";
2
+ import React from "react";
3
+ import { Controller } from "react-hook-form";
4
+ export const CustomField = ({ field, formControl, }) => {
5
+ const { control } = formControl;
6
+ const CustomComponent = field.component;
7
+ return (React.createElement(Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (React.createElement(FormControl, { fullWidth: true, error: !!error },
8
+ React.createElement(FormLabel, { component: "legend", required: field.required }, field.label),
9
+ React.createElement(CustomComponent, { value: controlField.value, onChange: controlField.onChange, ...field.otherProps }),
10
+ error && React.createElement(FormHelperText, null, error.message))) }));
11
+ };
12
+ //# sourceMappingURL=CustomField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomField.js","sourceRoot":"","sources":["../../../src/components/fields/CustomField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACtE,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAoC,MAAM,iBAAiB,CAAA;AAQ9E,MAAM,CAAC,MAAM,WAAW,GAAG,CAAwB,EACjD,KAAK,EACL,WAAW,GACS,EAAE,EAAE;IACxB,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;IAC/B,MAAM,eAAe,GAAG,KAAK,CAAC,SAAS,CAAA;IAEvC,OAAO,CACL,oBAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,IAAe,EAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EACnC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAC1D,oBAAC,WAAW,IAAC,SAAS,QAAC,KAAK,EAAE,CAAC,CAAC,KAAK;YACnC,oBAAC,SAAS,IAAC,SAAS,EAAC,QAAQ,EAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IACnD,KAAK,CAAC,KAAK,CACF;YACZ,oBAAC,eAAe,IACd,KAAK,EAAE,YAAY,CAAC,KAAK,EACzB,QAAQ,EAAE,YAAY,CAAC,QAAQ,KAC3B,KAAK,CAAC,UAAU,GACpB;YACD,KAAK,IAAI,oBAAC,cAAc,QAAE,KAAK,CAAC,OAAO,CAAkB,CAC9C,CACf,GACD,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
3
+ import { IDateField } from "../../types";
4
+ interface DateFieldProps<T extends FieldValues> {
5
+ field: IDateField<Path<T>>;
6
+ formControl: UseFormReturn<T>;
7
+ }
8
+ export declare const DateField: <T extends FieldValues>({ field, formControl, }: DateFieldProps<T>) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,9 @@
1
+ import { TextField as MuiTextField } from "@mui/material";
2
+ import { DatePicker } from "@mui/x-date-pickers";
3
+ import React from "react";
4
+ import { Controller } from "react-hook-form";
5
+ export const DateField = ({ field, formControl, }) => {
6
+ const { control } = formControl;
7
+ return (React.createElement(Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (React.createElement(DatePicker, { ...controlField, value: controlField.value || null, ...field.otherProps, label: field.label, onChange: (date) => controlField.onChange(date), renderInput: (params) => (React.createElement(MuiTextField, { ...params, required: field.required, error: !!error, helperText: error?.message, fullWidth: true })) })) }));
8
+ };
9
+ //# sourceMappingURL=DateField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateField.js","sourceRoot":"","sources":["../../../src/components/fields/DateField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,YAAY,EAAkB,MAAM,eAAe,CAAA;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAoC,MAAM,iBAAiB,CAAA;AAQ9E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAwB,EAC/C,KAAK,EACL,WAAW,GACO,EAAE,EAAE;IACtB,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;IAE/B,OAAO,CACL,oBAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,IAAe,EAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EACnC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAC1D,oBAAC,UAAU,OACL,YAAY,EAChB,KAAK,EAAE,YAAY,CAAC,KAAK,IAAI,IAAI,KAC7B,KAAK,CAAC,UAAU,EACpB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC/C,WAAW,EAAE,CAAC,MAAsB,EAAE,EAAE,CAAC,CACvC,oBAAC,YAAY,OACP,MAAM,EACV,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,UAAU,EAAE,KAAK,EAAE,OAAO,EAC1B,SAAS,SACT,CACH,GACD,CACH,GACD,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
3
+ import { IFileField } from "../../types";
4
+ interface FileFieldProps<T extends FieldValues> {
5
+ field: IFileField<Path<T>>;
6
+ formControl: UseFormReturn<T>;
7
+ }
8
+ export declare const FileField: <T extends FieldValues>({ field, formControl, }: FileFieldProps<T>) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,44 @@
1
+ import { Box, Button, FormControl, FormHelperText, FormLabel, IconButton, Stack, Typography, } from "@mui/material";
2
+ import { Close, InsertDriveFile } from "@mui/icons-material";
3
+ import React, { useRef } from "react";
4
+ import { Controller } from "react-hook-form";
5
+ export const FileField = ({ field, formControl, }) => {
6
+ const { control } = formControl;
7
+ const fileInputRef = useRef(null);
8
+ return (React.createElement(Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => {
9
+ const selectedFile = controlField.value?.[0];
10
+ const previewUrl = selectedFile
11
+ ? URL.createObjectURL(selectedFile)
12
+ : null;
13
+ return (React.createElement(FormControl, { fullWidth: true, error: !!error },
14
+ React.createElement(FormLabel, { component: "legend", required: field.required }, field.label),
15
+ React.createElement(Stack, { direction: "row", alignItems: "center", spacing: 2 },
16
+ React.createElement(Box, { onClick: () => fileInputRef.current?.click(), sx: { cursor: "pointer" }, ...field.otherProps },
17
+ field.fileInputComponent ? (typeof field.fileInputComponent === "function" ? (React.createElement(field.fileInputComponent)) : (field.fileInputComponent)) : (React.createElement(Button, { variant: "contained", component: "span" }, "Upload File")),
18
+ React.createElement("input", { type: "file", hidden: true, ref: fileInputRef, onChange: (e) => {
19
+ const fileValue = e.target.files && e.target.files.length > 0
20
+ ? e.target.files
21
+ : undefined;
22
+ controlField.onChange(fileValue);
23
+ } })),
24
+ selectedFile && (React.createElement(Stack, { direction: "row", alignItems: "center", spacing: 1 },
25
+ selectedFile.type.startsWith("image/") && previewUrl ? (React.createElement("img", { src: previewUrl, alt: "Preview", style: {
26
+ maxWidth: "50px",
27
+ maxHeight: "50px",
28
+ objectFit: "contain",
29
+ } })) : (React.createElement(InsertDriveFile, { sx: { fontSize: 50 } })),
30
+ React.createElement(Typography, { variant: "body2" }, selectedFile.name),
31
+ React.createElement(IconButton, { size: "small", onClick: () => {
32
+ controlField.onChange(undefined);
33
+ if (fileInputRef.current) {
34
+ fileInputRef.current.value = ""; // Clear the input element
35
+ }
36
+ if (previewUrl) {
37
+ URL.revokeObjectURL(previewUrl); // Clean up the object URL
38
+ }
39
+ } },
40
+ React.createElement(Close, { fontSize: "small" }))))),
41
+ error && React.createElement(FormHelperText, null, error.message)));
42
+ } }));
43
+ };
44
+ //# sourceMappingURL=FileField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileField.js","sourceRoot":"","sources":["../../../src/components/fields/FileField.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EACH,MAAM,EACN,WAAW,EACX,cAAc,EACd,SAAS,EACT,UAAU,EACV,KAAK,EACL,UAAU,GACX,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AACrC,OAAO,EAAE,UAAU,EAAoC,MAAM,iBAAiB,CAAA;AAQ9E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAwB,EAC/C,KAAK,EACL,WAAW,GACO,EAAE,EAAE;IACtB,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;IAC/B,MAAM,YAAY,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAA;IAEnD,OAAO,CACL,oBAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,IAAe,EAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EACnC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACzD,MAAM,YAAY,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,CAAqB,CAAA;YAChE,MAAM,UAAU,GAAG,YAAY;gBAC7B,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC;gBACnC,CAAC,CAAC,IAAI,CAAA;YAER,OAAO,CACL,oBAAC,WAAW,IAAC,SAAS,QAAC,KAAK,EAAE,CAAC,CAAC,KAAK;gBACnC,oBAAC,SAAS,IAAC,SAAS,EAAC,QAAQ,EAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IACnD,KAAK,CAAC,KAAK,CACF;gBACZ,oBAAC,KAAK,IAAC,SAAS,EAAC,KAAK,EAAC,UAAU,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC;oBACnD,oBAAC,GAAG,IACF,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,EAC5C,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,KACrB,KAAK,CAAC,UAAU;wBACnB,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAC1B,OAAO,KAAK,CAAC,kBAAkB,KAAK,UAAU,CAAC,CAAC,CAAC,CAC/C,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAC9C,CAAC,CAAC,CAAC,CACF,KAAK,CAAC,kBAAkB,CACzB,CACF,CAAC,CAAC,CAAC,CACF,oBAAC,MAAM,IAAC,OAAO,EAAC,WAAW,EAAC,SAAS,EAAC,MAAM,kBAEnC,CACV;wBACD,+BACE,IAAI,EAAC,MAAM,EACX,MAAM,QACN,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;gCACd,MAAM,SAAS,GACb,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;oCACzC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK;oCAChB,CAAC,CAAC,SAAS,CAAA;gCACf,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;4BAClC,CAAC,GACD,CACE;oBAEL,YAAY,IAAI,CACf,oBAAC,KAAK,IAAC,SAAS,EAAC,KAAK,EAAC,UAAU,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC;wBAClD,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CACtD,6BACE,GAAG,EAAE,UAAU,EACf,GAAG,EAAC,SAAS,EACb,KAAK,EAAE;gCACL,QAAQ,EAAE,MAAM;gCAChB,SAAS,EAAE,MAAM;gCACjB,SAAS,EAAE,SAAS;6BACrB,GACD,CACH,CAAC,CAAC,CAAC,CACF,oBAAC,eAAe,IAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,GAAI,CAC1C;wBACD,oBAAC,UAAU,IAAC,OAAO,EAAC,OAAO,IAAE,YAAY,CAAC,IAAI,CAAc;wBAC5D,oBAAC,UAAU,IACT,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,GAAG,EAAE;gCACZ,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;gCAChC,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;oCACzB,YAAY,CAAC,OAAO,CAAC,KAAK,GAAG,EAAE,CAAA,CAAC,0BAA0B;gCAC5D,CAAC;gCACD,IAAI,UAAU,EAAE,CAAC;oCACf,GAAG,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA,CAAC,0BAA0B;gCAC5D,CAAC;4BACH,CAAC;4BACD,oBAAC,KAAK,IAAC,QAAQ,EAAC,OAAO,GAAG,CACf,CACP,CACT,CACK;gBACP,KAAK,IAAI,oBAAC,cAAc,QAAE,KAAK,CAAC,OAAO,CAAkB,CAC9C,CACf,CAAA;QACH,CAAC,GACD,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
3
+ import { IRadioGroupField } from "../../types";
4
+ interface RadioGroupFieldProps<T extends FieldValues> {
5
+ field: IRadioGroupField<Path<T>>;
6
+ formControl: UseFormReturn<T>;
7
+ }
8
+ export declare const RadioGroupField: <T extends FieldValues>({ field, formControl, }: RadioGroupFieldProps<T>) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,11 @@
1
+ import { FormControl, FormControlLabel, FormHelperText, FormLabel, Radio, RadioGroup, } from "@mui/material";
2
+ import React from "react";
3
+ import { Controller } from "react-hook-form";
4
+ export const RadioGroupField = ({ field, formControl, }) => {
5
+ const { control } = formControl;
6
+ return (React.createElement(Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (React.createElement(FormControl, { component: "fieldset", error: !!error },
7
+ React.createElement(FormLabel, { component: "legend", required: field.required }, field.label),
8
+ React.createElement(RadioGroup, { ...controlField, value: controlField.value || "", onChange: (e) => controlField.onChange(e.target.value), row: field.otherProps?.row || false }, field.list?.map((option) => (React.createElement(FormControlLabel, { key: option.value, value: option.value, control: React.createElement(Radio, { ...field.otherProps }), label: option.label })))),
9
+ error && React.createElement(FormHelperText, null, error.message))) }));
10
+ };
11
+ //# sourceMappingURL=RadioGroupField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioGroupField.js","sourceRoot":"","sources":["../../../src/components/fields/RadioGroupField.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,SAAS,EACT,KAAK,EACL,UAAU,GACX,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAoC,MAAM,iBAAiB,CAAA;AAQ9E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAwB,EACrD,KAAK,EACL,WAAW,GACa,EAAE,EAAE;IAC5B,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;IAE/B,OAAO,CACL,oBAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,IAAe,EAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EACnC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAC1D,oBAAC,WAAW,IAAC,SAAS,EAAC,UAAU,EAAC,KAAK,EAAE,CAAC,CAAC,KAAK;YAC9C,oBAAC,SAAS,IAAC,SAAS,EAAC,QAAQ,EAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IACnD,KAAK,CAAC,KAAK,CACF;YACZ,oBAAC,UAAU,OACL,YAAY,EAChB,KAAK,EAAE,YAAY,CAAC,KAAK,IAAI,EAAE,EAC/B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACtD,GAAG,EAAE,KAAK,CAAC,UAAU,EAAE,GAAG,IAAI,KAAK,IAClC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC3B,oBAAC,gBAAgB,IACf,GAAG,EAAE,MAAM,CAAC,KAAK,EACjB,KAAK,EAAE,MAAM,CAAC,KAAK,EACnB,OAAO,EAAE,oBAAC,KAAK,OAAK,KAAK,CAAC,UAAU,GAAI,EACxC,KAAK,EAAE,MAAM,CAAC,KAAK,GACnB,CACH,CAAC,CACS;YACZ,KAAK,IAAI,oBAAC,cAAc,QAAE,KAAK,CAAC,OAAO,CAAkB,CAC9C,CACf,GACD,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
3
+ import { ISelectField } from "../../types";
4
+ interface SelectFieldProps<T extends FieldValues> {
5
+ field: ISelectField<Path<T>>;
6
+ formControl: UseFormReturn<T>;
7
+ }
8
+ export declare const SelectField: <T extends FieldValues>({ field, formControl, }: SelectFieldProps<T>) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,11 @@
1
+ import { FormControl, InputLabel, MenuItem, Select as MuiSelect, FormHelperText, } from "@mui/material";
2
+ import React from "react";
3
+ import { Controller } from "react-hook-form";
4
+ export const SelectField = ({ field, formControl, }) => {
5
+ const { control } = formControl;
6
+ return (React.createElement(Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (React.createElement(FormControl, { fullWidth: true, error: !!error },
7
+ React.createElement(InputLabel, { required: field.required }, field.label),
8
+ React.createElement(MuiSelect, { label: field.label, ...controlField, value: controlField.value || (field.type === "multi-select" ? [] : ""), ...field.otherProps, multiple: field.type === "multi-select" }, field.list?.map((item) => (React.createElement(MenuItem, { key: item.value, value: item.value }, item.label)))),
9
+ error && React.createElement(FormHelperText, null, error.message))) }));
10
+ };
11
+ //# sourceMappingURL=SelectField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectField.js","sourceRoot":"","sources":["../../../src/components/fields/SelectField.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,UAAU,EACV,QAAQ,EACR,MAAM,IAAI,SAAS,EACnB,cAAc,GACf,MAAM,eAAe,CAAA;AACtB,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAoC,MAAM,iBAAiB,CAAA;AAQ9E,MAAM,CAAC,MAAM,WAAW,GAAG,CAAwB,EACjD,KAAK,EACL,WAAW,GACS,EAAE,EAAE;IACxB,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;IAE/B,OAAO,CACL,oBAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,IAAe,EAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EACnC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAC1D,oBAAC,WAAW,IAAC,SAAS,QAAC,KAAK,EAAE,CAAC,CAAC,KAAK;YACnC,oBAAC,UAAU,IAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAG,KAAK,CAAC,KAAK,CAAc;YAChE,oBAAC,SAAS,IACR,KAAK,EAAE,KAAK,CAAC,KAAK,KACd,YAAY,EAChB,KAAK,EACH,YAAY,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAE7D,KAAK,CAAC,UAAU,EACpB,QAAQ,EAAE,KAAK,CAAC,IAAI,KAAK,cAAc,IACtC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACzB,oBAAC,QAAQ,IAAC,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,IACzC,IAAI,CAAC,KAAK,CACF,CACZ,CAAC,CACQ;YACX,KAAK,IAAI,oBAAC,cAAc,QAAE,KAAK,CAAC,OAAO,CAAkB,CAC9C,CACf,GACD,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
3
+ import { ISwitchField } from "../../types";
4
+ interface SwitchFieldProps<T extends FieldValues> {
5
+ field: ISwitchField<Path<T>>;
6
+ formControl: UseFormReturn<T>;
7
+ }
8
+ export declare const SwitchField: <T extends FieldValues>({ field, formControl, }: SwitchFieldProps<T>) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,8 @@
1
+ import { FormControlLabel, Switch as MuiSwitch } from "@mui/material";
2
+ import React from "react";
3
+ import { Controller } from "react-hook-form";
4
+ export const SwitchField = ({ field, formControl, }) => {
5
+ const { control } = formControl;
6
+ return (React.createElement(Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (React.createElement(FormControlLabel, { control: React.createElement(MuiSwitch, { ...controlField, checked: !!controlField.value, onChange: (e) => controlField.onChange(e.target.checked), ...field.otherProps }), label: field.label })) }));
7
+ };
8
+ //# sourceMappingURL=SwitchField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwitchField.js","sourceRoot":"","sources":["../../../src/components/fields/SwitchField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,eAAe,CAAA;AACrE,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAoC,MAAM,iBAAiB,CAAA;AAQ9E,MAAM,CAAC,MAAM,WAAW,GAAG,CAAwB,EACjD,KAAK,EACL,WAAW,GACS,EAAE,EAAE;IACxB,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;IAE/B,OAAO,CACL,oBAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,IAAe,EAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EACnC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAC1D,oBAAC,gBAAgB,IACf,OAAO,EACL,oBAAC,SAAS,OACJ,YAAY,EAChB,OAAO,EAAE,CAAC,CAAC,YAAY,CAAC,KAAK,EAC7B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KACpD,KAAK,CAAC,UAAU,GACpB,EAEJ,KAAK,EAAE,KAAK,CAAC,KAAK,GAClB,CACH,GACD,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
3
+ import { ICustomField } from "../../types";
4
+ interface TextFieldProps<T extends FieldValues> {
5
+ field: ICustomField<Path<T>>;
6
+ formControl: UseFormReturn<T>;
7
+ }
8
+ export declare const TextField: <T extends FieldValues>({ field, formControl, }: TextFieldProps<T>) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,14 @@
1
+ import { TextField as MuiTextField } from "@mui/material";
2
+ import React from "react";
3
+ import { Controller } from "react-hook-form";
4
+ export const TextField = ({ field, formControl, }) => {
5
+ const { control } = formControl;
6
+ return (React.createElement(Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (React.createElement(MuiTextField, { ...controlField, value: controlField.value || "", ...field.otherProps, label: field.label, type: field.type, fullWidth: true, required: field.required, error: !!error, helperText: error?.message, onChange: (e) => {
7
+ if (!e.target.value)
8
+ return controlField.onChange(undefined);
9
+ controlField.onChange(field.type === "number"
10
+ ? parseFloat(e.target.value)
11
+ : e.target.value);
12
+ } })) }));
13
+ };
14
+ //# sourceMappingURL=TextField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextField.js","sourceRoot":"","sources":["../../../src/components/fields/TextField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,YAAY,EAAE,MAAM,eAAe,CAAA;AACzD,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAoC,MAAM,iBAAiB,CAAA;AAQ9E,MAAM,CAAC,MAAM,SAAS,GAAG,CAAwB,EAC/C,KAAK,EACL,WAAW,GACO,EAAE,EAAE;IACtB,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;IAE/B,OAAO,CACL,oBAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,IAAe,EAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EACnC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAC1D,oBAAC,YAAY,OACP,YAAY,EAChB,KAAK,EAAE,YAAY,CAAC,KAAK,IAAI,EAAE,KAC3B,KAAK,CAAC,UAAU,EACpB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,SAAS,QACT,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,UAAU,EAAE,KAAK,EAAE,OAAO,EAC1B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;gBACd,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK;oBAAE,OAAO,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;gBAC5D,YAAY,CAAC,QAAQ,CACnB,KAAK,CAAC,IAAI,KAAK,QAAQ;oBACrB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;oBAC5B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACnB,CAAA;YACH,CAAC,GACD,CACH,GACD,CACH,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { FieldValues, Path, UseFormReturn } from "react-hook-form";
3
+ import { ICustomField } from "../../types";
4
+ interface TextareaFieldProps<T extends FieldValues> {
5
+ field: ICustomField<Path<T>>;
6
+ formControl: UseFormReturn<T>;
7
+ }
8
+ export declare const TextareaField: <T extends FieldValues>({ field, formControl, }: TextareaFieldProps<T>) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,8 @@
1
+ import { TextField as MuiTextField } from "@mui/material";
2
+ import React from "react";
3
+ import { Controller } from "react-hook-form";
4
+ export const TextareaField = ({ field, formControl, }) => {
5
+ const { control } = formControl;
6
+ return (React.createElement(Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => (React.createElement(MuiTextField, { ...controlField, value: controlField.value || "", ...field.otherProps, label: field.label, type: "text", fullWidth: true, multiline: true, rows: field.otherProps?.rows || 4, required: field.required, error: !!error, helperText: error?.message, onChange: controlField.onChange })) }));
7
+ };
8
+ //# sourceMappingURL=TextareaField.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextareaField.js","sourceRoot":"","sources":["../../../src/components/fields/TextareaField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,YAAY,EAAE,MAAM,eAAe,CAAA;AACzD,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,UAAU,EAAoC,MAAM,iBAAiB,CAAA;AAQ9E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAwB,EACnD,KAAK,EACL,WAAW,GACW,EAAE,EAAE;IAC1B,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;IAE/B,OAAO,CACL,oBAAC,UAAU,IACT,IAAI,EAAE,KAAK,CAAC,IAAe,EAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EACnC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,CAC1D,oBAAC,YAAY,OACP,YAAY,EAChB,KAAK,EAAE,YAAY,CAAC,KAAK,IAAI,EAAE,KAC3B,KAAK,CAAC,UAAU,EACpB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,IAAI,EAAC,MAAM,EACX,SAAS,QACT,SAAS,QACT,IAAI,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,IAAI,CAAC,EACjC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,KAAK,EAAE,CAAC,CAAC,KAAK,EACd,UAAU,EAAE,KAAK,EAAE,OAAO,EAC1B,QAAQ,EAAE,YAAY,CAAC,QAAQ,GAC/B,CACH,GACD,CACH,CAAA;AACH,CAAC,CAAA"}
package/dist/types.d.ts CHANGED
@@ -1,42 +1,57 @@
1
1
  import { ButtonProps, StackProps } from "@mui/material";
2
- import { CSSProperties } from "react";
3
2
  import { FieldPath, FieldValues, SubmitErrorHandler, SubmitHandler, UseFormReturn } from "react-hook-form";
4
- type SelectTypes = "single-select" | "multi-select";
5
- type BaseTypes = "text" | "number" | "date" | "file" | "password" | "textarea" | "switch" | "checkbox-group" | "radio-group" | "custom";
6
- export interface ISelectField {
7
- type: SelectTypes;
8
- list: TOption[];
9
- }
10
- export interface IOtherField {
11
- type: BaseTypes;
12
- list?: TOption[];
13
- component?: React.ComponentType<CustomComponentProps>;
14
- }
15
- export type ICustomField<T extends string> = {
3
+ export type TOption<T = any> = {
4
+ icon?: React.ReactNode;
5
+ label: string;
6
+ value: T;
7
+ };
8
+ type FileInputComponent = React.ReactNode | React.ElementType;
9
+ export interface ICustomFieldBase<T extends string> {
16
10
  label: string;
17
11
  name: T;
18
12
  required?: boolean;
19
13
  otherProps?: any;
20
14
  span?: number;
21
- } & ({
22
- type: SelectTypes;
15
+ }
16
+ export interface ITextField<T extends string> extends ICustomFieldBase<T> {
17
+ type: "text" | "number" | "password";
18
+ }
19
+ export interface ITextareaField<T extends string> extends ICustomFieldBase<T> {
20
+ type: "textarea";
21
+ }
22
+ export interface ISelectField<T extends string> extends ICustomFieldBase<T> {
23
+ type: "single-select" | "multi-select";
23
24
  list: TOption[];
24
- } | {
25
- type: BaseTypes;
26
- list?: TOption[];
27
- component?: React.ComponentType<CustomComponentProps>;
28
- });
29
- export type TOption<T = any> = {
30
- icon?: React.ReactNode;
31
- label: string;
32
- value: T;
33
- };
25
+ }
26
+ export interface IDateField<T extends string> extends ICustomFieldBase<T> {
27
+ type: "date";
28
+ }
29
+ export interface IFileField<T extends string> extends ICustomFieldBase<T> {
30
+ type: "file";
31
+ fileInputComponent?: FileInputComponent;
32
+ }
33
+ export interface ISwitchField<T extends string> extends ICustomFieldBase<T> {
34
+ type: "switch";
35
+ }
36
+ export interface ICheckboxGroupField<T extends string> extends ICustomFieldBase<T> {
37
+ type: "checkbox-group";
38
+ list: TOption[];
39
+ }
40
+ export interface IRadioGroupField<T extends string> extends ICustomFieldBase<T> {
41
+ type: "radio-group";
42
+ list: TOption[];
43
+ }
44
+ export interface ICustomComponentField<T extends string> extends ICustomFieldBase<T> {
45
+ type: "custom";
46
+ component: React.ComponentType<CustomComponentProps>;
47
+ }
48
+ export type ICustomField<T extends string> = ITextField<T> | ITextareaField<T> | ISelectField<T> | IDateField<T> | IFileField<T> | ISwitchField<T> | ICheckboxGroupField<T> | IRadioGroupField<T> | ICustomComponentField<T>;
34
49
  export type IFieldGroup<TFormValues extends FieldValues = FieldValues> = ICustomField<FieldPath<TFormValues>>[][];
35
50
  export interface ICustomForm<T extends FieldValues> {
36
51
  fieldsGroups: IFieldGroup<T>;
37
52
  onSubmit: [SubmitHandler<T>, SubmitErrorHandler<T>?];
38
53
  formControl: UseFormReturn<T>;
39
- actionButtonsPlacement?: CSSProperties["justifyContent"];
54
+ actionButtonsPlacement?: StackProps["justifyContent"];
40
55
  submitButton?: ButtonProps | boolean;
41
56
  resetButton?: ButtonProps | boolean;
42
57
  layout?: StackProps["direction"];
package/dist/types.js CHANGED
@@ -1,3 +1,2 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
3
2
  //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mui-custom-form",
3
- "version": "1.1.8",
3
+ "version": "1.1.9",
4
4
  "description": "A versatile React form component utilizing MUI components and react-hook-form.",
5
5
  "main": "dist/CustomForm.js",
6
6
  "types": "dist/CustomForm.d.ts",
@@ -12,6 +12,12 @@
12
12
  "type": "git",
13
13
  "url": "git+https://github.com/DevOsamaIslam/mui-custom-form.git"
14
14
  },
15
+ "author": "DevOsamaIslam",
16
+ "license": "MIT",
17
+ "bugs": {
18
+ "url": "https://github.com/DevOsamaIslam/mui-custom-form/issues"
19
+ },
20
+ "homepage": "https://github.com/DevOsamaIslam/mui-custom-form#readme",
15
21
  "keywords": [
16
22
  "react",
17
23
  "form",
@@ -19,15 +25,10 @@
19
25
  "react-hook-form",
20
26
  "customizable"
21
27
  ],
22
- "author": "Your Name",
23
- "license": "MIT",
24
- "bugs": {
25
- "url": "https://github.com/DevOsamaIslam/mui-custom-form/issues"
26
- },
27
- "homepage": "https://github.com/DevOsamaIslam/mui-custom-form#readme",
28
28
  "peerDependencies": {
29
29
  "@emotion/react": "^11.14.0",
30
30
  "@emotion/styled": "^11.14.0",
31
+ "@mui/x-date-pickers": "^8.3.1",
31
32
  "date-fns": "^4.1.0",
32
33
  "dayjs": "^1.11.13",
33
34
  "moment": "^2.30.1",
@@ -42,8 +43,8 @@
42
43
  "typescript": "^5.8.3"
43
44
  },
44
45
  "dependencies": {
46
+ "@mui/icons-material": "^7.1.0",
45
47
  "@mui/material": "^7.1.0",
46
- "@mui/x-date-pickers": "^8.3.1",
47
48
  "react-hook-form": "^7.56.3"
48
49
  }
49
50
  }