A versatile button component.
A Button component has the following properties:
| Prop | Required | Description |
|---|---|---|
type | no | Default type: button. |
href | no | Render button as anchor when present. |
variant | no | filled (default) or outlined. |
onclick | no | Optional click handler. |
class | no | Additional classes. |
| Name | Required | Description |
|---|---|---|
children | no | Omit for an icon-only button. |
icon | no | Snippet to add an icon. |
This is the default button:
<script lang="ts">
import { Button } from '$lib/components/index.js';
let isSpinning = $state(false);
function handleClick() {
isSpinning = true;
setTimeout(() => {
isSpinning = false;
}, 600);
}
</script>
<Button onclick={handleClick} class={isSpinning ? 'spin' : ''}>Click me!</Button>
<style>
:global(.spin) {
animation: spin 0.6s ease-in-out;
}
@keyframes spin {
to {
transform: rotateZ(360deg);
}
}
</style>
This is a disabled default button:
<script lang="ts">
import { Button } from '$lib/components/index.js';
</script>
<Button onclick={() => alert('Button clicked!')} disabled>I am disabled</Button>
This is an outlined button:
<script lang="ts">
import { Button } from '$lib/components/index.js';
</script>
<Button variant="outlined" onclick={() => alert('Button clicked!')}>Click me!</Button>
This is a disabled outlined button:
<script lang="ts">
import { Button } from '$lib/components/index.js';
</script>
<Button variant="outlined" onclick={() => alert('Button clicked!')} disabled>I am disabled</Button>
You can add an icon to the button using the icon snippet:
<script lang="ts">
import { Check, Save } from '@lucide/svelte';
import { Button } from '$lib/components/index.js';
let clicked = $state(false);
function handleClick() {
clicked = true;
setTimeout(() => {
clicked = false;
}, 1000);
}
</script>
<Button onclick={handleClick}>
{#snippet icon()}
{#if clicked}
<Check />
{:else}
<Save />
{/if}
{/snippet}
Save
</Button>
When only the icon snippet is provided (and children is omitted), the button is rendered in
icon-only mode with a square shape:
<script lang="ts">
import { Check, Save } from '@lucide/svelte';
import { Button } from '$lib/components/index.js';
let clicked = $state(false);
function handleClick() {
clicked = true;
setTimeout(() => {
clicked = false;
}, 1000);
}
</script>
<Button onclick={handleClick} aria-label="Save">
{#snippet icon()}
{#if clicked}
<Check />
{:else}
<Save />
{/if}
{/snippet}
</Button>
If the href prop is provided, the button will be rendered as an anchor:
<script lang="ts">
import { House } from '@lucide/svelte';
import { Button } from '$lib/components/index.js';
</script>
<Button href="/">
{#snippet icon()}
<House class="size-4"></House>
{/snippet}
Home
</Button>