Button

Primary action. Variants, tones and sizes.

Usage

Import the component and use it. No setup, no config — it ships fully styled.

Variants

Four visual treatments via the variant prop.

Colors

Semantic tones, all driven by --sve-* tokens.

Sizes

Three sizes from the size prop.

States

Disabled is fully styled and non-interactive. Icons compose inline.

Loading

loading shows a spinner and sets aria-busy while an action is in flight. Activation is blocked, so a double submit is not possible.

It stays focusable. disabled is the obvious choice and the wrong one: a disabled element loses focus, so a keyboard user who just pressed Enter is dropped back to the top of the document with no idea anything happened.

The children stay on screen, so the button keeps its width and nothing around it shifts. The spinner is aria-hiddenaria-busy already carries the state — and a visually hidden loadingLabel is what gets announced. Say what is happening: "Saving your changes" beats "Loading". It respects prefers-reduced-motion.

Props

PropTypeDefault
variant 'solid' | 'outline' | 'ghost' | 'flat''solid'
color 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'default''default'
size 'sm' | 'md' | 'lg''md'
href Render an anchor instead of a button. Pass this whenever activating the control takes the user somewhere. A `<button>` that navigates in its `onclick` cannot be opened in a new tab or middle-clicked, shows no URL on hover, is announced as a button rather than a link, and does nothing at all until JavaScript has run.string
target Anchor target. Only meaningful with `href`.HTMLAnchorAttributes['target']
rel Anchor rel. Set automatically for `target="_blank"` unless you pass it.string
loading Shows a spinner and marks the button busy while an action is in flight. It stays FOCUSABLE on purpose. `disabled` would be the obvious choice and it is the wrong one: a disabled element loses focus, so a keyboard user who just pressed Enter is dropped back to the top of the document with no idea anything happened. Activation is blocked instead, and `aria-busy` tells assistive technology the control is working. Only meaningful on a button; a link navigates rather than performing work.booleanfalse
loadingLabel Announced while `loading`. Say what is happening, not that something is.string'Loading'
class string
children Snippet
disabled html boolean | null | undefined
onclick html MouseEventHandler<HTMLButtonElement> | null | undefined

Plus every native <button> attribute via prop spreading.