Skip to content

Commit b12b3a6

Browse files
committed
[sveltekit] Add SvelteKitForm component
1 parent c7a8a5b commit b12b3a6

File tree

6 files changed

+97
-3
lines changed

6 files changed

+97
-3
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@sjsf/sveltekit": minor
3+
---
4+
5+
Add `SvelteKitForm` component

packages/sveltekit/src/lib/client/create-form.svelte.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export function createSvelteKitForm<
9999
const additionalPropertyKeyValidationError = $derived(
100100
options.additionalPropertyKeyValidationError
101101
);
102-
const proto = {
102+
const defaults = {
103103
...initialFormData,
104104
additionalPropertyKeyValidator:
105105
additionalPropertyKeyValidationError !== undefined
@@ -160,8 +160,18 @@ export function createSvelteKitForm<
160160
}
161161
: undefined
162162
};
163-
const form = createForm3<FormOptions<Meta['__formValue'], E>>(
164-
Object.setPrototypeOf(options, proto)
163+
const form = createForm3(
164+
new Proxy(options, {
165+
has(target, p) {
166+
return Reflect.has(target, p) || p in defaults
167+
},
168+
get(target, p, receiver) {
169+
if (!(p in target)) {
170+
return defaults[p as keyof typeof defaults];
171+
}
172+
return Reflect.get(target, p, receiver);
173+
}
174+
}) as unknown as FormOptions<Meta['__formValue'], E>
165175
);
166176
$effect(() => {
167177
if (!isRecord(page.form)) {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<script lang="ts" generics="Meta extends SvelteKitFormMeta<any, any, string, any>">
2+
import { RawForm } from '@sjsf/form';
3+
4+
import type { SvelteKitFormMeta } from './meta.js';
5+
import { createSvelteKitForm, type SvelteKitFormOptions2 } from './create-form.svelte.js';
6+
import { createSvelteKitRequest, type SveltekitRequestOptions } from './create-request.svelte.js';
7+
8+
type Props = {
9+
meta: Meta;
10+
} & SveltekitRequestOptions<Meta['__actionData'], Meta['__formValue']> &
11+
Omit<
12+
SvelteKitFormOptions2<Meta['__formValue'], Meta['__validationError'], Meta['__sendSchema']>,
13+
'onSubmit'
14+
>;
15+
16+
const props: Props = $props();
17+
18+
const request = createSvelteKitRequest(props.meta, props);
19+
20+
const form = createSvelteKitForm(
21+
props.meta,
22+
// @ts-expect-error
23+
new Proxy(props, {
24+
has(target, p) {
25+
if (p === 'onSubmit') {
26+
return true;
27+
}
28+
return Reflect.has(target, p);
29+
},
30+
get(target, p, receiver) {
31+
if (p === 'onSubmit') {
32+
return request.run;
33+
}
34+
return Reflect.get(target, p, receiver);
35+
}
36+
})
37+
);
38+
</script>
39+
40+
<RawForm {form} method="POST" />

packages/sveltekit/src/lib/client/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export * from './create-request.svelte';
33
export * from './create-form.svelte';
44
export * from './use-mutation.svelte';
55
export * from './use-form.svelte';
6+
export { default as SvelteKitForm } from './form.svelte'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
<script lang="ts">
22
import Form1 from './form1.svelte';
33
import Form2 from './form2.svelte';
4+
import Form3 from './form3.svelte';
45
</script>
56

67
<Form1 />
78

89
<Form2 />
10+
11+
<Form3 />
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script lang="ts">
2+
import { SvelteKitForm, createMeta } from '$lib/client/index.js';
3+
import { theme } from '@sjsf/form/basic-theme';
4+
import { createValidator2 } from '@sjsf/ajv8-validator';
5+
import { translation } from '@sjsf/form/translations/en';
6+
7+
import type { ActionData, PageData } from './$types.js';
8+
9+
import { ERROR_TYPE_OBJECTS } from './model.js';
10+
11+
const meta = createMeta<ActionData, PageData, 'form'>('form');
12+
</script>
13+
14+
<SvelteKitForm
15+
{...theme}
16+
{meta}
17+
idPrefix="form3"
18+
validator={createValidator2()}
19+
{translation}
20+
onSubmitError={console.warn}
21+
onSuccess={console.log}
22+
onFailure={console.error}
23+
additionalPropertyKeyValidationError={({ type, values }) =>
24+
`The presence of these ${ERROR_TYPE_OBJECTS[type]} ("${values.join('", "')}") is prohibited`}
25+
uiSchema={{
26+
'ui:formElement': {
27+
'ui:options': {
28+
form: {
29+
action: "?/first",
30+
novalidate: true
31+
}
32+
}
33+
}
34+
}}
35+
/>

0 commit comments

Comments
 (0)