Skip to content
UI
v0.3.1

Search the docs

Button

Starts an action. Four variants, three sizes, icons and a busy state.

Example

button.example.svelte
<script lang="ts">
  import { Button, IconButton } from '@onlywin/ui-svelte';

  let saved = $state(false);
</script>

<div class="example-row">
  <Button variant="primary" iconStart="play">Play demo</Button>
  <Button>Secondary</Button>
  <Button variant="ghost">Ghost</Button>
  <Button variant="danger" iconStart="ban">Close round</Button>
  <Button loading={saved} onclick={() => (saved = !saved)}>Save</Button>
  <IconButton icon="settings" label="Settings" />
</div>

Usage

Do

  • One primary button per view: the main thing to do next.
  • Name the action with a verb: Save, Close round, Play demo.

Don’t

  • Do not use a button to go to another page; pass href and get a link.
  • Do not disable a button without saying why nearby.

Accessibility

  • A native <button>, or a native <a> with href: focusable, with the platform behaviour of each.
  • While loading the button is disabled and aria-busy, and the spinner is hidden from screen readers.
  • Icons are decorative; the text names the action.

Keyboard

Button keyboard interactions
Keys Action
Enter, Space Activate
Tab, Shift+Tab Move focus in and out

Props

The same props in both frameworks. In React, class is className, events are camelCase (onClick), content passed as Svelte snippets is a ReactNode prop, every bindable value has a default… twin for uncontrolled use, and elementRef reaches the DOM element.

Button props
Prop Type Default Description
block boolean false
children Snippet —
class string —
href string — Renders a link that looks like a button.
iconEnd TUiIconName —
iconStart TUiIconName —
loading boolean false
size 'lg' | 'md' | 'sm' 'md'
type 'button' | 'reset' | 'submit' 'button'
variant 'danger' | 'ghost' | 'primary' | 'secondary' 'secondary'