@akinon/akiform-builder 0.4.0 → 0.6.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/cjs/FormBuilderWatch.d.ts.map +1 -0
- package/dist/cjs/FormBuilderWatch.js +72 -0
- package/dist/cjs/RenderField.d.ts.map +1 -0
- package/dist/cjs/RenderField.js +45 -0
- package/dist/cjs/component.d.ts.map +1 -0
- package/dist/cjs/component.js +46 -0
- package/dist/cjs/hook.d.ts.map +1 -0
- package/dist/cjs/hook.js +38 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +26 -0
- package/dist/cjs/transformers/index.d.ts.map +1 -0
- package/dist/cjs/transformers/index.js +77 -0
- package/dist/cjs/transformers/types.d.ts.map +1 -0
- package/dist/cjs/transformers/types.js +18 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +2 -0
- package/dist/esm/FormBuilderWatch.d.ts +16 -0
- package/dist/esm/FormBuilderWatch.d.ts.map +1 -0
- package/dist/esm/FormBuilderWatch.js +68 -0
- package/dist/esm/RenderField.d.ts +5 -0
- package/dist/esm/RenderField.d.ts.map +1 -0
- package/dist/esm/RenderField.js +41 -0
- package/dist/esm/component.d.ts +4 -0
- package/dist/esm/component.d.ts.map +1 -0
- package/dist/esm/component.js +42 -0
- package/dist/esm/hook.d.ts +3 -0
- package/dist/esm/hook.d.ts.map +1 -0
- package/dist/esm/hook.js +34 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/transformers/index.d.ts +4 -0
- package/dist/esm/transformers/index.d.ts.map +1 -0
- package/dist/esm/transformers/index.js +73 -0
- package/dist/esm/transformers/types.d.ts +22 -0
- package/dist/esm/transformers/types.d.ts.map +1 -0
- package/dist/esm/transformers/types.js +15 -0
- package/dist/esm/types.d.ts +82 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +1 -0
- package/package.json +14 -8
- package/dist/FormBuilderWatch.d.ts.map +0 -1
- package/dist/RenderField.d.ts.map +0 -1
- package/dist/component.d.ts.map +0 -1
- package/dist/hook.d.ts.map +0 -1
- package/dist/index.cjs +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -3129
- package/dist/transformers/index.d.ts.map +0 -1
- package/dist/transformers/types.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- /package/dist/{FormBuilderWatch.d.ts → cjs/FormBuilderWatch.d.ts} +0 -0
- /package/dist/{RenderField.d.ts → cjs/RenderField.d.ts} +0 -0
- /package/dist/{component.d.ts → cjs/component.d.ts} +0 -0
- /package/dist/{hook.d.ts → cjs/hook.d.ts} +0 -0
- /package/dist/{index.d.ts → cjs/index.d.ts} +0 -0
- /package/dist/{transformers → cjs/transformers}/index.d.ts +0 -0
- /package/dist/{transformers → cjs/transformers}/types.d.ts +0 -0
- /package/dist/{types.d.ts → cjs/types.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormBuilderWatch.d.ts","sourceRoot":"","sources":["../../src/FormBuilderWatch.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,KAAK,qBAAqB,GAAG;IAC3B,aAAa,EAAE,SAAS,EAAE,CAAC;IAE3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,iDAI1B,qBAAqB,sBAgFvB,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FormBuilderWatch = void 0;
|
|
4
|
+
const akiform_1 = require("@akinon/akiform");
|
|
5
|
+
const dayjs_1 = require("dayjs");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const RenderField_1 = require("./RenderField");
|
|
8
|
+
/**
|
|
9
|
+
* Reasons why seperate FormBuilderWatch component is created from FormBuilder:
|
|
10
|
+
* 1. FormBuilderWatch is a controlled component, value of form fields is controlled. In any given time, value of any field can be forced from parent. It's directly working with value instead of defaultValues. Also there is no way to change defaultValues after first render.
|
|
11
|
+
* 2. FormBuilderWatch is watching form changes and calls the given callback function. It's not using form methods like handleSubmit, reset, etc.
|
|
12
|
+
* 3. It's meticulously designed to not create loop. Since it's controlled and watching form changes, it's easy to create infinite loop. For example, callback can be called as result of form change, and parent can react to this change by returning same values to form.
|
|
13
|
+
*/
|
|
14
|
+
const FormBuilderWatch = ({ builderFields, handleChange, isDebounced = false }) => {
|
|
15
|
+
const { control, setValue } = (0, akiform_1.useForm)();
|
|
16
|
+
const formWatch = (0, akiform_1.useWatch)({ control });
|
|
17
|
+
react_1.default.useEffect(() => {
|
|
18
|
+
// if formWatch are empty object, it means it's the first render. Do not call handleChange
|
|
19
|
+
if (!Object.keys(formWatch).length)
|
|
20
|
+
return;
|
|
21
|
+
// if item.value is same with formWatch do not call handleChange to prevent infinite loop
|
|
22
|
+
const isSame = builderFields.every(field => {
|
|
23
|
+
// if field type is datepicker, convert the formWatch value to string before comparing
|
|
24
|
+
if (field.type === 'datepicker') {
|
|
25
|
+
if (formWatch[field.key] === null) {
|
|
26
|
+
formWatch[field.key] = undefined;
|
|
27
|
+
}
|
|
28
|
+
if (!formWatch[field.key]) {
|
|
29
|
+
return field.value === formWatch[field.key];
|
|
30
|
+
}
|
|
31
|
+
const compareResult = (0, dayjs_1.default)(field.value).isSame((0, dayjs_1.default)(formWatch[field.key]), 'day');
|
|
32
|
+
return compareResult;
|
|
33
|
+
}
|
|
34
|
+
// TODO write tests for this part because it can be a source of bug
|
|
35
|
+
// if watch value is object, should stringify before comparing
|
|
36
|
+
const isWatchValueObject = typeof formWatch[field.key] === 'object';
|
|
37
|
+
if (isWatchValueObject) {
|
|
38
|
+
return (JSON.stringify(field.value) === JSON.stringify(formWatch[field.key]));
|
|
39
|
+
}
|
|
40
|
+
return field.value === formWatch[field.key];
|
|
41
|
+
});
|
|
42
|
+
if (isSame) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (!isDebounced) {
|
|
46
|
+
handleChange(formWatch);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const timeout = setTimeout(() => {
|
|
50
|
+
handleChange(formWatch);
|
|
51
|
+
}, 1000);
|
|
52
|
+
return () => {
|
|
53
|
+
clearTimeout(timeout);
|
|
54
|
+
};
|
|
55
|
+
}, [formWatch]);
|
|
56
|
+
// value of fields can be set by parent
|
|
57
|
+
react_1.default.useEffect(() => {
|
|
58
|
+
builderFields.forEach(field => {
|
|
59
|
+
const { key, value, type } = field;
|
|
60
|
+
// if type is datepicker and value is set, convert it to dayjs
|
|
61
|
+
if (type === 'datepicker' && value) {
|
|
62
|
+
setValue(key, (0, dayjs_1.default)(value));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
setValue(key, value);
|
|
66
|
+
});
|
|
67
|
+
}, [builderFields]);
|
|
68
|
+
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
69
|
+
react_1.default.createElement("div", { className: "form-builder" },
|
|
70
|
+
react_1.default.createElement(akiform_1.Akiform, null, builderFields.map(field => (0, RenderField_1.RenderField)(field, control))))));
|
|
71
|
+
};
|
|
72
|
+
exports.FormBuilderWatch = FormBuilderWatch;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenderField.d.ts","sourceRoot":"","sources":["../../src/RenderField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,iBAAiB,CAAC;AAMpD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAGL,SAAS,EAIV,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,WAAW,UAAW,SAAS,WAAW,OAAO,6DA+F7D,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RenderField = void 0;
|
|
4
|
+
const akiform_1 = require("@akinon/akiform");
|
|
5
|
+
const ui_checkbox_1 = require("@akinon/ui-checkbox");
|
|
6
|
+
const ui_date_picker_1 = require("@akinon/ui-date-picker");
|
|
7
|
+
const ui_input_1 = require("@akinon/ui-input");
|
|
8
|
+
const ui_input_number_1 = require("@akinon/ui-input-number");
|
|
9
|
+
const ui_select_1 = require("@akinon/ui-select");
|
|
10
|
+
const react_1 = require("react");
|
|
11
|
+
const RenderField = (field, control) => {
|
|
12
|
+
var _a, _b;
|
|
13
|
+
switch (field.type) {
|
|
14
|
+
case 'input':
|
|
15
|
+
const inputField = field;
|
|
16
|
+
return (react_1.default.createElement(akiform_1.FormItem, { key: inputField.key, name: inputField.key, label: inputField.label, control: control }, ((_a = inputField.props) === null || _a === void 0 ? void 0 : _a.mode) !== 'multiple' ? (react_1.default.createElement(ui_input_1.Input, { placeholder: inputField.placeholder })) : (react_1.default.createElement(ui_select_1.Select, { mode: "tags", placeholder: inputField.placeholder }))));
|
|
17
|
+
case 'number':
|
|
18
|
+
const numberField = field;
|
|
19
|
+
return (react_1.default.createElement(akiform_1.FormItem, { key: numberField.key, name: numberField.key, label: numberField.label, control: control },
|
|
20
|
+
react_1.default.createElement(ui_input_number_1.InputNumber, { keyboard: false, placeholder: numberField.placeholder })));
|
|
21
|
+
case 'select':
|
|
22
|
+
const selectField = field;
|
|
23
|
+
return (react_1.default.createElement(akiform_1.FormItem, { key: selectField.key, name: selectField.key, label: selectField.label, control: control },
|
|
24
|
+
react_1.default.createElement(ui_select_1.Select, { mode: (_b = selectField.props) === null || _b === void 0 ? void 0 : _b.mode, options: selectField.options, placeholder: selectField.placeholder })));
|
|
25
|
+
case 'checkbox':
|
|
26
|
+
const checkboxField = field;
|
|
27
|
+
const { labelRightAligned } = checkboxField.props || {};
|
|
28
|
+
return (react_1.default.createElement(akiform_1.FormItem, { key: checkboxField.key, name: checkboxField.key, initialValue: checkboxField.value, control: control, valuePropName: "checked",
|
|
29
|
+
// if labelRightAligned is true, don't pass label prop to Checkbox
|
|
30
|
+
label: labelRightAligned ? '' : checkboxField.label },
|
|
31
|
+
react_1.default.createElement(ui_checkbox_1.Checkbox, null, labelRightAligned ? checkboxField.label : '')));
|
|
32
|
+
case 'datepicker':
|
|
33
|
+
const datePickerField = field;
|
|
34
|
+
return (react_1.default.createElement(akiform_1.FormItem, { key: datePickerField.key, name: datePickerField.key, label: datePickerField.label, control: control },
|
|
35
|
+
react_1.default.createElement(ui_date_picker_1.DatePicker, { placeholder: datePickerField.placeholder })));
|
|
36
|
+
case 'field-array':
|
|
37
|
+
if (field.config) {
|
|
38
|
+
return (react_1.default.createElement(react_1.default.Fragment, { key: field.key }, field.config.fields.map(nestedField => (0, exports.RenderField)(nestedField, control))));
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
return 'unsupported field type';
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
exports.RenderField = RenderField;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/component.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA0ClD,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.FormBuilder = void 0;
|
|
15
|
+
const akiform_1 = require("@akinon/akiform");
|
|
16
|
+
const akival = require("@akinon/akival");
|
|
17
|
+
const react_1 = require("react");
|
|
18
|
+
const RenderField_1 = require("./RenderField");
|
|
19
|
+
const FormBuilder = (_a) => {
|
|
20
|
+
var { builderFields, children } = _a, formProps = __rest(_a, ["builderFields", "children"]);
|
|
21
|
+
const validationSchema = akival.object(builderFields.reduce((schema, field) => {
|
|
22
|
+
if (field.type !== 'field-array' && field.validation) {
|
|
23
|
+
return Object.assign(Object.assign({}, schema), { [field.key]: field.validation });
|
|
24
|
+
}
|
|
25
|
+
return schema;
|
|
26
|
+
}, {}));
|
|
27
|
+
const formMethods = (0, akiform_1.useForm)({
|
|
28
|
+
defaultValues: builderFields.reduce((defaultValues, field) => {
|
|
29
|
+
if (field.defaultValue !== undefined) {
|
|
30
|
+
defaultValues[field.key] = field.defaultValue;
|
|
31
|
+
}
|
|
32
|
+
return defaultValues;
|
|
33
|
+
}, {}),
|
|
34
|
+
resolver: (0, akiform_1.akivalResolver)(validationSchema)
|
|
35
|
+
});
|
|
36
|
+
const { control } = formMethods;
|
|
37
|
+
return (react_1.default.createElement(akiform_1.Akiform, Object.assign({}, formProps, { onFinish: formMethods.handleSubmit(() => {
|
|
38
|
+
var _a;
|
|
39
|
+
return (_a = formProps.onFinish) === null || _a === void 0 ? void 0 : _a.call(formProps, formMethods.getValues());
|
|
40
|
+
}, () => {
|
|
41
|
+
return console.error('Form validation failed');
|
|
42
|
+
}) }),
|
|
43
|
+
builderFields.map(field => (0, RenderField_1.RenderField)(field, control)),
|
|
44
|
+
react_1.default.createElement("div", null, children)));
|
|
45
|
+
};
|
|
46
|
+
exports.FormBuilder = FormBuilder;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/hook.ts"],"names":[],"mappings":"AAQA,OAAO,EAAmB,kBAAkB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzE,eAAO,MAAM,cAAc,WAAY,SAAS,EAAE,KAAG,kBAkCpD,CAAC"}
|
package/dist/cjs/hook.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.useFormBuilder = void 0;
|
|
15
|
+
const akiform_1 = require("@akinon/akiform");
|
|
16
|
+
const akival = require("@akinon/akival");
|
|
17
|
+
const useFormBuilder = (fields) => {
|
|
18
|
+
const validationSchema = akival.object(fields.reduce((schema, field) => {
|
|
19
|
+
if (field.type !== 'field-array' && field.validation) {
|
|
20
|
+
return Object.assign(Object.assign({}, schema), { [field.key]: field.validation });
|
|
21
|
+
}
|
|
22
|
+
return schema;
|
|
23
|
+
}, {}));
|
|
24
|
+
const formMethods = (0, akiform_1.useForm)({
|
|
25
|
+
resolver: (0, akiform_1.akivalResolver)(validationSchema)
|
|
26
|
+
});
|
|
27
|
+
const fieldArrays = fields
|
|
28
|
+
.filter((field) => field.type === 'field-array')
|
|
29
|
+
.map(fieldArray => {
|
|
30
|
+
const _a = (0, akiform_1.useFieldArray)({
|
|
31
|
+
control: formMethods.control,
|
|
32
|
+
name: fieldArray.config.name
|
|
33
|
+
}), { fields: nestedFields } = _a, arrayHelpers = __rest(_a, ["fields"]);
|
|
34
|
+
return Object.assign(Object.assign(Object.assign({}, fieldArray), { name: fieldArray.config.name, fields: nestedFields }), arrayHelpers);
|
|
35
|
+
});
|
|
36
|
+
return Object.assign(Object.assign({}, formMethods), { fieldArrays });
|
|
37
|
+
};
|
|
38
|
+
exports.useFormBuilder = useFormBuilder;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.transformToFormFields = exports.useFormBuilder = exports.FormBuilderWatch = exports.FormBuilder = void 0;
|
|
18
|
+
var component_1 = require("./component");
|
|
19
|
+
Object.defineProperty(exports, "FormBuilder", { enumerable: true, get: function () { return component_1.FormBuilder; } });
|
|
20
|
+
var FormBuilderWatch_1 = require("./FormBuilderWatch");
|
|
21
|
+
Object.defineProperty(exports, "FormBuilderWatch", { enumerable: true, get: function () { return FormBuilderWatch_1.FormBuilderWatch; } });
|
|
22
|
+
var hook_1 = require("./hook");
|
|
23
|
+
Object.defineProperty(exports, "useFormBuilder", { enumerable: true, get: function () { return hook_1.useFormBuilder; } });
|
|
24
|
+
var transformers_1 = require("./transformers");
|
|
25
|
+
Object.defineProperty(exports, "transformToFormFields", { enumerable: true, get: function () { return transformers_1.transformToFormFields; } });
|
|
26
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transformers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,SAAS,EAGV,MAAM,UAAU,CAAC;AAClB,OAAO,EAAiB,WAAW,EAAE,MAAM,SAAS,CAAC;AAsBrD,eAAO,MAAM,qBAAqB,SAC1B,OAAO,MAAM,EAAE,WAAW,CAAC,KAChC,SAAS,EA8EX,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.transformToFormFields = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const fieldTypeMap = {
|
|
6
|
+
text: 'input',
|
|
7
|
+
input: 'input',
|
|
8
|
+
dropdown: 'select',
|
|
9
|
+
select: 'select',
|
|
10
|
+
datetime: 'datepicker',
|
|
11
|
+
nested: 'field-array',
|
|
12
|
+
boolean: 'select',
|
|
13
|
+
bool: 'checkbox'
|
|
14
|
+
};
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
+
function isItemCompatible(item) {
|
|
17
|
+
return (typeof item.key === 'string' &&
|
|
18
|
+
typeof item.name === 'string' &&
|
|
19
|
+
Object.values(types_1.DataTypesEnum).includes(item.data_type));
|
|
20
|
+
}
|
|
21
|
+
const transformToFormFields = (data) => {
|
|
22
|
+
return Object.values(data)
|
|
23
|
+
.reduce((acc, item) => {
|
|
24
|
+
if (!isItemCompatible(item)) {
|
|
25
|
+
console.warn('Incompatible item detected on field type transformer:', item);
|
|
26
|
+
return acc;
|
|
27
|
+
}
|
|
28
|
+
const fieldType = fieldTypeMap[item.data_type];
|
|
29
|
+
if (!fieldType) {
|
|
30
|
+
console.error('Unsupported data type:', item.data_type);
|
|
31
|
+
return acc;
|
|
32
|
+
}
|
|
33
|
+
let field = null;
|
|
34
|
+
// TODO: add defaultValue to all fields
|
|
35
|
+
switch (fieldType) {
|
|
36
|
+
case 'field-array':
|
|
37
|
+
if (item.schema) {
|
|
38
|
+
field = {
|
|
39
|
+
key: item.key,
|
|
40
|
+
label: item.name,
|
|
41
|
+
type: fieldType,
|
|
42
|
+
config: {
|
|
43
|
+
name: item.key,
|
|
44
|
+
fields: (0, exports.transformToFormFields)(item.schema)
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
break;
|
|
49
|
+
case 'select':
|
|
50
|
+
if (item.choices) {
|
|
51
|
+
const choices = item.choices;
|
|
52
|
+
field = {
|
|
53
|
+
key: item.key,
|
|
54
|
+
label: item.name,
|
|
55
|
+
type: fieldType,
|
|
56
|
+
placeholder: item.placeholder,
|
|
57
|
+
options: choices.map(choice => ({
|
|
58
|
+
key: choice.value.toString(),
|
|
59
|
+
value: choice.value,
|
|
60
|
+
label: choice.label
|
|
61
|
+
})),
|
|
62
|
+
validation: item.validation
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
default:
|
|
67
|
+
field = Object.assign(Object.assign({}, item), { key: item.key, label: item.name, validation: item.validation, type: fieldType, children: null, control: item.control });
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
if (field !== null) {
|
|
71
|
+
acc.push(field);
|
|
72
|
+
}
|
|
73
|
+
return acc;
|
|
74
|
+
}, [])
|
|
75
|
+
.filter((item) => item !== null);
|
|
76
|
+
};
|
|
77
|
+
exports.transformToFormFields = transformToFormFields;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/transformers/types.ts"],"names":[],"mappings":"AAAA,oBAAY,aAAa;IAEvB,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,IAAI,SAAS;IAIb,QAAQ,aAAa;IAErB,MAAM,WAAW;CAClB;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,aAAa,CAAC,MAAM,aAAa,CAAC,CAAC;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC,CAAC;IAEH,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataTypesEnum = void 0;
|
|
4
|
+
var DataTypesEnum;
|
|
5
|
+
(function (DataTypesEnum) {
|
|
6
|
+
// Area = 'area',
|
|
7
|
+
DataTypesEnum["Dropdown"] = "dropdown";
|
|
8
|
+
DataTypesEnum["Input"] = "input";
|
|
9
|
+
DataTypesEnum["Select"] = "select";
|
|
10
|
+
DataTypesEnum["Text"] = "text";
|
|
11
|
+
DataTypesEnum["Bool"] = "bool";
|
|
12
|
+
// Image = 'image',
|
|
13
|
+
// ValueLabel = 'valuelabel',
|
|
14
|
+
// File = 'file',
|
|
15
|
+
DataTypesEnum["DateTime"] = "datetime";
|
|
16
|
+
// Multiple = 'multiple',
|
|
17
|
+
DataTypesEnum["Nested"] = "nested";
|
|
18
|
+
})(DataTypesEnum || (exports.DataTypesEnum = DataTypesEnum = {}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FormField } from './types';
|
|
3
|
+
type FormBuilderWatchProps = {
|
|
4
|
+
builderFields: FormField[];
|
|
5
|
+
isDebounced?: boolean;
|
|
6
|
+
handleChange: (data: any) => void;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Reasons why seperate FormBuilderWatch component is created from FormBuilder:
|
|
10
|
+
* 1. FormBuilderWatch is a controlled component, value of form fields is controlled. In any given time, value of any field can be forced from parent. It's directly working with value instead of defaultValues. Also there is no way to change defaultValues after first render.
|
|
11
|
+
* 2. FormBuilderWatch is watching form changes and calls the given callback function. It's not using form methods like handleSubmit, reset, etc.
|
|
12
|
+
* 3. It's meticulously designed to not create loop. Since it's controlled and watching form changes, it's easy to create infinite loop. For example, callback can be called as result of form change, and parent can react to this change by returning same values to form.
|
|
13
|
+
*/
|
|
14
|
+
export declare const FormBuilderWatch: ({ builderFields, handleChange, isDebounced }: FormBuilderWatchProps) => React.JSX.Element;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=FormBuilderWatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormBuilderWatch.d.ts","sourceRoot":"","sources":["../../src/FormBuilderWatch.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,KAAK,qBAAqB,GAAG;IAC3B,aAAa,EAAE,SAAS,EAAE,CAAC;IAE3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,iDAI1B,qBAAqB,sBAgFvB,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Akiform, useForm, useWatch } from '@akinon/akiform';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { RenderField } from './RenderField';
|
|
5
|
+
/**
|
|
6
|
+
* Reasons why seperate FormBuilderWatch component is created from FormBuilder:
|
|
7
|
+
* 1. FormBuilderWatch is a controlled component, value of form fields is controlled. In any given time, value of any field can be forced from parent. It's directly working with value instead of defaultValues. Also there is no way to change defaultValues after first render.
|
|
8
|
+
* 2. FormBuilderWatch is watching form changes and calls the given callback function. It's not using form methods like handleSubmit, reset, etc.
|
|
9
|
+
* 3. It's meticulously designed to not create loop. Since it's controlled and watching form changes, it's easy to create infinite loop. For example, callback can be called as result of form change, and parent can react to this change by returning same values to form.
|
|
10
|
+
*/
|
|
11
|
+
export const FormBuilderWatch = ({ builderFields, handleChange, isDebounced = false }) => {
|
|
12
|
+
const { control, setValue } = useForm();
|
|
13
|
+
const formWatch = useWatch({ control });
|
|
14
|
+
React.useEffect(() => {
|
|
15
|
+
// if formWatch are empty object, it means it's the first render. Do not call handleChange
|
|
16
|
+
if (!Object.keys(formWatch).length)
|
|
17
|
+
return;
|
|
18
|
+
// if item.value is same with formWatch do not call handleChange to prevent infinite loop
|
|
19
|
+
const isSame = builderFields.every(field => {
|
|
20
|
+
// if field type is datepicker, convert the formWatch value to string before comparing
|
|
21
|
+
if (field.type === 'datepicker') {
|
|
22
|
+
if (formWatch[field.key] === null) {
|
|
23
|
+
formWatch[field.key] = undefined;
|
|
24
|
+
}
|
|
25
|
+
if (!formWatch[field.key]) {
|
|
26
|
+
return field.value === formWatch[field.key];
|
|
27
|
+
}
|
|
28
|
+
const compareResult = dayjs(field.value).isSame(dayjs(formWatch[field.key]), 'day');
|
|
29
|
+
return compareResult;
|
|
30
|
+
}
|
|
31
|
+
// TODO write tests for this part because it can be a source of bug
|
|
32
|
+
// if watch value is object, should stringify before comparing
|
|
33
|
+
const isWatchValueObject = typeof formWatch[field.key] === 'object';
|
|
34
|
+
if (isWatchValueObject) {
|
|
35
|
+
return (JSON.stringify(field.value) === JSON.stringify(formWatch[field.key]));
|
|
36
|
+
}
|
|
37
|
+
return field.value === formWatch[field.key];
|
|
38
|
+
});
|
|
39
|
+
if (isSame) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (!isDebounced) {
|
|
43
|
+
handleChange(formWatch);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const timeout = setTimeout(() => {
|
|
47
|
+
handleChange(formWatch);
|
|
48
|
+
}, 1000);
|
|
49
|
+
return () => {
|
|
50
|
+
clearTimeout(timeout);
|
|
51
|
+
};
|
|
52
|
+
}, [formWatch]);
|
|
53
|
+
// value of fields can be set by parent
|
|
54
|
+
React.useEffect(() => {
|
|
55
|
+
builderFields.forEach(field => {
|
|
56
|
+
const { key, value, type } = field;
|
|
57
|
+
// if type is datepicker and value is set, convert it to dayjs
|
|
58
|
+
if (type === 'datepicker' && value) {
|
|
59
|
+
setValue(key, dayjs(value));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
setValue(key, value);
|
|
63
|
+
});
|
|
64
|
+
}, [builderFields]);
|
|
65
|
+
return (React.createElement(React.Fragment, null,
|
|
66
|
+
React.createElement("div", { className: "form-builder" },
|
|
67
|
+
React.createElement(Akiform, null, builderFields.map(field => RenderField(field, control))))));
|
|
68
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Control } from '@akinon/akiform';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { FormField } from './types';
|
|
4
|
+
export declare const RenderField: (field: FormField, control: Control) => React.JSX.Element | "unsupported field type" | undefined;
|
|
5
|
+
//# sourceMappingURL=RenderField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RenderField.d.ts","sourceRoot":"","sources":["../../src/RenderField.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,iBAAiB,CAAC;AAMpD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAGL,SAAS,EAIV,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,WAAW,UAAW,SAAS,WAAW,OAAO,6DA+F7D,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { FormItem } from '@akinon/akiform';
|
|
2
|
+
import { Checkbox } from '@akinon/ui-checkbox';
|
|
3
|
+
import { DatePicker } from '@akinon/ui-date-picker';
|
|
4
|
+
import { Input } from '@akinon/ui-input';
|
|
5
|
+
import { InputNumber } from '@akinon/ui-input-number';
|
|
6
|
+
import { Select } from '@akinon/ui-select';
|
|
7
|
+
import React from 'react';
|
|
8
|
+
export const RenderField = (field, control) => {
|
|
9
|
+
var _a, _b;
|
|
10
|
+
switch (field.type) {
|
|
11
|
+
case 'input':
|
|
12
|
+
const inputField = field;
|
|
13
|
+
return (React.createElement(FormItem, { key: inputField.key, name: inputField.key, label: inputField.label, control: control }, ((_a = inputField.props) === null || _a === void 0 ? void 0 : _a.mode) !== 'multiple' ? (React.createElement(Input, { placeholder: inputField.placeholder })) : (React.createElement(Select, { mode: "tags", placeholder: inputField.placeholder }))));
|
|
14
|
+
case 'number':
|
|
15
|
+
const numberField = field;
|
|
16
|
+
return (React.createElement(FormItem, { key: numberField.key, name: numberField.key, label: numberField.label, control: control },
|
|
17
|
+
React.createElement(InputNumber, { keyboard: false, placeholder: numberField.placeholder })));
|
|
18
|
+
case 'select':
|
|
19
|
+
const selectField = field;
|
|
20
|
+
return (React.createElement(FormItem, { key: selectField.key, name: selectField.key, label: selectField.label, control: control },
|
|
21
|
+
React.createElement(Select, { mode: (_b = selectField.props) === null || _b === void 0 ? void 0 : _b.mode, options: selectField.options, placeholder: selectField.placeholder })));
|
|
22
|
+
case 'checkbox':
|
|
23
|
+
const checkboxField = field;
|
|
24
|
+
const { labelRightAligned } = checkboxField.props || {};
|
|
25
|
+
return (React.createElement(FormItem, { key: checkboxField.key, name: checkboxField.key, initialValue: checkboxField.value, control: control, valuePropName: "checked",
|
|
26
|
+
// if labelRightAligned is true, don't pass label prop to Checkbox
|
|
27
|
+
label: labelRightAligned ? '' : checkboxField.label },
|
|
28
|
+
React.createElement(Checkbox, null, labelRightAligned ? checkboxField.label : '')));
|
|
29
|
+
case 'datepicker':
|
|
30
|
+
const datePickerField = field;
|
|
31
|
+
return (React.createElement(FormItem, { key: datePickerField.key, name: datePickerField.key, label: datePickerField.label, control: control },
|
|
32
|
+
React.createElement(DatePicker, { placeholder: datePickerField.placeholder })));
|
|
33
|
+
case 'field-array':
|
|
34
|
+
if (field.config) {
|
|
35
|
+
return (React.createElement(React.Fragment, { key: field.key }, field.config.fields.map(nestedField => RenderField(nestedField, control))));
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
return 'unsupported field type';
|
|
40
|
+
}
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../../src/component.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA0ClD,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { Akiform, akivalResolver, useForm } from '@akinon/akiform';
|
|
13
|
+
import * as akival from '@akinon/akival';
|
|
14
|
+
import React from 'react';
|
|
15
|
+
import { RenderField } from './RenderField';
|
|
16
|
+
export const FormBuilder = (_a) => {
|
|
17
|
+
var { builderFields, children } = _a, formProps = __rest(_a, ["builderFields", "children"]);
|
|
18
|
+
const validationSchema = akival.object(builderFields.reduce((schema, field) => {
|
|
19
|
+
if (field.type !== 'field-array' && field.validation) {
|
|
20
|
+
return Object.assign(Object.assign({}, schema), { [field.key]: field.validation });
|
|
21
|
+
}
|
|
22
|
+
return schema;
|
|
23
|
+
}, {}));
|
|
24
|
+
const formMethods = useForm({
|
|
25
|
+
defaultValues: builderFields.reduce((defaultValues, field) => {
|
|
26
|
+
if (field.defaultValue !== undefined) {
|
|
27
|
+
defaultValues[field.key] = field.defaultValue;
|
|
28
|
+
}
|
|
29
|
+
return defaultValues;
|
|
30
|
+
}, {}),
|
|
31
|
+
resolver: akivalResolver(validationSchema)
|
|
32
|
+
});
|
|
33
|
+
const { control } = formMethods;
|
|
34
|
+
return (React.createElement(Akiform, Object.assign({}, formProps, { onFinish: formMethods.handleSubmit(() => {
|
|
35
|
+
var _a;
|
|
36
|
+
return (_a = formProps.onFinish) === null || _a === void 0 ? void 0 : _a.call(formProps, formMethods.getValues());
|
|
37
|
+
}, () => {
|
|
38
|
+
return console.error('Form validation failed');
|
|
39
|
+
}) }),
|
|
40
|
+
builderFields.map(field => RenderField(field, control)),
|
|
41
|
+
React.createElement("div", null, children)));
|
|
42
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../src/hook.ts"],"names":[],"mappings":"AAQA,OAAO,EAAmB,kBAAkB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzE,eAAO,MAAM,cAAc,WAAY,SAAS,EAAE,KAAG,kBAkCpD,CAAC"}
|
package/dist/esm/hook.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { akivalResolver, useFieldArray, useForm } from '@akinon/akiform';
|
|
13
|
+
import * as akival from '@akinon/akival';
|
|
14
|
+
export const useFormBuilder = (fields) => {
|
|
15
|
+
const validationSchema = akival.object(fields.reduce((schema, field) => {
|
|
16
|
+
if (field.type !== 'field-array' && field.validation) {
|
|
17
|
+
return Object.assign(Object.assign({}, schema), { [field.key]: field.validation });
|
|
18
|
+
}
|
|
19
|
+
return schema;
|
|
20
|
+
}, {}));
|
|
21
|
+
const formMethods = useForm({
|
|
22
|
+
resolver: akivalResolver(validationSchema)
|
|
23
|
+
});
|
|
24
|
+
const fieldArrays = fields
|
|
25
|
+
.filter((field) => field.type === 'field-array')
|
|
26
|
+
.map(fieldArray => {
|
|
27
|
+
const _a = useFieldArray({
|
|
28
|
+
control: formMethods.control,
|
|
29
|
+
name: fieldArray.config.name
|
|
30
|
+
}), { fields: nestedFields } = _a, arrayHelpers = __rest(_a, ["fields"]);
|
|
31
|
+
return Object.assign(Object.assign(Object.assign({}, fieldArray), { name: fieldArray.config.name, fields: nestedFields }), arrayHelpers);
|
|
32
|
+
});
|
|
33
|
+
return Object.assign(Object.assign({}, formMethods), { fieldArrays });
|
|
34
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACvD,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transformers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,SAAS,EAGV,MAAM,UAAU,CAAC;AAClB,OAAO,EAAiB,WAAW,EAAE,MAAM,SAAS,CAAC;AAsBrD,eAAO,MAAM,qBAAqB,SAC1B,OAAO,MAAM,EAAE,WAAW,CAAC,KAChC,SAAS,EA8EX,CAAC"}
|