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.
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 reaching the whole input suite from one schema in Svelte 5: phone, country, mask, combobox, radio, slider, tags, datetime and file fields, plus per-field help text, a readonly field, a column span across the two-column layout, an error summary and a promise toast on submit. The fields array is the whole form.
SvForm rich field types - a schema-driven form that now reaches the whole input suite: phone, country, mask, combobox, radio, slider, tags, datetime and file, plus per-field help text, a readonly field and column span.
Imports, features and API used
Imports: @svgrid/grid
Frequently asked questions
How do I add a field?
Push an object to fields with a name, a type such as phone or tags, a label and any validation. SvForm renders the matching kit component and includes the value in onSubmit.
How do I make a field span both columns?
Set span: 2 on the field. With columns={2} it takes the full row, which the demo uses for the file field.
What does errorSummary do?
On a failed submit it lists every error above the form with links that focus the field, in addition to the inline messages.
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.
- Column Definitions in SvGrid - Fields, Accessors, and Formatting - A practical look at how ColumnDef controls field binding, value resolution, sort behavior, and custom cell rendering in SvGrid.
- Stable Row Identity in SvGrid (and why it matters) - How SvGrid tracks rows across mutations, why object reference stability is the key to correct selection and editing, and the exact patterns to use with live data feeds.
Source code (404-form-rich-fields.svelte)
<script lang="ts">
/**
* SvForm rich field types - a schema-driven form that now reaches the whole
* input suite: phone, country, mask, combobox, radio, slider, tags, datetime
* and file, plus per-field `help` text, a `readonly` field and column `span`.
*/
import { SvForm, SvToaster, toast, type FormField } from '@svgrid/grid'
const roles = [
{ value: 'admin', label: 'Administrator' },
{ value: 'editor', label: 'Editor' },
{ value: 'viewer', label: 'Viewer' },
]
const plans = [
{ value: 'free', label: 'Free' },
{ value: 'pro', label: 'Pro' },
{ value: 'business', label: 'Business' },
{ value: 'enterprise', label: 'Enterprise' },
]
const fields: FormField[] = [
{ name: 'name', label: 'Full name', required: true, span: 2 },
{ name: 'accountId', label: 'Account ID', type: 'text', readonly: true, help: 'Assigned automatically - cannot be changed.' },
{ name: 'phone', label: 'Phone', type: 'phone' },
{ name: 'country', label: 'Country', type: 'country' },
{ name: 'ssn', label: 'Tax ID', type: 'mask', mask: '###-##-####', placeholder: '000-00-0000', help: 'US format; the raw digits are stored.' },
{ name: 'role', label: 'Role', type: 'radio', options: roles, required: true },
{ name: 'plan', label: 'Plan', type: 'combobox', options: plans, placeholder: 'Choose a plan', required: true },
{ name: 'seats', label: 'Seats', type: 'slider', min: 1, max: 100, step: 1, help: 'Drag to set the seat count.' },
{ name: 'tags', label: 'Tags', type: 'tags', placeholder: 'Add a tag', span: 2 },
{ name: 'starts', label: 'Start date', type: 'datetime', span: 2 },
{ name: 'avatar', label: 'Avatar', type: 'file', accept: 'image/*', span: 2 },
{ name: 'notes', label: 'Notes', type: 'textarea', span: 2 },
]
const initial = { accountId: 'ACC-4821', seats: 10, role: 'editor' }
// Awaited (not returned) so the handler stays `Promise<void>` - SvForm keeps the
// Submit button in its loading state until the toast promise settles.
async function onSubmit(values: Record<string, unknown>) {
await toast.promise(new Promise((res) => setTimeout(res, 900)), {
loading: 'Creating account...', success: `Account created for ${values.name}`, error: 'Failed',
})
}
</script>
<div class="wrap">
<h2>New account</h2>
<p class="muted">Rich field types on a single SvForm schema.</p>
<SvForm {fields} {initial} columns={2} submitLabel="Create account" errorSummary {onSubmit} />
</div>
<SvToaster position="bottom-right" />
<style>
.wrap { padding: 22px; max-width: 640px; }
h2 { margin: 0; font-size: 19px; font-weight: 700; }
.muted { margin: 3px 0 16px; color: var(--sg-muted, #64748b); font-size: 13px; }
</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: 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.
- Layout & feedback primitives - The structural + status kit: SvStack / SvGroup / SvSimpleGrid layout primitives, SvCollapsible show/hide sections, SvSpinner + SvLoadingOverlay for async states, and SvResult for a full outcome page. All themed from the --sg-* tokens.