Native controls

Button

A clickable action in several variants and sizes. Pick a variant for what the action means.

Installation

pnpm dlx @mielui/svelte add button

Usage

Set href to render a link, including an empty href. Without it, Button renders a native button.

Disabled links have no navigation destination and are skipped by Tab. aria-disabled also blocks activation. Loading controls remain focusable but cannot activate.

Use status for loading, success, and error feedback. Changing status keeps the button width stable. labels sets the text for each state. Every key of ButtonLabels is optional; omitted keys keep Loadingโ€ฆ, Done, and Try again.

<script lang="ts">
    import { Button, type ButtonStatus } from '@mielui/svelte/components/button';

    let status = $state<ButtonStatus>('idle');
</script>

<Button {status} labels={{ loading: 'Publishingโ€ฆ', success: 'Published' }}>
  Publish
</Button>

Examples

Variants

Every button takes the theme's control radius. primary, secondary, and destructive are flat fills: one solid color held by a hairline ring, with no gradient or drop shadow. Hover shifts the fill toward the ink at once and press shifts it further. A theme with an edge highlight above 0 lights them. outline is a flat hairline on the field color, ghost shows a wash on hover, and quiet is text alone. panel is a hairline on the card fill, so a whole card can be the control. Use one primary action per view.

Glow

variant="glow" is the lit material, for a page's one headline button: a gradient of the button's own color under faint white light, with every edge drawn by an inner rim. It stays lit when the theme is flat. It is filled with a light tint of the primary color under dark text. Set --mielui-glow-color to change the fill and a text color class to match it. --mielui-glow-light scales the white light from 0 to 1 and starts at 1: lower it on dark fills so the light stays soft. --mielui-glow-ring replaces the outer edge, which is a darker tint of the fill by default. The same three properties work on any filled variant.

Sizes

Disabled

Leading icon

Trailing icon

Loading, success, and retry

Icon group

Element, handlers and unstyled

Button renders its children. Bind element to reach the DOM node, a button or a link depending on href. onkeydown runs on key down before the button handles the key itself.

unstyled drops the variant and size classes so class alone styles the button. The behavior stays: loading, disabled and link handling all still work. Menus use it for rows that have their own look.

API reference

Button

Triggers an action or navigation.

  • disabled
    boolean

    Prevents activation. A disabled link loses its destination and is skipped by Tab.

    Default false

  • variant
    ButtonVariant

    Visual style. Choose it for what the action means, not for decoration.

    Default 'primary'

  • size
    "sm" | "md" | "lg" | "icon"

    Control height. icon is a square button for a single icon.

    Default 'md'

  • children
    Snippet<[]>

    Content rendered inside.

  • element Bindable
    HTMLButtonElement | HTMLAnchorElement

    Bindable reference to the rendered DOM element. Type is the union of the two possible element types -- narrow at the use site:

  • unstyled
    boolean

    Skip the variant/size base classes and render with class alone.

    Default false

  • status
    ButtonStatus

    Controlled visual state. Loading remains focusable and refuses activation.

  • loading
    boolean

    Convenience alias for status="loading".

  • labels
    ButtonLabels

    Overrides the built-in text and accessible names. Every key is optional and English is the fallback.

  • onclick
    ((event: MouseEvent) => void)

    Called when the button is activated. Loading and disabled buttons do not call it.

  • onkeydown
    ((event: KeyboardEvent) => void)

    Called on key down, before the button handles the key itself.

  • href
    string

    Renders a link to this address instead of a button.