mui-custom-form 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/dist/CustomForm.d.ts +0 -25
- package/dist/CustomForm.js +0 -75
- package/src/CustomForm.tsx +0 -171
- package/tsconfig.json +0 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mui-custom-form",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "A versatile React form component utilizing MUI components and react-hook-form.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "git+https://github.com/DevOsamaIslam/
|
|
13
|
+
"url": "git+https://github.com/DevOsamaIslam/mui-custom-form.git"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
16
16
|
"react",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"author": "Your Name",
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"bugs": {
|
|
25
|
-
"url": "https://github.com/
|
|
25
|
+
"url": "https://github.com/DevOsamaIslam/mui-custom-form/issues"
|
|
26
26
|
},
|
|
27
|
-
"homepage": "https://github.com/
|
|
27
|
+
"homepage": "https://github.com/DevOsamaIslam/mui-custom-form#readme",
|
|
28
28
|
"peerDependencies": {
|
|
29
29
|
"@mui/material": "5.14.2",
|
|
30
30
|
"@mui/x-date-pickers": "^6.10.2",
|
package/dist/CustomForm.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { useForm } from "react-hook-form";
|
|
2
|
-
import React from "react";
|
|
3
|
-
export type $option<T = any> = {
|
|
4
|
-
icon?: React.ReactNode;
|
|
5
|
-
label: string;
|
|
6
|
-
value: T;
|
|
7
|
-
};
|
|
8
|
-
export interface ICustomField<T = string> {
|
|
9
|
-
label: string;
|
|
10
|
-
name: T extends string ? string : keyof T;
|
|
11
|
-
type: "text" | "number" | "single-select" | "multi-select" | "date" | "file";
|
|
12
|
-
list?: $option[];
|
|
13
|
-
required?: boolean;
|
|
14
|
-
otherProps?: any;
|
|
15
|
-
span?: number;
|
|
16
|
-
}
|
|
17
|
-
interface ICustomForm {
|
|
18
|
-
fieldsGroups: ICustomField<any>[][];
|
|
19
|
-
onSubmit: ReturnType<this["formControl"]["handleSubmit"]>;
|
|
20
|
-
formControl: ReturnType<typeof useForm>;
|
|
21
|
-
submitButton?: boolean;
|
|
22
|
-
otherProps?: any;
|
|
23
|
-
}
|
|
24
|
-
export declare const CustomForm: React.FC<ICustomForm>;
|
|
25
|
-
export {};
|
package/dist/CustomForm.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.CustomForm = void 0;
|
|
18
|
-
var material_1 = require("@mui/material");
|
|
19
|
-
var x_date_pickers_1 = require("@mui/x-date-pickers");
|
|
20
|
-
var react_hook_form_1 = require("react-hook-form");
|
|
21
|
-
var react_1 = __importDefault(require("react"));
|
|
22
|
-
var CustomForm = function (_a) {
|
|
23
|
-
var fieldsGroups = _a.fieldsGroups, onSubmit = _a.onSubmit, formControl = _a.formControl, _b = _a.submitButton, submitButton = _b === void 0 ? true : _b, otherProps = _a.otherProps;
|
|
24
|
-
var control = formControl.control, setValue = formControl.setValue;
|
|
25
|
-
var renderField = function (field) {
|
|
26
|
-
switch (field.type) {
|
|
27
|
-
case "text":
|
|
28
|
-
case "number":
|
|
29
|
-
return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, render: function (_a) {
|
|
30
|
-
var controlField = _a.field, error = _a.fieldState.error;
|
|
31
|
-
return (react_1.default.createElement(material_1.TextField, __assign({}, controlField, 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 })));
|
|
32
|
-
} }));
|
|
33
|
-
case "single-select":
|
|
34
|
-
case "multi-select":
|
|
35
|
-
return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, render: function (_a) {
|
|
36
|
-
var _b;
|
|
37
|
-
var controlField = _a.field, error = _a.fieldState.error;
|
|
38
|
-
return (react_1.default.createElement(material_1.FormControl, { fullWidth: true, error: !!error },
|
|
39
|
-
react_1.default.createElement(material_1.InputLabel, { required: field.required }, field.label),
|
|
40
|
-
react_1.default.createElement(material_1.Select, __assign({}, controlField, 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)); })),
|
|
41
|
-
error && react_1.default.createElement(material_1.FormHelperText, null, error.message)));
|
|
42
|
-
} }));
|
|
43
|
-
case "date":
|
|
44
|
-
return (react_1.default.createElement(react_hook_form_1.Controller, { name: field.name, control: control, render: function (_a) {
|
|
45
|
-
var controlField = _a.field, error = _a.fieldState.error;
|
|
46
|
-
return (react_1.default.createElement(x_date_pickers_1.DatePicker, __assign({}, controlField, field.otherProps, { label: field.label, onChange: controlField.onChange, slotProps: {
|
|
47
|
-
textField: {
|
|
48
|
-
required: field.required,
|
|
49
|
-
error: !!error,
|
|
50
|
-
helperText: error === null || error === void 0 ? void 0 : error.message,
|
|
51
|
-
fullWidth: true,
|
|
52
|
-
},
|
|
53
|
-
} })));
|
|
54
|
-
} }));
|
|
55
|
-
case "file":
|
|
56
|
-
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
57
|
-
react_1.default.createElement(material_1.FormLabel, { component: "legend" }, field.label),
|
|
58
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", component: "label" },
|
|
59
|
-
"Upload File",
|
|
60
|
-
react_1.default.createElement("input", { type: "file", hidden: true, onChange: function (e) {
|
|
61
|
-
// Set the value to either the File instance or undefined
|
|
62
|
-
var fileValue = e.target.files && e.target.files.length > 0
|
|
63
|
-
? e.target.files[0]
|
|
64
|
-
: undefined;
|
|
65
|
-
setValue(field.name, fileValue);
|
|
66
|
-
} }))));
|
|
67
|
-
default:
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
return (react_1.default.createElement(material_1.Stack, __assign({ component: "form", onSubmit: onSubmit, noValidate: true }, otherProps, { spacing: 3 }),
|
|
72
|
-
react_1.default.createElement(material_1.Grid, { container: true, spacing: 1 }, fieldsGroups.map(function (fields, rowIndex) { return (react_1.default.createElement(material_1.Grid, { container: true, item: true, key: rowIndex, spacing: 2 }, fields.map(function (field, fieldIndex) { return (react_1.default.createElement(material_1.Grid, { item: true, key: fieldIndex, xs: field.span || true }, renderField(field))); }))); })),
|
|
73
|
-
submitButton && (react_1.default.createElement(material_1.Button, { type: "submit", variant: "contained" }, "Submit"))));
|
|
74
|
-
};
|
|
75
|
-
exports.CustomForm = CustomForm;
|
package/src/CustomForm.tsx
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Button,
|
|
3
|
-
FormControl,
|
|
4
|
-
FormHelperText,
|
|
5
|
-
FormLabel,
|
|
6
|
-
Grid,
|
|
7
|
-
InputLabel,
|
|
8
|
-
MenuItem,
|
|
9
|
-
Select,
|
|
10
|
-
Stack,
|
|
11
|
-
TextField,
|
|
12
|
-
} from "@mui/material"
|
|
13
|
-
import { DatePicker } from "@mui/x-date-pickers"
|
|
14
|
-
import { Controller } from "react-hook-form"
|
|
15
|
-
import { useForm } from "react-hook-form"
|
|
16
|
-
import React from "react"
|
|
17
|
-
|
|
18
|
-
export type $option<T = any> = {
|
|
19
|
-
icon?: React.ReactNode
|
|
20
|
-
label: string
|
|
21
|
-
value: T
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface ICustomField<T = string> {
|
|
25
|
-
label: string
|
|
26
|
-
name: T extends string ? string : keyof T
|
|
27
|
-
type: "text" | "number" | "single-select" | "multi-select" | "date" | "file"
|
|
28
|
-
list?: $option[]
|
|
29
|
-
required?: boolean // This can be further refined to your validation rules
|
|
30
|
-
otherProps?: any
|
|
31
|
-
span?: number // A number between 1 and 12, representing MUI's grid system
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
interface ICustomForm {
|
|
35
|
-
fieldsGroups: ICustomField<any>[][]
|
|
36
|
-
onSubmit: ReturnType<this["formControl"]["handleSubmit"]>
|
|
37
|
-
formControl: ReturnType<typeof useForm>
|
|
38
|
-
submitButton?: boolean
|
|
39
|
-
otherProps?: any
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export const CustomForm: React.FC<ICustomForm> = ({
|
|
43
|
-
fieldsGroups,
|
|
44
|
-
onSubmit,
|
|
45
|
-
formControl,
|
|
46
|
-
submitButton = true,
|
|
47
|
-
otherProps,
|
|
48
|
-
}) => {
|
|
49
|
-
const { control, setValue } = formControl
|
|
50
|
-
|
|
51
|
-
const renderField = (field: ICustomField<string>) => {
|
|
52
|
-
switch (field.type) {
|
|
53
|
-
case "text":
|
|
54
|
-
case "number":
|
|
55
|
-
return (
|
|
56
|
-
<Controller
|
|
57
|
-
name={field.name}
|
|
58
|
-
control={control}
|
|
59
|
-
render={({ field: controlField, fieldState: { error } }) => (
|
|
60
|
-
<TextField
|
|
61
|
-
{...controlField}
|
|
62
|
-
{...field.otherProps}
|
|
63
|
-
label={field.label}
|
|
64
|
-
type={field.type}
|
|
65
|
-
fullWidth
|
|
66
|
-
required={field.required}
|
|
67
|
-
error={!!error}
|
|
68
|
-
helperText={error?.message}
|
|
69
|
-
/>
|
|
70
|
-
)}
|
|
71
|
-
/>
|
|
72
|
-
)
|
|
73
|
-
case "single-select":
|
|
74
|
-
case "multi-select":
|
|
75
|
-
return (
|
|
76
|
-
<Controller
|
|
77
|
-
name={field.name}
|
|
78
|
-
control={control}
|
|
79
|
-
render={({ field: controlField, fieldState: { error } }) => (
|
|
80
|
-
<FormControl fullWidth error={!!error}>
|
|
81
|
-
<InputLabel required={field.required}>{field.label}</InputLabel>
|
|
82
|
-
<Select
|
|
83
|
-
{...controlField}
|
|
84
|
-
{...field.otherProps}
|
|
85
|
-
multiple={field.type === "multi-select"}>
|
|
86
|
-
{field.list?.map((item) => (
|
|
87
|
-
<MenuItem key={item.value} value={item.value}>
|
|
88
|
-
{item.label}
|
|
89
|
-
</MenuItem>
|
|
90
|
-
))}
|
|
91
|
-
</Select>
|
|
92
|
-
{error && <FormHelperText>{error.message}</FormHelperText>}
|
|
93
|
-
</FormControl>
|
|
94
|
-
)}
|
|
95
|
-
/>
|
|
96
|
-
)
|
|
97
|
-
case "date":
|
|
98
|
-
return (
|
|
99
|
-
<Controller
|
|
100
|
-
name={field.name}
|
|
101
|
-
control={control}
|
|
102
|
-
render={({ field: controlField, fieldState: { error } }) => (
|
|
103
|
-
<DatePicker
|
|
104
|
-
{...controlField}
|
|
105
|
-
{...field.otherProps}
|
|
106
|
-
label={field.label}
|
|
107
|
-
onChange={controlField.onChange}
|
|
108
|
-
slotProps={{
|
|
109
|
-
textField: {
|
|
110
|
-
required: field.required,
|
|
111
|
-
error: !!error,
|
|
112
|
-
helperText: error?.message,
|
|
113
|
-
fullWidth: true,
|
|
114
|
-
},
|
|
115
|
-
}}
|
|
116
|
-
/>
|
|
117
|
-
)}
|
|
118
|
-
/>
|
|
119
|
-
)
|
|
120
|
-
case "file":
|
|
121
|
-
return (
|
|
122
|
-
<>
|
|
123
|
-
<FormLabel component="legend">{field.label}</FormLabel>
|
|
124
|
-
<Button variant="contained" component="label">
|
|
125
|
-
Upload File
|
|
126
|
-
<input
|
|
127
|
-
type="file"
|
|
128
|
-
hidden
|
|
129
|
-
onChange={(e) => {
|
|
130
|
-
// Set the value to either the File instance or undefined
|
|
131
|
-
const fileValue =
|
|
132
|
-
e.target.files && e.target.files.length > 0
|
|
133
|
-
? e.target.files[0]
|
|
134
|
-
: undefined
|
|
135
|
-
setValue(field.name, fileValue)
|
|
136
|
-
}}
|
|
137
|
-
/>
|
|
138
|
-
</Button>
|
|
139
|
-
</>
|
|
140
|
-
)
|
|
141
|
-
default:
|
|
142
|
-
return null
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return (
|
|
147
|
-
<Stack
|
|
148
|
-
component="form"
|
|
149
|
-
onSubmit={onSubmit}
|
|
150
|
-
noValidate
|
|
151
|
-
{...otherProps}
|
|
152
|
-
spacing={3}>
|
|
153
|
-
<Grid container spacing={1}>
|
|
154
|
-
{fieldsGroups.map((fields, rowIndex) => (
|
|
155
|
-
<Grid container item key={rowIndex} spacing={2}>
|
|
156
|
-
{fields.map((field, fieldIndex) => (
|
|
157
|
-
<Grid item key={fieldIndex} xs={field.span || true}>
|
|
158
|
-
{renderField(field as unknown as ICustomField<string>)}
|
|
159
|
-
</Grid>
|
|
160
|
-
))}
|
|
161
|
-
</Grid>
|
|
162
|
-
))}
|
|
163
|
-
</Grid>
|
|
164
|
-
{submitButton && (
|
|
165
|
-
<Button type="submit" variant="contained">
|
|
166
|
-
Submit
|
|
167
|
-
</Button>
|
|
168
|
-
)}
|
|
169
|
-
</Stack>
|
|
170
|
-
)
|
|
171
|
-
}
|
package/tsconfig.json
DELETED