Skip to content

Commit caad3c5

Browse files
Fix: made small changes to utility functions to fix rjsf-team#3997 and rjsf-team#4322
Fixes rjsf-team#3997 and rjsf-team#4322 - In `@rjsf/utils`, made the following changes: - Updated `mergeDefaultsWithFormData()` to not overwrite a default when the formData has an undefined value - Updated `getClosestMatchingOption()` to improve the scoring function so that an object container that matches a key gets an extra point - In `@rjsf/core`, updated `MultiSchemaField` to call `onChange` after setting the new option in state rather than before - Updated the `CHANGELOG.md` accordingly
1 parent a347257 commit caad3c5

File tree

6 files changed

+25
-6
lines changed

6 files changed

+25
-6
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,15 @@ should change the heading of the (upcoming) version to include a major version b
1818

1919
# 5.21.3
2020

21+
## @rjsf/core
22+
23+
- Updated `MultiSchemaField` to call the `onChange` handler after setting the new option, fixing [#3997](https://github.com/rjsf-team/react-jsonschema-form/issues/3977)
24+
2125
## @rjsf/utils
2226

2327
- Added `experimental_customMergeAllOf` option to `retrieveSchema` to allow custom merging of `allOf` schemas
28+
- Updated `mergeDefaultsWithFormData()` to not merge `undefined` when there is a proper default for it, fixing [#4322](https://github.com/rjsf-team/react-jsonschema-form/issues/4322)
29+
- Updated `getClosestMatchingOption()` to improve the scoring of sub-property objects that are provided over ones that aren't, fixing [#3997](https://github.com/rjsf-team/react-jsonschema-form/issues/3977)
2430

2531
# 5.21.2
2632

packages/core/src/components/fields/MultiSchemaField.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,10 @@ class AnyOfField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends For
128128
// so that only the root objects themselves are created without adding undefined children properties
129129
newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, 'excludeObjectChildren') as T;
130130
}
131-
onChange(newFormData, undefined, this.getFieldId());
132131

133-
this.setState({ selectedOption: intOption });
132+
this.setState({ selectedOption: intOption }, () => {
133+
onChange(newFormData, undefined, this.getFieldId());
134+
});
134135
};
135136

136137
getFieldId() {

packages/utils/src/mergeDefaultsWithFormData.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,5 @@ export default function mergeDefaultsWithFormData<T = any>(
4949
return acc;
5050
}, acc);
5151
}
52-
return formData;
52+
return formData === undefined ? defaults : formData;
5353
}

packages/utils/src/schema/getClosestMatchingOption.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
5151
validator: ValidatorType<T, S, F>,
5252
rootSchema: S,
5353
schema?: S,
54-
formData: any = {}
54+
formData?: any
5555
): number {
5656
let totalScore = 0;
5757
if (schema) {
@@ -83,7 +83,11 @@ export function calculateIndexScore<T = any, S extends StrictRJSFSchema = RJSFSc
8383
);
8484
}
8585
if (value.type === 'object') {
86-
return score + calculateIndexScore<T, S, F>(validator, rootSchema, value as S, formValue || {});
86+
if (isObject(formValue)) {
87+
// If the structure is matching then give it a little boost in score
88+
score += 1;
89+
}
90+
return score + calculateIndexScore<T, S, F>(validator, rootSchema, value as S, formValue);
8791
}
8892
if (value.type === guessType(formValue)) {
8993
// If the types match, then we bump the score by one

packages/utils/test/mergeDefaultsWithFormData.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ describe('mergeDefaultsWithFormData()', () => {
1717
expect(mergeDefaultsWithFormData(undefined, [2])).toEqual([2]);
1818
});
1919

20+
it('should return default when formData is undefined', () => {
21+
expect(mergeDefaultsWithFormData({}, undefined)).toEqual({});
22+
});
23+
24+
it('should return undefined when formData is undefined', () => {
25+
expect(mergeDefaultsWithFormData(undefined, undefined)).toBeUndefined();
26+
});
27+
2028
it('should merge two one-level deep objects', () => {
2129
expect(mergeDefaultsWithFormData({ a: 1 }, { b: 2 })).toEqual({
2230
a: 1,

packages/utils/test/schema/getClosestMatchingOptionTest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export default function getClosestMatchingOptionTest(testValidator: TestValidato
4949
expect(calculateIndexScore(testValidator, oneOfSchema, firstOption, ONE_OF_SCHEMA_DATA)).toEqual(1);
5050
});
5151
it('returns 8 for second option in oneOf schema', () => {
52-
expect(calculateIndexScore(testValidator, oneOfSchema, secondOption, ONE_OF_SCHEMA_DATA)).toEqual(8);
52+
expect(calculateIndexScore(testValidator, oneOfSchema, secondOption, ONE_OF_SCHEMA_DATA)).toEqual(9);
5353
});
5454
it('returns 1 for a schema that has a type matching the formData type', () => {
5555
expect(calculateIndexScore(testValidator, oneOfSchema, { type: 'boolean' }, true)).toEqual(1);

0 commit comments

Comments
 (0)