SvToggleButton

A button with a sticky pressed on/off state, exposed to assistive tech via aria-pressed.

SvToggleButton looks like a button but remembers whether it is on. Use it for binary controls where the label stays constant - bold/italic in a formatting toolbar, a pin, a mute, a "live" toggle. It is controlled: drive pressed from your state and flip it in onChange. It carries the shared editor contract (label, hint, validation, dir/RTL) through SvField.

Related: SvSwitchButton · SvButtonGroup · Buttons & toggles overview

Installation

Add it with the CLI - this drops a ready-to-edit SvToggleButton starter into your app:

Prefer to see it first? npx @svgrid/ui try toggle-button opens it in a throwaway sandbox - no project needed.

Or install the package and import it directly. SvToggleButton ships free in @svgrid/grid and is part of the grid's editor kit - the same control SvGrid mounts when you edit a matching cell:

The examples on this page run against these rows:

<script lang="ts">
  import { SvGrid } from '@svgrid/grid'

  type Person = {
    id: number
    name: string
    email: string
    department: string
    age: number
    salary: number
    city: string
    startDate: string
    active: boolean
  }

  const people: Person[] = [
    { id: 1, name: 'Ada Lovelace',   email: '[email protected]',   department: 'Engineering', age: 36, salary: 142000, city: 'London',   startDate: '2021-03-01', active: true },
    { id: 2, name: 'Grace Hopper',   email: '[email protected]', department: 'Engineering', age: 45, salary: 168000, city: 'New York', startDate: '2019-07-15', active: true },
    { id: 3, name: 'Linus Torvalds', email: '[email protected]', department: 'Platform',    age: 54, salary: 155000, city: 'Portland', startDate: '2020-01-20', active: false },
    { id: 4, name: 'Radia Perlman',  email: '[email protected]', department: 'Networking',  age: 49, salary: 161000, city: 'Seattle',  startDate: '2022-09-05', active: true },
    { id: 5, name: 'Barbara Liskov', email: '[email protected]', department: 'Platform',  age: 52, salary: 172000, city: 'Boston',   startDate: '2018-11-11', active: true },
  ]

  let rows = $state<Person[]>(people)
</script>
import { SvToggleButton } from '@svgrid/grid'

Example

Open the live example: Toggle button (Buttons & Toggles)

<script lang="ts">
  import { SvToggleButton } from '@svgrid/grid'
  let bold = $state(false)
</script>

<SvToggleButton pressed={bold} onChange={(v) => (bold = v)}>Bold</SvToggleButton>

Props

Prop Type Default Description
pressed boolean false Current on/off state (controlled).
onChange (pressed: boolean) => void - Fires with the next state when toggled.
disabled boolean false Blocks toggling and dims the control.
size sm | md | lg md Padding and font size, shared with the rest of the kit.
label string - Visible field label, rendered above the button.
hint string - Helper text under the button.
error string - Error message announced via aria-describedby.
required boolean false Adds aria-required.
invalid boolean false Marks the control invalid (danger border).
dir ltr | rtl | auto auto Text direction.
ariaLabel string - Accessible name for an icon-only toggle.
id string auto Root id; label/hint/error ids derive from it.
children Snippet - The button label.

Examples

Formatting toolbar

A row of toggles, each bound to its own state, reads as an inline formatting bar:

<SvToggleButton pressed={bold} onChange={(v) => (bold = v)}>B</SvToggleButton>
<SvToggleButton pressed={italic} onChange={(v) => (italic = v)}>I</SvToggleButton>

Icon toggle with a label

Give an icon-only toggle an ariaLabel so the on/off state is announced with a name:

<SvToggleButton ariaLabel="Pin row" pressed={pinned} onChange={(v) => (pinned = v)}>📌</SvToggleButton>

Reflecting external state

Because it is controlled, the pressed look always mirrors your state - toggle it from anywhere and the button follows:

<SvToggleButton pressed={isLive} onChange={(v) => setLive(v)}>Live</SvToggleButton>

Toolbar filter toggle

A toggle whose pressed state drives a $derived list makes a compact "show only" filter - the button stays lit while the filter is active:

<script lang="ts">
  import { SvToggleButton } from '@svgrid/grid'
  let favoritesOnly = $state(false)
  const shown = $derived(favoritesOnly ? rows.filter((r) => r.starred) : rows)
</script>

<SvToggleButton pressed={favoritesOnly} onChange={(v) => (favoritesOnly = v)}>
  ★ Favorites only
</SvToggleButton>

Accessibility

More examples

Toggle button - headless

Styled SvToggleButton plus a custom on/off pill, one bound pressed value with a readout.

Open the live example: Toggle button - headless (Headless Editors)

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.

Open the live example: Buttons & toggles (Buttons & Toggles)

See also

Live examples

  • Toggle button - SvToggleButton: a pressed on/off button (aria-pressed) - a text-formatting toolbar and pin / live state toggles.
  • Toggle button - headless - Styled SvToggleButton plus a custom on/off pill, one bound pressed value with a readout.
  • 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.