@gravity-ui/dynamic-forms 3.2.0 → 3.4.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.
Files changed (79) hide show
  1. package/build/cjs/lib/core/components/Form/Controller/Controller.js +120 -0
  2. package/build/cjs/lib/core/components/Form/Controller/index.js +4 -0
  3. package/build/cjs/lib/core/components/Form/Controller/types.js +2 -0
  4. package/build/cjs/lib/core/components/Form/Controller/utils.js +305 -0
  5. package/build/cjs/lib/core/components/Form/hooks/index.js +0 -4
  6. package/build/cjs/lib/core/components/Form/hooks/useMutators.js +21 -1
  7. package/build/cjs/lib/core/components/Form/utils/common.js +1 -5
  8. package/build/cjs/lib/kit/components/AccordeonCard/AccordeonCard.css +6 -6
  9. package/build/cjs/lib/kit/components/Card/Card.css +3 -3
  10. package/build/cjs/lib/kit/components/ErrorWrapper/ErrorWrapper.css +4 -4
  11. package/build/cjs/lib/kit/components/GroupIndent/GroupIndent.css +1 -1
  12. package/build/cjs/lib/kit/components/Inputs/FileInput/FileInput.css +1 -1
  13. package/build/cjs/lib/kit/components/Inputs/MonacoInput/MonacoHeader.css +1 -1
  14. package/build/cjs/lib/kit/components/Inputs/MonacoInput/MonacoInputBase.css +1 -1
  15. package/build/cjs/lib/kit/components/Inputs/MonacoInput/MonacoInputDialog.css +1 -1
  16. package/build/cjs/lib/kit/components/Inputs/OneOf/OneOf.css +1 -1
  17. package/build/cjs/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.css +1 -1
  18. package/build/cjs/lib/kit/components/Layouts/Row/Row.css +3 -3
  19. package/build/cjs/lib/kit/components/LongValue/LongValue.css +1 -1
  20. package/build/cjs/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.css +4 -4
  21. package/build/cjs/lib/kit/components/ViewLayouts/ViewRow/ViewRow.css +2 -2
  22. package/build/cjs/lib/kit/components/Views/MonacoInputView/MonacoBaseView.css +1 -1
  23. package/build/cjs/lib/kit/components/Views/MonacoInputView/MonacoViewDialog.css +1 -1
  24. package/build/cjs/lib/kit/components/Views/ObjectValueInputView/ObjectValueInputView.js +1 -1
  25. package/build/cjs/lib/kit/validators/types.js +2 -0
  26. package/build/cjs/lib/kit/validators/validators.js +32 -25
  27. package/build/esm/lib/core/components/Form/Controller/Controller.d.ts +10 -0
  28. package/build/esm/lib/core/components/Form/Controller/Controller.js +115 -0
  29. package/build/esm/lib/core/components/Form/Controller/index.d.ts +1 -0
  30. package/build/esm/lib/core/components/Form/Controller/index.js +1 -0
  31. package/build/esm/lib/core/components/Form/Controller/types.d.ts +98 -0
  32. package/build/esm/lib/core/components/Form/Controller/types.js +1 -0
  33. package/build/esm/lib/core/components/Form/Controller/utils.d.ts +26 -0
  34. package/build/esm/lib/core/components/Form/Controller/utils.js +291 -0
  35. package/build/esm/lib/core/components/Form/hooks/index.d.ts +0 -4
  36. package/build/esm/lib/core/components/Form/hooks/index.js +0 -4
  37. package/build/esm/lib/core/components/Form/hooks/useMutators.js +21 -1
  38. package/build/esm/lib/core/components/Form/types/mirror.d.ts +3 -5
  39. package/build/esm/lib/core/components/Form/types/mutators.d.ts +13 -2
  40. package/build/esm/lib/core/components/Form/utils/common.d.ts +0 -3
  41. package/build/esm/lib/core/components/Form/utils/common.js +0 -2
  42. package/build/esm/lib/kit/components/AccordeonCard/AccordeonCard.css +6 -6
  43. package/build/esm/lib/kit/components/Card/Card.css +3 -3
  44. package/build/esm/lib/kit/components/ErrorWrapper/ErrorWrapper.css +4 -4
  45. package/build/esm/lib/kit/components/GroupIndent/GroupIndent.css +1 -1
  46. package/build/esm/lib/kit/components/Inputs/FileInput/FileInput.css +1 -1
  47. package/build/esm/lib/kit/components/Inputs/MonacoInput/MonacoHeader.css +1 -1
  48. package/build/esm/lib/kit/components/Inputs/MonacoInput/MonacoInputBase.css +1 -1
  49. package/build/esm/lib/kit/components/Inputs/MonacoInput/MonacoInputDialog.css +1 -1
  50. package/build/esm/lib/kit/components/Inputs/OneOf/OneOf.css +1 -1
  51. package/build/esm/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.css +1 -1
  52. package/build/esm/lib/kit/components/Layouts/Row/Row.css +3 -3
  53. package/build/esm/lib/kit/components/LongValue/LongValue.css +1 -1
  54. package/build/esm/lib/kit/components/SimpleVerticalAccordeon/SimpleVerticalAccordeon.css +4 -4
  55. package/build/esm/lib/kit/components/ViewLayouts/ViewRow/ViewRow.css +2 -2
  56. package/build/esm/lib/kit/components/Views/MonacoInputView/MonacoBaseView.css +1 -1
  57. package/build/esm/lib/kit/components/Views/MonacoInputView/MonacoViewDialog.css +1 -1
  58. package/build/esm/lib/kit/components/Views/ObjectValueInputView/ObjectValueInputView.js +1 -1
  59. package/build/esm/lib/kit/validators/messages.d.ts +2 -16
  60. package/build/esm/lib/kit/validators/types.d.ts +16 -0
  61. package/build/esm/lib/kit/validators/types.js +1 -0
  62. package/build/esm/lib/kit/validators/validators.d.ts +10 -9
  63. package/build/esm/lib/kit/validators/validators.js +32 -25
  64. package/package.json +10 -2
  65. package/build/cjs/lib/core/components/Form/Controller.js +0 -42
  66. package/build/cjs/lib/core/components/Form/hooks/useComponents.js +0 -40
  67. package/build/cjs/lib/core/components/Form/hooks/useField.js +0 -176
  68. package/build/cjs/lib/core/components/Form/hooks/useRender.js +0 -28
  69. package/build/cjs/lib/core/components/Form/hooks/useValidate.js +0 -32
  70. package/build/esm/lib/core/components/Form/Controller.d.ts +0 -10
  71. package/build/esm/lib/core/components/Form/Controller.js +0 -37
  72. package/build/esm/lib/core/components/Form/hooks/useComponents.d.ts +0 -6
  73. package/build/esm/lib/core/components/Form/hooks/useComponents.js +0 -35
  74. package/build/esm/lib/core/components/Form/hooks/useField.d.ts +0 -14
  75. package/build/esm/lib/core/components/Form/hooks/useField.js +0 -171
  76. package/build/esm/lib/core/components/Form/hooks/useRender.d.ts +0 -9
  77. package/build/esm/lib/core/components/Form/hooks/useRender.js +0 -23
  78. package/build/esm/lib/core/components/Form/hooks/useValidate.d.ts +0 -3
  79. package/build/esm/lib/core/components/Form/hooks/useValidate.js +0 -27
@@ -1,16 +1,2 @@
1
- export declare let ErrorMessages: {
2
- REQUIRED: string;
3
- INVALID: string;
4
- INT: string;
5
- NUMBER: string;
6
- minLength(count: number | bigint): string;
7
- minLengthArr(count: number | bigint): string;
8
- maxLength(count: number | bigint): string;
9
- maxLengthArr(count: number | bigint): string;
10
- minNumber(count: number | bigint): string;
11
- maxNumber(count: number | bigint): string;
12
- SPACE_START: string;
13
- SPACE_END: string;
14
- DOT_END: string;
15
- ZERO_START: string;
16
- };
1
+ import type { ErrorMessagesType } from './types';
2
+ export declare let ErrorMessages: ErrorMessagesType;
@@ -0,0 +1,16 @@
1
+ export interface ErrorMessagesType {
2
+ REQUIRED: string;
3
+ INVALID: string;
4
+ INT: string;
5
+ NUMBER: string;
6
+ minLength: (count: number | bigint) => string;
7
+ minLengthArr: (count: number | bigint) => string;
8
+ maxLength: (count: number | bigint) => string;
9
+ maxLengthArr: (count: number | bigint) => string;
10
+ minNumber: (count: number | bigint) => string;
11
+ maxNumber: (count: number | bigint) => string;
12
+ SPACE_START: string;
13
+ SPACE_END: string;
14
+ DOT_END: string;
15
+ ZERO_START: string;
16
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,16 +1,18 @@
1
1
  import { ArraySpec, ArrayValue, BooleanSpec, NumberSpec, ObjectSpec, ObjectValue, StringSpec } from '../../core';
2
- export interface GetArrayValidatorParams {
2
+ import { ErrorMessagesType } from './types';
3
+ interface CommonValidatorParams {
3
4
  ignoreRequiredCheck?: boolean;
5
+ customErrorMessages?: Partial<ErrorMessagesType>;
6
+ }
7
+ export interface GetArrayValidatorParams extends CommonValidatorParams {
4
8
  ignoreMaxLengthCheck?: boolean;
5
9
  ignoreMinLengthCheck?: boolean;
6
10
  }
7
11
  export declare const getArrayValidator: (params?: GetArrayValidatorParams) => (spec: ArraySpec, value?: ArrayValue) => string | false;
8
- export interface GetBooleanValidatorParams {
9
- ignoreRequiredCheck?: boolean;
12
+ export interface GetBooleanValidatorParams extends CommonValidatorParams {
10
13
  }
11
14
  export declare const getBooleanValidator: (params?: GetBooleanValidatorParams) => (spec: BooleanSpec, value?: boolean) => string | false;
12
- export interface GetNumberValidatorParams {
13
- ignoreRequiredCheck?: boolean;
15
+ export interface GetNumberValidatorParams extends CommonValidatorParams {
14
16
  ignoreSpaceStartCheck?: boolean;
15
17
  ignoreSpaceEndCheck?: boolean;
16
18
  ignoreNumberCheck?: boolean;
@@ -21,12 +23,10 @@ export interface GetNumberValidatorParams {
21
23
  ignoreZeroStart?: boolean;
22
24
  }
23
25
  export declare const getNumberValidator: (params?: GetNumberValidatorParams) => (spec: NumberSpec, value?: string | number) => string | false;
24
- export interface GetObjectValidatorParams {
25
- ignoreRequiredCheck?: boolean;
26
+ export interface GetObjectValidatorParams extends CommonValidatorParams {
26
27
  }
27
28
  export declare const getObjectValidator: (params?: GetObjectValidatorParams) => (spec: ObjectSpec, value?: ObjectValue) => string | false;
28
- export interface GetStringValidatorParams {
29
- ignoreRequiredCheck?: boolean;
29
+ export interface GetStringValidatorParams extends CommonValidatorParams {
30
30
  ignoreSpaceStartCheck?: boolean;
31
31
  ignoreSpaceEndCheck?: boolean;
32
32
  ignoreMaxLengthCheck?: boolean;
@@ -34,3 +34,4 @@ export interface GetStringValidatorParams {
34
34
  ignoreRegExpCheck?: boolean;
35
35
  }
36
36
  export declare const getStringValidator: (params?: GetStringValidatorParams) => (spec: StringSpec, value?: string) => string | false;
37
+ export {};
@@ -2,122 +2,129 @@ import _ from 'lodash';
2
2
  import { ErrorMessages } from '../validators';
3
3
  import { isFloat, isInt } from './helpers';
4
4
  export const getArrayValidator = (params = {}) => {
5
- const { ignoreRequiredCheck, ignoreMaxLengthCheck, ignoreMinLengthCheck } = params;
5
+ const { ignoreRequiredCheck, ignoreMaxLengthCheck, ignoreMinLengthCheck, customErrorMessages } = params;
6
+ const errorMessages = Object.assign(Object.assign({}, ErrorMessages), customErrorMessages);
6
7
  return (spec, value) => {
7
8
  const valueLength = (value === null || value === void 0 ? void 0 : value.length) || 0;
8
9
  if (!ignoreRequiredCheck && spec.required && !_.isArray(value)) {
9
- return ErrorMessages.REQUIRED;
10
+ return errorMessages.REQUIRED;
10
11
  }
11
12
  if (!ignoreMaxLengthCheck &&
12
13
  typeof spec.maxLength === 'bigint' &&
13
14
  valueLength > spec.maxLength) {
14
- return ErrorMessages.maxLengthArr(spec.maxLength);
15
+ return errorMessages.maxLengthArr(spec.maxLength);
15
16
  }
16
17
  if (!ignoreMinLengthCheck &&
17
18
  typeof spec.minLength === 'bigint' &&
18
19
  valueLength < spec.minLength) {
19
- return ErrorMessages.minLengthArr(spec.minLength);
20
+ return errorMessages.minLengthArr(spec.minLength);
20
21
  }
21
22
  return false;
22
23
  };
23
24
  };
24
25
  export const getBooleanValidator = (params = {}) => {
25
- const { ignoreRequiredCheck } = params;
26
+ const { ignoreRequiredCheck, customErrorMessages } = params;
27
+ const errorMessages = Object.assign(Object.assign({}, ErrorMessages), customErrorMessages);
26
28
  return (spec, value) => {
27
29
  if (!ignoreRequiredCheck && spec.required && !value) {
28
- return ErrorMessages.REQUIRED;
30
+ return errorMessages.REQUIRED;
29
31
  }
30
32
  return false;
31
33
  };
32
34
  };
33
35
  export const getNumberValidator = (params = {}) => {
34
- const { ignoreRequiredCheck, ignoreSpaceStartCheck, ignoreSpaceEndCheck, ignoreNumberCheck, ignoreMaximumCheck, ignoreMinimumCheck, ignoreIntCheck, ignoreDotEnd, ignoreZeroStart, } = params;
36
+ const { ignoreRequiredCheck, ignoreSpaceStartCheck, ignoreSpaceEndCheck, ignoreNumberCheck, ignoreMaximumCheck, ignoreMinimumCheck, ignoreIntCheck, ignoreDotEnd, ignoreZeroStart, customErrorMessages, } = params;
37
+ const errorMessages = Object.assign(Object.assign({}, ErrorMessages), customErrorMessages);
38
+ // eslint-disable-next-line complexity
35
39
  return (spec, value = '') => {
36
40
  const stringValue = String(value);
37
41
  if (!ignoreRequiredCheck && spec.required && !stringValue.length) {
38
- return ErrorMessages.REQUIRED;
42
+ return errorMessages.REQUIRED;
39
43
  }
40
44
  if (stringValue.length) {
41
45
  if (!ignoreSpaceStartCheck && !stringValue[0].trim()) {
42
- return ErrorMessages.SPACE_START;
46
+ return errorMessages.SPACE_START;
43
47
  }
44
48
  if (!ignoreSpaceEndCheck && !stringValue[stringValue.length - 1].trim()) {
45
- return ErrorMessages.SPACE_END;
49
+ return errorMessages.SPACE_END;
46
50
  }
47
51
  if (!ignoreDotEnd && stringValue[stringValue.length - 1] === '.') {
48
- return ErrorMessages.DOT_END;
52
+ return errorMessages.DOT_END;
49
53
  }
50
54
  if (!ignoreNumberCheck && !isFloat(stringValue)) {
51
- return ErrorMessages.NUMBER;
55
+ return errorMessages.NUMBER;
52
56
  }
53
57
  if (!ignoreZeroStart &&
54
58
  ((stringValue.length > 1 && stringValue[0] === '0' && stringValue[1] !== '.') ||
55
59
  (stringValue.length > 2 &&
56
60
  stringValue.substring(0, 2) === '-0' &&
57
61
  stringValue[2] !== '.'))) {
58
- return ErrorMessages.ZERO_START;
62
+ return errorMessages.ZERO_START;
59
63
  }
60
64
  }
61
65
  if (!ignoreMaximumCheck &&
62
66
  _.isNumber(spec.maximum) &&
63
67
  stringValue.length &&
64
68
  Number(stringValue) > spec.maximum) {
65
- return ErrorMessages.maxNumber(spec.maximum);
69
+ return errorMessages.maxNumber(spec.maximum);
66
70
  }
67
71
  if (!ignoreMinimumCheck &&
68
72
  _.isNumber(spec.minimum) &&
69
73
  stringValue.length &&
70
74
  spec.minimum > Number(stringValue)) {
71
- return ErrorMessages.minNumber(spec.minimum);
75
+ return errorMessages.minNumber(spec.minimum);
72
76
  }
73
77
  if (_.isString(spec.format) && stringValue.length) {
74
78
  if (!ignoreIntCheck && spec.format === 'int64' && !isInt(stringValue)) {
75
- return ErrorMessages.INT;
79
+ return errorMessages.INT;
76
80
  }
77
81
  }
78
82
  return false;
79
83
  };
80
84
  };
81
85
  export const getObjectValidator = (params = {}) => {
82
- const { ignoreRequiredCheck } = params;
86
+ const { ignoreRequiredCheck, customErrorMessages } = params;
87
+ const errorMessages = Object.assign(Object.assign({}, ErrorMessages), customErrorMessages);
83
88
  return (spec, value) => {
84
89
  if (!ignoreRequiredCheck && spec.required && !value) {
85
- return ErrorMessages.REQUIRED;
90
+ return errorMessages.REQUIRED;
86
91
  }
87
92
  return false;
88
93
  };
89
94
  };
90
95
  export const getStringValidator = (params = {}) => {
91
- const { ignoreRequiredCheck, ignoreSpaceStartCheck, ignoreSpaceEndCheck, ignoreMaxLengthCheck, ignoreMinLengthCheck, ignoreRegExpCheck, } = params;
96
+ const { ignoreRequiredCheck, ignoreSpaceStartCheck, ignoreSpaceEndCheck, ignoreMaxLengthCheck, ignoreMinLengthCheck, ignoreRegExpCheck, customErrorMessages, } = params;
97
+ const errorMessages = Object.assign(Object.assign({}, ErrorMessages), customErrorMessages);
98
+ // eslint-disable-next-line complexity
92
99
  return (spec, value = '') => {
93
100
  const valueLength = value === null || value === void 0 ? void 0 : value.length;
94
101
  if (!ignoreRequiredCheck && spec.required && !valueLength) {
95
- return ErrorMessages.REQUIRED;
102
+ return errorMessages.REQUIRED;
96
103
  }
97
104
  if (valueLength) {
98
105
  if (!ignoreSpaceStartCheck && !value[0].trim()) {
99
- return ErrorMessages.SPACE_START;
106
+ return errorMessages.SPACE_START;
100
107
  }
101
108
  if (!ignoreSpaceEndCheck && !value[value.length - 1].trim()) {
102
- return ErrorMessages.SPACE_END;
109
+ return errorMessages.SPACE_END;
103
110
  }
104
111
  }
105
112
  if (!ignoreMaxLengthCheck &&
106
113
  typeof spec.maxLength === 'bigint' &&
107
114
  valueLength > spec.maxLength) {
108
- return ErrorMessages.maxLength(spec.maxLength);
115
+ return errorMessages.maxLength(spec.maxLength);
109
116
  }
110
117
  if (!ignoreMinLengthCheck &&
111
118
  typeof spec.minLength === 'bigint' &&
112
119
  valueLength < spec.minLength) {
113
- return ErrorMessages.minLength(spec.minLength);
120
+ return errorMessages.minLength(spec.minLength);
114
121
  }
115
122
  if (_.isString(spec.pattern) && spec.pattern.length) {
116
123
  const regex = new RegExp(spec.pattern);
117
124
  if (!ignoreRegExpCheck && !regex.test(value)) {
118
125
  return _.isString(spec.patternError) && spec.patternError.length
119
126
  ? spec.patternError
120
- : ErrorMessages.INVALID;
127
+ : errorMessages.INVALID;
121
128
  }
122
129
  }
123
130
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/dynamic-forms",
3
- "version": "3.2.0",
3
+ "version": "3.4.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "build/cjs/index.js",
@@ -34,7 +34,12 @@
34
34
  "build-storybook": "sb build",
35
35
  "dev": "sb dev -p 6006",
36
36
  "start": "sb dev",
37
- "prepublishOnly": "npm run build"
37
+ "prepublishOnly": "npm run build",
38
+ "playwright:install": "playwright install --with-deps",
39
+ "playwright": "playwright test --config=playwright/playwright.config.ts",
40
+ "playwright:update": "npm run playwright -- -u",
41
+ "playwright:docker": "docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.39.0-jammy /bin/bash -c 'npm ci && npx playwright install && npm run playwright'",
42
+ "playwright:docker:update": " docker run --rm --network host -v $(pwd):/work/ -w /work/ -it mcr.microsoft.com/playwright:v1.39.0-jammy /bin/bash -c 'npm ci && npx playwright install && npm run playwright:update'"
38
43
  },
39
44
  "dependencies": {
40
45
  "@bem-react/classname": "^1.6.0",
@@ -53,6 +58,8 @@
53
58
  "@gravity-ui/stylelint-config": "^2.0.0",
54
59
  "@gravity-ui/tsconfig": "^1.0.0",
55
60
  "@gravity-ui/uikit": "^5.19.1",
61
+ "@playwright/experimental-ct-react": "^1.40.0",
62
+ "@playwright/test": "^1.40.0",
56
63
  "@storybook/addon-essentials": "^7.0.27",
57
64
  "@storybook/preset-scss": "^1.0.3",
58
65
  "@storybook/react": "^7.0.27",
@@ -66,6 +73,7 @@
66
73
  "@types/react-dom": "^18.0.11",
67
74
  "@types/react-is": "^17.0.3",
68
75
  "@types/uuid": "^9.0.4",
76
+ "@vitejs/plugin-react": "^4.2.0",
69
77
  "css-loader": "^5.2.6",
70
78
  "eslint": "^8.27.0",
71
79
  "final-form": "^4.20.2",
@@ -1,42 +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 react_1 = tslib_1.__importDefault(require("react"));
6
- const lodash_1 = tslib_1.__importDefault(require("lodash"));
7
- const constants_1 = require("./constants");
8
- const hooks_1 = require("./hooks");
9
- const Controller = ({ spec: _spec, name, value, parentOnChange, parentOnUnmount, }) => {
10
- const { tools, mutators, __mirror } = (0, hooks_1.useDynamicFormsCtx)();
11
- const spec = react_1.default.useMemo(() => {
12
- const specMutator = lodash_1.default.get(mutators.spec, name, constants_1.EMPTY_MUTATOR);
13
- if (specMutator !== constants_1.EMPTY_MUTATOR) {
14
- return lodash_1.default.merge(_spec, specMutator);
15
- }
16
- return _spec;
17
- }, [_spec, mutators.spec, name]);
18
- const { inputEntity, Layout } = (0, hooks_1.useComponents)(spec);
19
- const render = (0, hooks_1.useRender)({ name, spec, inputEntity, Layout });
20
- const validate = (0, hooks_1.useValidate)(spec);
21
- const renderProps = (0, hooks_1.useField)({
22
- name,
23
- initialValue: lodash_1.default.get(tools.initialValue, name),
24
- value,
25
- spec,
26
- validate,
27
- tools,
28
- parentOnChange,
29
- parentOnUnmount,
30
- mutators,
31
- });
32
- const withSearch = (0, hooks_1.useSearch)(spec, renderProps.input.value, name);
33
- (0, hooks_1.useControllerMirror)(name, {
34
- useComponents: { inputEntity, Layout },
35
- useRender: render,
36
- useValidate: validate,
37
- useField: renderProps,
38
- useSearch: withSearch,
39
- }, __mirror);
40
- return withSearch(render(renderProps));
41
- };
42
- 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,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
- };