SvButton
The press primitive for the whole UI kit - a themeable button with variants,
sizes, a built-in loading state, an icon slot, and automatic anchor rendering
when you pass an href.
SvButton is the button every other component leans on. It carries no opinion
about your color scheme: every color comes from the grid's --sg-* tokens, so
it matches your grid, edit forms, and the rest of the kit out of the box, in
light and dark. It renders a real <button> (or an <a> when given href),
so keyboard focus, Enter / Space activation, and screen-reader semantics are
the platform's, not a re-implementation.
Related: SvButtonGroup · SvToggleButton · SvSwitchButton · SvRepeatButton · Buttons & toggles overview
Installation
Add it with the CLI - this drops a ready-to-edit SvButton starter into your app:
Prefer to see it first? npx @svgrid/ui try button opens it in a throwaway sandbox - no project needed.
Or install the package and import it directly. SvButton ships free in
@svgrid/grid (dependency-free):
import { SvButton } from '@svgrid/grid'
Example
Open the live example: Button (Buttons & Toggles)
<script lang="ts">
import { SvButton } from '@svgrid/grid'
let saving = $state(false)
</script>
<SvButton variant="primary" onclick={save}>Save</SvButton>
<SvButton variant="outline">Cancel</SvButton>
<SvButton variant="danger" loading={saving}>Delete</SvButton>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant |
primary | secondary | outline | ghost | danger |
primary |
Visual weight. danger uses the destructive accent. |
size |
sm | md | lg |
md |
Padding and font size. Shared with the rest of the kit. |
type |
button | submit | reset |
button |
Native button type. Use submit inside an SvForm. |
disabled |
boolean |
false |
Blocks clicks and dims the control. |
loading |
boolean |
false |
Shows a spinner and disables interaction. Keeps the label width. |
block |
boolean |
false |
Stretches to the full width of the container. |
href |
string |
- | When set, renders an <a> styled as a button (a real link). |
ariaLabel |
string |
- | Accessible name for icon-only buttons with no text child. |
onclick |
(e: MouseEvent) => void |
- | Click handler. Suppressed while disabled or loading. |
icon |
Snippet |
- | Leading icon slot, rendered before the label. |
children |
Snippet |
- | The button label. |
Examples
Icon buttons
Pass an icon snippet for a leading glyph, or make an icon-only button by
omitting the label and giving it an ariaLabel so it still announces:
<SvButton ariaLabel="Add row" onclick={addRow}>
{#snippet icon()}<PlusIcon />{/snippet}
</SvButton>
Async actions
Drive loading from your async handler so the button disables itself for the
duration and can't be double-submitted:
<script lang="ts">
let saving = $state(false)
async function save() {
saving = true
try { await api.save() } finally { saving = false }
}
</script>
<SvButton variant="primary" loading={saving} onclick={save}>Save</SvButton>
Links that look like buttons
Give href and SvButton renders an anchor - correct for navigation, so
middle-click and "open in new tab" work:
<SvButton variant="outline" href="/reports/export.csv">Download CSV</SvButton>
Full-width form submit
Set type="submit" so the button submits its enclosing form, and block to
stretch it across a narrow column. Combine with loading while the request is
in flight:
<form onsubmit={handleSubmit}>
<!-- fields... -->
<SvButton type="submit" variant="primary" block loading={saving}>
Create account
</SvButton>
</form>
Theming tip: the fill comes entirely from tokens - primary and outline
read --sg-accent (with --sg-on-accent for text), and danger reads
--sg-danger. Set those on any ancestor to rebrand every button without
touching the component.
Accessibility
- Renders a native
<button>(or<a>withhref), so focus,Taborder, andEnter/Spaceactivation are the browser's own. disabledandloadingset the disabled state; clicks are suppressed even if a handler fires.- Icon-only buttons must set
ariaLabel- there is no visible text to announce.
See also
- SvButtonGroup - a segmented set of buttons with one selected value.
- SvToggleButton / SvSwitchButton - on/off controls.
- SvRepeatButton - fires repeatedly while held.
- Buttons & toggles overview - the whole family at a glance.
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.