@rjsf/utils 6.0.0-beta.1 → 6.0.0-beta.11
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 +177 -111
- package/dist/index.js.map +3 -3
- package/dist/utils.esm.js +177 -111
- package/dist/utils.esm.js.map +3 -3
- package/dist/utils.umd.js +151 -89
- package/lib/canExpand.d.ts +1 -1
- package/lib/constants.d.ts +4 -0
- package/lib/constants.js +4 -0
- package/lib/constants.js.map +1 -1
- package/lib/findSchemaDefinition.d.ts +4 -2
- package/lib/findSchemaDefinition.js +53 -10
- package/lib/findSchemaDefinition.js.map +1 -1
- package/lib/mergeDefaultsWithFormData.js +13 -1
- package/lib/mergeDefaultsWithFormData.js.map +1 -1
- package/lib/schema/findFieldInSchema.d.ts +1 -1
- package/lib/schema/findFieldInSchema.js +1 -1
- package/lib/schema/getDefaultFormState.js +21 -4
- package/lib/schema/getDefaultFormState.js.map +1 -1
- package/lib/schema/retrieveSchema.d.ts +2 -1
- package/lib/schema/retrieveSchema.js +14 -7
- package/lib/schema/retrieveSchema.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.d.ts +22 -12
- package/package.json +2 -1
- package/src/constants.ts +5 -0
- package/src/findSchemaDefinition.ts +53 -8
- package/src/mergeDefaultsWithFormData.ts +15 -1
- package/src/schema/findFieldInSchema.ts +1 -1
- package/src/schema/getDefaultFormState.ts +24 -5
- package/src/schema/retrieveSchema.ts +14 -5
- package/src/types.ts +27 -11
package/lib/types.d.ts
CHANGED
|
@@ -199,7 +199,7 @@ export type FormValidation<T = any> = FieldValidation & {
|
|
|
199
199
|
export type RJSFBaseProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> = {
|
|
200
200
|
/** The schema object for the field being described */
|
|
201
201
|
schema: S;
|
|
202
|
-
/** The uiSchema object for this
|
|
202
|
+
/** The uiSchema object for this base component */
|
|
203
203
|
uiSchema?: UiSchema<T, S, F>;
|
|
204
204
|
/** The `registry` object */
|
|
205
205
|
registry: Registry<T, S, F>;
|
|
@@ -276,6 +276,8 @@ export type TemplatesType<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
276
276
|
FieldTemplate: ComponentType<FieldTemplateProps<T, S, F>>;
|
|
277
277
|
/** The template to use to render a Grid element */
|
|
278
278
|
GridTemplate: ComponentType<GridTemplateProps>;
|
|
279
|
+
/** The template to use while rendering a multi-schema field (i.e. anyOf, oneOf) */
|
|
280
|
+
MultiSchemaFieldTemplate: ComponentType<MultiSchemaFieldTemplateProps<T, S, F>>;
|
|
279
281
|
/** The template to use while rendering an object */
|
|
280
282
|
ObjectFieldTemplate: ComponentType<ObjectFieldTemplateProps<T, S, F>>;
|
|
281
283
|
/** The template to use for rendering the title of a field */
|
|
@@ -306,9 +308,10 @@ export type TemplatesType<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
306
308
|
} | undefined;
|
|
307
309
|
};
|
|
308
310
|
/** The set of UiSchema options that can be set globally and used as fallbacks at an individual template, field or
|
|
309
|
-
* widget level when no field-level value of the option is provided.
|
|
311
|
+
* widget level when no field-level value of the option is provided. Extends GenericObjectType to support allowing users
|
|
312
|
+
* to provide any value they need for their customizations.
|
|
310
313
|
*/
|
|
311
|
-
export type GlobalUISchemaOptions = {
|
|
314
|
+
export type GlobalUISchemaOptions = GenericObjectType & {
|
|
312
315
|
/** Flag, if set to `false`, new items cannot be added to array fields, unless overridden (defaults to true) */
|
|
313
316
|
addable?: boolean;
|
|
314
317
|
/** Flag, if set to `true`, array items can be copied (defaults to false) */
|
|
@@ -323,6 +326,9 @@ export type GlobalUISchemaOptions = {
|
|
|
323
326
|
* This option allows you to change the separator between the original key name and the integer. Default is "-"
|
|
324
327
|
*/
|
|
325
328
|
duplicateKeySuffixSeparator?: string;
|
|
329
|
+
/** Enables the displaying of description text that contains markdown
|
|
330
|
+
*/
|
|
331
|
+
enableMarkdownInDescription?: boolean;
|
|
326
332
|
};
|
|
327
333
|
/** The object containing the registered core, theme and custom fields and widgets as well as the root schema, form
|
|
328
334
|
* context, schema utils and templates.
|
|
@@ -354,11 +360,7 @@ export interface Registry<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
354
360
|
globalUiOptions?: GlobalUISchemaOptions;
|
|
355
361
|
}
|
|
356
362
|
/** The properties that are passed to a Field implementation */
|
|
357
|
-
export interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> extends GenericObjectType, Pick<HTMLAttributes<HTMLElement>, Exclude<keyof HTMLAttributes<HTMLElement>, 'onBlur' | 'onFocus' | 'onChange'>> {
|
|
358
|
-
/** The JSON subschema object for this field */
|
|
359
|
-
schema: S;
|
|
360
|
-
/** The uiSchema for this field */
|
|
361
|
-
uiSchema?: UiSchema<T, S, F>;
|
|
363
|
+
export interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> extends GenericObjectType, RJSFBaseProps<T, S, F>, Pick<HTMLAttributes<HTMLElement>, Exclude<keyof HTMLAttributes<HTMLElement>, 'onBlur' | 'onFocus' | 'onChange'>> {
|
|
362
364
|
/** The tree of unique ids for every child field */
|
|
363
365
|
idSchema: IdSchema<T>;
|
|
364
366
|
/** The data for this field */
|
|
@@ -395,11 +397,12 @@ export interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F
|
|
|
395
397
|
idSeparator?: string;
|
|
396
398
|
/** An array of strings listing all generated error messages from encountered errors for this field */
|
|
397
399
|
rawErrors?: string[];
|
|
398
|
-
/** The `registry` object */
|
|
399
|
-
registry: Registry<T, S, F>;
|
|
400
400
|
}
|
|
401
401
|
/** The definition of a React-based Field component */
|
|
402
|
-
export type Field<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> = ComponentType<FieldProps<T, S, F
|
|
402
|
+
export type Field<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> = ComponentType<FieldProps<T, S, F>> & {
|
|
403
|
+
/** The optional TEST_IDS block that some fields contain, exported for testing purposes */
|
|
404
|
+
TEST_IDS?: TestIdShape;
|
|
405
|
+
};
|
|
403
406
|
/** The properties that are passed to a FieldTemplate implementation */
|
|
404
407
|
export type FieldTemplateProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> = RJSFBaseProps<T, S, F> & {
|
|
405
408
|
/** The id of the field in the hierarchy. You can use it to render a label targeting the wrapped widget */
|
|
@@ -599,7 +602,7 @@ export type ObjectFieldTemplateProps<T = any, S extends StrictRJSFSchema = RJSFS
|
|
|
599
602
|
/** A string value containing the title for the object */
|
|
600
603
|
title: string;
|
|
601
604
|
/** A string value containing the description for the object */
|
|
602
|
-
description?: string;
|
|
605
|
+
description?: string | ReactElement;
|
|
603
606
|
/** A boolean value stating if the object is disabled */
|
|
604
607
|
disabled?: boolean;
|
|
605
608
|
/** An array of objects representing the properties in the object */
|
|
@@ -626,6 +629,13 @@ export type WrapIfAdditionalTemplateProps<T = any, S extends StrictRJSFSchema =
|
|
|
626
629
|
/** The field or widget component instance for this field row */
|
|
627
630
|
children: ReactNode;
|
|
628
631
|
} & Pick<FieldTemplateProps<T, S, F>, 'id' | 'classNames' | 'hideError' | 'rawErrors' | 'style' | 'label' | 'required' | 'readonly' | 'disabled' | 'schema' | 'uiSchema' | 'onKeyChange' | 'onDropPropertyClick' | 'registry'>;
|
|
632
|
+
/** The properties that are passed to a MultiSchemaFieldTemplate implementation */
|
|
633
|
+
export interface MultiSchemaFieldTemplateProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> extends RJSFBaseProps<T, S, F> {
|
|
634
|
+
/** The rendered widget used to select a schema option */
|
|
635
|
+
selector: ReactNode;
|
|
636
|
+
/** The rendered SchemaField for the selected schema option */
|
|
637
|
+
optionSchemaField: ReactNode;
|
|
638
|
+
}
|
|
629
639
|
/** The properties that are passed to a Widget implementation */
|
|
630
640
|
export interface WidgetProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> extends GenericObjectType, RJSFBaseProps<T, S, F>, Pick<HTMLAttributes<HTMLElement>, Exclude<keyof HTMLAttributes<HTMLElement>, 'onBlur' | 'onFocus'>> {
|
|
631
641
|
/** The generated id for this widget, used to provide unique `name`s and `id`s for the HTML field elements rendered by
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rjsf/utils",
|
|
3
|
-
"version": "6.0.0-beta.
|
|
3
|
+
"version": "6.0.0-beta.11",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"react": ">=18"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
+
"fast-uri": "^3.0.6",
|
|
68
69
|
"json-schema-merge-allof": "^0.8.1",
|
|
69
70
|
"jsonpointer": "^5.0.1",
|
|
70
71
|
"lodash": "^4.17.21",
|
package/src/constants.ts
CHANGED
|
@@ -25,6 +25,7 @@ export const READONLY_KEY = 'readonly';
|
|
|
25
25
|
export const REQUIRED_KEY = 'required';
|
|
26
26
|
export const SUBMIT_BTN_OPTIONS_KEY = 'submitButtonOptions';
|
|
27
27
|
export const REF_KEY = '$ref';
|
|
28
|
+
export const SCHEMA_KEY = '$schema';
|
|
28
29
|
/** The path of the discriminator value returned by the schema endpoint.
|
|
29
30
|
* The discriminator is the value in a `oneOf` that determines which option is selected.
|
|
30
31
|
*/
|
|
@@ -42,3 +43,7 @@ export const UI_FIELD_KEY = 'ui:field';
|
|
|
42
43
|
export const UI_WIDGET_KEY = 'ui:widget';
|
|
43
44
|
export const UI_OPTIONS_KEY = 'ui:options';
|
|
44
45
|
export const UI_GLOBAL_OPTIONS_KEY = 'ui:globalOptions';
|
|
46
|
+
|
|
47
|
+
/** The JSON Schema version strings
|
|
48
|
+
*/
|
|
49
|
+
export const JSON_SCHEMA_DRAFT_2020_12 = 'https://json-schema.org/draft/2020-12/schema';
|
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
import jsonpointer from 'jsonpointer';
|
|
2
2
|
import omit from 'lodash/omit';
|
|
3
3
|
|
|
4
|
-
import { REF_KEY } from './constants';
|
|
4
|
+
import { ID_KEY, JSON_SCHEMA_DRAFT_2020_12, REF_KEY, SCHEMA_KEY } from './constants';
|
|
5
5
|
import { GenericObjectType, RJSFSchema, StrictRJSFSchema } from './types';
|
|
6
|
+
import isObject from 'lodash/isObject';
|
|
7
|
+
import isEmpty from 'lodash/isEmpty';
|
|
8
|
+
import UriResolver from 'fast-uri';
|
|
9
|
+
import get from 'lodash/get';
|
|
10
|
+
|
|
11
|
+
/** Looks for the `$id` pointed by `ref` in the schema definitions embedded in
|
|
12
|
+
* a JSON Schema bundle
|
|
13
|
+
*
|
|
14
|
+
* @param schema - The schema wherein `ref` should be searched
|
|
15
|
+
* @param ref - The `$id` of the reference to search for
|
|
16
|
+
* @returns - The schema matching the reference, or `undefined` if no match is found
|
|
17
|
+
*/
|
|
18
|
+
function findEmbeddedSchemaRecursive<S extends StrictRJSFSchema = RJSFSchema>(schema: S, ref: string): S | undefined {
|
|
19
|
+
if (ID_KEY in schema && UriResolver.equal(schema[ID_KEY] as string, ref)) {
|
|
20
|
+
return schema;
|
|
21
|
+
}
|
|
22
|
+
for (const subSchema of Object.values(schema)) {
|
|
23
|
+
if (isObject(subSchema)) {
|
|
24
|
+
const result = findEmbeddedSchemaRecursive<S>(subSchema as S, ref);
|
|
25
|
+
if (result !== undefined) {
|
|
26
|
+
return result as S;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
6
32
|
|
|
7
33
|
/** Splits out the value at the `key` in `object` from the `object`, returning an array that contains in the first
|
|
8
34
|
* location, the `object` minus the `key: value` and in the second location the `value`.
|
|
@@ -26,6 +52,7 @@ export function splitKeyElementFromObject(key: string, object: GenericObjectType
|
|
|
26
52
|
* @param $ref - The ref string for which the schema definition is desired
|
|
27
53
|
* @param [rootSchema={}] - The root schema in which to search for the definition
|
|
28
54
|
* @param recurseList - List of $refs already resolved to prevent recursion
|
|
55
|
+
* @param [baseURI=rootSchema['$id']] - The base URI to be used for resolving relative references
|
|
29
56
|
* @returns - The sub-schema within the `rootSchema` which matches the `$ref` if it exists
|
|
30
57
|
* @throws - Error indicating that no schema for that reference could be resolved
|
|
31
58
|
*/
|
|
@@ -33,16 +60,32 @@ export function findSchemaDefinitionRecursive<S extends StrictRJSFSchema = RJSFS
|
|
|
33
60
|
$ref?: string,
|
|
34
61
|
rootSchema: S = {} as S,
|
|
35
62
|
recurseList: string[] = [],
|
|
63
|
+
baseURI: string | undefined = get(rootSchema, [ID_KEY]),
|
|
36
64
|
): S {
|
|
37
65
|
const ref = $ref || '';
|
|
38
|
-
let
|
|
66
|
+
let current: S | undefined = undefined;
|
|
39
67
|
if (ref.startsWith('#')) {
|
|
40
68
|
// Decode URI fragment representation.
|
|
41
|
-
decodedRef = decodeURIComponent(ref.substring(1));
|
|
42
|
-
|
|
43
|
-
|
|
69
|
+
const decodedRef = decodeURIComponent(ref.substring(1));
|
|
70
|
+
if (baseURI === undefined || (ID_KEY in rootSchema && rootSchema[ID_KEY] === baseURI)) {
|
|
71
|
+
current = jsonpointer.get(rootSchema, decodedRef);
|
|
72
|
+
} else if (rootSchema[SCHEMA_KEY] === JSON_SCHEMA_DRAFT_2020_12) {
|
|
73
|
+
current = findEmbeddedSchemaRecursive<S>(rootSchema, baseURI.replace(/\/$/, ''));
|
|
74
|
+
if (current !== undefined) {
|
|
75
|
+
current = jsonpointer.get(current, decodedRef);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} else if (rootSchema[SCHEMA_KEY] === JSON_SCHEMA_DRAFT_2020_12) {
|
|
79
|
+
const resolvedRef = baseURI ? UriResolver.resolve(baseURI, ref) : ref;
|
|
80
|
+
const [refId, ...refAnchor] = resolvedRef.replace(/#\/?$/, '').split('#');
|
|
81
|
+
current = findEmbeddedSchemaRecursive<S>(rootSchema, refId.replace(/\/$/, ''));
|
|
82
|
+
if (current !== undefined) {
|
|
83
|
+
baseURI = current[ID_KEY];
|
|
84
|
+
if (!isEmpty(refAnchor)) {
|
|
85
|
+
current = jsonpointer.get(current, decodeURIComponent(refAnchor.join('#')));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
44
88
|
}
|
|
45
|
-
const current: S = jsonpointer.get(rootSchema, decodedRef);
|
|
46
89
|
if (current === undefined) {
|
|
47
90
|
throw new Error(`Could not find a definition for ${$ref}.`);
|
|
48
91
|
}
|
|
@@ -58,7 +101,7 @@ export function findSchemaDefinitionRecursive<S extends StrictRJSFSchema = RJSFS
|
|
|
58
101
|
throw new Error(`Definition for ${firstRef} contains a circular reference through ${circularPath}`);
|
|
59
102
|
}
|
|
60
103
|
const [remaining, theRef] = splitKeyElementFromObject(REF_KEY, current);
|
|
61
|
-
const subSchema = findSchemaDefinitionRecursive<S>(theRef, rootSchema, [...recurseList, ref]);
|
|
104
|
+
const subSchema = findSchemaDefinitionRecursive<S>(theRef, rootSchema, [...recurseList, ref], baseURI);
|
|
62
105
|
if (Object.keys(remaining).length > 0) {
|
|
63
106
|
return { ...remaining, ...subSchema };
|
|
64
107
|
}
|
|
@@ -74,13 +117,15 @@ export function findSchemaDefinitionRecursive<S extends StrictRJSFSchema = RJSFS
|
|
|
74
117
|
*
|
|
75
118
|
* @param $ref - The ref string for which the schema definition is desired
|
|
76
119
|
* @param [rootSchema={}] - The root schema in which to search for the definition
|
|
120
|
+
* @param [baseURI=rootSchema['$id']] - The base URI to be used for resolving relative references
|
|
77
121
|
* @returns - The sub-schema within the `rootSchema` which matches the `$ref` if it exists
|
|
78
122
|
* @throws - Error indicating that no schema for that reference could be resolved
|
|
79
123
|
*/
|
|
80
124
|
export default function findSchemaDefinition<S extends StrictRJSFSchema = RJSFSchema>(
|
|
81
125
|
$ref?: string,
|
|
82
126
|
rootSchema: S = {} as S,
|
|
127
|
+
baseURI: string | undefined = get(rootSchema, [ID_KEY]),
|
|
83
128
|
): S {
|
|
84
129
|
const recurseList: string[] = [];
|
|
85
|
-
return findSchemaDefinitionRecursive($ref, rootSchema, recurseList);
|
|
130
|
+
return findSchemaDefinitionRecursive($ref, rootSchema, recurseList, baseURI);
|
|
86
131
|
}
|
|
@@ -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,
|
|
@@ -22,7 +22,7 @@ export const NOT_FOUND_SCHEMA = { title: '!@#$_UNKNOWN_$#@!' };
|
|
|
22
22
|
*
|
|
23
23
|
* @param validator - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
|
|
24
24
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
25
|
-
|
|
25
|
+
* @param schema - The node within the JSON schema in which to search
|
|
26
26
|
* @param path - The keys in the path to the desired field
|
|
27
27
|
* @param [formData={}] - The form data that is used to determine which anyOf/oneOf option to descend
|
|
28
28
|
* @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
|
|
@@ -204,7 +204,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
204
204
|
required,
|
|
205
205
|
shouldMergeDefaultsIntoFormData = false,
|
|
206
206
|
} = computeDefaultsProps;
|
|
207
|
-
|
|
207
|
+
let formData: T = (isObject(rawFormData) ? rawFormData : {}) as T;
|
|
208
208
|
const schema: S = isObject(rawSchema) ? rawSchema : ({} as S);
|
|
209
209
|
// Compute the defaults recursively: give highest priority to deepest nodes.
|
|
210
210
|
let defaults: T | T[] | undefined = parentDefaults;
|
|
@@ -212,9 +212,8 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
212
212
|
let schemaToCompute: S | null = null;
|
|
213
213
|
let experimental_dfsb_to_compute = experimental_defaultFormStateBehavior;
|
|
214
214
|
let updatedRecurseList = _recurseList;
|
|
215
|
-
|
|
216
215
|
if (
|
|
217
|
-
schema[CONST_KEY] &&
|
|
216
|
+
schema[CONST_KEY] !== undefined &&
|
|
218
217
|
experimental_defaultFormStateBehavior?.constAsDefaults !== 'never' &&
|
|
219
218
|
!constIsAjvDataReference(schema)
|
|
220
219
|
) {
|
|
@@ -223,7 +222,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
223
222
|
// For object defaults, only override parent defaults that are defined in
|
|
224
223
|
// schema.default.
|
|
225
224
|
defaults = mergeObjects(defaults!, schema.default as GenericObjectType) as T;
|
|
226
|
-
} else if (DEFAULT_KEY in schema && !schema[ANY_OF_KEY] && !schema[ONE_OF_KEY]) {
|
|
225
|
+
} else if (DEFAULT_KEY in schema && !schema[ANY_OF_KEY] && !schema[ONE_OF_KEY] && !schema[REF_KEY]) {
|
|
227
226
|
// If the schema has a default value, then we should use it as the default.
|
|
228
227
|
// And if the schema does not have anyOf or oneOf, this is done because we need to merge the defaults with the formData.
|
|
229
228
|
defaults = schema.default as unknown as T;
|
|
@@ -234,6 +233,19 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
234
233
|
updatedRecurseList = _recurseList.concat(refName!);
|
|
235
234
|
schemaToCompute = findSchemaDefinition<S>(refName, rootSchema);
|
|
236
235
|
}
|
|
236
|
+
|
|
237
|
+
// If the referenced schema exists and parentDefaults is not set
|
|
238
|
+
// Then set the defaults from the current schema for the referenced schema
|
|
239
|
+
if (schemaToCompute && !defaults) {
|
|
240
|
+
defaults = schema.default as T | undefined;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// If shouldMergeDefaultsIntoFormData is true
|
|
244
|
+
// And the schemaToCompute is set and the rawFormData is not an object
|
|
245
|
+
// Then set the formData to the rawFormData
|
|
246
|
+
if (shouldMergeDefaultsIntoFormData && schemaToCompute && !isObject(rawFormData)) {
|
|
247
|
+
formData = rawFormData as T;
|
|
248
|
+
}
|
|
237
249
|
} else if (DEPENDENCIES_KEY in schema) {
|
|
238
250
|
// Get the default if set from properties to ensure the dependencies conditions are resolved based on it
|
|
239
251
|
const defaultFormData: T = {
|
|
@@ -322,7 +334,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
|
|
|
322
334
|
experimental_defaultFormStateBehavior: experimental_dfsb_to_compute,
|
|
323
335
|
experimental_customMergeAllOf,
|
|
324
336
|
parentDefaults: defaults as T | undefined,
|
|
325
|
-
rawFormData: formData as T,
|
|
337
|
+
rawFormData: (rawFormData ?? formData) as T,
|
|
326
338
|
required,
|
|
327
339
|
shouldMergeDefaultsIntoFormData,
|
|
328
340
|
});
|
|
@@ -716,6 +728,13 @@ export default function getDefaultFormState<
|
|
|
716
728
|
shouldMergeDefaultsIntoFormData: true,
|
|
717
729
|
});
|
|
718
730
|
|
|
731
|
+
if (schema.type !== 'object' && isObject(schema.default)) {
|
|
732
|
+
return {
|
|
733
|
+
...defaults,
|
|
734
|
+
...formData,
|
|
735
|
+
} as T;
|
|
736
|
+
}
|
|
737
|
+
|
|
719
738
|
// If the formData is an object or an array, add additional properties from formData and override formData with
|
|
720
739
|
// defaults since the defaults are already merged with formData.
|
|
721
740
|
if (isObject(formData) || Array.isArray(formData)) {
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
ALL_OF_KEY,
|
|
14
14
|
ANY_OF_KEY,
|
|
15
15
|
DEPENDENCIES_KEY,
|
|
16
|
+
ID_KEY,
|
|
16
17
|
IF_KEY,
|
|
17
18
|
ITEMS_KEY,
|
|
18
19
|
ONE_OF_KEY,
|
|
@@ -333,12 +334,14 @@ export function resolveReference<T = any, S extends StrictRJSFSchema = RJSFSchem
|
|
|
333
334
|
* @param schema - The schema for which resolving all references is desired
|
|
334
335
|
* @param rootSchema - The root schema that will be forwarded to all the APIs
|
|
335
336
|
* @param recurseList - List of $refs already resolved to prevent recursion
|
|
337
|
+
* @param [baseURI] - The base URI to be used for resolving relative references
|
|
336
338
|
* @returns - given schema will all references resolved or the original schema if no internal `$refs` were resolved
|
|
337
339
|
*/
|
|
338
340
|
export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
|
|
339
341
|
schema: S,
|
|
340
342
|
rootSchema: S,
|
|
341
343
|
recurseList: string[],
|
|
344
|
+
baseURI?: string,
|
|
342
345
|
): S {
|
|
343
346
|
if (!isObject(schema)) {
|
|
344
347
|
return schema;
|
|
@@ -353,8 +356,11 @@ export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
|
|
|
353
356
|
}
|
|
354
357
|
recurseList.push($ref!);
|
|
355
358
|
// Retrieve the referenced schema definition.
|
|
356
|
-
const refSchema = findSchemaDefinition<S>($ref, rootSchema);
|
|
359
|
+
const refSchema = findSchemaDefinition<S>($ref, rootSchema, baseURI);
|
|
357
360
|
resolvedSchema = { ...refSchema, ...localSchema };
|
|
361
|
+
if (ID_KEY in resolvedSchema) {
|
|
362
|
+
baseURI = resolvedSchema[ID_KEY];
|
|
363
|
+
}
|
|
358
364
|
}
|
|
359
365
|
|
|
360
366
|
if (PROPERTIES_KEY in resolvedSchema) {
|
|
@@ -363,7 +369,7 @@ export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
|
|
|
363
369
|
resolvedSchema[PROPERTIES_KEY]!,
|
|
364
370
|
(result, value, key: string) => {
|
|
365
371
|
const childList: string[] = [...recurseList];
|
|
366
|
-
result[key] = resolveAllReferences(value as S, rootSchema, childList);
|
|
372
|
+
result[key] = resolveAllReferences(value as S, rootSchema, childList, baseURI);
|
|
367
373
|
childrenLists.push(childList);
|
|
368
374
|
},
|
|
369
375
|
{} as RJSFSchema,
|
|
@@ -379,7 +385,7 @@ export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
|
|
|
379
385
|
) {
|
|
380
386
|
resolvedSchema = {
|
|
381
387
|
...resolvedSchema,
|
|
382
|
-
items: resolveAllReferences(resolvedSchema.items as S, rootSchema, recurseList),
|
|
388
|
+
items: resolveAllReferences(resolvedSchema.items as S, rootSchema, recurseList, baseURI),
|
|
383
389
|
};
|
|
384
390
|
}
|
|
385
391
|
|
|
@@ -426,7 +432,7 @@ export function stubExistingAdditionalProperties<
|
|
|
426
432
|
validator,
|
|
427
433
|
{ allOf: Object.values(matchingProperties) } as S,
|
|
428
434
|
rootSchema,
|
|
429
|
-
formData as T,
|
|
435
|
+
get(formData, [key]) as T,
|
|
430
436
|
experimental_customMergeAllOf,
|
|
431
437
|
);
|
|
432
438
|
set(schema.properties, [key, ADDITIONAL_PROPERTY_FLAG], true);
|
|
@@ -550,6 +556,9 @@ export function retrieveSchemaInternal<
|
|
|
550
556
|
? experimental_customMergeAllOf(resolvedSchema)
|
|
551
557
|
: (mergeAllOf(resolvedSchema, {
|
|
552
558
|
deep: false,
|
|
559
|
+
resolvers: {
|
|
560
|
+
$defs: mergeAllOf.options.resolvers.definitions,
|
|
561
|
+
},
|
|
553
562
|
} as Options) as S);
|
|
554
563
|
if (withContainsSchemas.length) {
|
|
555
564
|
resolvedSchema.allOf = withContainsSchemas;
|
|
@@ -569,7 +578,7 @@ export function retrieveSchemaInternal<
|
|
|
569
578
|
validator,
|
|
570
579
|
{ allOf: [schema.properties[key], ...Object.values(matchingProperties)] } as S,
|
|
571
580
|
rootSchema,
|
|
572
|
-
rawFormData as T,
|
|
581
|
+
get(rawFormData, [key]) as T,
|
|
573
582
|
experimental_customMergeAllOf,
|
|
574
583
|
);
|
|
575
584
|
}
|
package/src/types.ts
CHANGED
|
@@ -245,7 +245,7 @@ export type FormValidation<T = any> = FieldValidation & {
|
|
|
245
245
|
export type RJSFBaseProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> = {
|
|
246
246
|
/** The schema object for the field being described */
|
|
247
247
|
schema: S;
|
|
248
|
-
/** The uiSchema object for this
|
|
248
|
+
/** The uiSchema object for this base component */
|
|
249
249
|
uiSchema?: UiSchema<T, S, F>;
|
|
250
250
|
/** The `registry` object */
|
|
251
251
|
registry: Registry<T, S, F>;
|
|
@@ -341,6 +341,8 @@ export type TemplatesType<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
341
341
|
FieldTemplate: ComponentType<FieldTemplateProps<T, S, F>>;
|
|
342
342
|
/** The template to use to render a Grid element */
|
|
343
343
|
GridTemplate: ComponentType<GridTemplateProps>;
|
|
344
|
+
/** The template to use while rendering a multi-schema field (i.e. anyOf, oneOf) */
|
|
345
|
+
MultiSchemaFieldTemplate: ComponentType<MultiSchemaFieldTemplateProps<T, S, F>>;
|
|
344
346
|
/** The template to use while rendering an object */
|
|
345
347
|
ObjectFieldTemplate: ComponentType<ObjectFieldTemplateProps<T, S, F>>;
|
|
346
348
|
/** The template to use for rendering the title of a field */
|
|
@@ -370,9 +372,10 @@ export type TemplatesType<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
370
372
|
};
|
|
371
373
|
|
|
372
374
|
/** The set of UiSchema options that can be set globally and used as fallbacks at an individual template, field or
|
|
373
|
-
* widget level when no field-level value of the option is provided.
|
|
375
|
+
* widget level when no field-level value of the option is provided. Extends GenericObjectType to support allowing users
|
|
376
|
+
* to provide any value they need for their customizations.
|
|
374
377
|
*/
|
|
375
|
-
export type GlobalUISchemaOptions = {
|
|
378
|
+
export type GlobalUISchemaOptions = GenericObjectType & {
|
|
376
379
|
/** Flag, if set to `false`, new items cannot be added to array fields, unless overridden (defaults to true) */
|
|
377
380
|
addable?: boolean;
|
|
378
381
|
/** Flag, if set to `true`, array items can be copied (defaults to false) */
|
|
@@ -387,6 +390,9 @@ export type GlobalUISchemaOptions = {
|
|
|
387
390
|
* This option allows you to change the separator between the original key name and the integer. Default is "-"
|
|
388
391
|
*/
|
|
389
392
|
duplicateKeySuffixSeparator?: string;
|
|
393
|
+
/** Enables the displaying of description text that contains markdown
|
|
394
|
+
*/
|
|
395
|
+
enableMarkdownInDescription?: boolean;
|
|
390
396
|
};
|
|
391
397
|
|
|
392
398
|
/** The object containing the registered core, theme and custom fields and widgets as well as the root schema, form
|
|
@@ -422,11 +428,8 @@ export interface Registry<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
|
|
|
422
428
|
/** The properties that are passed to a Field implementation */
|
|
423
429
|
export interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>
|
|
424
430
|
extends GenericObjectType,
|
|
431
|
+
RJSFBaseProps<T, S, F>,
|
|
425
432
|
Pick<HTMLAttributes<HTMLElement>, Exclude<keyof HTMLAttributes<HTMLElement>, 'onBlur' | 'onFocus' | 'onChange'>> {
|
|
426
|
-
/** The JSON subschema object for this field */
|
|
427
|
-
schema: S;
|
|
428
|
-
/** The uiSchema for this field */
|
|
429
|
-
uiSchema?: UiSchema<T, S, F>;
|
|
430
433
|
/** The tree of unique ids for every child field */
|
|
431
434
|
idSchema: IdSchema<T>;
|
|
432
435
|
/** The data for this field */
|
|
@@ -463,14 +466,15 @@ export interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F
|
|
|
463
466
|
idSeparator?: string;
|
|
464
467
|
/** An array of strings listing all generated error messages from encountered errors for this field */
|
|
465
468
|
rawErrors?: string[];
|
|
466
|
-
/** The `registry` object */
|
|
467
|
-
registry: Registry<T, S, F>;
|
|
468
469
|
}
|
|
469
470
|
|
|
470
471
|
/** The definition of a React-based Field component */
|
|
471
472
|
export type Field<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> = ComponentType<
|
|
472
473
|
FieldProps<T, S, F>
|
|
473
|
-
|
|
474
|
+
> & {
|
|
475
|
+
/** The optional TEST_IDS block that some fields contain, exported for testing purposes */
|
|
476
|
+
TEST_IDS?: TestIdShape;
|
|
477
|
+
};
|
|
474
478
|
|
|
475
479
|
/** The properties that are passed to a FieldTemplate implementation */
|
|
476
480
|
export type FieldTemplateProps<
|
|
@@ -726,7 +730,7 @@ export type ObjectFieldTemplateProps<
|
|
|
726
730
|
/** A string value containing the title for the object */
|
|
727
731
|
title: string;
|
|
728
732
|
/** A string value containing the description for the object */
|
|
729
|
-
description?: string;
|
|
733
|
+
description?: string | ReactElement;
|
|
730
734
|
/** A boolean value stating if the object is disabled */
|
|
731
735
|
disabled?: boolean;
|
|
732
736
|
/** An array of objects representing the properties in the object */
|
|
@@ -775,6 +779,18 @@ export type WrapIfAdditionalTemplateProps<
|
|
|
775
779
|
| 'registry'
|
|
776
780
|
>;
|
|
777
781
|
|
|
782
|
+
/** The properties that are passed to a MultiSchemaFieldTemplate implementation */
|
|
783
|
+
export interface MultiSchemaFieldTemplateProps<
|
|
784
|
+
T = any,
|
|
785
|
+
S extends StrictRJSFSchema = RJSFSchema,
|
|
786
|
+
F extends FormContextType = any,
|
|
787
|
+
> extends RJSFBaseProps<T, S, F> {
|
|
788
|
+
/** The rendered widget used to select a schema option */
|
|
789
|
+
selector: ReactNode;
|
|
790
|
+
/** The rendered SchemaField for the selected schema option */
|
|
791
|
+
optionSchemaField: ReactNode;
|
|
792
|
+
}
|
|
793
|
+
|
|
778
794
|
/** The properties that are passed to a Widget implementation */
|
|
779
795
|
export interface WidgetProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>
|
|
780
796
|
extends GenericObjectType,
|