mui-custom-form 1.1.3 → 1.1.5

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,145 +1,124 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
14
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
15
- if (ar || !(i in from)) {
16
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
17
- ar[i] = from[i];
18
- }
19
- }
20
- return to.concat(ar || Array.prototype.slice.call(from));
21
- };
22
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
23
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
24
4
  };
25
5
  Object.defineProperty(exports, "__esModule", { value: true });
26
6
  exports.CustomForm = void 0;
27
7
  // CustomForm.tsx
28
- var material_1 = require("@mui/material");
29
- var x_date_pickers_1 = require("@mui/x-date-pickers");
30
- var react_1 = __importDefault(require("react"));
31
- var react_hook_form_1 = require("react-hook-form");
32
- var CustomForm = function (_a) {
33
- var fieldsGroups = _a.fieldsGroups, onSubmit = _a.onSubmit, formControl = _a.formControl, _b = _a.submitButton, submitButton = _b === void 0 ? true : _b, resetButton = _a.resetButton, actionButtonsPlacement = _a.actionButtonsPlacement, layout = _a.layout, otherProps = _a.otherProps;
34
- var control = formControl.control, setValue = formControl.setValue, reset = formControl.reset;
35
- var renderField = function (field) {
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;
14
+ const renderField = (field) => {
36
15
  switch (field.type) {
37
16
  case "text":
38
17
  case "number":
39
18
  case "password":
40
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: function (_a) {
41
- var controlField = _a.field, error = _a.fieldState.error;
42
- return (react_1.default.createElement(material_1.TextField, __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: function (e) {
43
- if (!e.target.value)
44
- return controlField.onChange(undefined);
45
- controlField.onChange(field.type === "number"
46
- ? parseFloat(e.target.value)
47
- : e.target.value);
48
- } })));
49
- } }));
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
+ } }))) }));
50
26
  case "textarea":
51
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: function (_a) {
52
- var _b;
53
- var controlField = _a.field, error = _a.fieldState.error;
54
- return (react_1.default.createElement(material_1.TextField, __assign({}, controlField, { value: controlField.value || "" }, field.otherProps, { label: field.label, type: "text", fullWidth: true, required: field.required, multiline: true, rows: ((_b = field.otherProps) === null || _b === void 0 ? void 0 : _b.rows) || 4, error: !!error, helperText: error === null || error === void 0 ? void 0 : error.message, onChange: controlField.onChange })));
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 })));
55
30
  } }));
56
31
  case "single-select":
57
32
  case "multi-select":
58
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: function (_a) {
59
- var _b;
60
- var controlField = _a.field, error = _a.fieldState.error;
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;
61
35
  return (react_1.default.createElement(material_1.FormControl, { fullWidth: true, error: !!error },
62
36
  react_1.default.createElement(material_1.InputLabel, { required: field.required }, field.label),
63
- react_1.default.createElement(material_1.Select, __assign({ label: field.label }, controlField, { value: controlField.value ||
64
- (field.type === "multi-select" ? [] : "") }, field.otherProps, { multiple: field.type === "multi-select" }), (_b = field.list) === null || _b === void 0 ? void 0 : _b.map(function (item) { return (react_1.default.createElement(material_1.MenuItem, { key: item.value, value: item.value }, item.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)))),
65
39
  error && react_1.default.createElement(material_1.FormHelperText, null, error.message)));
66
40
  } }));
67
41
  case "date":
68
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: function (_a) {
69
- var controlField = _a.field, error = _a.fieldState.error;
70
- return (react_1.default.createElement(x_date_pickers_1.DatePicker, __assign({}, controlField, { value: controlField.value || null }, field.otherProps, { label: field.label, onChange: function (date) { return controlField.onChange(date); }, renderInput: function (params) { return (react_1.default.createElement(material_1.TextField, __assign({}, params, { required: field.required, error: !!error, helperText: error === null || error === void 0 ? void 0 : error.message, fullWidth: true }))); } })));
71
- } }));
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 }))) }))) }));
72
43
  case "file":
73
44
  return (react_1.default.createElement(material_1.FormControl, { fullWidth: true, error: !!field.required },
74
45
  react_1.default.createElement(material_1.FormLabel, { component: "legend", required: field.required }, field.label),
75
46
  react_1.default.createElement(material_1.Button, { variant: "contained", component: "label" },
76
47
  "Upload File",
77
- react_1.default.createElement("input", __assign({ type: "file", hidden: true, onChange: function (e) {
78
- var fileValue = e.target.files && e.target.files.length > 0
48
+ react_1.default.createElement("input", Object.assign({ type: "file", hidden: true, onChange: (e) => {
49
+ const fileValue = e.target.files && e.target.files.length > 0
79
50
  ? e.target.files
80
51
  : undefined;
81
52
  setValue(field.name, fileValue);
82
53
  } }, field.otherProps)))));
83
54
  case "switch":
84
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: function (_a) {
85
- var controlField = _a.field, error = _a.fieldState.error;
86
- return (react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Switch, __assign({}, controlField, { checked: !!controlField.value, onChange: function (e) { return controlField.onChange(e.target.checked); } }, field.otherProps)), label: field.label }));
87
- } }));
55
+ 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 })) }));
88
56
  case "checkbox-group":
89
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: function (_a) {
90
- var _b;
91
- var controlField = _a.field, error = _a.fieldState.error;
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 } }) => {
58
+ var _a;
92
59
  return (react_1.default.createElement(material_1.FormControl, { component: "fieldset", error: !!error },
93
60
  react_1.default.createElement(material_1.FormLabel, { component: "legend", required: field.required }, field.label),
94
- react_1.default.createElement(material_1.Stack, { direction: "row", spacing: 2 }, (_b = field.list) === null || _b === void 0 ? void 0 : _b.map(function (option) {
61
+ react_1.default.createElement(material_1.Stack, { direction: "row", spacing: 2 }, (_a = field.list) === null || _a === void 0 ? void 0 : _a.map((option) => {
95
62
  var _a;
96
- return (react_1.default.createElement(material_1.FormControlLabel, { key: option.value, control: react_1.default.createElement(material_1.Checkbox, __assign({ checked: ((_a = controlField.value) === null || _a === void 0 ? void 0 : _a.includes(option.value)) || false, onChange: function (e) {
97
- var checked = e.target.checked;
98
- var value = option.value;
63
+ 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) => {
64
+ const checked = e.target.checked;
65
+ const value = option.value;
99
66
  if (checked) {
100
- controlField.onChange(__spreadArray(__spreadArray([], (controlField.value || []), true), [
67
+ controlField.onChange([
68
+ ...(controlField.value || []),
101
69
  value,
102
- ], false));
70
+ ]);
103
71
  }
104
72
  else {
105
- controlField.onChange((controlField.value || []).filter(function (v) { return v !== value; }));
73
+ controlField.onChange((controlField.value || []).filter((v) => v !== value));
106
74
  }
107
75
  } }, field.otherProps)), label: option.label }));
108
76
  })),
109
77
  error && react_1.default.createElement(material_1.FormHelperText, null, error.message)));
110
78
  } }));
111
79
  case "radio-group":
112
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: function (_a) {
113
- var _b, _c;
114
- var controlField = _a.field, error = _a.fieldState.error;
80
+ return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: ({ field: controlField, fieldState: { error } }) => {
81
+ var _a, _b;
115
82
  return (react_1.default.createElement(material_1.FormControl, { component: "fieldset", error: !!error },
116
83
  react_1.default.createElement(material_1.FormLabel, { component: "legend", required: field.required }, field.label),
117
- react_1.default.createElement(material_1.RadioGroup, __assign({}, controlField, { value: controlField.value || "", onChange: function (e) { return controlField.onChange(e.target.value); }, row: ((_b = field.otherProps) === null || _b === void 0 ? void 0 : _b.row) || false }), (_c = field.list) === null || _c === void 0 ? void 0 : _c.map(function (option) { return (react_1.default.createElement(material_1.FormControlLabel, { key: option.value, value: option.value, control: react_1.default.createElement(material_1.Radio, __assign({}, field.otherProps)), label: option.label })); })),
84
+ 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 })))),
118
85
  error && react_1.default.createElement(material_1.FormHelperText, null, error.message)));
119
86
  } }));
120
87
  case "custom":
121
88
  if (field.component) {
122
- var CustomComponent_1 = field.component;
123
- return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, rules: { required: field.required }, render: function (_a) {
124
- var controlField = _a.field, error = _a.fieldState.error;
125
- return (react_1.default.createElement(material_1.FormControl, { fullWidth: true, error: !!error },
126
- react_1.default.createElement(material_1.FormLabel, { component: "legend", required: field.required }, field.label),
127
- react_1.default.createElement(CustomComponent_1, __assign({ value: controlField.value, onChange: controlField.onChange }, field.otherProps)),
128
- error && react_1.default.createElement(material_1.FormHelperText, null, error.message)));
129
- } }));
89
+ const CustomComponent = field.component;
90
+ 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 },
91
+ react_1.default.createElement(material_1.FormLabel, { component: "legend", required: field.required }, field.label),
92
+ react_1.default.createElement(CustomComponent, Object.assign({ value: controlField.value, onChange: controlField.onChange }, field.otherProps)),
93
+ error && react_1.default.createElement(material_1.FormHelperText, null, error.message))) }));
130
94
  }
131
95
  return null;
132
96
  default:
133
97
  return null;
134
98
  }
135
99
  };
136
- var submitButtonProps = submitButton && submitButton !== true ? submitButton : {};
137
- var resetButtonProps = resetButton && resetButton !== true ? resetButton : {};
138
- return (react_1.default.createElement(material_1.Stack, __assign({ component: "form", onSubmit: formControl.handleSubmit(onSubmit[0], onSubmit[1]), noValidate: true, direction: layout }, otherProps, { spacing: 3 }),
139
- fieldsGroups.map(function (fields, rowIndex) { return (react_1.default.createElement(material_1.Grid2, { container: true, key: rowIndex, spacing: 2, className: "debug" }, fields.map(function (field, fieldIndex) { return (react_1.default.createElement(material_1.Grid2, { key: fieldIndex, size: field.span || 12 }, renderField(field))); }))); }),
100
+ const submitButtonProps = submitButton && submitButton !== true ? submitButton : {};
101
+ const resetButtonProps = resetButton && resetButton !== true ? resetButton : {};
102
+ // Function to calculate spans dynamically
103
+ const calculateSpan = (fields) => {
104
+ const totalDefinedSpan = fields.reduce((acc, field) => acc + (field.span || 0), 0);
105
+ const autoSpanFields = fields.filter((field) => !field.span).length;
106
+ const remainingSpan = 12 - totalDefinedSpan;
107
+ const calculatedSpan = autoSpanFields > 0 ? Math.floor(remainingSpan / autoSpanFields) : 12;
108
+ return { calculatedSpan, autoSpanFields };
109
+ };
110
+ 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 }),
111
+ fieldsGroups.map((fields, rowIndex) => {
112
+ const { calculatedSpan, autoSpanFields } = calculateSpan(fields);
113
+ 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
114
+ ? field.span
115
+ : autoSpanFields > 0
116
+ ? calculatedSpan
117
+ : 12 }, renderField(field))))));
118
+ }),
140
119
  react_1.default.createElement(material_1.Stack, { direction: "row", justifyContent: actionButtonsPlacement || "flex-end", spacing: 2 },
141
- resetButton && (react_1.default.createElement(material_1.Button, __assign({ type: "reset", variant: "contained", onClick: function () { return reset(); } }, resetButtonProps), "Reset")),
142
- submitButton && (react_1.default.createElement(material_1.Button, __assign({ type: "submit", variant: "contained" }, submitButtonProps), "Submit")))));
120
+ resetButton && (react_1.default.createElement(material_1.Button, Object.assign({ type: "reset", variant: "contained", onClick: () => reset() }, resetButtonProps), "Reset")),
121
+ submitButton && (react_1.default.createElement(material_1.Button, Object.assign({ type: "submit", variant: "contained" }, submitButtonProps), "Submit")))));
143
122
  };
144
123
  exports.CustomForm = CustomForm;
145
124
  //# sourceMappingURL=CustomForm.js.map
package/dist/types.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ButtonProps, StackProps } from "@mui/material";
2
2
  import { CSSProperties } from "react";
3
- import { FieldValues, SubmitErrorHandler, SubmitHandler, useForm } from "react-hook-form";
3
+ import { FieldValues, SubmitErrorHandler, SubmitHandler, UseFormReturn } from "react-hook-form";
4
4
  type name<T> = T extends string ? string : keyof T;
5
5
  type SelectTypes = "single-select" | "multi-select";
6
6
  type BaseTypes = "text" | "number" | "date" | "file" | "password" | "textarea" | "switch" | "checkbox-group" | "radio-group" | "custom";
@@ -36,7 +36,7 @@ export type IFieldGroup<T = any> = ICustomField<T>[][];
36
36
  export interface ICustomForm<T extends FieldValues> {
37
37
  fieldsGroups: IFieldGroup<any>;
38
38
  onSubmit: [SubmitHandler<T>, SubmitErrorHandler<T>?];
39
- formControl: ReturnType<typeof useForm<T>>;
39
+ formControl: UseFormReturn<T>;
40
40
  actionButtonsPlacement?: CSSProperties["justifyContent"];
41
41
  submitButton?: ButtonProps | boolean;
42
42
  resetButton?: ButtonProps | boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mui-custom-form",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
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",
@@ -26,19 +26,24 @@
26
26
  },
27
27
  "homepage": "https://github.com/DevOsamaIslam/mui-custom-form#readme",
28
28
  "peerDependencies": {
29
- "@mui/material": "^6.1.1",
30
- "@mui/x-date-pickers": "^7.15.0",
31
- "react-hook-form": "^7.45.2",
29
+ "@emotion/react": "^11.14.0",
30
+ "@emotion/styled": "^11.14.0",
32
31
  "date-fns": "^4.1.0",
33
- "dayjs": "^1.11.9",
34
- "moment": "^2.29.4"
32
+ "dayjs": "^1.11.13",
33
+ "moment": "^2.30.1",
34
+ "react": "^18.0.0 || ^19.0.0",
35
+ "react-hook-form": "^7.56.3",
36
+ "react-dom": "^18.0.0 || ^19.0.0"
35
37
  },
36
38
  "devDependencies": {
37
- "@emotion/react": "^11.11.1",
38
- "@emotion/styled": "^11.11.0",
39
- "@types/node": "^22.7.0",
40
- "@types/react": "^18.3.9",
41
- "typescript": "^5.6.2"
39
+ "@types/node": "^22.15.18",
40
+ "@types/react": "^18.0.0 || ^19.0.0",
41
+ "@types/react-dom": "^18.0.0 || ^19.0.0",
42
+ "typescript": "^5.8.3"
42
43
  },
43
- "dependencies": {}
44
+ "dependencies": {
45
+ "react-hook-form": "^7.56.3",
46
+ "@mui/material": "^7.1.0",
47
+ "@mui/x-date-pickers": "^8.3.1"
48
+ }
44
49
  }