Button
Starts an action. Four variants, three sizes, icons and a busy state.
Example
<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
| 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.
| 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' |