@gravity-ui/dynamic-forms 3.1.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/DynamicField.js +6 -4
- package/build/cjs/lib/core/components/Form/constants.js +2 -1
- package/build/cjs/lib/core/components/Form/hooks/index.js +3 -4
- package/build/cjs/lib/core/components/Form/hooks/useMutateDFState.js +6 -0
- package/build/cjs/lib/core/components/Form/hooks/useMutators.js +43 -0
- package/build/cjs/lib/core/components/Form/hooks/useStoreValue.js +6 -0
- package/build/cjs/lib/core/components/Form/index.js +4 -0
- package/build/cjs/lib/core/components/Form/types/index.js +1 -0
- package/build/cjs/lib/core/components/Form/types/mutators.js +2 -0
- 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/DynamicField.d.ts +2 -2
- package/build/esm/lib/core/components/Form/DynamicField.js +7 -5
- package/build/esm/lib/core/components/Form/constants.d.ts +1 -0
- package/build/esm/lib/core/components/Form/constants.js +1 -0
- package/build/esm/lib/core/components/Form/hooks/index.d.ts +3 -4
- package/build/esm/lib/core/components/Form/hooks/index.js +3 -4
- package/build/esm/lib/core/components/Form/hooks/useMutateDFState.d.ts +1 -0
- package/build/esm/lib/core/components/Form/hooks/useMutateDFState.js +2 -0
- package/build/esm/lib/core/components/Form/hooks/useMutators.d.ts +5 -0
- package/build/esm/lib/core/components/Form/hooks/useMutators.js +38 -0
- package/build/esm/lib/core/components/Form/hooks/useStoreValue.d.ts +1 -0
- package/build/esm/lib/core/components/Form/hooks/useStoreValue.js +2 -0
- package/build/esm/lib/core/components/Form/index.d.ts +1 -0
- package/build/esm/lib/core/components/Form/index.js +1 -0
- package/build/esm/lib/core/components/Form/types/context.d.ts +4 -2
- package/build/esm/lib/core/components/Form/types/index.d.ts +1 -0
- package/build/esm/lib/core/components/Form/types/index.js +1 -0
- package/build/esm/lib/core/components/Form/types/mirror.d.ts +3 -5
- package/build/esm/lib/core/components/Form/types/mutators.d.ts +18 -0
- package/build/esm/lib/core/components/Form/types/mutators.js +1 -0
- package/package.json +1 -1
- package/build/cjs/lib/core/components/Form/Controller.js +0 -33
- package/build/cjs/lib/core/components/Form/hooks/useComponents.js +0 -40
- package/build/cjs/lib/core/components/Form/hooks/useField.js +0 -167
- 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 -28
- 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 -162
- 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
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
export const useMutators = (externalMutators) => {
|
|
4
|
+
const firstRenderRef = React.useRef(true);
|
|
5
|
+
const [store, setStore] = React.useState(externalMutators || {});
|
|
6
|
+
const mutateDFState = React.useCallback((mutators) => {
|
|
7
|
+
const mergeSpec = (a, b) => {
|
|
8
|
+
const result = _.cloneDeep(a);
|
|
9
|
+
const getKeys = (parent) => {
|
|
10
|
+
if (_.isObjectLike(parent)) {
|
|
11
|
+
return _.keys(parent).reduce((acc, parentKey) => {
|
|
12
|
+
const childKeys = getKeys(parent[parentKey]);
|
|
13
|
+
return [
|
|
14
|
+
...acc,
|
|
15
|
+
...(childKeys.length ? [] : [[parentKey]]),
|
|
16
|
+
...childKeys.map((childKey) => [parentKey, ...childKey]),
|
|
17
|
+
];
|
|
18
|
+
}, []);
|
|
19
|
+
}
|
|
20
|
+
return [];
|
|
21
|
+
};
|
|
22
|
+
getKeys(b).forEach((key) => {
|
|
23
|
+
_.set(result, key, _.get(b, key));
|
|
24
|
+
});
|
|
25
|
+
return result;
|
|
26
|
+
};
|
|
27
|
+
setStore((store) => (Object.assign(Object.assign(Object.assign(Object.assign({}, store), (mutators.errors ? { errors: _.merge(store.errors, mutators.errors) } : {})), (mutators.values ? { values: _.merge(store.values, mutators.values) } : {})), (mutators.spec ? { spec: mergeSpec(store.spec || {}, mutators.spec) } : {}))));
|
|
28
|
+
}, [setStore]);
|
|
29
|
+
React.useEffect(() => {
|
|
30
|
+
if (firstRenderRef.current) {
|
|
31
|
+
firstRenderRef.current = false;
|
|
32
|
+
}
|
|
33
|
+
else if (externalMutators) {
|
|
34
|
+
mutateDFState(externalMutators);
|
|
35
|
+
}
|
|
36
|
+
}, [externalMutators]);
|
|
37
|
+
return { mutators: store, mutateDFState };
|
|
38
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useStoreValue: () => import("..").DynamicFieldStore;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { MonacoEditorProps } from 'react-monaco-editor/lib/types';
|
|
3
3
|
import { StringSpec } from '../../../types';
|
|
4
|
-
import {
|
|
4
|
+
import { DynamicFieldStore, DynamicFormConfig, DynamicFormMutators, FieldValue, ValidateError, WonderMirror } from './';
|
|
5
5
|
export interface DynamicFormsContext {
|
|
6
6
|
config: DynamicFormConfig;
|
|
7
7
|
Monaco?: React.ComponentType<MonacoEditorProps>;
|
|
@@ -11,7 +11,9 @@ export interface DynamicFormsContext {
|
|
|
11
11
|
onChange: (name: string, value: FieldValue, errors?: Record<string, ValidateError>) => void;
|
|
12
12
|
onUnmount: (name: string) => void;
|
|
13
13
|
submitFailed: boolean;
|
|
14
|
+
mutateDFState: (mutators: DynamicFormMutators) => void;
|
|
14
15
|
};
|
|
15
|
-
|
|
16
|
+
store: DynamicFieldStore;
|
|
17
|
+
mutators: DynamicFormMutators;
|
|
16
18
|
__mirror?: WonderMirror;
|
|
17
19
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useIntegrationFF, useSearch, useSearchStore, useStore } from '../hooks';
|
|
2
|
+
import { FieldRenderProps } from './field';
|
|
2
3
|
export interface ControllerMirror {
|
|
3
|
-
|
|
4
|
-
useRender?: ReturnType<typeof useRender>;
|
|
5
|
-
useValidate?: ReturnType<typeof useValidate>;
|
|
6
|
-
useField?: ReturnType<typeof useField>;
|
|
4
|
+
useField?: FieldRenderProps<any>;
|
|
7
5
|
useSearch?: ReturnType<typeof useSearch>;
|
|
8
6
|
}
|
|
9
7
|
export interface DynamicFieldMirror {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ArraySpec, BooleanSpec, FormValue, NumberSpec, ObjectSpec, StringSpec } from '../../../types';
|
|
2
|
+
import { BaseValidateError } from './';
|
|
3
|
+
export type SpecMutator = Partial<(Omit<ArraySpec, 'viewSpec'> & {
|
|
4
|
+
viewSpec: Partial<ArraySpec['viewSpec']>;
|
|
5
|
+
}) | (Omit<BooleanSpec, 'viewSpec'> & {
|
|
6
|
+
viewSpec: Partial<BooleanSpec['viewSpec']>;
|
|
7
|
+
}) | (Omit<NumberSpec, 'viewSpec'> & {
|
|
8
|
+
viewSpec: Partial<NumberSpec['viewSpec']>;
|
|
9
|
+
}) | (Omit<ObjectSpec, 'viewSpec'> & {
|
|
10
|
+
viewSpec: Partial<ObjectSpec['viewSpec']>;
|
|
11
|
+
}) | (Omit<StringSpec, 'viewSpec'> & {
|
|
12
|
+
viewSpec: Partial<StringSpec['viewSpec']>;
|
|
13
|
+
})>;
|
|
14
|
+
export interface DynamicFormMutators {
|
|
15
|
+
errors?: Record<string, BaseValidateError>;
|
|
16
|
+
values?: Record<string, FormValue>;
|
|
17
|
+
spec?: Record<string, SpecMutator>;
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Controller = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const lodash_1 = tslib_1.__importDefault(require("lodash"));
|
|
6
|
-
const hooks_1 = require("./hooks");
|
|
7
|
-
const Controller = ({ spec, name, value, parentOnChange, parentOnUnmount, }) => {
|
|
8
|
-
const { tools, externalErrors, __mirror } = (0, hooks_1.useDynamicFormsCtx)();
|
|
9
|
-
const { inputEntity, Layout } = (0, hooks_1.useComponents)(spec);
|
|
10
|
-
const render = (0, hooks_1.useRender)({ name, spec, inputEntity, Layout });
|
|
11
|
-
const validate = (0, hooks_1.useValidate)(spec);
|
|
12
|
-
const renderProps = (0, hooks_1.useField)({
|
|
13
|
-
name,
|
|
14
|
-
initialValue: lodash_1.default.get(tools.initialValue, name),
|
|
15
|
-
value,
|
|
16
|
-
spec,
|
|
17
|
-
validate,
|
|
18
|
-
tools,
|
|
19
|
-
parentOnChange,
|
|
20
|
-
parentOnUnmount,
|
|
21
|
-
externalErrors,
|
|
22
|
-
});
|
|
23
|
-
const withSearch = (0, hooks_1.useSearch)(spec, renderProps.input.value, name);
|
|
24
|
-
(0, hooks_1.useControllerMirror)(name, {
|
|
25
|
-
useComponents: { inputEntity, Layout },
|
|
26
|
-
useRender: render,
|
|
27
|
-
useValidate: validate,
|
|
28
|
-
useField: renderProps,
|
|
29
|
-
useSearch: withSearch,
|
|
30
|
-
}, __mirror);
|
|
31
|
-
return withSearch(render(renderProps));
|
|
32
|
-
};
|
|
33
|
-
exports.Controller = Controller;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useComponents = 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 react_is_1 = require("react-is");
|
|
8
|
-
const helpers_1 = require("../../../helpers");
|
|
9
|
-
const utils_1 = require("../utils");
|
|
10
|
-
const _1 = require("./");
|
|
11
|
-
const useComponents = (spec) => {
|
|
12
|
-
var _a, _b;
|
|
13
|
-
const { config } = (0, _1.useDynamicFormsCtx)();
|
|
14
|
-
const { inputs, layouts } = react_1.default.useMemo(() => {
|
|
15
|
-
if ((0, utils_1.isCorrectConfig)(config) && (0, helpers_1.isCorrectSpec)(spec)) {
|
|
16
|
-
return config[spec.type];
|
|
17
|
-
}
|
|
18
|
-
return {};
|
|
19
|
-
}, [config, spec]);
|
|
20
|
-
const inputEntity = react_1.default.useMemo(() => {
|
|
21
|
-
if (inputs) {
|
|
22
|
-
const entity = inputs[spec.viewSpec.type];
|
|
23
|
-
if ((0, react_is_1.isValidElementType)(entity === null || entity === void 0 ? void 0 : entity.Component)) {
|
|
24
|
-
return entity;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return;
|
|
28
|
-
}, [inputs, (_a = spec === null || spec === void 0 ? void 0 : spec.viewSpec) === null || _a === void 0 ? void 0 : _a.type]);
|
|
29
|
-
const Layout = react_1.default.useMemo(() => {
|
|
30
|
-
if (layouts && lodash_1.default.isString(spec.viewSpec.layout)) {
|
|
31
|
-
const Component = layouts[spec.viewSpec.layout];
|
|
32
|
-
if ((0, react_is_1.isValidElementType)(Component)) {
|
|
33
|
-
return Component;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return;
|
|
37
|
-
}, [layouts, (_b = spec === null || spec === void 0 ? void 0 : spec.viewSpec) === null || _b === void 0 ? void 0 : _b.layout]);
|
|
38
|
-
return { inputEntity, Layout };
|
|
39
|
-
};
|
|
40
|
-
exports.useComponents = useComponents;
|
|
@@ -1,167 +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, externalErrors, }) => {
|
|
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
|
-
let value = lodash_1.default.cloneDeep(externalValue);
|
|
15
|
-
if (lodash_1.default.isNil(value)) {
|
|
16
|
-
if (spec.defaultValue) {
|
|
17
|
-
value = (0, utils_1.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 ((0, helpers_1.isArraySpec)(spec)) {
|
|
23
|
-
value = { [constants_1.OBJECT_ARRAY_FLAG]: true, [constants_1.OBJECT_ARRAY_CNT]: 0 };
|
|
24
|
-
}
|
|
25
|
-
else if ((0, helpers_1.isObjectSpec)(spec)) {
|
|
26
|
-
value = {};
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
let externalError = lodash_1.default.get(externalErrors, name);
|
|
31
|
-
if (!(lodash_1.default.isString(externalError) ||
|
|
32
|
-
lodash_1.default.isBoolean(externalError) ||
|
|
33
|
-
lodash_1.default.isUndefined(externalError))) {
|
|
34
|
-
externalError = undefined;
|
|
35
|
-
}
|
|
36
|
-
const error = (validate === null || validate === void 0 ? void 0 : validate(value)) || externalError;
|
|
37
|
-
const dirty = !lodash_1.default.isEqual(value, initialValue);
|
|
38
|
-
return {
|
|
39
|
-
active: false,
|
|
40
|
-
dirty,
|
|
41
|
-
error,
|
|
42
|
-
invalid: Boolean(error),
|
|
43
|
-
modified: dirty,
|
|
44
|
-
pristine: true,
|
|
45
|
-
touched: false,
|
|
46
|
-
valid: !error,
|
|
47
|
-
value,
|
|
48
|
-
visited: false,
|
|
49
|
-
childErrors: {},
|
|
50
|
-
};
|
|
51
|
-
});
|
|
52
|
-
const { onChange, onDrop } = react_1.default.useMemo(() => {
|
|
53
|
-
const onChange = (valOrSetter, childErrors) => {
|
|
54
|
-
setState((state) => {
|
|
55
|
-
const _value = lodash_1.default.isFunction(valOrSetter) ? valOrSetter(state.value) : valOrSetter;
|
|
56
|
-
const error = validate === null || validate === void 0 ? void 0 : validate(_value);
|
|
57
|
-
let value = (0, utils_1.transformArrIn)(_value);
|
|
58
|
-
if ((0, helpers_1.isNumberSpec)(spec) && !error) {
|
|
59
|
-
value = (value ? Number(value) : undefined);
|
|
60
|
-
}
|
|
61
|
-
let newChildErrors = Object.assign({}, state.childErrors);
|
|
62
|
-
if (childErrors) {
|
|
63
|
-
const nearestChildName = lodash_1.default.keys(childErrors).sort((a, b) => a.length - b.length)[0];
|
|
64
|
-
if (nearestChildName) {
|
|
65
|
-
const existingСhildNames = lodash_1.default.keys(newChildErrors).filter((childName) => childName.startsWith(nearestChildName));
|
|
66
|
-
newChildErrors = Object.assign(Object.assign({}, lodash_1.default.omit(newChildErrors, existingСhildNames)), childErrors);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
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 });
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
const onDrop = () => {
|
|
73
|
-
if ((0, utils_1.isArrayItem)(name)) {
|
|
74
|
-
(externalParentOnUnmount ? externalParentOnUnmount : tools.onUnmount)(name);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
onChange(undefined, { [name]: false });
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
return { onChange, onDrop };
|
|
81
|
-
}, [initialValue, setState, name, validate, spec, externalParentOnUnmount, tools.onUnmount]);
|
|
82
|
-
const onBlur = react_1.default.useCallback(() => {
|
|
83
|
-
setState((state) => (Object.assign(Object.assign({}, state), { active: false, touched: true })));
|
|
84
|
-
}, [setState]);
|
|
85
|
-
const onFocus = react_1.default.useCallback(() => {
|
|
86
|
-
setState((state) => (Object.assign(Object.assign({}, state), { active: true, visited: true })));
|
|
87
|
-
}, [setState]);
|
|
88
|
-
const parentOnUnmount = react_1.default.useCallback((childName) => {
|
|
89
|
-
if ((0, helpers_1.isArraySpec)(spec) || (0, helpers_1.isObjectSpec)(spec)) {
|
|
90
|
-
onChange((currentValue) => currentValue
|
|
91
|
-
? lodash_1.default.omit(currentValue, childName.split(`${name}.`)[1])
|
|
92
|
-
: currentValue, {
|
|
93
|
-
[childName]: false,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}, [onChange, name, spec]);
|
|
97
|
-
const renderProps = react_1.default.useMemo(() => {
|
|
98
|
-
const onItemAdd = (_value) => {
|
|
99
|
-
const stateValue = (state.value || {
|
|
100
|
-
[constants_1.OBJECT_ARRAY_FLAG]: true,
|
|
101
|
-
[constants_1.OBJECT_ARRAY_CNT]: 0,
|
|
102
|
-
});
|
|
103
|
-
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 });
|
|
104
|
-
const error = validate === null || validate === void 0 ? void 0 : validate(value);
|
|
105
|
-
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 })));
|
|
106
|
-
};
|
|
107
|
-
const onItemRemove = (idx) => {
|
|
108
|
-
parentOnUnmount(`${name}.<${idx}>`);
|
|
109
|
-
};
|
|
110
|
-
return {
|
|
111
|
-
input: {
|
|
112
|
-
name,
|
|
113
|
-
value: state.value,
|
|
114
|
-
onChange,
|
|
115
|
-
onBlur,
|
|
116
|
-
onFocus,
|
|
117
|
-
onDrop,
|
|
118
|
-
parentOnUnmount,
|
|
119
|
-
},
|
|
120
|
-
arrayInput: {
|
|
121
|
-
name,
|
|
122
|
-
value: state.value,
|
|
123
|
-
onItemAdd,
|
|
124
|
-
onItemRemove,
|
|
125
|
-
onDrop,
|
|
126
|
-
},
|
|
127
|
-
meta: Object.assign(Object.assign({}, lodash_1.default.omit(state, 'value')), { submitFailed: tools.submitFailed }),
|
|
128
|
-
};
|
|
129
|
-
}, [
|
|
130
|
-
state,
|
|
131
|
-
setState,
|
|
132
|
-
validate,
|
|
133
|
-
name,
|
|
134
|
-
initialValue,
|
|
135
|
-
tools.submitFailed,
|
|
136
|
-
onChange,
|
|
137
|
-
onBlur,
|
|
138
|
-
onFocus,
|
|
139
|
-
onDrop,
|
|
140
|
-
parentOnUnmount,
|
|
141
|
-
]);
|
|
142
|
-
react_1.default.useEffect(() => {
|
|
143
|
-
if (!firstRenderRef.current || !lodash_1.default.isEqual(externalValue, state.value) || state.error) {
|
|
144
|
-
(parentOnChange ? parentOnChange : tools.onChange)(name, state.value, Object.assign(Object.assign({}, state.childErrors), { [name]: state.error }));
|
|
145
|
-
}
|
|
146
|
-
}, [state.value]);
|
|
147
|
-
react_1.default.useEffect(() => {
|
|
148
|
-
const externalError = lodash_1.default.get(externalErrors, name);
|
|
149
|
-
if (!firstRenderRef.current &&
|
|
150
|
-
(lodash_1.default.isString(externalError) ||
|
|
151
|
-
lodash_1.default.isBoolean(externalError) ||
|
|
152
|
-
lodash_1.default.isUndefined(externalError)) &&
|
|
153
|
-
state.error !== externalError &&
|
|
154
|
-
!(state.error && !externalError)) {
|
|
155
|
-
setState(Object.assign(Object.assign({}, state), { error: externalError }));
|
|
156
|
-
(parentOnChange ? parentOnChange : tools.onChange)(name, state.value, Object.assign(Object.assign({}, state.childErrors), { [name]: externalError }));
|
|
157
|
-
}
|
|
158
|
-
}, [externalErrors]);
|
|
159
|
-
react_1.default.useEffect(() => {
|
|
160
|
-
firstRenderRef.current = false;
|
|
161
|
-
return () => {
|
|
162
|
-
(externalParentOnUnmount ? externalParentOnUnmount : tools.onUnmount)(name);
|
|
163
|
-
};
|
|
164
|
-
}, []);
|
|
165
|
-
return renderProps;
|
|
166
|
-
};
|
|
167
|
-
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, name, value, parentOnChange, parentOnUnmount, }: ControllerProps<Value, SpecType>) => JSX.Element | null;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import { useComponents, useControllerMirror, useDynamicFormsCtx, useField, useRender, useSearch, useValidate, } from './hooks';
|
|
3
|
-
export const Controller = ({ spec, name, value, parentOnChange, parentOnUnmount, }) => {
|
|
4
|
-
const { tools, externalErrors, __mirror } = useDynamicFormsCtx();
|
|
5
|
-
const { inputEntity, Layout } = useComponents(spec);
|
|
6
|
-
const render = useRender({ name, spec, inputEntity, Layout });
|
|
7
|
-
const validate = useValidate(spec);
|
|
8
|
-
const renderProps = useField({
|
|
9
|
-
name,
|
|
10
|
-
initialValue: _.get(tools.initialValue, name),
|
|
11
|
-
value,
|
|
12
|
-
spec,
|
|
13
|
-
validate,
|
|
14
|
-
tools,
|
|
15
|
-
parentOnChange,
|
|
16
|
-
parentOnUnmount,
|
|
17
|
-
externalErrors,
|
|
18
|
-
});
|
|
19
|
-
const withSearch = useSearch(spec, renderProps.input.value, name);
|
|
20
|
-
useControllerMirror(name, {
|
|
21
|
-
useComponents: { inputEntity, Layout },
|
|
22
|
-
useRender: render,
|
|
23
|
-
useValidate: validate,
|
|
24
|
-
useField: renderProps,
|
|
25
|
-
useSearch: withSearch,
|
|
26
|
-
}, __mirror);
|
|
27
|
-
return withSearch(render(renderProps));
|
|
28
|
-
};
|
|
@@ -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 { BaseValidateError, 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
|
-
externalErrors?: Record<string, BaseValidateError>;
|
|
13
|
-
}
|
|
14
|
-
export declare const useField: <Value extends FieldValue, SpecType extends Spec>({ name, spec, initialValue, value: externalValue, validate: propsValidate, tools, parentOnChange, parentOnUnmount: externalParentOnUnmount, externalErrors, }: UseFieldProps<Value, SpecType>) => FieldRenderProps<Value>;
|