@rjsf/utils 6.0.0-beta.9 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index.js → index.cjs} +563 -200
- package/dist/index.cjs.map +7 -0
- package/dist/utils.esm.js +562 -199
- package/dist/utils.esm.js.map +4 -4
- package/dist/utils.umd.js +533 -193
- package/lib/ErrorSchemaBuilder.d.ts +2 -2
- package/lib/constants.d.ts +3 -0
- package/lib/constants.js +3 -0
- package/lib/constants.js.map +1 -1
- package/lib/createSchemaUtils.js +25 -18
- package/lib/createSchemaUtils.js.map +1 -1
- package/lib/enums.d.ts +13 -3
- package/lib/enums.js +13 -3
- package/lib/enums.js.map +1 -1
- package/lib/findSchemaDefinition.d.ts +6 -0
- package/lib/findSchemaDefinition.js +44 -3
- package/lib/findSchemaDefinition.js.map +1 -1
- package/lib/getDateElementProps.d.ts +1 -2
- package/lib/getTestIds.js +2 -2
- package/lib/getTestIds.js.map +1 -1
- package/lib/getUiOptions.js +4 -0
- package/lib/getUiOptions.js.map +1 -1
- package/lib/getWidget.js +3 -3
- package/lib/getWidget.js.map +1 -1
- package/lib/guessType.d.ts +1 -1
- package/lib/idGenerators.d.ts +22 -15
- package/lib/idGenerators.js +17 -8
- package/lib/idGenerators.js.map +1 -1
- package/lib/index.d.ts +16 -6
- package/lib/index.js +13 -4
- package/lib/index.js.map +1 -1
- package/lib/isFormDataAvailable.d.ts +7 -0
- package/lib/isFormDataAvailable.js +13 -0
- package/lib/isFormDataAvailable.js.map +1 -0
- package/lib/isRootSchema.d.ts +13 -0
- package/lib/isRootSchema.js +25 -0
- package/lib/isRootSchema.js.map +1 -0
- package/lib/mergeDefaultsWithFormData.js +14 -2
- package/lib/mergeDefaultsWithFormData.js.map +1 -1
- package/lib/nameGenerators.d.ts +13 -0
- package/lib/nameGenerators.js +30 -0
- package/lib/nameGenerators.js.map +1 -0
- package/lib/schema/getDefaultFormState.d.ts +17 -3
- package/lib/schema/getDefaultFormState.js +66 -26
- package/lib/schema/getDefaultFormState.js.map +1 -1
- package/lib/schema/getDisplayLabel.js +2 -2
- package/lib/schema/getDisplayLabel.js.map +1 -1
- package/lib/schema/index.d.ts +1 -2
- package/lib/schema/index.js +1 -2
- package/lib/schema/index.js.map +1 -1
- package/lib/schema/retrieveSchema.d.ts +10 -5
- package/lib/schema/retrieveSchema.js +40 -17
- package/lib/schema/retrieveSchema.js.map +1 -1
- package/lib/shallowEquals.d.ts +8 -0
- package/lib/shallowEquals.js +36 -0
- package/lib/shallowEquals.js.map +1 -0
- package/lib/shouldRender.d.ts +8 -2
- package/lib/shouldRender.js +17 -2
- package/lib/shouldRender.js.map +1 -1
- package/lib/shouldRenderOptionalField.d.ts +18 -0
- package/lib/shouldRenderOptionalField.js +47 -0
- package/lib/shouldRenderOptionalField.js.map +1 -0
- package/lib/toFieldPathId.d.ts +14 -0
- package/lib/toFieldPathId.js +26 -0
- package/lib/toFieldPathId.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.d.ts +196 -105
- package/lib/useAltDateWidgetProps.d.ts +39 -0
- package/lib/useAltDateWidgetProps.js +71 -0
- package/lib/useAltDateWidgetProps.js.map +1 -0
- package/lib/useDeepCompareMemo.d.ts +8 -0
- package/lib/useDeepCompareMemo.js +17 -0
- package/lib/useDeepCompareMemo.js.map +1 -0
- package/lib/useFileWidgetProps.d.ts +29 -0
- package/lib/useFileWidgetProps.js +119 -0
- package/lib/useFileWidgetProps.js.map +1 -0
- package/lib/validationDataMerge.d.ts +2 -1
- package/lib/validationDataMerge.js +3 -2
- package/lib/validationDataMerge.js.map +1 -1
- package/package.json +13 -14
- package/src/ErrorSchemaBuilder.ts +2 -2
- package/src/constants.ts +3 -0
- package/src/createSchemaUtils.ts +25 -26
- package/src/enums.ts +13 -3
- package/src/findSchemaDefinition.ts +51 -3
- package/src/getDateElementProps.ts +1 -1
- package/src/getTestIds.ts +2 -2
- package/src/getUiOptions.ts +4 -0
- package/src/getWidget.tsx +3 -3
- package/src/idGenerators.ts +35 -25
- package/src/index.ts +36 -5
- package/src/isFormDataAvailable.ts +13 -0
- package/src/isRootSchema.ts +30 -0
- package/src/mergeDefaultsWithFormData.ts +16 -2
- package/src/nameGenerators.ts +43 -0
- package/src/schema/getDefaultFormState.ts +87 -31
- package/src/schema/getDisplayLabel.ts +2 -2
- package/src/schema/index.ts +0 -2
- package/src/schema/retrieveSchema.ts +43 -7
- package/src/shallowEquals.ts +41 -0
- package/src/shouldRender.ts +27 -2
- package/src/shouldRenderOptionalField.ts +56 -0
- package/src/toFieldPathId.ts +34 -0
- package/src/types.ts +229 -113
- package/src/useAltDateWidgetProps.tsx +163 -0
- package/src/useDeepCompareMemo.ts +17 -0
- package/src/useFileWidgetProps.ts +155 -0
- package/src/validationDataMerge.ts +7 -1
- package/dist/index.js.map +0 -7
- package/lib/schema/toIdSchema.d.ts +0 -14
- package/lib/schema/toIdSchema.js +0 -62
- package/lib/schema/toIdSchema.js.map +0 -1
- package/src/schema/toIdSchema.ts +0 -131
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import jsonpointer from 'jsonpointer';
|
|
2
2
|
import omit from 'lodash/omit';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ALL_OF_KEY,
|
|
6
|
+
ID_KEY,
|
|
7
|
+
JSON_SCHEMA_DRAFT_2019_09,
|
|
8
|
+
JSON_SCHEMA_DRAFT_2020_12,
|
|
9
|
+
REF_KEY,
|
|
10
|
+
SCHEMA_KEY,
|
|
11
|
+
} from './constants';
|
|
5
12
|
import { GenericObjectType, RJSFSchema, StrictRJSFSchema } from './types';
|
|
6
13
|
import isObject from 'lodash/isObject';
|
|
7
14
|
import isEmpty from 'lodash/isEmpty';
|
|
@@ -20,7 +27,16 @@ function findEmbeddedSchemaRecursive<S extends StrictRJSFSchema = RJSFSchema>(sc
|
|
|
20
27
|
return schema;
|
|
21
28
|
}
|
|
22
29
|
for (const subSchema of Object.values(schema)) {
|
|
23
|
-
if (
|
|
30
|
+
if (Array.isArray(subSchema)) {
|
|
31
|
+
for (const item of subSchema) {
|
|
32
|
+
if (isObject(item)) {
|
|
33
|
+
const result = findEmbeddedSchemaRecursive<S>(item as S, ref);
|
|
34
|
+
if (result !== undefined) {
|
|
35
|
+
return result as S;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
} else if (isObject(subSchema)) {
|
|
24
40
|
const result = findEmbeddedSchemaRecursive<S>(subSchema as S, ref);
|
|
25
41
|
if (result !== undefined) {
|
|
26
42
|
return result as S;
|
|
@@ -30,6 +46,31 @@ function findEmbeddedSchemaRecursive<S extends StrictRJSFSchema = RJSFSchema>(sc
|
|
|
30
46
|
return undefined;
|
|
31
47
|
}
|
|
32
48
|
|
|
49
|
+
/** Parses a JSONSchema and makes all references absolute with respect to
|
|
50
|
+
* the `baseURI` argument
|
|
51
|
+
* @param schema - The schema to be processed
|
|
52
|
+
* @param baseURI - The base URI to be used for resolving relative references
|
|
53
|
+
*/
|
|
54
|
+
export function makeAllReferencesAbsolute<S extends StrictRJSFSchema = RJSFSchema>(schema: S, baseURI: string): S {
|
|
55
|
+
const currentURI = get(schema, ID_KEY, baseURI);
|
|
56
|
+
// Make all other references absolute
|
|
57
|
+
if (REF_KEY in schema) {
|
|
58
|
+
schema = { ...schema, [REF_KEY]: UriResolver.resolve(currentURI, schema[REF_KEY]!) };
|
|
59
|
+
}
|
|
60
|
+
// Look for references in nested subschemas
|
|
61
|
+
for (const [key, subSchema] of Object.entries(schema)) {
|
|
62
|
+
if (Array.isArray(subSchema)) {
|
|
63
|
+
schema = {
|
|
64
|
+
...schema,
|
|
65
|
+
[key]: subSchema.map((item) => (isObject(item) ? makeAllReferencesAbsolute(item as S, currentURI) : item)),
|
|
66
|
+
};
|
|
67
|
+
} else if (isObject(subSchema)) {
|
|
68
|
+
schema = { ...schema, [key]: makeAllReferencesAbsolute(subSchema as S, currentURI) };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return schema;
|
|
72
|
+
}
|
|
73
|
+
|
|
33
74
|
/** Splits out the value at the `key` in `object` from the `object`, returning an array that contains in the first
|
|
34
75
|
* location, the `object` minus the `key: value` and in the second location the `value`.
|
|
35
76
|
*
|
|
@@ -103,7 +144,14 @@ export function findSchemaDefinitionRecursive<S extends StrictRJSFSchema = RJSFS
|
|
|
103
144
|
const [remaining, theRef] = splitKeyElementFromObject(REF_KEY, current);
|
|
104
145
|
const subSchema = findSchemaDefinitionRecursive<S>(theRef, rootSchema, [...recurseList, ref], baseURI);
|
|
105
146
|
if (Object.keys(remaining).length > 0) {
|
|
106
|
-
|
|
147
|
+
if (
|
|
148
|
+
rootSchema[SCHEMA_KEY] === JSON_SCHEMA_DRAFT_2019_09 ||
|
|
149
|
+
rootSchema[SCHEMA_KEY] === JSON_SCHEMA_DRAFT_2020_12
|
|
150
|
+
) {
|
|
151
|
+
return { [ALL_OF_KEY]: [remaining, subSchema] } as S;
|
|
152
|
+
} else {
|
|
153
|
+
return { ...remaining, ...subSchema };
|
|
154
|
+
}
|
|
107
155
|
}
|
|
108
156
|
return subSchema;
|
|
109
157
|
}
|
|
@@ -4,7 +4,7 @@ import { type DateObject } from './types';
|
|
|
4
4
|
export type DateElementFormat = 'DMY' | 'MDY' | 'YMD';
|
|
5
5
|
|
|
6
6
|
/** Type describing format of DateElement prop */
|
|
7
|
-
type DateElementProp = {
|
|
7
|
+
export type DateElementProp = {
|
|
8
8
|
type: string;
|
|
9
9
|
range: [number, number];
|
|
10
10
|
value: number | undefined;
|
package/src/getTestIds.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { nanoid } from 'nanoid';
|
|
2
1
|
import get from 'lodash/get';
|
|
2
|
+
import uniqueId from 'lodash/uniqueId';
|
|
3
3
|
|
|
4
4
|
import { TestIdShape } from './types';
|
|
5
5
|
|
|
@@ -31,7 +31,7 @@ export default function getTestIds(): TestIdShape {
|
|
|
31
31
|
{
|
|
32
32
|
get(_obj, prop) {
|
|
33
33
|
if (!ids.has(prop)) {
|
|
34
|
-
ids.set(prop,
|
|
34
|
+
ids.set(prop, uniqueId('test-id-'));
|
|
35
35
|
}
|
|
36
36
|
return ids.get(prop);
|
|
37
37
|
},
|
package/src/getUiOptions.ts
CHANGED
|
@@ -13,6 +13,10 @@ export default function getUiOptions<T = any, S extends StrictRJSFSchema = RJSFS
|
|
|
13
13
|
uiSchema: UiSchema<T, S, F> = {},
|
|
14
14
|
globalOptions: GlobalUISchemaOptions = {},
|
|
15
15
|
): UIOptionsType<T, S, F> {
|
|
16
|
+
// Handle null or undefined uiSchema
|
|
17
|
+
if (!uiSchema) {
|
|
18
|
+
return { ...globalOptions };
|
|
19
|
+
}
|
|
16
20
|
return Object.keys(uiSchema)
|
|
17
21
|
.filter((key) => key.indexOf('ui:') === 0)
|
|
18
22
|
.reduce(
|
package/src/getWidget.tsx
CHANGED
|
@@ -110,7 +110,7 @@ export default function getWidget<T = any, S extends StrictRJSFSchema = RJSFSche
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
if (typeof widget !== 'string') {
|
|
113
|
-
throw new Error(`Unsupported widget definition: ${typeof widget}`);
|
|
113
|
+
throw new Error(`Unsupported widget definition: ${typeof widget} in schema: ${JSON.stringify(schema)}`);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
if (widget in registeredWidgets) {
|
|
@@ -120,7 +120,7 @@ export default function getWidget<T = any, S extends StrictRJSFSchema = RJSFSche
|
|
|
120
120
|
|
|
121
121
|
if (typeof type === 'string') {
|
|
122
122
|
if (!(type in widgetMap)) {
|
|
123
|
-
throw new Error(`No widget for type '${type}'`);
|
|
123
|
+
throw new Error(`No widget for type '${type}' in schema: ${JSON.stringify(schema)}`);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
if (widget in widgetMap[type]) {
|
|
@@ -129,5 +129,5 @@ export default function getWidget<T = any, S extends StrictRJSFSchema = RJSFSche
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
throw new Error(`No widget '${widget}' for type '${type}'`);
|
|
132
|
+
throw new Error(`No widget '${widget}' for type '${type}' in schema: ${JSON.stringify(schema)}`);
|
|
133
133
|
}
|
package/src/idGenerators.ts
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
1
|
import isString from 'lodash/isString';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { FieldPathId } from './types';
|
|
4
4
|
import { ID_KEY } from './constants';
|
|
5
5
|
|
|
6
6
|
/** Generates a consistent `id` pattern for a given `id` and a `suffix`
|
|
7
7
|
*
|
|
8
|
-
* @param id - Either simple string id or an
|
|
8
|
+
* @param id - Either simple string id or an FieldPathId from which to extract it
|
|
9
9
|
* @param suffix - The suffix to append to the id
|
|
10
10
|
*/
|
|
11
|
-
function idGenerator
|
|
11
|
+
function idGenerator(id: FieldPathId | string, suffix: string) {
|
|
12
12
|
const theId = isString(id) ? id : id[ID_KEY];
|
|
13
13
|
return `${theId}__${suffix}`;
|
|
14
14
|
}
|
|
15
15
|
/** Return a consistent `id` for the field description element
|
|
16
16
|
*
|
|
17
|
-
* @param id - Either simple string id or an
|
|
17
|
+
* @param id - Either simple string id or an FieldPathId from which to extract it
|
|
18
18
|
* @returns - The consistent id for the field description element from the given `id`
|
|
19
19
|
*/
|
|
20
|
-
export function descriptionId
|
|
21
|
-
return idGenerator
|
|
20
|
+
export function descriptionId(id: FieldPathId | string) {
|
|
21
|
+
return idGenerator(id, 'description');
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/** Return a consistent `id` for the field error element
|
|
25
25
|
*
|
|
26
|
-
* @param id - Either simple string id or an
|
|
26
|
+
* @param id - Either simple string id or an FieldPathId from which to extract it
|
|
27
27
|
* @returns - The consistent id for the field error element from the given `id`
|
|
28
28
|
*/
|
|
29
|
-
export function errorId
|
|
30
|
-
return idGenerator
|
|
29
|
+
export function errorId(id: FieldPathId | string) {
|
|
30
|
+
return idGenerator(id, 'error');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/** Return a consistent `id` for the field examples element
|
|
34
34
|
*
|
|
35
|
-
* @param id - Either simple string id or an
|
|
35
|
+
* @param id - Either simple string id or an FieldPathId from which to extract it
|
|
36
36
|
* @returns - The consistent id for the field examples element from the given `id`
|
|
37
37
|
*/
|
|
38
|
-
export function examplesId
|
|
39
|
-
return idGenerator
|
|
38
|
+
export function examplesId(id: FieldPathId | string) {
|
|
39
|
+
return idGenerator(id, 'examples');
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/** Return a consistent `id` for the field help element
|
|
43
43
|
*
|
|
44
|
-
* @param id - Either simple string id or an
|
|
44
|
+
* @param id - Either simple string id or an FieldPathId from which to extract it
|
|
45
45
|
* @returns - The consistent id for the field help element from the given `id`
|
|
46
46
|
*/
|
|
47
|
-
export function helpId
|
|
48
|
-
return idGenerator
|
|
47
|
+
export function helpId(id: FieldPathId | string) {
|
|
48
|
+
return idGenerator(id, 'help');
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
/** Return a consistent `id` for the field title element
|
|
52
52
|
*
|
|
53
|
-
* @param id - Either simple string id or an
|
|
53
|
+
* @param id - Either simple string id or an FieldPathId from which to extract it
|
|
54
54
|
* @returns - The consistent id for the field title element from the given `id`
|
|
55
55
|
*/
|
|
56
|
-
export function titleId
|
|
57
|
-
return idGenerator
|
|
56
|
+
export function titleId(id: FieldPathId | string) {
|
|
57
|
+
return idGenerator(id, 'title');
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/** Return a list of element ids that contain additional information about the field that can be used to as the aria
|
|
61
61
|
* description of the field. This is correctly omitting `titleId` which would be "labeling" rather than "describing" the
|
|
62
62
|
* element.
|
|
63
63
|
*
|
|
64
|
-
* @param id - Either simple string id or an
|
|
64
|
+
* @param id - Either simple string id or an FieldPathId from which to extract it
|
|
65
65
|
* @param [includeExamples=false] - Optional flag, if true, will add the `examplesId` into the list
|
|
66
66
|
* @returns - The string containing the list of ids for use in an `aria-describedBy` attribute
|
|
67
67
|
*/
|
|
68
|
-
export function ariaDescribedByIds
|
|
69
|
-
const examples = includeExamples ? ` ${examplesId
|
|
70
|
-
return `${errorId
|
|
68
|
+
export function ariaDescribedByIds(id: FieldPathId | string, includeExamples = false) {
|
|
69
|
+
const examples = includeExamples ? ` ${examplesId(id)}` : '';
|
|
70
|
+
return `${errorId(id)} ${descriptionId(id)} ${helpId(id)}${examples}`;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/** Return a consistent `id` for the `optionIndex`s of a `Radio` or `Checkboxes` widget
|
|
@@ -82,10 +82,20 @@ export function optionId(id: string, optionIndex: number) {
|
|
|
82
82
|
|
|
83
83
|
/** Return a consistent `id` for the `btn` button element
|
|
84
84
|
*
|
|
85
|
-
* @param id -
|
|
85
|
+
* @param id - The id of the parent component for the option
|
|
86
86
|
* @param btn - The button type for which to generate the id
|
|
87
87
|
* @returns - The consistent id for the button from the given `id` and `btn` type
|
|
88
88
|
*/
|
|
89
|
-
export function buttonId
|
|
90
|
-
return idGenerator
|
|
89
|
+
export function buttonId(id: FieldPathId | string, btn: 'add' | 'copy' | 'moveDown' | 'moveUp' | 'remove') {
|
|
90
|
+
return idGenerator(id, btn);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Return a consistent `id` for the optional data controls `element`
|
|
94
|
+
*
|
|
95
|
+
* @param id - The id of the parent component for the option
|
|
96
|
+
* @param element - The element type for which to generate the id
|
|
97
|
+
* @returns - The consistent id for the optional data controls element from the given `id` and `element` type
|
|
98
|
+
*/
|
|
99
|
+
export function optionalControlsId(id: FieldPathId | string, element: 'Add' | 'Msg' | 'Remove') {
|
|
100
|
+
return idGenerator(id, `optional${element}`);
|
|
91
101
|
}
|
package/src/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import createSchemaUtils from './createSchemaUtils';
|
|
|
6
6
|
import dataURItoBlob from './dataURItoBlob';
|
|
7
7
|
import dateRangeOptions from './dateRangeOptions';
|
|
8
8
|
import deepEquals from './deepEquals';
|
|
9
|
+
import shallowEquals from './shallowEquals';
|
|
9
10
|
import englishStringTranslator from './englishStringTranslator';
|
|
10
11
|
import enumOptionsDeselectValue from './enumOptionsDeselectValue';
|
|
11
12
|
import enumOptionsIndexForValue from './enumOptionsIndexForValue';
|
|
@@ -14,9 +15,11 @@ import enumOptionsSelectValue from './enumOptionsSelectValue';
|
|
|
14
15
|
import enumOptionsValueForIndex from './enumOptionsValueForIndex';
|
|
15
16
|
import ErrorSchemaBuilder from './ErrorSchemaBuilder';
|
|
16
17
|
import findSchemaDefinition from './findSchemaDefinition';
|
|
17
|
-
import
|
|
18
|
+
import getChangedFields from './getChangedFields';
|
|
19
|
+
import getDateElementProps, { DateElementFormat, DateElementProp } from './getDateElementProps';
|
|
18
20
|
import getDiscriminatorFieldFromSchema from './getDiscriminatorFieldFromSchema';
|
|
19
21
|
import getInputProps from './getInputProps';
|
|
22
|
+
import getOptionMatchingSimpleDiscriminator from './getOptionMatchingSimpleDiscriminator';
|
|
20
23
|
import getSchemaType from './getSchemaType';
|
|
21
24
|
import getSubmitButtonOptions from './getSubmitButtonOptions';
|
|
22
25
|
import getTemplate from './getTemplate';
|
|
@@ -33,13 +36,16 @@ import {
|
|
|
33
36
|
errorId,
|
|
34
37
|
examplesId,
|
|
35
38
|
helpId,
|
|
39
|
+
optionalControlsId,
|
|
36
40
|
optionId,
|
|
37
41
|
titleId,
|
|
38
42
|
} from './idGenerators';
|
|
39
43
|
import isConstant from './isConstant';
|
|
40
44
|
import isCustomWidget from './isCustomWidget';
|
|
41
45
|
import isFixedItems from './isFixedItems';
|
|
46
|
+
import isFormDataAvailable from './isFormDataAvailable';
|
|
42
47
|
import isObject from './isObject';
|
|
48
|
+
import isRootSchema from './isRootSchema';
|
|
43
49
|
import labelValue from './labelValue';
|
|
44
50
|
import localToUTC from './localToUTC';
|
|
45
51
|
import lookupFromFormContext from './lookupFromFormContext';
|
|
@@ -53,17 +59,21 @@ import parseDateString from './parseDateString';
|
|
|
53
59
|
import rangeSpec from './rangeSpec';
|
|
54
60
|
import replaceStringParameters from './replaceStringParameters';
|
|
55
61
|
import schemaRequiresTrueValue from './schemaRequiresTrueValue';
|
|
56
|
-
import shouldRender from './shouldRender';
|
|
62
|
+
import shouldRender, { ComponentUpdateStrategy } from './shouldRender';
|
|
63
|
+
import shouldRenderOptionalField from './shouldRenderOptionalField';
|
|
57
64
|
import toConstant from './toConstant';
|
|
58
65
|
import toDateString from './toDateString';
|
|
59
66
|
import toErrorList from './toErrorList';
|
|
60
67
|
import toErrorSchema from './toErrorSchema';
|
|
68
|
+
import toFieldPathId from './toFieldPathId';
|
|
61
69
|
import unwrapErrorHandler from './unwrapErrorHandler';
|
|
70
|
+
import useAltDateWidgetProps, { DateElement, DateElementProps, UseAltDateWidgetResult } from './useAltDateWidgetProps';
|
|
71
|
+
import useDeepCompareMemo from './useDeepCompareMemo';
|
|
72
|
+
import useFileWidgetProps, { FileInfoType, UseFileWidgetPropsResult } from './useFileWidgetProps';
|
|
62
73
|
import utcToLocal from './utcToLocal';
|
|
63
74
|
import validationDataMerge from './validationDataMerge';
|
|
64
75
|
import withIdRefPrefix from './withIdRefPrefix';
|
|
65
|
-
import
|
|
66
|
-
import getChangedFields from './getChangedFields';
|
|
76
|
+
import { bracketNameGenerator, dotNotationNameGenerator } from './nameGenerators';
|
|
67
77
|
|
|
68
78
|
export * from './types';
|
|
69
79
|
export * from './enums';
|
|
@@ -72,6 +82,16 @@ export * from './constants';
|
|
|
72
82
|
export * from './parser';
|
|
73
83
|
export * from './schema';
|
|
74
84
|
|
|
85
|
+
export type {
|
|
86
|
+
ComponentUpdateStrategy,
|
|
87
|
+
DateElementFormat,
|
|
88
|
+
DateElementProp,
|
|
89
|
+
DateElementProps,
|
|
90
|
+
FileInfoType,
|
|
91
|
+
UseAltDateWidgetResult,
|
|
92
|
+
UseFileWidgetPropsResult,
|
|
93
|
+
};
|
|
94
|
+
|
|
75
95
|
export {
|
|
76
96
|
allowAdditionalItems,
|
|
77
97
|
ariaDescribedByIds,
|
|
@@ -80,7 +100,7 @@ export {
|
|
|
80
100
|
canExpand,
|
|
81
101
|
createErrorHandler,
|
|
82
102
|
createSchemaUtils,
|
|
83
|
-
|
|
103
|
+
DateElement,
|
|
84
104
|
dataURItoBlob,
|
|
85
105
|
dateRangeOptions,
|
|
86
106
|
deepEquals,
|
|
@@ -115,13 +135,16 @@ export {
|
|
|
115
135
|
isConstant,
|
|
116
136
|
isCustomWidget,
|
|
117
137
|
isFixedItems,
|
|
138
|
+
isFormDataAvailable,
|
|
118
139
|
isObject,
|
|
140
|
+
isRootSchema,
|
|
119
141
|
labelValue,
|
|
120
142
|
localToUTC,
|
|
121
143
|
lookupFromFormContext,
|
|
122
144
|
mergeDefaultsWithFormData,
|
|
123
145
|
mergeObjects,
|
|
124
146
|
mergeSchemas,
|
|
147
|
+
optionalControlsId,
|
|
125
148
|
optionId,
|
|
126
149
|
optionsList,
|
|
127
150
|
orderProperties,
|
|
@@ -130,15 +153,23 @@ export {
|
|
|
130
153
|
rangeSpec,
|
|
131
154
|
replaceStringParameters,
|
|
132
155
|
schemaRequiresTrueValue,
|
|
156
|
+
shallowEquals,
|
|
133
157
|
shouldRender,
|
|
158
|
+
shouldRenderOptionalField,
|
|
134
159
|
sortedJSONStringify,
|
|
135
160
|
titleId,
|
|
136
161
|
toConstant,
|
|
137
162
|
toDateString,
|
|
138
163
|
toErrorList,
|
|
139
164
|
toErrorSchema,
|
|
165
|
+
toFieldPathId,
|
|
140
166
|
unwrapErrorHandler,
|
|
167
|
+
useAltDateWidgetProps,
|
|
168
|
+
useDeepCompareMemo,
|
|
169
|
+
useFileWidgetProps,
|
|
141
170
|
utcToLocal,
|
|
142
171
|
validationDataMerge,
|
|
143
172
|
withIdRefPrefix,
|
|
173
|
+
bracketNameGenerator,
|
|
174
|
+
dotNotationNameGenerator,
|
|
144
175
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import isNil from 'lodash/isNil';
|
|
2
|
+
import isEmpty from 'lodash/isEmpty';
|
|
3
|
+
import isObject from 'lodash/isObject';
|
|
4
|
+
|
|
5
|
+
/** Determines whether the given `formData` represents valid form data, such as a primitive type, an array, or a
|
|
6
|
+
* non-empty object.
|
|
7
|
+
*
|
|
8
|
+
* @param formData - The data to check
|
|
9
|
+
* @returns - True if `formData` is not undefined, null, a primitive type or an array or an empty object
|
|
10
|
+
*/
|
|
11
|
+
export default function isFormDataAvailable<T = any>(formData?: T): boolean {
|
|
12
|
+
return !isNil(formData) && (!isObject(formData) || Array.isArray(formData) || !isEmpty(formData));
|
|
13
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import isEqual from 'lodash/isEqual';
|
|
2
|
+
|
|
3
|
+
import { FormContextType, Registry, RJSFSchema, StrictRJSFSchema } from './types';
|
|
4
|
+
import { REF_KEY } from './constants';
|
|
5
|
+
|
|
6
|
+
/** Helper to check whether a JSON schema object is the root schema. The schema is a root schema with root `properties`
|
|
7
|
+
* key or a root `$ref` key. If the `schemaToCompare` has a root `oneOf` property, the function will
|
|
8
|
+
* return false. Else if `schemaToCompare` and `rootSchema` are the same object or equal, the function will return
|
|
9
|
+
* `true`. Else if the `rootSchema` has a $ref, it will be resolved using `schemaUtils.resolveSchema` utility. If the
|
|
10
|
+
* resolved schema matches the `schemaToCompare` the function will return `true`. Otherwise, it will return false.
|
|
11
|
+
*
|
|
12
|
+
* @param registry - The `Registry` used to get the `rootSchema` and `schemaUtils`
|
|
13
|
+
* @param schemaToCompare - The JSON schema object to check. If `schemaToCompare` is an root schema, the
|
|
14
|
+
* function will return true.
|
|
15
|
+
* @returns - Flag indicating whether the `schemaToCompare` is the root schema
|
|
16
|
+
*/
|
|
17
|
+
export default function isRootSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
|
|
18
|
+
registry: Registry<T, S, F>,
|
|
19
|
+
schemaToCompare: S,
|
|
20
|
+
): boolean {
|
|
21
|
+
const { rootSchema, schemaUtils } = registry;
|
|
22
|
+
if (isEqual(schemaToCompare, rootSchema)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
if (REF_KEY in rootSchema) {
|
|
26
|
+
const resolvedSchema = schemaUtils.retrieveSchema(rootSchema);
|
|
27
|
+
return isEqual(schemaToCompare, resolvedSchema);
|
|
28
|
+
}
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
@@ -67,8 +67,22 @@ export default function mergeDefaultsWithFormData<T = any>(
|
|
|
67
67
|
const keyValue = get(formData, key);
|
|
68
68
|
const keyExistsInDefaults = isObject(defaults) && key in (defaults as GenericObjectType);
|
|
69
69
|
const keyExistsInFormData = key in (formData as GenericObjectType);
|
|
70
|
+
const keyDefault = get(defaults, key) ?? {};
|
|
71
|
+
const defaultValueIsNestedObject = keyExistsInDefaults && Object.entries(keyDefault).some(([, v]) => isObject(v));
|
|
72
|
+
|
|
73
|
+
const keyDefaultIsObject = keyExistsInDefaults && isObject(get(defaults, key));
|
|
74
|
+
const keyHasFormDataObject = keyExistsInFormData && isObject(keyValue);
|
|
75
|
+
|
|
76
|
+
if (keyDefaultIsObject && keyHasFormDataObject && !defaultValueIsNestedObject) {
|
|
77
|
+
acc[key as keyof T] = {
|
|
78
|
+
...get(defaults, key),
|
|
79
|
+
...keyValue,
|
|
80
|
+
};
|
|
81
|
+
return acc;
|
|
82
|
+
}
|
|
83
|
+
|
|
70
84
|
acc[key as keyof T] = mergeDefaultsWithFormData<T>(
|
|
71
|
-
|
|
85
|
+
get(defaults, key),
|
|
72
86
|
keyValue,
|
|
73
87
|
mergeExtraArrayDefaults,
|
|
74
88
|
defaultSupercedesUndefined,
|
|
@@ -88,7 +102,7 @@ export default function mergeDefaultsWithFormData<T = any>(
|
|
|
88
102
|
*/
|
|
89
103
|
if (
|
|
90
104
|
(defaultSupercedesUndefined &&
|
|
91
|
-
((!
|
|
105
|
+
((!(defaults === undefined) && isNil(formData)) || (typeof formData === 'number' && isNaN(formData)))) ||
|
|
92
106
|
(overrideFormDataWithDefaults && !isNil(formData))
|
|
93
107
|
) {
|
|
94
108
|
return defaults;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { NameGeneratorFunction, FieldPathList } from './types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generates bracketed names
|
|
5
|
+
* Example: root[tasks][0][title]
|
|
6
|
+
* For multi-value fields (checkboxes, multi-select): root[hobbies][]
|
|
7
|
+
*/
|
|
8
|
+
export const bracketNameGenerator: NameGeneratorFunction = (
|
|
9
|
+
path: FieldPathList,
|
|
10
|
+
idPrefix: string,
|
|
11
|
+
isMultiValue?: boolean,
|
|
12
|
+
): string => {
|
|
13
|
+
if (!path || path.length === 0) {
|
|
14
|
+
return idPrefix;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const baseName = path.reduce<string>((acc, pathUnit, index) => {
|
|
18
|
+
if (index === 0) {
|
|
19
|
+
return `${idPrefix}[${String(pathUnit)}]`;
|
|
20
|
+
}
|
|
21
|
+
return `${acc}[${String(pathUnit)}]`;
|
|
22
|
+
}, '');
|
|
23
|
+
|
|
24
|
+
// For multi-value fields, append [] to allow multiple values with the same name
|
|
25
|
+
return isMultiValue ? `${baseName}[]` : baseName;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Generates dot-notation names
|
|
30
|
+
* Example: root.tasks.0.title
|
|
31
|
+
* Multi-value fields are handled the same as single-value fields in dot notation
|
|
32
|
+
*/
|
|
33
|
+
export const dotNotationNameGenerator: NameGeneratorFunction = (
|
|
34
|
+
path: FieldPathList,
|
|
35
|
+
idPrefix: string,
|
|
36
|
+
_isMultiValue?: boolean,
|
|
37
|
+
): string => {
|
|
38
|
+
if (!path || path.length === 0) {
|
|
39
|
+
return idPrefix;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return `${idPrefix}.${path.map(String).join('.')}`;
|
|
43
|
+
};
|