@nerd-coder/svelte-zod-form
v1.6.1
Published
Building forms with breeze, using Svelte + Zod
Downloads
261
Readme
🌵 Svelte Zod Form
Building forms in Svelte with breeze, using Zod
Example
Installation
npm i @nerd-coder/svelte-zod-form
JSR (Recommended)
npx jsr add @nerd-coder/svelte-zod-form
How to use
First you need to create a Zod's schema
import { z } from 'zod'
const loginSchema = z.object({
email: z.string().email(),
pass: z.string().min(4),
})
Then pass the schema to ZodFormStore
:
const form = new ZodFormStore(loginSchema, { onSubmit: v => console.log('Submitted values:', v) })
All the field's handler, value will be generated and typed for you:
// We need pull the generated field store out, in order
// to use the Svelte's "auto subscription" feature "$"
const { email_value, email_error, email_dirty, pass_value, pass_error, pass_dirty } = form.stores
Finally, use it in html
<form on:submit|preventDefault={form.triggerSubmit}>
<fieldset>
<input
name="email"
on:input={form.fields.email.handleChange}
on:blur={form.fields.email.handleBlur}
value={$email_value || ''}
class:invalid={!!$email_error}
class:valid={!$email_error && !!$email_dirty}
/>
{#if $email_error}<p>{$email_error}</p>{/if}
</fieldset>
<fieldset>
<input
name="pass"
type="password"
on:input={form.fields.pass.handleChange}
on:blur={form.fields.pass.handleBlur}
value={$pass_value || ''}
class:invalid={!!$pass_error}
class:valid={!$pass_error && !!$pass_dirty}
/>
{#if $pass_error}<p>{$pass_error}</p>{/if}
</fieldset>
<button type="submit">Sign In</button>
</form>
Configuration
initialValue
- type:
Partial<T>
- required:
false
- default:
undefined
The initial data in the form. Will revert to this value if call form.reset
.
const form = new ZodFormStore(schema, {
initialValue: { email: '[email protected]' },
...
})
onSubmit
- type:
(v: T) => Promise<void | string> | string | void
- required:
true
Async callback to handle submmition of the form. Should return nothing, or an string
contain error message
const form = new ZodFormStore(schema, {
onSubmit: (values) => console.log('Submitted values:', values),
...
})
debug
- type:
boolean
- required:
false
- default:
false
Print various debug messages.
const form = new ZodFormStore(schema, {
debug: true,
...
})
API
| Prop | Type | Description |
| --------------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| model | Readable<T>
| Form's data. Will be passed to onSubmit handler |
| options | readonly ZodFormStoreOptions<T>
| Form settings. Should not be update |
| triggerSubmit | () => Promise<void>
| Function to start parsing, validating and submit the form's data |
| setupAutoSubmit | (delay: number) => Unsubscriber
| Setup auto submit on every change of the model |
| reset | () => void
| Function to reset the form to original state. |
| submitting | Readable<boolean>
| True of submitting the form. |
| error | Readable<string>
| Error message returned from onSubmit
handler, or custom validation message. |
| errors | Readable<string[]>
| Array of string contains all error messages (including fields's errors and error return from onSubmit
handler). |
| dirty | Readable<boolean>
| Indicate if the form is edited or submitted. |
| valid | Readable<boolean>
| Indicate if the form is valid. |
| fields | object
| Generated fields's functions. |
| stores | object
| Generated fields's stores. |
Generated stores's props
| Prop | Type | Description |
| ----------------------------- | -------------------------- | ------------------------------------------ |
| stores.fieldName
_value | Readable<T['fieldName']>
| Readable store holding field's value |
| stores.fieldName
_touched | Readable<boolean>
| The field have been touched or not |
| stores.fieldName
_dirty | Readable<boolean>
| The field value been changed or not |
| stores.fieldName
_error | Readable<string>
| The field validation error message, if any |
| stores.fieldName
_valid | Readable<boolean>
| The field value is valid or not |
Generated field's functions
| Prop | Type | Description |
| --------------------------------- | -------------------------------------------- | --------------------------------- |
| fields.fieldName
.updateValue | (updater: Updater<T['fieldName']>) => void
| Function to update field's value |
| stores.fieldName
.setValue | (val: T['fieldName']) => void
| Function to set field's value |
| stores.fieldName
.handleChange | (val: unknown) => void
| Callback to update field's value |
| stores.fieldName
.handleBlur | () => void
| Callback to mark field as touched |
| stores.fieldName
.reset | () => void
| Reset field to original state |
| stores.fieldName
.setError | (msg: string) => void
| Manually set field error |
| stores.fieldName
.setTouched | (val: boolean) => void
| Manually set touched state |
Features
- Use Svelte native stores
- Fast: only update what changed, and you only subscribe to what you need
- Validation using Zod (Peer dependencies)
- TypeScript
- Minimal
Extra
Why the cactus 🌵?
> For its resilience
TODO
- More tests
- Support nested object
- Support array
Contributions
Any contributions are highly appreciate, please make a pull-request. If you would like to discuses a new feature, please create an issue first.