Skip to content

HabButton

A button. Renders a native <button> by default, or any element via as.

The four variants
vue
<HabButton variant="primary">Primary</HabButton>

Sizes

Sizes map to the shared --spacing-control-* scale, so a button lines up with any other control of the same size.

sm / md / lg

States

disabled and loading are separate props. Both block interaction, but they say different things: disabled means unavailable, loading means busy. Assistive technology announces them differently, so reach for the one that is true.

Default, disabled, loading
vue
<HabButton disabled>Unavailable</HabButton>
<HabButton loading>Busy</HabButton>

Full width

block stretches to the container

Rendering as another element

Use as="a" for anything that navigates. A link that looks like a button should still be a link — it belongs in the browser's history and supports open-in-new-tab, which a <button> does not.

Rendered as an anchor
vue
<HabButton as="a" href="/settings">
	Settings
</HabButton>

Accessibility

  • Renders a real <button> by default, so keyboard and screen-reader behaviour is the platform's rather than something reimplemented.
  • loading sets aria-busy; disabled and loading both set aria-disabled.
  • disabled is only applied as an attribute when rendering an actual <button>, since it is not valid on other elements.
  • A focus ring is always visible on keyboard focus and never suppressed.

When using as="a", remember an anchor without href is not focusable — give it one, or use a button.

API

Props

PropTypeDefaultDescription
asstring"button"Element or component to render as. Use a for navigation.
blockbooleanfalseStretches the button to the full width of its container.
disabledbooleanfalseDisables interaction and removes the button from the tab order.
loadingbooleanfalseShows a busy state and blocks interaction. Kept separate from disabled so assistive technology announces "busy" rather than "unavailable".
size"md" | "sm" | "lg""md"Control height, aligned to the shared --spacing-control-* baseline.
variant"primary" | "secondary" | "ghost" | "danger""primary"Visual weight of the button. Use exactly one primary per view.

Slots

SlotBindingsDescription
defaultanyButton label.
leadinganyLeading adornment, typically an icon. Hidden while loading.
trailinganyTrailing adornment, typically an icon.

Proprietary — internal use only.