Button

buttonActions

The pill you press. One primary per view carries the orange; everything else steps down to outline, secondary or ghost.

bunx --bun shadcn@4.17.0 add @waimakers/button
Kit dependencies
utilsthemespinner
npm dependencies
@base-ui/react@1.9.0class-variance-authority@0.7.1

From the registry

Brand-restyled shadcn Button. Pill shape, ink label on the accent, the link variant dropped (orange is never text on a light ground). It presses in a pixel while held, unless it opens a popup; while its popup is open (aria-expanded) it holds its hover fill. loading keeps the label in place for width, lays a Spinner over it, sets aria-busy and disables the button; rendered as a link or another element, a loading or disabled Button is aria-disabled and refuses clicks and Enter, whichever element carries the label. The focus ring is the kit's shared --text outline, the transition takes the brand ease and stops under reduced motion.

Examples

Variants

Default is the one primary action. Destructive is for actions that remove something. Outline, secondary and ghost step down in weight.

Sizes

Default and large are 44px and above for touch. Small suits dense toolbars. Icon buttons need an aria-label.

With icons

Lucide icons sit at 16px and inherit the label colour.

States

Loading keeps the label's width and announces busy. Disabled refuses clicks and keys. The focus ring is the text colour, never orange.

State grid

Every variant in every state, held still so you can compare them. Hover, focus and pressed are held with data-kit-hover, data-kit-focus-visible and data-kit-active; loading and disabled use the props.

Every button variant in each state, held still
VariantRestHoverFocusPressedLoadingDisabled
default
destructive
outline
secondary
ghost

Render a link with the button's look. It stays a link for screen readers and middle-click.