Form

Button

Themed call-to-action control with size, variant, icon, link, and loading state support.

Loading playground

Overview

Button is the standard call-to-action control. Pass href to render an anchor (NuxtLink) instead of a <button>, and loading to show a spinner while a submit is in flight. The loading state sets aria-busy="true", blocks clicks, and hides the label without resizing the button so submits don't double-fire and adjacent layout doesn't shift.

Pick a variant by the role the button plays on the page:

variantWhen to use
'primary'The single most important action in the view (Save, Add to cart, Continue).
'secondary'Supporting actions that share the primary's emphasis (Cancel next to Save).
'tertiary'Low-emphasis actions inside dense UI (filter chips, inline edits).
'ghost-*'Transparent control for toolbars and chrome where the button shouldn't compete with content.
'glass-*'Buttons over imagery; the surface tints with the background.
'danger'Destructive actions (Delete, Remove).

For icon-only controls, use the dedicated IconButton atom.

Key Business & UX Benefits

  • A single CTA component covers every role on the page, so primary, supporting, destructive, and overlay actions stay visually consistent without per-team CSS forks.
  • The loading prop blocks double-submits and pins the label width, eliminating duplicate orders and the layout shift that erodes trust during checkout.
  • Role-based variants (primary, secondary, danger, ghost, glass) make action hierarchy obvious at a glance, lifting click-through on the actions that matter.
  • Built-in focus, hover, and aria-busy states keep the control accessible to keyboard and screen-reader users without extra accessibility work.
Pro-Tip from Larry: Use the loading prop on submit buttons so users know the action is in progress.

Primary Button

Primary Button
<LButton variant="primary" size="m">Save</LButton>

Secondary Button

Secondary Button
<LButton variant="secondary" size="m">Cancel</LButton>

Button with Icons

Button with both icons
<LButton variant="primary" icon-left="actions/plus" icon-right="actions/arrow-right">
  Add to cart
</LButton>

Button with Loading Animation

Button with loading Animation
<LButton variant="primary" loading>Saving...</LButton>

Feature List

  • Variant axis covers 'primary', 'secondary', 'tertiary', 'ghost-*', 'glass-*', and 'danger' for every action role from a single component
  • Three sizes ('s', 'm', 'l') line up with form, body, and hero placements without separate components
  • `href` prop swaps the rendered tag from `<button>` to NuxtLink, so navigation buttons keep prefetch and route-transition support
  • `loading` sets `aria-busy="true"`, blocks clicks, and hides the label without resizing, so submits never double-fire and layout stays still
  • `iconLeft` and `iconRight` props place size-matched icons either side of the label, useful for add-to-cart and forward arrows
  • Glass variants tint over imagery while primary and secondary track the theme accent, so the same control fits banners and forms

API Reference

PropDefaultType
disabledfalseboolean
sizem
variantprimary
hrefstring
targetstring
iconLeft
iconRight
loadingfalseboolean
buttonTypebutton"submit" | "button"
spinnerTyperow"row" | "round"

Loading spinner shape. Defaults to 'row' for text buttons; IconButton overrides to 'round' to fit the square footprint.

blockfalseboolean

When true, the button stretches to its container's width (display: flex; width: 100%). Default is false — the button hugs its content via display: inline-flex.

SlotType
defaultany
EventType
click(event: "click", e: MouseEvent): void
Copyright © 2026 Laioutr GmbH