From 94c63765ec723fc6fb7a438c4f00459b2c9021ca Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 19 Oct 2025 21:18:39 -0400 Subject: [PATCH 1/2] breaking: remove `submitter` option from experimental form `validate()` method, always provide default submitter --- .changeset/tangy-aliens-end.md | 5 +++++ packages/kit/src/exports/public.d.ts | 2 -- .../client/remote-functions/form.svelte.js | 8 ++++++-- .../src/routes/remote/form/validate/+page.svelte | 16 +++++++--------- .../routes/remote/form/validate/form.remote.ts | 2 +- packages/kit/types/index.d.ts | 2 -- 6 files changed, 19 insertions(+), 16 deletions(-) create mode 100644 .changeset/tangy-aliens-end.md diff --git a/.changeset/tangy-aliens-end.md b/.changeset/tangy-aliens-end.md new file mode 100644 index 000000000000..d2dc04d32866 --- /dev/null +++ b/.changeset/tangy-aliens-end.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +breaking: remove `submitter` option from experimental form `validate()` method, always provide default submitter diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 84fd0bb3067e..dc91d178f741 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -2025,8 +2025,6 @@ export type RemoteForm = { includeUntouched?: boolean; /** Set this to `true` to only run the `preflight` validation. */ preflightOnly?: boolean; - /** Perform validation as if the form was submitted by the given button. */ - submitter?: HTMLButtonElement | HTMLInputElement; }): Promise; /** The result of the form submission */ get result(): Output | undefined; diff --git a/packages/kit/src/runtime/client/remote-functions/form.svelte.js b/packages/kit/src/runtime/client/remote-functions/form.svelte.js index 3352231674c9..dd7c7095100d 100644 --- a/packages/kit/src/runtime/client/remote-functions/form.svelte.js +++ b/packages/kit/src/runtime/client/remote-functions/form.svelte.js @@ -572,7 +572,7 @@ export function form(id) { }, validate: { /** @type {RemoteForm['validate']} */ - value: async ({ includeUntouched = false, preflightOnly = false, submitter } = {}) => { + value: async ({ includeUntouched = false, preflightOnly = false } = {}) => { if (!element) return; const id = ++validate_id; @@ -580,7 +580,11 @@ export function form(id) { // wait a tick in case the user is calling validate() right after set() which takes time to propagate await tick(); - const form_data = new FormData(element, submitter); + const default_submitter = /** @type {HTMLElement | undefined} */ ( + element.querySelector('button, [type="submit"]') + ); + + const form_data = new FormData(element, default_submitter); /** @type {InternalRemoteFormIssue[]} */ let array = []; diff --git a/packages/kit/test/apps/basics/src/routes/remote/form/validate/+page.svelte b/packages/kit/test/apps/basics/src/routes/remote/form/validate/+page.svelte index ac9604b266fa..8ab0d0a5172b 100644 --- a/packages/kit/test/apps/basics/src/routes/remote/form/validate/+page.svelte +++ b/packages/kit/test/apps/basics/src/routes/remote/form/validate/+page.svelte @@ -7,7 +7,7 @@ bar: v.picklist(['d', 'e']), button: v.optional(v.literal('submitter')) }); - let submitter; + $inspect(my_form.fields.allIssues()); @@ -24,18 +24,16 @@ - + - {#each my_form.fields.button.issues() as issue}

{issue.message}

{/each} + + - diff --git a/packages/kit/test/apps/basics/src/routes/remote/form/validate/form.remote.ts b/packages/kit/test/apps/basics/src/routes/remote/form/validate/form.remote.ts index 10df815353a7..4775c3919aec 100644 --- a/packages/kit/test/apps/basics/src/routes/remote/form/validate/form.remote.ts +++ b/packages/kit/test/apps/basics/src/routes/remote/form/validate/form.remote.ts @@ -5,7 +5,7 @@ export const my_form = form( v.object({ foo: v.picklist(['a', 'b', 'c']), bar: v.picklist(['d', 'e', 'f']), - button: v.optional(v.literal('submitter')) + button: v.literal('submitter') }), async (data, invalid) => { // Test imperative validation diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index cc02ddb3e4c1..96679189609e 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -2001,8 +2001,6 @@ declare module '@sveltejs/kit' { includeUntouched?: boolean; /** Set this to `true` to only run the `preflight` validation. */ preflightOnly?: boolean; - /** Perform validation as if the form was submitted by the given button. */ - submitter?: HTMLButtonElement | HTMLInputElement; }): Promise; /** The result of the form submission */ get result(): Output | undefined; From ef782d27ba8d1c450065aa992992c5baf25544db Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Mon, 20 Oct 2025 09:35:41 -0400 Subject: [PATCH 2/2] fix --- .../apps/basics/src/routes/remote/form/validate/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/test/apps/basics/src/routes/remote/form/validate/+page.svelte b/packages/kit/test/apps/basics/src/routes/remote/form/validate/+page.svelte index 8ab0d0a5172b..b1fb774f59a4 100644 --- a/packages/kit/test/apps/basics/src/routes/remote/form/validate/+page.svelte +++ b/packages/kit/test/apps/basics/src/routes/remote/form/validate/+page.svelte @@ -5,7 +5,7 @@ const schema = v.object({ foo: v.picklist(['a', 'b', 'c']), bar: v.picklist(['d', 'e']), - button: v.optional(v.literal('submitter')) + button: v.literal('submitter') }); $inspect(my_form.fields.allIssues());