Skip to content

Commit ba140fb

Browse files
committed
1 parent 00a1ea1 commit ba140fb

File tree

4 files changed

+84
-8
lines changed

4 files changed

+84
-8
lines changed

.changeset/early-wings-tell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@sjsf/form": patch
3+
---
4+
5+
Port https://github.com/rjsf-team/react-jsonschema-form/pull/4637

packages/form/src/core/default-state.test.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1807,6 +1807,32 @@ describe("getDefaultFormState2()", () => {
18071807
});
18081808
});
18091809

1810+
describe("an object with a valid formData and enum property with default value", () => {
1811+
test("getDefaultFormState", () => {
1812+
const schema: Schema = {
1813+
type: "object",
1814+
properties: {
1815+
test: {
1816+
type: "string",
1817+
enum: [
1818+
{ label: "a", value: "a" },
1819+
{ label: "b", value: "b" },
1820+
],
1821+
default: { label: "a", value: "a" },
1822+
},
1823+
},
1824+
};
1825+
1826+
expect(
1827+
getDefaultFormState(testValidator, defaultMerger, schema, {
1828+
test: { label: "b", value: "b" },
1829+
})
1830+
).toEqual({
1831+
test: { label: "b", value: "b" },
1832+
});
1833+
});
1834+
});
1835+
18101836
describe("oneOf with const values", () => {
18111837
const schema: Schema = {
18121838
type: "object",
@@ -2549,6 +2575,26 @@ describe("getDefaultFormState2()", () => {
25492575
)
25502576
).toEqual("a");
25512577
});
2578+
it("Test schema with valid formData with an enum and its default value", () => {
2579+
schema = {
2580+
type: "string",
2581+
enum: [
2582+
{ label: "a", value: "a" },
2583+
{ label: "b", value: "b" },
2584+
],
2585+
default: { label: "a", value: "a" },
2586+
};
2587+
2588+
expect(
2589+
getDefaultFormState(testValidator, defaultMerger, schema, {
2590+
label: "b",
2591+
value: "b",
2592+
})
2593+
).toEqual({
2594+
label: "b",
2595+
value: "b",
2596+
});
2597+
});
25522598
});
25532599

25542600
// NOTE: We don't support AJV `$data` property
@@ -3926,7 +3972,7 @@ describe("getDefaultFormState2()", () => {
39263972
],
39273973
},
39283974
value: { leaf1: "a" },
3929-
result: true
3975+
result: true,
39303976
},
39313977
],
39323978
});

packages/form/src/core/default-state.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,20 @@ export function getDefaultFormState(
8686
shouldMergeDefaultsIntoFormData: true,
8787
});
8888

89+
// WARN: How about fixed arrays?
90+
if (
91+
schema.type !== "object" &&
92+
isSchemaObjectValue(schema.default) &&
93+
// CHANGED: Added those conditions for typesafety, while original intentions is unknown
94+
(defaults === undefined || typeof defaults === "object") &&
95+
(formData === undefined || typeof formData === "object")
96+
) {
97+
return {
98+
...defaults,
99+
...formData,
100+
};
101+
}
102+
89103
// If the formData is an object or an array, add additional properties from formData and override formData with
90104
// defaults since the defaults are already merged with formData.
91105
if (isSchemaObjectValue(formData) || Array.isArray(formData)) {

packages/form/src/core/merge.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,6 @@ export function mergeDefaultsWithFormData<T = any>(
166166
defaultsSupersedesUndefined = false,
167167
overrideFormDataWithDefaults = false
168168
): T | undefined {
169-
// NOTE: I missed the PR where this line was removed, but it is not present in 5.24.0
170-
// if (formData === undefined && defaultsSupersedesUndefined) {
171-
// return defaults;
172-
// }
173169
if (Array.isArray(formData)) {
174170
const defaultsArray = Array.isArray(defaults) ? defaults : [];
175171

@@ -210,7 +206,20 @@ export function mergeDefaultsWithFormData<T = any>(
210206
: {};
211207
for (const [key, value] of Object.entries(formData)) {
212208
const keyExistsInDefaults = key in defaultsObject;
213-
const keyExistsInFormData = key in formData;
209+
const keyDefault = defaultsObject[key];
210+
211+
// NOTE: This code is bad, but maintaining compatibility with RSJF > "good" code
212+
if (
213+
isSchemaObjectValue(keyDefault) &&
214+
isSchemaObjectValue(value) &&
215+
!Object.values(keyDefault).some(isSchemaObjectValue)
216+
) {
217+
acc[key as keyof T] = {
218+
...keyDefault,
219+
...value,
220+
};
221+
continue;
222+
}
214223

215224
acc[key as keyof T] = mergeDefaultsWithFormData(
216225
defaultsObject[key],
@@ -219,8 +228,10 @@ export function mergeDefaultsWithFormData<T = any>(
219228
defaultsSupersedesUndefined,
220229
// overrideFormDataWithDefaults can be true only when the key value exists in defaults
221230
// Or if the key value doesn't exist in formData
222-
overrideFormDataWithDefaults &&
223-
(keyExistsInDefaults || !keyExistsInFormData)
231+
// CHANGED: key is always in form data, maybe this condition should be value === undefined
232+
// overrideFormDataWithDefaults &&
233+
// (keyExistsInDefaults || !keyExistsInFormData)
234+
overrideFormDataWithDefaults && keyExistsInDefaults
224235
);
225236
}
226237
return acc;

0 commit comments

Comments
 (0)