diff --git a/.changeset/chatty-bugs-pump.md b/.changeset/chatty-bugs-pump.md new file mode 100644 index 000000000000..89f2a08b8fe0 --- /dev/null +++ b/.changeset/chatty-bugs-pump.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +fix fields.value() returning undefined when input_value is passed to .as() diff --git a/packages/kit/src/runtime/form-utils.js b/packages/kit/src/runtime/form-utils.js index 72b9cb84abb5..52fb05d0271c 100644 --- a/packages/kit/src/runtime/form-utils.js +++ b/packages/kit/src/runtime/form-utils.js @@ -6,6 +6,7 @@ import { DEV } from 'esm-env'; import * as devalue from 'devalue'; import { text_decoder, text_encoder } from './utils.js'; import { SvelteKitError } from '@sveltejs/kit/internal'; +import { untrack } from 'svelte'; /** * Sets a value in a nested object using a path string, mutating the original object @@ -679,6 +680,11 @@ export function create_field_proxy(target, get_input, set_input, get_issues, pat ? 'b:' : ''; + // If the input has a default value and there is no current value, set it to the default value + if (input_value !== undefined && get_value() == null) { + untrack(() => set_input(path, input_value)); + } + // Base properties for all input types /** @type {Record} */ const base_props = { diff --git a/packages/kit/test/apps/async/src/routes/remote/form/as-value/+page.svelte b/packages/kit/test/apps/async/src/routes/remote/form/as-value/+page.svelte index dc06e5dcceae..48f8a46ac347 100644 --- a/packages/kit/test/apps/async/src/routes/remote/form/as-value/+page.svelte +++ b/packages/kit/test/apps/async/src/routes/remote/form/as-value/+page.svelte @@ -11,27 +11,28 @@ {/each} {#each values as value (value.id)} + {@const form = as_value_form.for(value.id)}
{ + {...form.enhance(({ submit }) => { // TODO: needed to keep the values when JS is enabled, remove when reset is implemented submit(); })} > - + - + - - + - + - +
{/each} diff --git a/packages/kit/test/apps/async/src/routes/remote/form/value-default/+page.svelte b/packages/kit/test/apps/async/src/routes/remote/form/value-default/+page.svelte new file mode 100644 index 000000000000..a809c9e6b5bb --- /dev/null +++ b/packages/kit/test/apps/async/src/routes/remote/form/value-default/+page.svelte @@ -0,0 +1,11 @@ + + +
+

{test_form.fields.name.value()}

+ +
diff --git a/packages/kit/test/apps/async/src/routes/remote/form/value-default/form.remote.ts b/packages/kit/test/apps/async/src/routes/remote/form/value-default/form.remote.ts new file mode 100644 index 000000000000..999468eb5f56 --- /dev/null +++ b/packages/kit/test/apps/async/src/routes/remote/form/value-default/form.remote.ts @@ -0,0 +1,4 @@ +import { form } from '$app/server'; +import * as v from 'valibot'; + +export const test_form = form(v.object({ name: v.string() }), async (data) => {}); diff --git a/packages/kit/test/apps/async/test/client.test.js b/packages/kit/test/apps/async/test/client.test.js index 1f02d02d2f0d..7f2947659064 100644 --- a/packages/kit/test/apps/async/test/client.test.js +++ b/packages/kit/test/apps/async/test/client.test.js @@ -484,6 +484,19 @@ test.describe('remote function mutations', () => { } }); + test('.value() reflects input_value default before any user interaction', async ({ page }) => { + await page.goto('/remote/form/value-default'); + + const input = page.locator('[data-testid="as-value-default-input"]'); + const display = page.locator('#default-value-display'); + + // input has to output the default value provided + await expect(input).toHaveValue('default text'); + + // value() also needs to output the default value provided WITHOUT any user interaction + await expect(display).toHaveText('default text'); + }); + test('.as(type, value) updates when data changes after submission', async ({ page }) => { await page.goto('/remote/form/as-value');