4 Button
L4stIdi0t edited this page 2026-10-09 22:01:06 +02:00

Button

The kit's primary action.

Six variants and four sizes, composed as plain class tables merged with cn() — class always wins, so a caller can override anything without a wrapper. An icon child is sized automatically. Given href it renders an <a> with the same look, for an action that navigates.

Actions · keyboard contract

<script lang="ts">
	import { Button } from '@l4st/driftwood';
</script>
Light Dark
button button in dark mode
button-link button-link in dark mode

Props

Prop Type Default What it does
variant Variant 'default' destructive for actions that lose data; ghost inside dense toolbars; link for a text action that sits in a row of buttons.
size Size 'default' icon is square, for a single glyph with an aria-label.
href string — Renders an <a> to this address instead of a <button>, in any variant; target, rel and download pass through to it. With disabled the address is dropped and the link leaves the tab order.
disabled boolean | null — Greys the button out and stops it working; on a link it also removes href.
class string — Merged with the component's own classes, last — so yours win.
children required Snippet — The content.

Everything not listed above is spread onto the underlying element (HTMLButtonAttributes): aria-*, data-*, event handlers, and the rest of the native attributes.

Keyboard

Key Does
Enter / Space activate

Example

The markup behind the screenshot above, lifted from src/routes/shots/ — so it compiles, and it is exactly what produced the image.

<Button>Start scan</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="destructive">Delete</Button>
<Button variant="link">Link</Button>
<Button disabled>Disabled</Button>

Notes

variant="link" is for a text action that sits in a row of buttons — "Open folder" next to "Raise limit" — where plain text would not look clickable. The text is in --primary with no fill, and it is underlined on hover and on keyboard focus. Height and padding come from size like every other variant, so it lines up with the buttons beside it; give all of them the same size.

<Button size="sm" variant="outline">Raise limit</Button>
<Button size="sm" variant="secondary">Mute for a week</Button>
<Button size="sm" variant="link" href="/files/volume1">Open folder</Button>

For a link inside running text, write a plain <a>: the button padding would push the words around it apart.

href

Any variant takes href and then renders an <a> instead of a <button>, with the same classes. Use it when the action navigates, so the browser's own link behaviour (open in a new tab, copy the address) works. An <a> cannot be disabled, so disabled on a link removes href, sets aria-disabled="true" and takes it out of the tab order. Event handler types still say HTMLButtonElement; on a link the element is an HTMLAnchorElement.

Actions · ButtonGroup · CopyButton · Toggle · Menu · ContextMenu


← All components · Getting started · Theming · source