Skip to content

Commit 4facf25

Browse files
committed
chore: add tests and fix issues with usage
1 parent 39fd204 commit 4facf25

File tree

8 files changed

+114
-5
lines changed

8 files changed

+114
-5
lines changed

packages/svelte-form/src/AppField.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
form: any
88
fieldComponents: any
99
children: Snippet
10+
fieldProps: any
1011
}
11-
const { children, form, fieldComponents }: Props = $props()
12+
const { children, form, fieldComponents, fieldProps }: Props = $props()
1213
</script>
1314

14-
<form.Field name="fullName">
15+
<form.Field {...fieldProps}>
1516
{#snippet children(field: any)}
1617
<InnerAppField field={field} children={children} fieldComponents={fieldComponents}/>
1718
{/snippet}

packages/svelte-form/src/createFormRune.svelte.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ export function createFormRune<
241241
fieldComponents,
242242
formComponents,
243243
}: CreateFormRuneProps<TComponents, TFormComponents>) {
244-
function useAppForm<
244+
function createAppForm<
245245
TFormData,
246246
TOnMount extends undefined | FormValidateOrFn<TFormData>,
247247
TOnChange extends undefined | FormValidateOrFn<TFormData>,
@@ -291,7 +291,7 @@ export function createFormRune<
291291
return AppFormSvelte(internal, { ...props, form })
292292
}) as Component<{ children: Snippet }>
293293

294-
const AppField = ((internal, props) => AppFieldSvelte(internal, { ...props, form, fieldComponents } as never)) as FieldComponent<
294+
const AppField = ((internal, {children, ...fieldProps}) => AppFieldSvelte(internal, { fieldProps, form, fieldComponents, children } as never)) as FieldComponent<
295295
TFormData,
296296
TOnMount,
297297
TOnChange,
@@ -317,6 +317,6 @@ export function createFormRune<
317317
}
318318

319319
return {
320-
useAppForm,
320+
createAppForm,
321321
}
322322
}

packages/svelte-form/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ export { createForm, type SvelteFormApi } from './createForm.svelte.js'
77
export { default as Field, createField } from './Field.svelte'
88

99
export type { CreateField, FieldComponent } from './types.js'
10+
11+
export { createFormRune, createFormRuneContexts } from "./createFormRune.svelte.js"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { createFormRuneContexts } from "../../src/index.js";
2+
3+
export const { useFieldContext } = createFormRuneContexts()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { createFormRune } from "../../src/createFormRune.svelte.js";
2+
import TextField from "./text-field.svelte";
3+
4+
export const { createAppForm } = createFormRune({
5+
fieldComponents: {
6+
TextField,
7+
},
8+
formComponents: {},
9+
})
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script lang="ts">
2+
import { useFieldContext } from './context.js'
3+
4+
const field = useFieldContext<string>()
5+
6+
const { label }: { label: string } = $props()
7+
</script>
8+
9+
<label>
10+
<span>{label}</span>
11+
<input
12+
id={field.name}
13+
value={field.state.value}
14+
oninput={(e) => field.handleChange((e.target as any).value)}
15+
/>
16+
</label>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<svelte:options runes />
2+
3+
<script module lang="ts">
4+
interface Employee {
5+
firstName: string
6+
}
7+
8+
let sampleData: Employee = $state({
9+
firstName: 'Corbin',
10+
})
11+
12+
export const getSampleData = () => sampleData
13+
</script>
14+
15+
<script lang="ts">
16+
import { createAppForm } from './large-components/rune.js'
17+
18+
const form = createAppForm(() => ({
19+
defaultValues: sampleData,
20+
}))
21+
22+
const formState = form.useStore()
23+
</script>
24+
25+
<form
26+
id="form"
27+
onsubmit={(e) => {
28+
e.preventDefault()
29+
e.stopPropagation()
30+
form.handleSubmit()
31+
}}
32+
>
33+
<h1>TanStack Form - Svelte Demo</h1>
34+
35+
<form.AppField name="firstName">
36+
{#snippet children(field)}
37+
<field.TextField label="First name" />
38+
{/snippet}
39+
</form.AppField>
40+
</form>
41+
42+
<pre>{JSON.stringify(formState.current, null, 2)}</pre>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
2+
import { userEvent } from '@testing-library/user-event'
3+
import { mount, unmount } from 'svelte'
4+
import TestForm, { getSampleData } from './large.svelte'
5+
6+
describe('Svelte Tests', () => {
7+
let element: HTMLDivElement
8+
let instance: any
9+
beforeEach(async () => {
10+
element = document.createElement('div')
11+
document.body.appendChild(element)
12+
instance = mount(TestForm, {
13+
target: element,
14+
})
15+
})
16+
17+
afterEach(() => {
18+
unmount(instance)
19+
element.remove()
20+
})
21+
22+
it('should have initial values', async () => {
23+
expect(element.querySelector<HTMLInputElement>('#firstName')).toHaveValue(
24+
getSampleData().firstName,
25+
)
26+
})
27+
28+
it('should mirror user input', async () => {
29+
const firstName = element.querySelector<HTMLInputElement>('#firstName')!
30+
const firstNameValue = 'Jobs'
31+
await userEvent.type(firstName, firstNameValue)
32+
33+
const form = JSON.parse(element.querySelector('pre')!.textContent!)
34+
expect(form.values.firstName).toBe(getSampleData().firstName + firstNameValue)
35+
})
36+
})

0 commit comments

Comments
 (0)