Buttons & toggles
The UI kit press/toggle primitives: SvButton (variants/sizes/loading), SvRepeatButton (hold-to-repeat), SvToggleButton, SvSwitchButton, SvCheckBox (+ indeterminate), SvRadioGroup (arrow-key nav) and SvRating (half stars). Theme-driven, standalone or as grid cell controls.
A live, editable Svelte 5 component example from the SvGrid gallery (Buttons & Toggles). Read the SvGrid UI component docs for the full API.
About this example
The press and toggle primitives of the SvGrid UI kit in Svelte 5: SvButton with variants, sizes and a loading state, SvRepeatButton that fires while held, SvToggleButton with a pressed state, SvSwitchButton, SvCheckBox with an indeterminate state, SvRadioGroup with arrow-key navigation and SvRating with half stars. Every one is themed from the --sg-* tokens and works standalone or as a grid cell control.
Buttons & Toggles - the SvGrid UI kit's press/toggle primitives. Every one is theme-driven (--sg-*) and works standalone or as a grid cell control.
Imports, features and API used
Imports: @svgrid/grid
Frequently asked questions
Do these controls share a theme with the grid?
Yes. They read the same --sg-* custom properties, so a theme preset applied to the page styles buttons, switches and the grid together.
How does SvRepeatButton differ from SvButton?
It fires onclick repeatedly while the pointer is held down, with acceleration, which suits steppers and scroll controls; SvButton fires once per click.
How do I set an indeterminate checkbox?
Pass indeterminate along with checked. The box shows the dash state and reports the next click as checked, which is the select-all parent pattern.
Related documentation
Related articles
- SvGrid UI Components Tips and Tricks: Svelte 5 Buttons, Inputs, Tree, Forms - Practical tips for the SvGrid UI component kit - SvButton states, a Cmd+K command palette, a virtualized searchable tree, schema-driven forms, a parsing date/time field, and the shared field contract - each with a code snippet.
- An Actions Column (Edit, Delete) in SvGrid - Build a per-row actions column with edit, delete, and duplicate buttons in SvGrid - handling data mutations, accessibility, and confirmation flows correctly.
Source code (253-buttons-toggles.svelte)
<script lang="ts">
/**
* Buttons & Toggles - the SvGrid UI kit's press/toggle primitives. Every one
* is theme-driven (--sg-*) and works standalone or as a grid cell control.
*/
import {
SvButton, SvRepeatButton, SvToggleButton, SvSwitchButton,
SvCheckBox, SvRadioGroup, SvRating,
} from '@svgrid/grid'
let count = $state(0)
let bold = $state(false)
let italic = $state(false)
let notify = $state(true)
let agree = $state(false)
let some = $state(true)
let plan = $state<string>('pro')
let stars = $state(3)
const plans = [
{ value: 'free', label: 'Free' },
{ value: 'pro', label: 'Pro' },
{ value: 'ent', label: 'Enterprise', disabled: true },
]
</script>
<div class="wrap">
<header>
<h2>Buttons & Toggles</h2>
<p>Press and toggle primitives from <code>@svgrid/grid</code>. Theme-driven, keyboard-accessible, standalone or in-grid.</p>
</header>
<section>
<h3>SvButton</h3>
<div class="row">
<SvButton>Primary</SvButton>
<SvButton variant="secondary">Secondary</SvButton>
<SvButton variant="outline">Outline</SvButton>
<SvButton variant="ghost">Ghost</SvButton>
<SvButton variant="danger">Danger</SvButton>
<SvButton loading>Loading</SvButton>
<SvButton disabled>Disabled</SvButton>
</div>
<div class="row">
<SvButton size="sm">Small</SvButton>
<SvButton size="md">Medium</SvButton>
<SvButton size="lg">Large</SvButton>
</div>
</section>
<section>
<h3>SvRepeatButton <span class="muted">(hold to repeat)</span></h3>
<div class="row center">
<SvRepeatButton onclick={() => (count -= 1)} ariaLabel="Decrease">−</SvRepeatButton>
<strong class="count">{count}</strong>
<SvRepeatButton onclick={() => (count += 1)} ariaLabel="Increase">+</SvRepeatButton>
</div>
</section>
<section>
<h3>SvToggleButton & SvSwitchButton</h3>
<div class="row center">
<SvToggleButton pressed={bold} onChange={(v) => (bold = v)} ariaLabel="Bold"><strong>B</strong></SvToggleButton>
<SvToggleButton pressed={italic} onChange={(v) => (italic = v)} ariaLabel="Italic"><em>I</em></SvToggleButton>
<span class="sep"></span>
<SvSwitchButton checked={notify} onChange={(v) => (notify = v)} ariaLabel="Notifications" />
<span class="muted">Notifications {notify ? 'on' : 'off'}</span>
</div>
</section>
<section>
<h3>SvCheckBox</h3>
<div class="row col">
<SvCheckBox checked={agree} onChange={(v) => (agree = v)}>I agree to the terms</SvCheckBox>
<SvCheckBox indeterminate={some} checked={some} onChange={() => (some = !some)}>Partially selected (indeterminate)</SvCheckBox>
<SvCheckBox checked disabled>Disabled, checked</SvCheckBox>
</div>
</section>
<section>
<h3>SvRadioGroup <span class="muted">(arrow keys navigate)</span></h3>
<SvRadioGroup options={plans} value={plan} onChange={(v) => (plan = String(v))} orientation="horizontal" ariaLabel="Plan" />
<p class="muted">Selected: <strong>{plan}</strong></p>
</section>
<section>
<h3>SvRating</h3>
<div class="row center">
<SvRating value={stars} onChange={(v) => (stars = v)} />
<span class="muted">{stars} / 5</span>
<span class="sep"></span>
<SvRating value={4.5} allowHalf readOnly size="sm" />
<span class="muted">read-only, half</span>
</div>
</section>
</div>
<style>
.wrap { padding: 22px; max-width: 820px; display: flex; flex-direction: column; gap: 22px; }
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; }
code { background: var(--sg-row-hover-bg, #eef2ff); padding: 1px 5px; border-radius: 5px; font-size: 12px; }
section h3 { margin: 0 0 10px; font-size: 14px; font-weight: 650; }
.row { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 8px; }
.row.center { align-items: center; }
.row.col { flex-direction: column; align-items: flex-start; gap: 8px; }
.muted { color: var(--sg-muted, #64748b); font-size: 12.5px; }
.count { font-size: 20px; min-width: 40px; text-align: center; font-variant-numeric: tabular-nums; }
.sep { width: 1px; height: 22px; background: var(--sg-border, #e2e8f0); margin: 0 6px; }
</style>More Buttons & Toggles examples
- Button group - SvButtonGroup: a segmented button bar - single-select (radio semantics, a view switcher), multi-select (a toggle set / formatting toolbar) or plain actions. Roving tabindex + arrow keys, and the shared editor contract (label, validation, dir/RTL).
- Button - SvButton in production: a toolbar (variants primary/secondary/outline/ghost/danger), sizes, icon slots, a loading state and a full-width CTA. Copy-paste-ready blocks.
- Repeat button - SvRepeatButton: hold-to-repeat with acceleration - a quantity stepper and a volume control block.
- Toggle button - SvToggleButton: a pressed on/off button (aria-pressed) - a text-formatting toolbar and pin / live state toggles.
- Switch - SvSwitchButton in a real settings panel: labelled rows with descriptions, on/off track labels and a disabled row.