Skip to content

Commit 5ac606b

Browse files
committed
experimental_customMergeAllOf draft
1 parent 9d1ff6d commit 5ac606b

File tree

6 files changed

+208
-50
lines changed

6 files changed

+208
-50
lines changed

packages/core/src/components/Form.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
validationDataMerge,
3434
ValidatorType,
3535
Experimental_DefaultFormStateBehavior,
36+
Experimental_CustomMergeAllOf,
3637
} from '@rjsf/utils';
3738
import _forEach from 'lodash/forEach';
3839
import _get from 'lodash/get';
@@ -195,6 +196,7 @@ export interface FormProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F e
195196
* `emptyObjectFields`
196197
*/
197198
experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior;
199+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>;
198200
// Private
199201
/**
200202
* _internalFormWrapper is currently used by the semantic-ui theme to provide a custom wrapper around `<Form />`
@@ -389,12 +391,26 @@ export default class Form<
389391
'experimental_defaultFormStateBehavior' in props
390392
? props.experimental_defaultFormStateBehavior
391393
: this.props.experimental_defaultFormStateBehavior;
394+
const experimental_customMergeAllOf =
395+
'experimental_customMergeAllOf' in props
396+
? props.experimental_customMergeAllOf
397+
: this.props.experimental_customMergeAllOf;
392398
let schemaUtils: SchemaUtilsType<T, S, F> = state.schemaUtils;
393399
if (
394400
!schemaUtils ||
395-
schemaUtils.doesSchemaUtilsDiffer(props.validator, rootSchema, experimental_defaultFormStateBehavior)
401+
schemaUtils.doesSchemaUtilsDiffer(
402+
props.validator,
403+
rootSchema,
404+
experimental_defaultFormStateBehavior,
405+
experimental_customMergeAllOf
406+
)
396407
) {
397-
schemaUtils = createSchemaUtils<T, S, F>(props.validator, rootSchema, experimental_defaultFormStateBehavior);
408+
schemaUtils = createSchemaUtils<T, S, F>(
409+
props.validator,
410+
rootSchema,
411+
experimental_defaultFormStateBehavior,
412+
experimental_customMergeAllOf
413+
);
398414
}
399415
const formData: T = schemaUtils.getDefaultFormState(schema, inputFormData) as T;
400416
const _retrievedSchema = retrievedSchema ?? schemaUtils.retrieveSchema(schema, formData);

packages/utils/src/createSchemaUtils.ts

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import deepEquals from './deepEquals';
22
import {
33
ErrorSchema,
4+
Experimental_CustomMergeAllOf,
45
Experimental_DefaultFormStateBehavior,
56
FormContextType,
67
GlobalUISchemaOptions,
@@ -40,6 +41,7 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
4041
rootSchema: S;
4142
validator: ValidatorType<T, S, F>;
4243
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior;
44+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>;
4345

4446
/** Constructs the `SchemaUtils` instance with the given `validator` and `rootSchema` stored as instance variables
4547
*
@@ -50,11 +52,13 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
5052
constructor(
5153
validator: ValidatorType<T, S, F>,
5254
rootSchema: S,
53-
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior
55+
experimental_defaultFormStateBehavior: Experimental_DefaultFormStateBehavior,
56+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
5457
) {
5558
this.rootSchema = rootSchema;
5659
this.validator = validator;
5760
this.experimental_defaultFormStateBehavior = experimental_defaultFormStateBehavior;
61+
this.experimental_customMergeAllOf = experimental_customMergeAllOf;
5862
}
5963

6064
/** Returns the `ValidatorType` in the `SchemaUtilsType`
@@ -77,15 +81,17 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
7781
doesSchemaUtilsDiffer(
7882
validator: ValidatorType<T, S, F>,
7983
rootSchema: S,
80-
experimental_defaultFormStateBehavior = {}
84+
experimental_defaultFormStateBehavior = {},
85+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
8186
): boolean {
8287
if (!validator || !rootSchema) {
8388
return false;
8489
}
8590
return (
8691
this.validator !== validator ||
8792
!deepEquals(this.rootSchema, rootSchema) ||
88-
!deepEquals(this.experimental_defaultFormStateBehavior, experimental_defaultFormStateBehavior)
93+
!deepEquals(this.experimental_defaultFormStateBehavior, experimental_defaultFormStateBehavior) ||
94+
this.experimental_customMergeAllOf !== experimental_customMergeAllOf
8995
);
9096
}
9197

@@ -110,7 +116,8 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
110116
formData,
111117
this.rootSchema,
112118
includeUndefinedValues,
113-
this.experimental_defaultFormStateBehavior
119+
this.experimental_defaultFormStateBehavior,
120+
this.experimental_customMergeAllOf
114121
);
115122
}
116123

@@ -234,7 +241,13 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
234241
* @returns - The schema having its conditions, additional properties, references and dependencies resolved
235242
*/
236243
retrieveSchema(schema: S, rawFormData?: T) {
237-
return retrieveSchema<T, S, F>(this.validator, schema, this.rootSchema, rawFormData);
244+
return retrieveSchema<T, S, F>(
245+
this.validator,
246+
schema,
247+
this.rootSchema,
248+
rawFormData,
249+
this.experimental_customMergeAllOf
250+
);
238251
}
239252

240253
/** Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`. If the
@@ -262,7 +275,16 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
262275
* @returns - The `IdSchema` object for the `schema`
263276
*/
264277
toIdSchema(schema: S, id?: string | null, formData?: T, idPrefix = 'root', idSeparator = '_'): IdSchema<T> {
265-
return toIdSchema<T, S, F>(this.validator, schema, id, this.rootSchema, formData, idPrefix, idSeparator);
278+
return toIdSchema<T, S, F>(
279+
this.validator,
280+
schema,
281+
id,
282+
this.rootSchema,
283+
formData,
284+
idPrefix,
285+
idSeparator,
286+
this.experimental_customMergeAllOf
287+
);
266288
}
267289

268290
/** Generates an `PathSchema` object for the `schema`, recursively
@@ -292,7 +314,13 @@ export default function createSchemaUtils<
292314
>(
293315
validator: ValidatorType<T, S, F>,
294316
rootSchema: S,
295-
experimental_defaultFormStateBehavior = {}
317+
experimental_defaultFormStateBehavior = {},
318+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
296319
): SchemaUtilsType<T, S, F> {
297-
return new SchemaUtils<T, S, F>(validator, rootSchema, experimental_defaultFormStateBehavior);
320+
return new SchemaUtils<T, S, F>(
321+
validator,
322+
rootSchema,
323+
experimental_defaultFormStateBehavior,
324+
experimental_customMergeAllOf
325+
);
298326
}

packages/utils/src/schema/getDefaultFormState.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import mergeDefaultsWithFormData from '../mergeDefaultsWithFormData';
2020
import mergeObjects from '../mergeObjects';
2121
import mergeSchemas from '../mergeSchemas';
2222
import {
23+
Experimental_CustomMergeAllOf,
2324
Experimental_DefaultFormStateBehavior,
2425
FormContextType,
2526
GenericObjectType,
@@ -156,6 +157,7 @@ interface ComputeDefaultsProps<T = any, S extends StrictRJSFSchema = RJSFSchema>
156157
_recurseList?: string[];
157158
/** Optional configuration object, if provided, allows users to override default form state behavior */
158159
experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior;
160+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>;
159161
/** Optional flag, if true, indicates this schema was required in the parent schema. */
160162
required?: boolean;
161163
}
@@ -180,6 +182,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
180182
includeUndefinedValues = false,
181183
_recurseList = [],
182184
experimental_defaultFormStateBehavior = undefined,
185+
experimental_customMergeAllOf = undefined,
183186
required,
184187
} = computeDefaultsProps;
185188
const formData: T = (isObject(rawFormData) ? rawFormData : {}) as T;
@@ -209,7 +212,15 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
209212
...formData,
210213
...getDefaultBasedOnSchemaType(validator, schema, computeDefaultsProps, defaults),
211214
};
212-
const resolvedSchema = resolveDependencies<T, S, F>(validator, schema, rootSchema, false, [], defaultFormData);
215+
const resolvedSchema = resolveDependencies<T, S, F>(
216+
validator,
217+
schema,
218+
rootSchema,
219+
false,
220+
[],
221+
defaultFormData,
222+
experimental_customMergeAllOf
223+
);
213224
schemaToCompute = resolvedSchema[0]; // pick the first element from resolve dependencies
214225
} else if (isFixedItems(schema)) {
215226
defaults = (schema.items! as S[]).map((itemSchema: S, idx: number) =>
@@ -298,6 +309,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
298309
includeUndefinedValues = false,
299310
_recurseList = [],
300311
experimental_defaultFormStateBehavior = undefined,
312+
experimental_customMergeAllOf = undefined,
301313
required,
302314
}: ComputeDefaultsProps<T, S> = {},
303315
defaults?: T | T[] | undefined
@@ -309,7 +321,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
309321
// https://github.com/rjsf-team/react-jsonschema-form/issues/3832
310322
const retrievedSchema =
311323
experimental_defaultFormStateBehavior?.allOf === 'populateDefaults' && ALL_OF_KEY in schema
312-
? retrieveSchema<T, S, F>(validator, schema, rootSchema, formData)
324+
? retrieveSchema<T, S, F>(validator, schema, rootSchema, formData, experimental_customMergeAllOf)
313325
: schema;
314326
const objectDefaults = Object.keys(retrievedSchema.properties || {}).reduce(
315327
(acc: GenericObjectType, key: string) => {
@@ -319,6 +331,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
319331
rootSchema,
320332
_recurseList,
321333
experimental_defaultFormStateBehavior,
334+
experimental_customMergeAllOf,
322335
includeUndefinedValues: includeUndefinedValues === true,
323336
parentDefaults: get(defaults, [key]),
324337
rawFormData: get(formData, [key]),
@@ -533,16 +546,18 @@ export default function getDefaultFormState<
533546
formData?: T,
534547
rootSchema?: S,
535548
includeUndefinedValues: boolean | 'excludeObjectChildren' = false,
536-
experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior
549+
experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior,
550+
experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>
537551
) {
538552
if (!isObject(theSchema)) {
539553
throw new Error('Invalid schema: ' + theSchema);
540554
}
541-
const schema = retrieveSchema<T, S, F>(validator, theSchema, rootSchema, formData);
555+
const schema = retrieveSchema<T, S, F>(validator, theSchema, rootSchema, formData, experimental_customMergeAllOf);
542556
const defaults = computeDefaults<T, S, F>(validator, schema, {
543557
rootSchema,
544558
includeUndefinedValues,
545559
experimental_defaultFormStateBehavior,
560+
experimental_customMergeAllOf,
546561
rawFormData: formData,
547562
});
548563
if (formData === undefined || formData === null || (typeof formData === 'number' && isNaN(formData))) {

0 commit comments

Comments
 (0)