Wizard form
SvForm as a multi-step wizard: titled FormSection groups become validated steps with Back / Next (gated on each step) and a final async Submit. Drop the stepper prop and the same schema renders as stacked fieldsets.
A live, editable Svelte 5 component example from the SvGrid gallery (Layout). Read the SvGrid UI component docs for the full API.
About this example
SvForm as a multi-step wizard in Svelte 5: group fields into titled FormSection entries and set stepper, and each section becomes a validated step with Back and Next, where Next is gated on that step's validation, and a Submit on the final step with an async finish. Drop the stepper prop and the same schema renders as stacked fieldsets.
SvForm as a multi-step WIZARD: group fields into titled FormSections and set stepper - each section becomes a validated step with Back / Next (Next is gated on that step's validation) and a Submit on the final step. Drop the stepper prop and the same schema renders as stacked fieldsets instead.
Imports, features and API used
Imports: @svgrid/grid
Frequently asked questions
How are steps defined?
Each FormSection has a title and its own fields; with stepper on, sections become steps in order and the stepper header shows progress.
Can the user skip ahead?
No. Next runs the current step's validation and only advances when it passes; Back always works and keeps the entered values.
Does the payload change between wizard and fieldset modes?
No. onSubmit receives the same flat object of all fields either way; stepper only changes presentation and when validation runs.
Related documentation
Related articles
- Avoiding Layout Thrash in Custom Grid Cells - Layout thrash from interleaved DOM reads and writes is the most common cause of scroll jank in grids with custom cells - here is how to find it and design your way out of it.
- Bundle Size of Svelte Data Grids - How to Compare - README bundle numbers are nearly useless. Here is how to measure the real delta a data grid adds to your Svelte app, and why feature-gated architectures change the math entirely.
- Saved Views - Persist Grid Layout and Filters - Give users named, switchable snapshots of column order, sorting, filters, and grouping - persisted to localStorage or a server adapter - using SvGrid's createNamedViews API.
Source code (324-form-wizard.svelte)
<script lang="ts">
/**
* SvForm as a multi-step WIZARD: group fields into titled `FormSection`s and set
* `stepper` - each section becomes a validated step with Back / Next (Next is
* gated on that step's validation) and a Submit on the final step. Drop the
* `stepper` prop and the same schema renders as stacked fieldsets instead.
*/
import { SvForm, rules } from '@svgrid/grid'
import type { FormEntry } from '@svgrid/grid'
const schema: FormEntry[] = [
{ section: 'Account', description: 'How you sign in.', fields: [
{ name: 'email', label: 'Work email', type: 'email', required: true, full: true, rules: [rules.email()] },
{ name: 'password', label: 'Password', type: 'password', required: true,
rules: [rules.minLength(8), rules.pattern(/\d/, { message: 'Include a number' })] },
{ name: 'confirm', label: 'Confirm', type: 'password', required: true,
rules: [rules.compare('password', '===', { message: 'Passwords do not match' })] },
] },
{ section: 'Profile', description: 'Tell us about you.', columns: 2, fields: [
{ name: 'firstName', label: 'First name', required: true },
{ name: 'lastName', label: 'Last name', required: true },
{ name: 'role', label: 'Role', type: 'select', required: true, full: true, options: [
{ value: 'dev', label: 'Developer' }, { value: 'design', label: 'Designer' }, { value: 'pm', label: 'Product manager' },
] },
{ name: 'bio', label: 'Short bio', type: 'textarea', full: true },
] },
{ section: 'Preferences', fields: [
{ name: 'newsletter', label: 'Send me product updates', type: 'switch' },
{ name: 'experience', label: 'Rate your Svelte experience', type: 'rating', full: true },
] },
]
let result = $state<string>('')
async function finish(values: Record<string, unknown>) {
await new Promise((r) => setTimeout(r, 800))
result = JSON.stringify(values, null, 2)
}
</script>
<div class="wrap">
<header>
<h2>Wizard form</h2>
<p>
Sections become validated steps. Next only advances when the current step is
valid; the last step submits (async, with a loading button). The same schema
without <code>stepper</code> renders as stacked sections.
</p>
</header>
<div class="card">
<SvForm
fields={schema}
stepper
columns={2}
submitLabel="Create account"
initial={{ role: 'dev', experience: 3 }}
onSubmit={finish}
/>
</div>
{#if result}
<pre class="result">{result}</pre>
{/if}
</div>
<style>
.wrap { padding: 20px; max-width: 640px; display: flex; flex-direction: column; gap: 16px; }
header h2 { margin: 0 0 4px; font-size: 20px; font-weight: 700; }
header p { margin: 0; color: var(--sg-muted, #64748b); font-size: 13.5px; line-height: 1.5; }
.card { padding: 20px; border: 1px solid var(--sg-border, #e2e8f0); border-radius: 12px; }
.result { margin: 0; padding: 14px; background: var(--sg-header-bg, #f8fafc); border: 1px solid var(--sg-border, #e2e8f0); border-radius: 10px; font-size: 12px; overflow: auto; }
</style>More Layout examples
- Account & security settings console - A real SaaS settings surface composed from the UI kit: SvMenubar app bar, promise + Undo-action toasts on save, SvPopconfirm on destructive rows, SvHoverCard teammate previews, and frame input adornments (leading icons, prefix affixes, masked API key). Profile / Team / Security tabs over SvCard + SvStat.
- Invoice builder - An adornment-heavy money form: currency prefixes, % suffixes, masked tax IDs (frame adornments), line items with SvPopconfirm delete + Undo action toasts, live SvStat totals, an SvHoverCard tax hint, and a promise toast on Send. Pure UI-kit composition.
- Operations KPI dashboard - A KPI console: SvStat + SvSparkline tiles, an SvGauge SLA dial, SvHoverCard drill-down previews per service, an SvMenubar toolbar (View / Range / Actions) and a promise toast on Refresh. Pure UI-kit composition, no grid dependency.
- Form: rich field types - SvForm reaching the whole input suite from one schema - phone, country, mask, combobox, radio, slider, tags, datetime and file - plus per-field help text, a readonly field, column span, and a promise toast on submit.
- Form: cascading fields - SvForm dependent selects - a child list derives from the parent value via a function `options`, and `dependsOn` clears the child when the parent changes so a stale selection never lingers. Country -> State -> City.