Button
Pre-alphaThe registry and the CLI are not published yet.Roadmap

Button

The main button, with solid, outline and ghost styles, sizes, loading and icon slots.

New event
Variants
Solid

Outline

Ghost

Sizes

Small

Medium

Large

States and icons

Saving

Disabled

Add guest

Next

Installation

npx axiom add button
pnpm dlx axiom add button
yarn dlx axiom add button
bun x axiom add button

Also copies: tappable, slot, text, icon.

Usage

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

<Button onPress={save}>Save</Button>
<Button variant="outline">Cancel</Button>
<Button variant="ghost" size="sm">Skip</Button>
<Button loading>Saving</Button>

Props

PropTypeDefaultDescription
childrenReactNodeThe label. Keep it to a short verb: “Save”, “Continue”.
variant'solid' | 'outline' | 'ghost' | 'destructive''solid'Visual weight. solid for the main action of the screen, outline for a secondary action next to it, ghost for a low-emphasis action like “Skip”, destructive (red) for an irreversible action like “Delete”.
size'sm' | 'md' | 'lg''md'Minimum height from the control size tokens: 32, 44 or 52pt. Grows with larger system text. sm still gets a 44pt touch area through Tappable.
onPress() => voidCalled when the press ends on the button. Not called while loading or disabled.
onLongPress() => voidCalled after the finger is held on the button.
loadingbooleanfalseReplaces the leading icon with a spinner and blocks presses. The button keeps its width so the layout doesn’t jump.
disabledbooleanfalseBlocks presses, applies the disabled component tokens and sets accessibilityState.disabled.
leadingIconIconNameIcon before the label, from your icon registry. Rendered with Icon, sized and colored for the button.
trailingIconIconNameIcon after the label, typically a chevron or an external-link mark.
fullWidthbooleanfalseStretches the button to the width of its parent. Common for the main action at the bottom of a screen.
asChildbooleanfalseRenders the child element instead of a pressable, and merges the button props and styles into it. See Slot.
accessibilityLabelstringlabel textWhat screen readers announce. Required when the label alone is ambiguous.
styleStyleProp<ViewStyle>Extra styles for the container, applied after the variant styles.

Use cases

Main action at the bottom of a form

One solid, full-width button pinned above the home indicator. It is the thing the screen exists for.

Password
••••••••••
Forgot password?

Sign in

Create an account

<Scaffold.Footer>
	<Button size="lg" fullWidth onPress={signIn}>
		Sign in
	</Button>
	<Button variant="ghost" fullWidth onPress={goToSignUp}>
		Create an account
	</Button>
</Scaffold.Footer>

Waiting for a request

loading blocks double submits and shows progress without changing the size of the button.

Order summary
Subtotal$84.00
Shipping$4.90
Total$88.90

Paying

<Button size="lg" fullWidth loading={isPaying} onPress={pay}>
	{isPaying ? "Paying" : "Pay $88.90"}
</Button>

Disabled until the form is valid

The button stays visible so the user knows what comes next, and turns active once the required fields are filled.

Rename
Album name
At least 3 characters.

Save

<Button fullWidth disabled={name.trim().length < 3} onPress={rename}>
	Save
</Button>

Primary and secondary side by side

Pair a solid button with an outline one when both choices are legitimate. Put the main action on the right.

Invitation
Team offsiteFriday, 10:00 · Lisbon
<Card.Footer>
	<Button variant="outline" style={{ flex: 1 }} onPress={decline}>
		Decline
	</Button>
	<Button style={{ flex: 1 }} onPress={accept}>
		Accept
	</Button>
</Card.Footer>

Label with an icon

An icon helps recognition when the action is frequent, like adding to a cart. Keep the label: the icon alone is an IconButton.

Canvas tote$32
Heavy cotton, inside pocket.

Add to cart

<Button size="lg" leadingIcon="cart" onPress={addToCart} style={{ flex: 1 }}>
	Add to cart
</Button>