From df9d7ed4380de31756cd5fb552a4b5aa14409203 Mon Sep 17 00:00:00 2001 From: Savva Mikhalevski Date: Tue, 23 Apr 2024 15:21:56 +0300 Subject: [PATCH] Default values for child fields (#34) --- packages/roqueform/src/main/createField.ts | 9 +++++++-- packages/roqueform/src/main/types.ts | 3 ++- packages/roqueform/src/test/createField.test.ts | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/roqueform/src/main/createField.ts b/packages/roqueform/src/main/createField.ts index 2261a4e..6a31f9b 100644 --- a/packages/roqueform/src/main/createField.ts +++ b/packages/roqueform/src/main/createField.ts @@ -94,7 +94,7 @@ function getOrCreateField( setValue(field, field.value, false); }, - at: key => getOrCreateField(field.valueAccessor, field, key, null, plugin), + at: (key, defaultValue) => getOrCreateField(field.valueAccessor, field, key, defaultValue, plugin), on: (type, subscriber) => { const subscribers = (field.subscribers[type] ||= []); @@ -111,7 +111,12 @@ function getOrCreateField( field.rootField = field; if (parentField !== null) { - field.value = parentField.valueAccessor.get(parentField.value, key); + const derivedValue = parentField.valueAccessor.get(parentField.value, key); + + if (derivedValue !== undefined) { + field.value = derivedValue; + } + field.initialValue = parentField.valueAccessor.get(parentField.initialValue, key); field.rootField = parentField.rootField; (parentField.children ||= []).push(field); diff --git a/packages/roqueform/src/main/types.ts b/packages/roqueform/src/main/types.ts index 8aa5e37..7ed146d 100644 --- a/packages/roqueform/src/main/types.ts +++ b/packages/roqueform/src/main/types.ts @@ -104,10 +104,11 @@ export interface BareField { * {@link value the current value}. * * @param key The key in the value of this field. + * @param defaultValue The default value used if the value at given key is `undefined`. * @returns The child field instance. * @template Key The key in the value of this field. */ - at>(key: Key): Field, Plugin>; + at>(key: Key, defaultValue?: ValueAt): Field, Plugin>; /** * Subscribes to all events. diff --git a/packages/roqueform/src/test/createField.test.ts b/packages/roqueform/src/test/createField.test.ts index edd0ef4..b6fe294 100644 --- a/packages/roqueform/src/test/createField.test.ts +++ b/packages/roqueform/src/test/createField.test.ts @@ -48,6 +48,20 @@ describe('createField', () => { expect(field.at('aaa')).toBe(field.at('aaa')); }); + test('returns a field at key with the default value', () => { + const field = createField<{ aaa?: number }>({}).at('aaa', 111); + + expect(field.value).toBe(111); + expect(field.initialValue).toBe(undefined); + }); + + test('default value does not override a defined value', () => { + const field = createField({ aaa: 222 }).at('aaa', 111); + + expect(field.value).toBe(222); + expect(field.initialValue).toBe(222); + }); + test('sets a value to a root field', () => { const field = createField(111);