✦ Asteria UI
Components

Button

Interactive button for actions and form submissions.

Installation

npx asteria-ui add button

Usage

import { Button } from "@/components/ui/button";

<Button>Save changes</Button>
<Button variant="secondary">Cancel</Button>

Examples

Variants

Primary, secondary, ghost, destructive, and link.

Sizes

sm 32px · md 40px · lg 48px · xl 56px.

With icon

leadingIcon accepts any element and sizes it automatically to match the button — 16px at sm/md, 20px at lg/xl. It's a decorative slot: the icon is marked aria-hidden for you.

States

loading shows a spinner, sets aria-busy, and disables the button — independent of the disabled prop, so a button can be disabled without being in a loading state.

API reference

PropTypeDefaultDescription
variant"primary" | "secondary" | "ghost" | "destructive" | "link""primary"Visual style.
size"sm" | "md" | "lg" | "xl""md"Density — 32 / 40 / 48 / 56px height.
leadingIconReactNodeInstance-swap icon slot rendered before the label, auto-sized to match the button's size (16px sm/md, 20px lg/xl).
loadingbooleanfalseShows a spinner, sets aria-busy, and disables the button.
disabledbooleanfalsePrevents interaction.

Accessibility

Accessibility

  • Role. Native <button>, so role="button" and keyboard activation (Enter/Space) come from the browser, not manual ARIA.

  • Focus. Visible glow-focus ring on Tab, via focus-visible — never shown on a pointer click.

  • Disabled. The native disabled attribute prevents all interaction, including from loading.

  • Loading. aria-busy="true" announces the busy state to screen readers while the spinner is visible.