Skip to content
This repository was archived by the owner on Nov 4, 2025. It is now read-only.
/ niceform Public archive

Convenient form validation and typing for SvelteKit

Notifications You must be signed in to change notification settings

probablykasper/niceform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 

Repository files navigation

niceform

Convenient form validation and typing for SvelteKit. Based on Superforms and Zod.

Might turn this into an actual package later

Features

  • name attribute typing
  • Multiple forms
  • i18n
  • Snapshots

Example +page.server.ts

import { z } from 'zod'
import { nice_form } from '$lib/niceform'

const schema = z.object({
	name: z.string(),
})

export const actions = {
	async default(event) {
		const form = await nice_form.zod(schema, event)
		if (!form.valid) {
			return form.fail(400)
		}
		if (form.data.name === 'Hi') {
			return form.set_error('name', 'You are a failure')
		}

		return {
			success: true,
		}
	},
}

Example Input wrapper component

Includes type-safe name attribute, automatic error messages and label with automatic ID

image
<script lang="ts" generics="F extends PartialNiceForm">
	import { sequential_num, type AddFormProps, type PartialNiceForm } from './niceform'
	import type { HTMLInputAttributes } from 'svelte/elements'

	let {
		form,
		label,
		value = $bindable(),
		...props
	}: AddFormProps<HTMLInputAttributes, F> = $props()

	let errors = $derived(form?.errors ?? {})

	const id = 'input-' + sequential_num()
</script>

<div>
	{#if label}
		<label class="text-label mb-0.5 block text-sm" for={props.id ?? id}>{label}</label>
	{/if}
	<input id={label ? id : undefined} bind:value {...props} class={['input', props['class']]} />
	{#if props.name && errors[props.name]}
		<span class="text-red-500">{errors[props.name]}</span>
	{/if}
</div>

i18n example

import { z } from 'zod'
import * as m from '$lib/paraglide/messages'
import { set_error_map } from './niceform'

export const form_errors = set_error_map({
	invalid_email: m.invalid_email,
})

export const email_schema = z.string().email(form_errors.invalid_email).max(100)

Snapshots

Might change this API

<script lang="ts">
import { enhance } from '$app/forms'
import { auto_snapshot } from '$lib/niceform'

const snapshotter = auto_snapshot()
export const snapshot = auto_snapshot()
</script>

<form method="post" use:enhance use:snapshotter.container>
	<Input {form} type="text" data-snapshot />
</form>

About

Convenient form validation and typing for SvelteKit

Resources

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published