@gravity-ui/dynamic-forms 3.2.0 → 3.3.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/build/cjs/lib/core/components/Form/Controller/Controller.js +120 -0
- package/build/cjs/lib/core/components/Form/Controller/index.js +4 -0
- package/build/cjs/lib/core/components/Form/Controller/types.js +2 -0
- package/build/cjs/lib/core/components/Form/Controller/utils.js +305 -0
- package/build/cjs/lib/core/components/Form/hooks/index.js +0 -4
- package/build/cjs/lib/core/components/Form/hooks/useMutators.js +21 -1
- package/build/cjs/lib/core/components/Form/utils/common.js +1 -5
- package/build/esm/lib/core/components/Form/Controller/Controller.d.ts +10 -0
- package/build/esm/lib/core/components/Form/Controller/Controller.js +115 -0
- package/build/esm/lib/core/components/Form/Controller/index.d.ts +1 -0
- package/build/esm/lib/core/components/Form/Controller/index.js +1 -0
- package/build/esm/lib/core/components/Form/Controller/types.d.ts +98 -0
- package/build/esm/lib/core/components/Form/Controller/types.js +1 -0
- package/build/esm/lib/core/components/Form/Controller/utils.d.ts +26 -0
- package/build/esm/lib/core/components/Form/Controller/utils.js +291 -0
- package/build/esm/lib/core/components/Form/hooks/index.d.ts +0 -4
- package/build/esm/lib/core/components/Form/hooks/index.js +0 -4
- package/build/esm/lib/core/components/Form/hooks/useMutators.js +21 -1
- package/build/esm/lib/core/components/Form/types/mirror.d.ts +3 -5
- package/build/esm/lib/core/components/Form/types/mutators.d.ts +13 -2
- package/build/esm/lib/core/components/Form/utils/common.d.ts +0 -3
- package/build/esm/lib/core/components/Form/utils/common.js +0 -2
- package/package.json +1 -1
- package/build/cjs/lib/core/components/Form/Controller.js +0 -42
- package/build/cjs/lib/core/components/Form/hooks/useComponents.js +0 -40
- package/build/cjs/lib/core/components/Form/hooks/useField.js +0 -176
- package/build/cjs/lib/core/components/Form/hooks/useRender.js +0 -28
- package/build/cjs/lib/core/components/Form/hooks/useValidate.js +0 -32
- package/build/esm/lib/core/components/Form/Controller.d.ts +0 -10
- package/build/esm/lib/core/components/Form/Controller.js +0 -37
- package/build/esm/lib/core/components/Form/hooks/useComponents.d.ts +0 -6
- package/build/esm/lib/core/components/Form/hooks/useComponents.js +0 -35
- package/build/esm/lib/core/components/Form/hooks/useField.d.ts +0 -14
- package/build/esm/lib/core/components/Form/hooks/useField.js +0 -171
- package/build/esm/lib/core/components/Form/hooks/useRender.d.ts +0 -9
- package/build/esm/lib/core/components/Form/hooks/useRender.js +0 -23
- package/build/esm/lib/core/components/Form/hooks/useValidate.d.ts +0 -3
- package/build/esm/lib/core/components/Form/hooks/useValidate.js +0 -27
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useField = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
-
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
7
|
-
const helpers_1 = require("../../../helpers");
|
|
8
|
-
const constants_1 = require("../constants");
|
|
9
|
-
const utils_1 = require("../utils");
|
|
10
|
-
const useField = ({ name, spec, initialValue, value: externalValue, validate: propsValidate, tools, parentOnChange, parentOnUnmount: externalParentOnUnmount, mutators, }) => {
|
|
11
|
-
const firstRenderRef = react_1.default.useRef(true);
|
|
12
|
-
const validate = react_1.default.useCallback((value) => propsValidate === null || propsValidate === void 0 ? void 0 : propsValidate((0, utils_1.transformArrOut)(value)), [propsValidate]);
|
|
13
|
-
const [state, setState] = react_1.default.useState(() => {
|
|
14
|
-
const valueMutator = lodash_1.default.get(mutators.values, name, constants_1.EMPTY_MUTATOR);
|
|
15
|
-
let value = lodash_1.default.cloneDeep(externalValue);
|
|
16
|
-
if ((0, utils_1.isValueMutatorCorrect)(valueMutator, spec) && valueMutator !== constants_1.EMPTY_MUTATOR) {
|
|
17
|
-
value = valueMutator;
|
|
18
|
-
}
|
|
19
|
-
if (lodash_1.default.isNil(value)) {
|
|
20
|
-
if (spec.defaultValue) {
|
|
21
|
-
value = (0, utils_1.transformArrIn)(spec.defaultValue);
|
|
22
|
-
}
|
|
23
|
-
// if the spec with type array or object, and this spec has "required === true",
|
|
24
|
-
// we immediately exclude empty value
|
|
25
|
-
else if (spec.required) {
|
|
26
|
-
if ((0, helpers_1.isArraySpec)(spec)) {
|
|
27
|
-
value = { [constants_1.OBJECT_ARRAY_FLAG]: true, [constants_1.OBJECT_ARRAY_CNT]: 0 };
|
|
28
|
-
}
|
|
29
|
-
else if ((0, helpers_1.isObjectSpec)(spec)) {
|
|
30
|
-
value = {};
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
let errorMutator = lodash_1.default.get(mutators.errors, name);
|
|
35
|
-
if (!(0, utils_1.isErrorMutatorCorrect)(errorMutator)) {
|
|
36
|
-
errorMutator = undefined;
|
|
37
|
-
}
|
|
38
|
-
const error = (validate === null || validate === void 0 ? void 0 : validate(value)) || errorMutator;
|
|
39
|
-
const dirty = !lodash_1.default.isEqual(value, initialValue);
|
|
40
|
-
return {
|
|
41
|
-
active: false,
|
|
42
|
-
dirty,
|
|
43
|
-
error,
|
|
44
|
-
invalid: Boolean(error),
|
|
45
|
-
modified: dirty,
|
|
46
|
-
pristine: true,
|
|
47
|
-
touched: false,
|
|
48
|
-
valid: !error,
|
|
49
|
-
value,
|
|
50
|
-
visited: false,
|
|
51
|
-
childErrors: {},
|
|
52
|
-
};
|
|
53
|
-
});
|
|
54
|
-
const { onChange, onLocalChange, onDrop } = react_1.default.useMemo(() => {
|
|
55
|
-
const onLocalChange = (valOrSetter, childErrors, errorMutator) => {
|
|
56
|
-
setState((state) => {
|
|
57
|
-
const _value = lodash_1.default.isFunction(valOrSetter) ? valOrSetter(state.value) : valOrSetter;
|
|
58
|
-
const error = (validate === null || validate === void 0 ? void 0 : validate(_value)) || errorMutator;
|
|
59
|
-
let value = (0, utils_1.transformArrIn)(_value);
|
|
60
|
-
if ((0, helpers_1.isNumberSpec)(spec) && !error) {
|
|
61
|
-
value = (value ? Number(value) : undefined);
|
|
62
|
-
}
|
|
63
|
-
let newChildErrors = Object.assign({}, state.childErrors);
|
|
64
|
-
if (childErrors) {
|
|
65
|
-
const nearestChildName = lodash_1.default.keys(childErrors).sort((a, b) => a.length - b.length)[0];
|
|
66
|
-
if (nearestChildName) {
|
|
67
|
-
const existingСhildNames = lodash_1.default.keys(newChildErrors).filter((childName) => childName.startsWith(nearestChildName));
|
|
68
|
-
newChildErrors = Object.assign(Object.assign({}, lodash_1.default.omit(newChildErrors, existingСhildNames)), childErrors);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return Object.assign(Object.assign({}, state), { dirty: !lodash_1.default.isEqual(value, initialValue), error, invalid: Boolean(error), modified: true, pristine: value === initialValue, touched: true, valid: !error, value, visited: true, childErrors: newChildErrors });
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
const onChange = (valOrSetter, childErrors) => onLocalChange(valOrSetter, childErrors);
|
|
75
|
-
const onDrop = () => {
|
|
76
|
-
if ((0, utils_1.isArrayItem)(name)) {
|
|
77
|
-
(externalParentOnUnmount ? externalParentOnUnmount : tools.onUnmount)(name);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
onChange(undefined, { [name]: false });
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
return { onChange, onLocalChange, onDrop };
|
|
84
|
-
}, [initialValue, setState, name, validate, spec, externalParentOnUnmount, tools.onUnmount]);
|
|
85
|
-
const onBlur = react_1.default.useCallback(() => {
|
|
86
|
-
setState((state) => (Object.assign(Object.assign({}, state), { active: false, touched: true })));
|
|
87
|
-
}, [setState]);
|
|
88
|
-
const onFocus = react_1.default.useCallback(() => {
|
|
89
|
-
setState((state) => (Object.assign(Object.assign({}, state), { active: true, visited: true })));
|
|
90
|
-
}, [setState]);
|
|
91
|
-
const parentOnUnmount = react_1.default.useCallback((childName) => {
|
|
92
|
-
if ((0, helpers_1.isArraySpec)(spec) || (0, helpers_1.isObjectSpec)(spec)) {
|
|
93
|
-
onChange((currentValue) => currentValue
|
|
94
|
-
? lodash_1.default.omit(currentValue, childName.split(`${name}.`)[1])
|
|
95
|
-
: currentValue, {
|
|
96
|
-
[childName]: false,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}, [onChange, name, spec]);
|
|
100
|
-
const renderProps = react_1.default.useMemo(() => {
|
|
101
|
-
const onItemAdd = (_value) => {
|
|
102
|
-
const stateValue = (state.value || {
|
|
103
|
-
[constants_1.OBJECT_ARRAY_FLAG]: true,
|
|
104
|
-
[constants_1.OBJECT_ARRAY_CNT]: 0,
|
|
105
|
-
});
|
|
106
|
-
const value = Object.assign(Object.assign({}, stateValue), { [`<${stateValue[constants_1.OBJECT_ARRAY_CNT]}>`]: (0, utils_1.transformArrIn)(_value), [constants_1.OBJECT_ARRAY_CNT]: stateValue[constants_1.OBJECT_ARRAY_CNT] + 1 });
|
|
107
|
-
const error = validate === null || validate === void 0 ? void 0 : validate(value);
|
|
108
|
-
setState((state) => (Object.assign(Object.assign({}, state), { dirty: !lodash_1.default.isEqual(value, initialValue), error, invalid: Boolean(error), modified: true, pristine: value === initialValue, touched: true, valid: !error, value, visited: true })));
|
|
109
|
-
};
|
|
110
|
-
const onItemRemove = (idx) => {
|
|
111
|
-
parentOnUnmount(`${name}.<${idx}>`);
|
|
112
|
-
};
|
|
113
|
-
return {
|
|
114
|
-
input: {
|
|
115
|
-
name,
|
|
116
|
-
value: state.value,
|
|
117
|
-
onChange,
|
|
118
|
-
onBlur,
|
|
119
|
-
onFocus,
|
|
120
|
-
onDrop,
|
|
121
|
-
parentOnUnmount,
|
|
122
|
-
},
|
|
123
|
-
arrayInput: {
|
|
124
|
-
name,
|
|
125
|
-
value: state.value,
|
|
126
|
-
onItemAdd,
|
|
127
|
-
onItemRemove,
|
|
128
|
-
onDrop,
|
|
129
|
-
},
|
|
130
|
-
meta: Object.assign(Object.assign({}, lodash_1.default.omit(state, 'value')), { submitFailed: tools.submitFailed }),
|
|
131
|
-
};
|
|
132
|
-
}, [
|
|
133
|
-
state,
|
|
134
|
-
setState,
|
|
135
|
-
validate,
|
|
136
|
-
name,
|
|
137
|
-
initialValue,
|
|
138
|
-
tools.submitFailed,
|
|
139
|
-
onChange,
|
|
140
|
-
onBlur,
|
|
141
|
-
onFocus,
|
|
142
|
-
onDrop,
|
|
143
|
-
parentOnUnmount,
|
|
144
|
-
]);
|
|
145
|
-
react_1.default.useEffect(() => {
|
|
146
|
-
if (!firstRenderRef.current || !lodash_1.default.isEqual(externalValue, state.value) || state.error) {
|
|
147
|
-
(parentOnChange ? parentOnChange : tools.onChange)(name, state.value, Object.assign(Object.assign({}, state.childErrors), { [name]: state.error }));
|
|
148
|
-
}
|
|
149
|
-
}, [state.value]);
|
|
150
|
-
react_1.default.useEffect(() => {
|
|
151
|
-
if (!firstRenderRef.current) {
|
|
152
|
-
const valueMutator = lodash_1.default.get(mutators.values, name, constants_1.EMPTY_MUTATOR);
|
|
153
|
-
let errorMutator = lodash_1.default.get(mutators.errors, name);
|
|
154
|
-
if (!(0, utils_1.isErrorMutatorCorrect)(errorMutator)) {
|
|
155
|
-
errorMutator = undefined;
|
|
156
|
-
}
|
|
157
|
-
if ((0, utils_1.isValueMutatorCorrect)(valueMutator, spec) &&
|
|
158
|
-
valueMutator !== state.value &&
|
|
159
|
-
valueMutator !== constants_1.EMPTY_MUTATOR) {
|
|
160
|
-
onLocalChange(valueMutator, undefined, errorMutator);
|
|
161
|
-
}
|
|
162
|
-
else if (state.error !== errorMutator && !(state.error && !errorMutator)) {
|
|
163
|
-
setState(Object.assign(Object.assign({}, state), { error: errorMutator }));
|
|
164
|
-
(parentOnChange ? parentOnChange : tools.onChange)(name, state.value, Object.assign(Object.assign({}, state.childErrors), { [name]: errorMutator }));
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}, [mutators]);
|
|
168
|
-
react_1.default.useEffect(() => {
|
|
169
|
-
firstRenderRef.current = false;
|
|
170
|
-
return () => {
|
|
171
|
-
(externalParentOnUnmount ? externalParentOnUnmount : tools.onUnmount)(name);
|
|
172
|
-
};
|
|
173
|
-
}, []);
|
|
174
|
-
return renderProps;
|
|
175
|
-
};
|
|
176
|
-
exports.useField = useField;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useRender = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
-
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
7
|
-
const helpers_1 = require("../../../helpers");
|
|
8
|
-
const useRender = ({ name, spec, inputEntity, Layout, }) => {
|
|
9
|
-
const render = react_1.default.useCallback((props) => {
|
|
10
|
-
if (inputEntity && (0, helpers_1.isCorrectSpec)(spec) && lodash_1.default.isString(name)) {
|
|
11
|
-
if (!spec.viewSpec.hidden) {
|
|
12
|
-
if (inputEntity.independent) {
|
|
13
|
-
const InputComponent = inputEntity.Component;
|
|
14
|
-
return (react_1.default.createElement(InputComponent, Object.assign({ spec: spec, name: name, Layout: Layout }, props)));
|
|
15
|
-
}
|
|
16
|
-
const InputComponent = inputEntity.Component;
|
|
17
|
-
const input = react_1.default.createElement(InputComponent, Object.assign({ spec: spec, name: name }, props));
|
|
18
|
-
if (Layout) {
|
|
19
|
-
return (react_1.default.createElement(Layout, Object.assign({ spec: spec, name: name }, props), input));
|
|
20
|
-
}
|
|
21
|
-
return input;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return null;
|
|
25
|
-
}, [spec, name, inputEntity, Layout]);
|
|
26
|
-
return render;
|
|
27
|
-
};
|
|
28
|
-
exports.useRender = useRender;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useValidate = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
-
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
7
|
-
const helpers_1 = require("../../../helpers");
|
|
8
|
-
const utils_1 = require("../utils");
|
|
9
|
-
const _1 = require("./");
|
|
10
|
-
const useValidate = (spec) => {
|
|
11
|
-
const { config } = (0, _1.useDynamicFormsCtx)();
|
|
12
|
-
const { validators } = react_1.default.useMemo(() => {
|
|
13
|
-
if ((0, utils_1.isCorrectConfig)(config) && (0, helpers_1.isCorrectSpec)(spec)) {
|
|
14
|
-
return config[spec.type];
|
|
15
|
-
}
|
|
16
|
-
return {};
|
|
17
|
-
}, [config, spec]);
|
|
18
|
-
const validate = react_1.default.useMemo(() => {
|
|
19
|
-
if (validators) {
|
|
20
|
-
if ((!lodash_1.default.isString(spec.validator) || !spec.validator.length) &&
|
|
21
|
-
lodash_1.default.isFunction(validators.base)) {
|
|
22
|
-
return (value) => validators.base(spec, value);
|
|
23
|
-
}
|
|
24
|
-
if (lodash_1.default.isString(spec.validator) && lodash_1.default.isFunction(validators[spec.validator])) {
|
|
25
|
-
return (value) => validators[spec.validator](spec, value);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return;
|
|
29
|
-
}, [validators, spec]);
|
|
30
|
-
return validate;
|
|
31
|
-
};
|
|
32
|
-
exports.useValidate = useValidate;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Spec } from '../../types';
|
|
2
|
-
import { FieldValue, ValidateError } from './types';
|
|
3
|
-
export interface ControllerProps<Value extends FieldValue, SpecType extends Spec> {
|
|
4
|
-
spec: SpecType;
|
|
5
|
-
name: string;
|
|
6
|
-
value: Value;
|
|
7
|
-
parentOnChange: ((childName: string, childValue: FieldValue, childErrors: Record<string, ValidateError>) => void) | null;
|
|
8
|
-
parentOnUnmount: ((childName: string) => void) | null;
|
|
9
|
-
}
|
|
10
|
-
export declare const Controller: <Value extends FieldValue, SpecType extends Spec>({ spec: _spec, name, value, parentOnChange, parentOnUnmount, }: ControllerProps<Value, SpecType>) => JSX.Element | null;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { EMPTY_MUTATOR } from './constants';
|
|
4
|
-
import { useComponents, useControllerMirror, useDynamicFormsCtx, useField, useRender, useSearch, useValidate, } from './hooks';
|
|
5
|
-
export const Controller = ({ spec: _spec, name, value, parentOnChange, parentOnUnmount, }) => {
|
|
6
|
-
const { tools, mutators, __mirror } = useDynamicFormsCtx();
|
|
7
|
-
const spec = React.useMemo(() => {
|
|
8
|
-
const specMutator = _.get(mutators.spec, name, EMPTY_MUTATOR);
|
|
9
|
-
if (specMutator !== EMPTY_MUTATOR) {
|
|
10
|
-
return _.merge(_spec, specMutator);
|
|
11
|
-
}
|
|
12
|
-
return _spec;
|
|
13
|
-
}, [_spec, mutators.spec, name]);
|
|
14
|
-
const { inputEntity, Layout } = useComponents(spec);
|
|
15
|
-
const render = useRender({ name, spec, inputEntity, Layout });
|
|
16
|
-
const validate = useValidate(spec);
|
|
17
|
-
const renderProps = useField({
|
|
18
|
-
name,
|
|
19
|
-
initialValue: _.get(tools.initialValue, name),
|
|
20
|
-
value,
|
|
21
|
-
spec,
|
|
22
|
-
validate,
|
|
23
|
-
tools,
|
|
24
|
-
parentOnChange,
|
|
25
|
-
parentOnUnmount,
|
|
26
|
-
mutators,
|
|
27
|
-
});
|
|
28
|
-
const withSearch = useSearch(spec, renderProps.input.value, name);
|
|
29
|
-
useControllerMirror(name, {
|
|
30
|
-
useComponents: { inputEntity, Layout },
|
|
31
|
-
useRender: render,
|
|
32
|
-
useValidate: validate,
|
|
33
|
-
useField: renderProps,
|
|
34
|
-
useSearch: withSearch,
|
|
35
|
-
}, __mirror);
|
|
36
|
-
return withSearch(render(renderProps));
|
|
37
|
-
};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { FormValue, Spec } from '../../../types';
|
|
2
|
-
import { FieldValue, IndependentInputEntity, InputEntity, LayoutType } from '../types';
|
|
3
|
-
export declare const useComponents: <DirtyValue extends FieldValue, Value extends FormValue, SpecType extends Spec>(spec: SpecType) => {
|
|
4
|
-
inputEntity: InputEntity<DirtyValue, SpecType> | IndependentInputEntity<DirtyValue, SpecType> | undefined;
|
|
5
|
-
Layout: LayoutType<DirtyValue, SpecType> | undefined;
|
|
6
|
-
};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { isValidElementType } from 'react-is';
|
|
4
|
-
import { isCorrectSpec } from '../../../helpers';
|
|
5
|
-
import { isCorrectConfig } from '../utils';
|
|
6
|
-
import { useDynamicFormsCtx } from './';
|
|
7
|
-
export const useComponents = (spec) => {
|
|
8
|
-
var _a, _b;
|
|
9
|
-
const { config } = useDynamicFormsCtx();
|
|
10
|
-
const { inputs, layouts } = React.useMemo(() => {
|
|
11
|
-
if (isCorrectConfig(config) && isCorrectSpec(spec)) {
|
|
12
|
-
return config[spec.type];
|
|
13
|
-
}
|
|
14
|
-
return {};
|
|
15
|
-
}, [config, spec]);
|
|
16
|
-
const inputEntity = React.useMemo(() => {
|
|
17
|
-
if (inputs) {
|
|
18
|
-
const entity = inputs[spec.viewSpec.type];
|
|
19
|
-
if (isValidElementType(entity === null || entity === void 0 ? void 0 : entity.Component)) {
|
|
20
|
-
return entity;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return;
|
|
24
|
-
}, [inputs, (_a = spec === null || spec === void 0 ? void 0 : spec.viewSpec) === null || _a === void 0 ? void 0 : _a.type]);
|
|
25
|
-
const Layout = React.useMemo(() => {
|
|
26
|
-
if (layouts && _.isString(spec.viewSpec.layout)) {
|
|
27
|
-
const Component = layouts[spec.viewSpec.layout];
|
|
28
|
-
if (isValidElementType(Component)) {
|
|
29
|
-
return Component;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return;
|
|
33
|
-
}, [layouts, (_b = spec === null || spec === void 0 ? void 0 : spec.viewSpec) === null || _b === void 0 ? void 0 : _b.layout]);
|
|
34
|
-
return { inputEntity, Layout };
|
|
35
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Spec } from '../../../types';
|
|
2
|
-
import { DynamicFormMutators, DynamicFormsContext, FieldRenderProps, FieldValue, ValidateError } from '../types';
|
|
3
|
-
export interface UseFieldProps<Value extends FieldValue, SpecType extends Spec> {
|
|
4
|
-
name: string;
|
|
5
|
-
spec: SpecType;
|
|
6
|
-
initialValue: Value;
|
|
7
|
-
value: Value;
|
|
8
|
-
validate?: (value?: Value) => ValidateError;
|
|
9
|
-
tools: DynamicFormsContext['tools'];
|
|
10
|
-
parentOnChange: ((childName: string, childValue: FieldValue, childErrors: Record<string, ValidateError>) => void) | null;
|
|
11
|
-
parentOnUnmount: ((childName: string) => void) | null;
|
|
12
|
-
mutators: DynamicFormMutators;
|
|
13
|
-
}
|
|
14
|
-
export declare const useField: <Value extends FieldValue, SpecType extends Spec>({ name, spec, initialValue, value: externalValue, validate: propsValidate, tools, parentOnChange, parentOnUnmount: externalParentOnUnmount, mutators, }: UseFieldProps<Value, SpecType>) => FieldRenderProps<Value>;
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { isArraySpec, isNumberSpec, isObjectSpec } from '../../../helpers';
|
|
4
|
-
import { EMPTY_MUTATOR, OBJECT_ARRAY_CNT, OBJECT_ARRAY_FLAG } from '../constants';
|
|
5
|
-
import { isArrayItem, isErrorMutatorCorrect, isValueMutatorCorrect, transformArrIn, transformArrOut, } from '../utils';
|
|
6
|
-
export const useField = ({ name, spec, initialValue, value: externalValue, validate: propsValidate, tools, parentOnChange, parentOnUnmount: externalParentOnUnmount, mutators, }) => {
|
|
7
|
-
const firstRenderRef = React.useRef(true);
|
|
8
|
-
const validate = React.useCallback((value) => propsValidate === null || propsValidate === void 0 ? void 0 : propsValidate(transformArrOut(value)), [propsValidate]);
|
|
9
|
-
const [state, setState] = React.useState(() => {
|
|
10
|
-
const valueMutator = _.get(mutators.values, name, EMPTY_MUTATOR);
|
|
11
|
-
let value = _.cloneDeep(externalValue);
|
|
12
|
-
if (isValueMutatorCorrect(valueMutator, spec) && valueMutator !== EMPTY_MUTATOR) {
|
|
13
|
-
value = valueMutator;
|
|
14
|
-
}
|
|
15
|
-
if (_.isNil(value)) {
|
|
16
|
-
if (spec.defaultValue) {
|
|
17
|
-
value = transformArrIn(spec.defaultValue);
|
|
18
|
-
}
|
|
19
|
-
// if the spec with type array or object, and this spec has "required === true",
|
|
20
|
-
// we immediately exclude empty value
|
|
21
|
-
else if (spec.required) {
|
|
22
|
-
if (isArraySpec(spec)) {
|
|
23
|
-
value = { [OBJECT_ARRAY_FLAG]: true, [OBJECT_ARRAY_CNT]: 0 };
|
|
24
|
-
}
|
|
25
|
-
else if (isObjectSpec(spec)) {
|
|
26
|
-
value = {};
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
let errorMutator = _.get(mutators.errors, name);
|
|
31
|
-
if (!isErrorMutatorCorrect(errorMutator)) {
|
|
32
|
-
errorMutator = undefined;
|
|
33
|
-
}
|
|
34
|
-
const error = (validate === null || validate === void 0 ? void 0 : validate(value)) || errorMutator;
|
|
35
|
-
const dirty = !_.isEqual(value, initialValue);
|
|
36
|
-
return {
|
|
37
|
-
active: false,
|
|
38
|
-
dirty,
|
|
39
|
-
error,
|
|
40
|
-
invalid: Boolean(error),
|
|
41
|
-
modified: dirty,
|
|
42
|
-
pristine: true,
|
|
43
|
-
touched: false,
|
|
44
|
-
valid: !error,
|
|
45
|
-
value,
|
|
46
|
-
visited: false,
|
|
47
|
-
childErrors: {},
|
|
48
|
-
};
|
|
49
|
-
});
|
|
50
|
-
const { onChange, onLocalChange, onDrop } = React.useMemo(() => {
|
|
51
|
-
const onLocalChange = (valOrSetter, childErrors, errorMutator) => {
|
|
52
|
-
setState((state) => {
|
|
53
|
-
const _value = _.isFunction(valOrSetter) ? valOrSetter(state.value) : valOrSetter;
|
|
54
|
-
const error = (validate === null || validate === void 0 ? void 0 : validate(_value)) || errorMutator;
|
|
55
|
-
let value = transformArrIn(_value);
|
|
56
|
-
if (isNumberSpec(spec) && !error) {
|
|
57
|
-
value = (value ? Number(value) : undefined);
|
|
58
|
-
}
|
|
59
|
-
let newChildErrors = Object.assign({}, state.childErrors);
|
|
60
|
-
if (childErrors) {
|
|
61
|
-
const nearestChildName = _.keys(childErrors).sort((a, b) => a.length - b.length)[0];
|
|
62
|
-
if (nearestChildName) {
|
|
63
|
-
const existingСhildNames = _.keys(newChildErrors).filter((childName) => childName.startsWith(nearestChildName));
|
|
64
|
-
newChildErrors = Object.assign(Object.assign({}, _.omit(newChildErrors, existingСhildNames)), childErrors);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return Object.assign(Object.assign({}, state), { dirty: !_.isEqual(value, initialValue), error, invalid: Boolean(error), modified: true, pristine: value === initialValue, touched: true, valid: !error, value, visited: true, childErrors: newChildErrors });
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
const onChange = (valOrSetter, childErrors) => onLocalChange(valOrSetter, childErrors);
|
|
71
|
-
const onDrop = () => {
|
|
72
|
-
if (isArrayItem(name)) {
|
|
73
|
-
(externalParentOnUnmount ? externalParentOnUnmount : tools.onUnmount)(name);
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
onChange(undefined, { [name]: false });
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
return { onChange, onLocalChange, onDrop };
|
|
80
|
-
}, [initialValue, setState, name, validate, spec, externalParentOnUnmount, tools.onUnmount]);
|
|
81
|
-
const onBlur = React.useCallback(() => {
|
|
82
|
-
setState((state) => (Object.assign(Object.assign({}, state), { active: false, touched: true })));
|
|
83
|
-
}, [setState]);
|
|
84
|
-
const onFocus = React.useCallback(() => {
|
|
85
|
-
setState((state) => (Object.assign(Object.assign({}, state), { active: true, visited: true })));
|
|
86
|
-
}, [setState]);
|
|
87
|
-
const parentOnUnmount = React.useCallback((childName) => {
|
|
88
|
-
if (isArraySpec(spec) || isObjectSpec(spec)) {
|
|
89
|
-
onChange((currentValue) => currentValue
|
|
90
|
-
? _.omit(currentValue, childName.split(`${name}.`)[1])
|
|
91
|
-
: currentValue, {
|
|
92
|
-
[childName]: false,
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
}, [onChange, name, spec]);
|
|
96
|
-
const renderProps = React.useMemo(() => {
|
|
97
|
-
const onItemAdd = (_value) => {
|
|
98
|
-
const stateValue = (state.value || {
|
|
99
|
-
[OBJECT_ARRAY_FLAG]: true,
|
|
100
|
-
[OBJECT_ARRAY_CNT]: 0,
|
|
101
|
-
});
|
|
102
|
-
const value = Object.assign(Object.assign({}, stateValue), { [`<${stateValue[OBJECT_ARRAY_CNT]}>`]: transformArrIn(_value), [OBJECT_ARRAY_CNT]: stateValue[OBJECT_ARRAY_CNT] + 1 });
|
|
103
|
-
const error = validate === null || validate === void 0 ? void 0 : validate(value);
|
|
104
|
-
setState((state) => (Object.assign(Object.assign({}, state), { dirty: !_.isEqual(value, initialValue), error, invalid: Boolean(error), modified: true, pristine: value === initialValue, touched: true, valid: !error, value, visited: true })));
|
|
105
|
-
};
|
|
106
|
-
const onItemRemove = (idx) => {
|
|
107
|
-
parentOnUnmount(`${name}.<${idx}>`);
|
|
108
|
-
};
|
|
109
|
-
return {
|
|
110
|
-
input: {
|
|
111
|
-
name,
|
|
112
|
-
value: state.value,
|
|
113
|
-
onChange,
|
|
114
|
-
onBlur,
|
|
115
|
-
onFocus,
|
|
116
|
-
onDrop,
|
|
117
|
-
parentOnUnmount,
|
|
118
|
-
},
|
|
119
|
-
arrayInput: {
|
|
120
|
-
name,
|
|
121
|
-
value: state.value,
|
|
122
|
-
onItemAdd,
|
|
123
|
-
onItemRemove,
|
|
124
|
-
onDrop,
|
|
125
|
-
},
|
|
126
|
-
meta: Object.assign(Object.assign({}, _.omit(state, 'value')), { submitFailed: tools.submitFailed }),
|
|
127
|
-
};
|
|
128
|
-
}, [
|
|
129
|
-
state,
|
|
130
|
-
setState,
|
|
131
|
-
validate,
|
|
132
|
-
name,
|
|
133
|
-
initialValue,
|
|
134
|
-
tools.submitFailed,
|
|
135
|
-
onChange,
|
|
136
|
-
onBlur,
|
|
137
|
-
onFocus,
|
|
138
|
-
onDrop,
|
|
139
|
-
parentOnUnmount,
|
|
140
|
-
]);
|
|
141
|
-
React.useEffect(() => {
|
|
142
|
-
if (!firstRenderRef.current || !_.isEqual(externalValue, state.value) || state.error) {
|
|
143
|
-
(parentOnChange ? parentOnChange : tools.onChange)(name, state.value, Object.assign(Object.assign({}, state.childErrors), { [name]: state.error }));
|
|
144
|
-
}
|
|
145
|
-
}, [state.value]);
|
|
146
|
-
React.useEffect(() => {
|
|
147
|
-
if (!firstRenderRef.current) {
|
|
148
|
-
const valueMutator = _.get(mutators.values, name, EMPTY_MUTATOR);
|
|
149
|
-
let errorMutator = _.get(mutators.errors, name);
|
|
150
|
-
if (!isErrorMutatorCorrect(errorMutator)) {
|
|
151
|
-
errorMutator = undefined;
|
|
152
|
-
}
|
|
153
|
-
if (isValueMutatorCorrect(valueMutator, spec) &&
|
|
154
|
-
valueMutator !== state.value &&
|
|
155
|
-
valueMutator !== EMPTY_MUTATOR) {
|
|
156
|
-
onLocalChange(valueMutator, undefined, errorMutator);
|
|
157
|
-
}
|
|
158
|
-
else if (state.error !== errorMutator && !(state.error && !errorMutator)) {
|
|
159
|
-
setState(Object.assign(Object.assign({}, state), { error: errorMutator }));
|
|
160
|
-
(parentOnChange ? parentOnChange : tools.onChange)(name, state.value, Object.assign(Object.assign({}, state.childErrors), { [name]: errorMutator }));
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}, [mutators]);
|
|
164
|
-
React.useEffect(() => {
|
|
165
|
-
firstRenderRef.current = false;
|
|
166
|
-
return () => {
|
|
167
|
-
(externalParentOnUnmount ? externalParentOnUnmount : tools.onUnmount)(name);
|
|
168
|
-
};
|
|
169
|
-
}, []);
|
|
170
|
-
return renderProps;
|
|
171
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Spec } from '../../../types';
|
|
2
|
-
import { FieldRenderProps, FieldValue, IndependentInputEntity, InputEntity, LayoutType } from '../types';
|
|
3
|
-
export interface UseRenderParams<Value extends FieldValue, SpecType extends Spec> {
|
|
4
|
-
name: string;
|
|
5
|
-
spec: SpecType;
|
|
6
|
-
inputEntity?: InputEntity<Value, SpecType> | IndependentInputEntity<Value, SpecType>;
|
|
7
|
-
Layout?: LayoutType<Value, SpecType>;
|
|
8
|
-
}
|
|
9
|
-
export declare const useRender: <Value extends FieldValue, SpecType extends Spec>({ name, spec, inputEntity, Layout, }: UseRenderParams<Value, SpecType>) => (props: FieldRenderProps<Value>) => JSX.Element | null;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { isCorrectSpec } from '../../../helpers';
|
|
4
|
-
export const useRender = ({ name, spec, inputEntity, Layout, }) => {
|
|
5
|
-
const render = React.useCallback((props) => {
|
|
6
|
-
if (inputEntity && isCorrectSpec(spec) && _.isString(name)) {
|
|
7
|
-
if (!spec.viewSpec.hidden) {
|
|
8
|
-
if (inputEntity.independent) {
|
|
9
|
-
const InputComponent = inputEntity.Component;
|
|
10
|
-
return (React.createElement(InputComponent, Object.assign({ spec: spec, name: name, Layout: Layout }, props)));
|
|
11
|
-
}
|
|
12
|
-
const InputComponent = inputEntity.Component;
|
|
13
|
-
const input = React.createElement(InputComponent, Object.assign({ spec: spec, name: name }, props));
|
|
14
|
-
if (Layout) {
|
|
15
|
-
return (React.createElement(Layout, Object.assign({ spec: spec, name: name }, props), input));
|
|
16
|
-
}
|
|
17
|
-
return input;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return null;
|
|
21
|
-
}, [spec, name, inputEntity, Layout]);
|
|
22
|
-
return render;
|
|
23
|
-
};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { FormValue, Spec } from '../../../types';
|
|
2
|
-
import { FieldValue } from '../types';
|
|
3
|
-
export declare const useValidate: <DirtyValue extends FieldValue, Value extends FormValue, SpecType extends Spec>(spec: SpecType) => ((value?: Value | undefined) => import("../types").ValidateError) | undefined;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { isCorrectSpec } from '../../../helpers';
|
|
4
|
-
import { isCorrectConfig } from '../utils';
|
|
5
|
-
import { useDynamicFormsCtx } from './';
|
|
6
|
-
export const useValidate = (spec) => {
|
|
7
|
-
const { config } = useDynamicFormsCtx();
|
|
8
|
-
const { validators } = React.useMemo(() => {
|
|
9
|
-
if (isCorrectConfig(config) && isCorrectSpec(spec)) {
|
|
10
|
-
return config[spec.type];
|
|
11
|
-
}
|
|
12
|
-
return {};
|
|
13
|
-
}, [config, spec]);
|
|
14
|
-
const validate = React.useMemo(() => {
|
|
15
|
-
if (validators) {
|
|
16
|
-
if ((!_.isString(spec.validator) || !spec.validator.length) &&
|
|
17
|
-
_.isFunction(validators.base)) {
|
|
18
|
-
return (value) => validators.base(spec, value);
|
|
19
|
-
}
|
|
20
|
-
if (_.isString(spec.validator) && _.isFunction(validators[spec.validator])) {
|
|
21
|
-
return (value) => validators[spec.validator](spec, value);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return;
|
|
25
|
-
}, [validators, spec]);
|
|
26
|
-
return validate;
|
|
27
|
-
};
|