diff --git a/packages/form-core/src/FieldApi/FieldApi.public.ts b/packages/form-core/src/FieldApi/FieldApi.public.ts index 26eb1057a..b5c07571b 100644 --- a/packages/form-core/src/FieldApi/FieldApi.public.ts +++ b/packages/form-core/src/FieldApi/FieldApi.public.ts @@ -202,7 +202,7 @@ export interface FieldApiOptions< name: TFieldName errorVisibility?: ErrorVisibility /** - * Route descendant field errors from form-level validation to this field. + * Route descendant field errors from form and form group validators to this field. */ errorBoundary?: boolean validators?: TFieldValidators diff --git a/packages/form-core/src/FormApi/FormApi.lib.ts b/packages/form-core/src/FormApi/FormApi.lib.ts index 202990346..affb00452 100644 --- a/packages/form-core/src/FormApi/FormApi.lib.ts +++ b/packages/form-core/src/FormApi/FormApi.lib.ts @@ -744,22 +744,47 @@ export class InternalFormApi< ) } - _resolveErrorFieldPath(fieldName: string): string { - let current: AnyInternalFieldApi | InternalRootFieldApi = - this._fieldRootNode - let boundary: AnyInternalFieldApi | null = null + /** + * Resolve relative field errors from a validation scope to their concrete + * field targets, coalescing errors captured by the same boundary. + */ + _resolveRoutedFieldErrors( + fieldErrors: Iterable]>, + routingRoot: AnyInternalFieldApi | InternalRootFieldApi = this + ._fieldRootNode, + ): Map> { + const resolvedFieldErrors = new Map< + AnyInternalFieldApi, + Array + >() + + for (const [fieldName, errors] of fieldErrors) { + const segments = nameToFieldNodeSegments(fieldName) + let current = routingRoot + let boundary: AnyInternalFieldApi | null = + routingRoot._isRoot || !routingRoot._errorBoundary ? null : routingRoot + + for (const segment of segments) { + const child: AnyInternalFieldApi | undefined = + current._getChild(segment) + if (!child) break + + if (child._errorBoundary) { + boundary = child + } + current = child + } - for (const segment of nameToFieldNodeSegments(fieldName)) { - const child: AnyInternalFieldApi | undefined = current._getChild(segment) - if (!child) break + const target = + boundary ?? getOrCreateFieldApi(routingRoot, segments.slice(), this) - if (child._errorBoundary) { - boundary = child - } - current = child + resolvedFieldErrors.set( + target, + (resolvedFieldErrors.get(target) ?? []).concat(errors), + ) } - return boundary?.name ?? fieldName + return resolvedFieldErrors } _setFormValidatorError( @@ -857,17 +882,9 @@ export class InternalFormApi< } const parsedResult = parseValidationResult(result.result) - const resolvedFieldErrors = new Map>() - - for (const [fieldName, fieldErrors] of Object.entries( - parsedResult.subfields ?? {}, - )) { - const resolvedName = this._resolveErrorFieldPath(fieldName) - resolvedFieldErrors.set( - resolvedName, - (resolvedFieldErrors.get(resolvedName) ?? []).concat(fieldErrors), - ) - } + const resolvedFieldErrors = this._resolveRoutedFieldErrors( + Object.entries(parsedResult.subfields ?? {}), + ) batch(() => { this._setFormValidatorError( @@ -883,7 +900,6 @@ export class InternalFormApi< result.validatorIndex, resolvedFieldErrors, oldFieldRefs, - (fieldName) => this._getOrCreateFieldApi({ name: fieldName }), (field, index, errors) => this._setFieldValidatorError(field, index, errors, sourceEvent), (field, index) => this._clearFieldValidatorError(field, index), diff --git a/packages/form-core/src/FormGroupApi/FormGroupApi.lib.ts b/packages/form-core/src/FormGroupApi/FormGroupApi.lib.ts index b32641ccc..eac61c9a6 100644 --- a/packages/form-core/src/FormGroupApi/FormGroupApi.lib.ts +++ b/packages/form-core/src/FormGroupApi/FormGroupApi.lib.ts @@ -340,27 +340,25 @@ export class InternalFormGroupApi< const validatorIndex = result.validatorIndex const groupField = this.form._getOrCreateFieldApi({ name: this.name }) const oldFieldRefs = this._fieldErrors[validatorIndex] + const resolvedFieldErrors = this.form._resolveRoutedFieldErrors( + Object.entries(parsedResult.subfields ?? {}), + groupField, + ) + const groupFieldErrors = resolvedFieldErrors.get(groupField) ?? [] + resolvedFieldErrors.delete(groupField) batch(() => { this._setFieldValidatorError( groupField, validatorIndex, - parsedResult.self ?? [], + (parsedResult.self ?? []).concat(groupFieldErrors), sourceEvent, ) - const normalizedFieldErrors = Object.entries( - parsedResult.subfields ?? {}, - ).map( - ([fieldName, fieldErrors]) => - [this._getPrefixedFieldName(fieldName), fieldErrors] as const, - ) - const { fieldRefs } = reconcileRoutedFieldErrors( validatorIndex, - normalizedFieldErrors, + resolvedFieldErrors, oldFieldRefs, - (fieldName) => this.form._getOrCreateFieldApi({ name: fieldName }), (field, index, errors) => this._setFieldValidatorError(field, index, errors, sourceEvent), (field, index) => this._clearFieldValidatorError(field, index), diff --git a/packages/form-core/src/validation.lib.ts b/packages/form-core/src/validation.lib.ts index 02c58c6ae..3851767f4 100644 --- a/packages/form-core/src/validation.lib.ts +++ b/packages/form-core/src/validation.lib.ts @@ -345,9 +345,8 @@ export function clearIndexedErrorsFromSource( export function reconcileRoutedFieldErrors( validatorIndex: number, - fieldErrors: Iterable]>, + fieldErrors: Iterable]>, oldFieldRefs: Set | undefined, - getField: (fieldName: string) => AnyInternalFieldApi, setFieldError: ( field: AnyInternalFieldApi, validatorIndex: number, @@ -363,8 +362,7 @@ export function reconcileRoutedFieldErrors( const affectedFields = new Set() const newFieldRefs = new Set() - for (const [fieldName, fieldError] of fieldErrors) { - const field = getField(fieldName) + for (const [field, fieldError] of fieldErrors) { setFieldError(field, validatorIndex, fieldError) newFieldRefs.add(field) affectedFields.add(field) diff --git a/packages/form-core/tests/FormGroupApi/FormGroupApi.spec.ts b/packages/form-core/tests/FormGroupApi/FormGroupApi.spec.ts index 54a6aa4ea..dd0955548 100644 --- a/packages/form-core/tests/FormGroupApi/FormGroupApi.spec.ts +++ b/packages/form-core/tests/FormGroupApi/FormGroupApi.spec.ts @@ -832,6 +832,143 @@ describe('FormGroupApi', () => { expect(group.state.errors).toEqual([]) }) + it('routes descendant Standard Schema issues to a field error boundary', async () => { + const form = new InternalFormApi({ + defaultValues: { + stayDates: { + dateRange: { from: '', to: '' }, + arrivalTime: '', + }, + }, + }) + const dateRangeField = form._getOrCreateFieldApi({ + name: 'stayDates.dateRange', + errorBoundary: true, + }) + const arrivalTimeField = form._getOrCreateFieldApi({ + name: 'stayDates.arrivalTime', + }) + const group = new InternalFormGroupApi({ + form, + name: 'stayDates', + validators: [ + { + triggers: [], + run: z.object({ + dateRange: z.object({ + from: z.string().min(1, 'Start date is required'), + to: z.string().min(1, 'End date is required'), + }), + arrivalTime: z.string().min(1, 'Arrival time is required'), + }), + }, + ], + }) + + await group.validate('submit') + + expect(dateRangeField.errors).toEqual([ + expect.objectContaining({ message: 'Start date is required' }), + expect.objectContaining({ message: 'End date is required' }), + ]) + expect(arrivalTimeField.errors).toEqual([ + expect.objectContaining({ message: 'Arrival time is required' }), + ]) + expect(form._tryGetFieldApi('stayDates.dateRange.from')).toBeNull() + expect(form._tryGetFieldApi('stayDates.dateRange.to')).toBeNull() + expect(group.state.isInvalid).toBe(true) + + dateRangeField.handleChange( + { from: '2026-08-10', to: '2026-08-12' }, + { causeValidation: false }, + ) + arrivalTimeField.handleChange('15:00', { causeValidation: false }) + await group.validate('submit') + + expect(dateRangeField.errors).toEqual([]) + expect(arrivalTimeField.errors).toEqual([]) + expect(group.state.isInvalid).toBe(false) + }) + + it('combines group self and descendant errors at a group root error boundary', async () => { + const form = new InternalFormApi({ + defaultValues: { + stayDates: { + dateRange: { from: '', to: '' }, + }, + }, + }) + const groupField = form._getOrCreateFieldApi({ + name: 'stayDates', + errorBoundary: true, + }) + const group = new InternalFormGroupApi({ + form, + name: 'stayDates', + validators: [ + { + triggers: [], + run: () => ({ + form: 'Stay dates are invalid', + fields: { + 'dateRange.from': 'Start date is required', + 'dateRange.to': 'End date is required', + }, + }), + }, + ], + }) + + await group.validate('submit') + + expect(groupField.errors).toEqual([ + { message: 'Stay dates are invalid' }, + { message: 'Start date is required' }, + { message: 'End date is required' }, + ]) + expect(group.state.errors).toEqual(groupField.errors) + expect(form._tryGetFieldApi('stayDates.dateRange.from')).toBeNull() + expect(form._tryGetFieldApi('stayDates.dateRange.to')).toBeNull() + }) + + it('does not route group errors to a boundary outside the group', async () => { + const form = new InternalFormApi({ + defaultValues: { + booking: { + stayDates: { + dateRange: { to: '' }, + }, + }, + }, + }) + const bookingField = form._getOrCreateFieldApi({ + name: 'booking', + errorBoundary: true, + }) + const group = new InternalFormGroupApi({ + form, + name: 'booking.stayDates', + validators: [ + { + triggers: [], + run: () => ({ + fields: { + 'dateRange.to': 'End date is required', + }, + }), + }, + ], + }) + + await group.validate('submit') + + expect(bookingField.errors).toEqual([]) + expect( + form._tryGetFieldApi('booking.stayDates.dateRange.to')?.errors, + ).toEqual([{ message: 'End date is required' }]) + expect(group.state.isInvalid).toBe(true) + }) + it('clears routed group field errors when validation later passes', async () => { let shouldError = true const form = new InternalFormApi({ diff --git a/packages/form-core/tests/validation.test.ts b/packages/form-core/tests/validation.test.ts index fabd53e61..805fdf84b 100644 --- a/packages/form-core/tests/validation.test.ts +++ b/packages/form-core/tests/validation.test.ts @@ -214,12 +214,28 @@ describe('parseValidationResult', () => { }) describe('reconcileRoutedFieldErrors', () => { + it('sets errors on already-resolved field refs', () => { + const field = { name: 'name' } as AnyInternalFieldApi + const errors = [{ message: 'Name is required' }] + const setFieldError = vi.fn() + const result = reconcileRoutedFieldErrors( + 2, + [[field, errors]], + undefined, + setFieldError, + vi.fn(), + ) + + expect(setFieldError).toHaveBeenCalledWith(field, 2, errors) + expect(result.fieldRefs).toEqual(new Set([field])) + expect(result.affectedFields).toEqual(new Set([field])) + }) + it('reports unchanged refs when no new or old field refs exist', () => { const result = reconcileRoutedFieldErrors( 0, [], undefined, - (fieldName) => ({ name: fieldName }) as AnyInternalFieldApi, vi.fn(), vi.fn(), ) @@ -234,7 +250,6 @@ describe('reconcileRoutedFieldErrors', () => { 0, [], new Set(), - (fieldName) => ({ name: fieldName }) as AnyInternalFieldApi, vi.fn(), vi.fn(), ) @@ -249,7 +264,6 @@ describe('reconcileRoutedFieldErrors', () => { 0, [], new Set([field]), - (fieldName) => ({ name: fieldName }) as AnyInternalFieldApi, vi.fn(), clearFieldError, ) diff --git a/packages/form-devtools/package.json b/packages/form-devtools/package.json index 878955556..9cca2f866 100644 --- a/packages/form-devtools/package.json +++ b/packages/form-devtools/package.json @@ -80,7 +80,8 @@ "resize-observer-polyfill": "^1.5.1", "solid-js": "^1.9.13", "vite": "^8.1.2", - "vite-plugin-solid": "^2.11.10" + "vite-plugin-solid": "^2.11.10", + "zod": "^4.4.3" }, "peerDependencies": { "solid-js": ">=1.9.5" diff --git a/packages/form-devtools/tests/fieldDebugCases.test.ts b/packages/form-devtools/tests/fieldDebugCases.test.ts index 33999c237..cb6a2f84d 100644 --- a/packages/form-devtools/tests/fieldDebugCases.test.ts +++ b/packages/form-devtools/tests/fieldDebugCases.test.ts @@ -3,6 +3,7 @@ import { InternalFormGroupApi, } from '@tanstack/form-core/internals' import { describe, expect, it } from 'vitest' +import { z } from 'zod' import { getFieldDebugSuspicions } from '../src/bridge/fields/fieldDebug' import type { AnyInternalFieldApi } from '@tanstack/form-core/internals' import type { FieldDebugCase } from '../src/bridge/fields/fieldDebug' @@ -19,13 +20,7 @@ const emptyTriggerValidator = { const schemaValidator = { triggers: ['change'] as const, - run: { - '~standard': { - version: 1, - vendor: 'field-debug-test', - validate: () => ({ value: undefined }), - }, - }, + run: z.unknown(), } function setFieldError(field: AnyInternalFieldApi) { diff --git a/packages/form-devtools/tests/fieldDetailsBridge.test.ts b/packages/form-devtools/tests/fieldDetailsBridge.test.ts index 65791609c..43c4c6a7c 100644 --- a/packages/form-devtools/tests/fieldDetailsBridge.test.ts +++ b/packages/form-devtools/tests/fieldDetailsBridge.test.ts @@ -4,6 +4,7 @@ import { installDevtoolsBridge, } from '@tanstack/form-core/internals' import { afterEach, describe, expect, it, vi } from 'vitest' +import { z } from 'zod' import { createFieldsController } from '../src/bridge/fields' import { createFieldIdentityController } from '../src/bridge/fields/identity' import { createMountedFormsController } from '../src/bridge/forms/mountedForms' @@ -25,13 +26,7 @@ const callbackValidator = { const schemaValidator = { triggers: ['change'] as const, - run: { - '~standard': { - version: 1, - vendor: 'field-detail-test', - validate: () => ({ value: undefined }), - }, - }, + run: z.unknown(), } function descriptor( @@ -72,7 +67,7 @@ describe('field detail snapshots', () => { validators: [callbackValidator, schemaValidator] as never, }) const unregister = field._register() - const subscription = descriptor('form' as FormId, 'field' as FieldId) + const subscription = descriptor('form', 'field') try { field._setMeta((meta) => ({ @@ -216,7 +211,7 @@ describe('field detail snapshots', () => { }) const source = form._getOrCreateFieldApi({ name: 'source' }) const other = form._getOrCreateFieldApi({ name: 'other' }) - const subscription = descriptor('form' as FormId, 'field' as FieldId) + const subscription = descriptor('form', 'field') const parentDetail = getDevtoolsFieldDetail(parent, subscription, identity) expect(parentDetail.relations.directChildCount).toBe(1) diff --git a/packages/form-devtools/tests/fieldGeneralDebugReportsBridge.test.ts b/packages/form-devtools/tests/fieldGeneralDebugReportsBridge.test.ts index d0b7bee7e..734dcd488 100644 --- a/packages/form-devtools/tests/fieldGeneralDebugReportsBridge.test.ts +++ b/packages/form-devtools/tests/fieldGeneralDebugReportsBridge.test.ts @@ -1,5 +1,6 @@ import { InternalFormApi } from '@tanstack/form-core/internals' import { describe, expect, it } from 'vitest' +import { z } from 'zod' import { createFieldsController } from '../src/bridge/fields' import { createMountedFormsController } from '../src/bridge/forms/mountedForms' import { formDevtoolsEventClient } from '../src/eventClient.lib' @@ -8,13 +9,7 @@ import type { FieldDebugReport } from '../src/eventClientTypes' const schemaValidator = { triggers: ['change'] as const, - run: { - '~standard': { - version: 1, - vendor: 'field-debug-bridge-test', - validate: () => ({ value: undefined }), - }, - }, + run: z.unknown(), } const emptyTriggerValidator = { diff --git a/packages/react-form/package.json b/packages/react-form/package.json index 66dba2ba3..c1d49aff6 100644 --- a/packages/react-form/package.json +++ b/packages/react-form/package.json @@ -53,7 +53,8 @@ "@vitejs/plugin-react": "^6.0.1", "eslint-plugin-react-compiler": "19.1.0-rc.2", "eslint-plugin-react-hooks": "^7.1.1", - "react": "19.2.4" + "react": "19.2.4", + "zod": "^4.4.3" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0" diff --git a/packages/react-form/tests/FormGroup.spec.tsx b/packages/react-form/tests/FormGroup.spec.tsx index 2fd3247aa..c040db8d9 100644 --- a/packages/react-form/tests/FormGroup.spec.tsx +++ b/packages/react-form/tests/FormGroup.spec.tsx @@ -2,9 +2,10 @@ import { describe, expect, it, vi } from 'vitest' import { render } from '@testing-library/react' import { userEvent } from '@testing-library/user-event' import React, { useState } from 'react' +import { z } from 'zod' import { createFormHook, getFormHookHelpers, useForm } from '../src' import type { AnyInternalFormApi } from '@tanstack/form-core/internals' -import type { FieldWithValue, StandardSchemaV1 } from '@tanstack/form-core' +import type { FieldWithValue } from '@tanstack/form-core' const user = userEvent.setup() @@ -403,26 +404,10 @@ describe('FormGroup', () => { it('renders Standard Schema group errors through AppForm field components', async () => { const formRef = { current: null as AnyInternalFormApi | null } - const validate = vi.fn((value: unknown) => { - const step = value as { name: string } - return step.name.length >= 2 - ? { value: step } - : { - issues: [ - { - message: 'Name must be at least 2 characters', - path: ['name'], - }, - ], - } + const step1Schema = z.object({ + name: z.string().min(2, 'Name must be at least 2 characters'), }) - const step1Schema = { - '~standard': { - version: 1, - vendor: 'test', - validate, - }, - } satisfies StandardSchemaV1<{ name: string }> + const validate = vi.spyOn(step1Schema['~standard'], 'validate') function Component() { const form = useAppForm({ @@ -480,6 +465,86 @@ describe('FormGroup', () => { }) }) + it('routes descendant Standard Schema group errors to an error boundary field', async () => { + const stayDatesSchema = z.object({ + dateRange: z.object({ + from: z + .date() + .optional() + .refine( + (value) => value !== undefined, + 'Please select a start date.', + ), + to: z + .date() + .optional() + .refine((value) => value !== undefined, 'Please select an end date.'), + }), + arrivalTime: z.string().min(1, 'Please select an arrival time.'), + }) + type StayDates = z.input + const defaultValues: { stayDates: StayDates } = { + stayDates: { + dateRange: { + from: undefined, + to: undefined, + }, + arrivalTime: '', + }, + } + + function Component() { + const form = useForm({ + defaultValues, + }) + + return ( + + {(group) => ( + <> + + {(field) => ( + + {field.errors.map((error) => error.message).join(',')} + + )} + + + {(field) => ( + + {field.errors.map((error) => error.message).join(',')} + + )} + + + + )} + + ) + } + + const { getByText, getByTestId } = render() + + await user.click(getByText('Continue')) + + await vi.waitFor(() => { + expect(getByTestId('arrival-time-errors')).toHaveTextContent( + 'Please select an arrival time.', + ) + expect(getByTestId('date-range-errors')).toHaveTextContent( + 'Please select a start date.,Please select an end date.', + ) + }) + }) + it('does not add a DOM-rendering StepForm helper', () => { function Component() { const form = useForm({ defaultValues: { guestDetails: { name: '' } } }) diff --git a/packages/react-form/tests/FormGroup.test-d.tsx b/packages/react-form/tests/FormGroup.test-d.tsx index 1dbe2958d..0ec0f5ad1 100644 --- a/packages/react-form/tests/FormGroup.test-d.tsx +++ b/packages/react-form/tests/FormGroup.test-d.tsx @@ -1,12 +1,12 @@ import React from 'react' import { expectTypeOf } from 'vitest' +import { z } from 'zod' import { useForm } from '../src' import type { DeepKeys, FieldApi, FormErrorTypes, FormGroupApi, - StandardSchemaV1, StandardSchemaV1Issue, ValidationIssue, } from '../src' @@ -142,17 +142,12 @@ type GroupValidationError = { fromGroup: true } -const guestDetailsSchema = { - '~standard': { - version: 1, - vendor: 'test', - validate: (value: unknown) => ({ - value: { - nameLength: (value as GuestDetails).name.length, - }, - }), - }, -} satisfies StandardSchemaV1 +const guestDetailsSchema = z + .object({ + name: z.string(), + emails: z.array(z.string()), + }) + .transform(({ name }) => ({ nameLength: name.length })) function FormGroupSubmitTypes() { const form = useForm({ diff --git a/packages/react-form/tests/submit-return.test-d.tsx b/packages/react-form/tests/submit-return.test-d.tsx index 91dd17452..bd9cb236b 100644 --- a/packages/react-form/tests/submit-return.test-d.tsx +++ b/packages/react-form/tests/submit-return.test-d.tsx @@ -1,22 +1,14 @@ import React from 'react' import { describe, expectTypeOf, it } from 'vitest' +import { z } from 'zod' import { createFormHook, formOptions, useForm } from '../src' import type { ReactFormType, - StandardSchemaV1, StandardSchemaV1Issue, ValidationIssue, } from '../src' -const emailSchema = { - '~standard': { - version: 1, - vendor: 'test', - validate: (value: unknown) => ({ - value: value as { email: string }, - }), - }, -} satisfies StandardSchemaV1<{ email: string }> +const emailSchema = z.object({ email: z.string() }) describe('submit return', () => { it('infers schema outputs and submit errors without a cycle', () => { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6a7c626f0..3314cf819 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -480,7 +480,7 @@ importers: version: link:../../../packages/react-form-nextjs next: specifier: 16.2.12 - version: 16.2.12(@babel/core@8.0.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.102.0) + version: 16.2.12(@babel/core@7.29.7)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.102.0) react: specifier: 19.2.4 version: 19.2.4 @@ -511,7 +511,7 @@ importers: version: link:../../../packages/react-form-nextjs next: specifier: 16.2.12 - version: 16.2.12(@babel/core@8.0.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.102.0) + version: 16.2.12(@babel/core@7.29.7)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.102.0) react: specifier: 19.2.4 version: 19.2.4 @@ -545,7 +545,7 @@ importers: version: link:../../../packages/react-form-nextjs next: specifier: 16.2.12 - version: 16.2.12(@babel/core@8.0.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.102.0) + version: 16.2.12(@babel/core@7.29.7)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.102.0) react: specifier: 19.2.4 version: 19.2.4 @@ -1009,6 +1009,9 @@ importers: vite-plugin-solid: specifier: ^2.11.10 version: 2.11.14(@testing-library/jest-dom@6.10.0(@testing-library/dom@10.4.1))(solid-js@1.9.14)(vite@8.2.0(@types/node@25.9.5)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1)(sass@1.102.0)(terser@5.49.0)(yaml@2.9.0)) + zod: + specifier: ^4.4.3 + version: 4.4.3 packages/lit-form: dependencies: @@ -1072,6 +1075,9 @@ importers: react: specifier: 19.2.4 version: 19.2.4 + zod: + specifier: ^4.4.3 + version: 4.4.3 packages/react-form-devtools: dependencies: @@ -21920,7 +21926,7 @@ snapshots: negotiator@1.0.0: {} - next@16.2.12(@babel/core@8.0.1)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.102.0): + next@16.2.12(@babel/core@7.29.7)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.102.0): dependencies: '@next/env': 16.2.12 '@swc/helpers': 0.5.15 @@ -21929,7 +21935,7 @@ snapshots: postcss: 8.4.31 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - styled-jsx: 5.1.6(@babel/core@8.0.1)(react@19.2.4) + styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.4) optionalDependencies: '@next/swc-darwin-arm64': 16.2.12 '@next/swc-darwin-x64': 16.2.12 @@ -23958,12 +23964,12 @@ snapshots: structured-headers@0.4.1: {} - styled-jsx@5.1.6(@babel/core@8.0.1)(react@19.2.4): + styled-jsx@5.1.6(@babel/core@7.29.7)(react@19.2.4): dependencies: client-only: 0.0.1 react: 19.2.4 optionalDependencies: - '@babel/core': 8.0.1 + '@babel/core': 7.29.7 styleq@0.1.3: {}