diff --git a/sandbox-app/index.tsx b/sandbox-app/index.tsx index 06d4365..67bd7be 100644 --- a/sandbox-app/index.tsx +++ b/sandbox-app/index.tsx @@ -2,6 +2,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { useForm } from '../src/index'; import { NestedField } from './nested-field'; +import { NestedValidation } from './nested-validation'; import { NullableField } from './nullable-field'; import { ObjectsArray } from './objects-array'; import { SimpleArray } from './simple-array'; @@ -39,6 +40,7 @@ function App(): JSX.Element { + ); diff --git a/sandbox-app/nested-validation.tsx b/sandbox-app/nested-validation.tsx new file mode 100644 index 0000000..b69c4e3 --- /dev/null +++ b/sandbox-app/nested-validation.tsx @@ -0,0 +1,59 @@ +import React from 'react'; +import { useForm } from '../src'; +import { Input } from './components/Input'; + +interface Model { + address?: { + streetName?: string; + }; +} + +const initialValue: Model = {}; + +export function NestedValidation(): JSX.Element { + const { + model, + changes, + fields, + onSubmit, + valid, + dirty, + submissionStatus, + reset, + } = useForm({ + model: initialValue, + onSubmit: async ({ model }) => { + // eslint-disable-next-line no-console + console.log(model); + }, + validations: { + address: { + streetName: 'required', + }, + }, + }); + + return ( + <> +

Nested Field

+
+
+ +
+ + +
+
+
+

Model

+
+        {JSON.stringify({ model, valid, dirty, submissionStatus }, null, 2)}
+      
+

Changes

+
{JSON.stringify({ changes }, null, 2)}
+ Back + + ); +} diff --git a/src/field.ts b/src/field.ts index cb80872..47ae164 100644 --- a/src/field.ts +++ b/src/field.ts @@ -103,7 +103,7 @@ export class FieldImplementation get fields(): MappedFields { if (!this.value) { this.value = {} as T; - this.#onUpdate(); + this.#onUpdate?.(); } const handler = { get: (target: MappedFields, key: string) => { diff --git a/src/form.spec.ts b/src/form.spec.ts index d8f1b63..3ac1ea6 100644 --- a/src/form.spec.ts +++ b/src/form.spec.ts @@ -662,6 +662,24 @@ describe(Form, () => { expect(emails.dirty).toBeTruthy(); expect(form.dirty).toBeTruthy(); }); + it('handles nested validation', () => { + const form = createForm({ + value: { + address: { + streetName: '', + }, + }, + validations: { + address: { + streetName: 'required', + }, + }, + }); + expect(form.fields.address.fields.streetName.errors).toHaveLength(1); + expect(form.fields.address.fields.streetName.errors[0]).toBe( + 'required-field' + ); + }); }); });