Skip to content

Commit 55ac0d5

Browse files
LeeWxxteemingc
andauthored
fix: ensure remote form fields.set triggers reactivity (#14661)
* fix: ensure remote form fields.set triggers reactivity * test: cover remote form fields.set reactivity * chore: changeset * Apply suggestion from @teemingc * Apply suggestion from @teemingc --------- Co-authored-by: Tee Ming <[email protected]>
1 parent bc3ec26 commit 55ac0d5

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

.changeset/easy-plants-remain.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
fix: ensure `form` remote functions' `fields.set` triggers reactivity

packages/kit/src/runtime/client/remote-functions/form.svelte.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,8 +537,21 @@ export function form(id) {
537537
(path, value) => {
538538
if (path.length === 0) {
539539
input = value;
540+
update_all_versions();
540541
} else {
541542
input = deep_set(input, path.map(String), value);
543+
544+
const key = build_path_string(path);
545+
versions[key] ??= 0;
546+
versions[key] += 1;
547+
touched[key] = true;
548+
549+
const parent_path = path.slice();
550+
while (parent_path.pop() !== undefined) {
551+
const parent_key = build_path_string(parent_path);
552+
versions[parent_key] ??= 0;
553+
versions[parent_key] += 1;
554+
}
542555
}
543556
},
544557
() => issues
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script lang="ts">
2+
import { set_message } from '../form.remote.js';
3+
import * as v from 'valibot';
4+
5+
const schema = v.object({
6+
message: v.picklist(
7+
['hello', 'goodbye', 'unexpected error', 'expected error', 'redirect'],
8+
'message is invalid'
9+
)
10+
});
11+
</script>
12+
13+
<form {...set_message.preflight(schema)}>
14+
<label>
15+
<span>Message</span>
16+
<input {...set_message.fields.message.as('text')} />
17+
</label>
18+
19+
<p id="issue">
20+
{set_message.fields.message.issues()?.[0]?.message ?? 'ok'}
21+
</p>
22+
<p id="value">{set_message.fields.message.value()}</p>
23+
24+
<button
25+
id="set-and-validate"
26+
type="button"
27+
on:click={async () => {
28+
set_message.fields.message.set('hello');
29+
await set_message.validate({ includeUntouched: true });
30+
}}
31+
>
32+
Set & validate
33+
</button>
34+
<button>Submit</button>
35+
</form>

packages/kit/test/apps/basics/test/client.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1965,6 +1965,18 @@ test.describe('remote functions', () => {
19651965
await expect(page.locator('p')).toHaveText('success');
19661966
});
19671967

1968+
test('fields.set updates DOM before validate', async ({ page }) => {
1969+
await page.goto('/remote/form/imperative');
1970+
1971+
const input = page.locator('input[name="message"]');
1972+
await input.fill('123');
1973+
1974+
await page.locator('#set-and-validate').click();
1975+
1976+
await expect(input).toHaveValue('hello');
1977+
await expect(page.locator('#issue')).toHaveText('ok');
1978+
});
1979+
19681980
test('command pending state is tracked correctly', async ({ page }) => {
19691981
await page.goto('/remote');
19701982

0 commit comments

Comments
 (0)