Button
A Base UI Button in three builds: the solid action, its outline twin and the text button.
import { Button } from '@fairgarden-private/design/components/Button'
Labels are a verb and an object, authored in title case. Handle presses with onClick; onPress is a deprecated alias kept for existing callers. A navigating action renders an anchor through render (with nativeButton={false}), keeping link semantics.
Variants and sizes
Variants and sizes
outline is the default; solid is the page's primary action; text carries a trailing glyph. Sizes run sm (32 px, hit area extended to 44), md (40 px, default), lg (48 px) and xl (56 px, the page's single transactional action). icon adds one functional glyph; iconOnly hides the label, which stays the accessible name. A disabled button draws a dotted edge.
Clicked 0 times
'use client'
import * as React from 'react'
import { Button } from '@fairgarden-private/design/components/Button'
import styles from './variants.module.css'
export function ButtonVariants() {
const [clicks, setClicks] = React.useState(0)
const count = () => setClicks((value) => value + 1)
return (
<div className={styles.stack}>
<div className={styles.row}>
<Button variant="solid" onClick={count}>
Donate Now
</Button>
<Button variant="outline" onClick={count}>
Learn More
</Button>
<Button variant="text" icon="chevron_right" iconPosition="end" onClick={count}>
See All Trails
</Button>
</div>
<div className={styles.row}>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button size="xl" variant="solid">
Extra Large
</Button>
</div>
<div className={styles.row}>
<Button icon="download" onClick={count}>
Download Map
</Button>
<Button iconOnly icon="search" onClick={count}>
Search
</Button>
<Button disabled>Sold Out</Button>
</div>
<p className={styles.status} aria-live="polite">
Clicked {clicks} {clicks === 1 ? 'time' : 'times'}
</p>
</div>
)
}
Primary and secondary
Primary and secondary
The solid fill is the scope's action scale until secondary overrides it. Outline edges, labels and the focus ring are primary roles, so primary recolors them.
import { Button } from '@fairgarden-private/design/components/Button'
import styles from './color.module.css'
/**
* A solid Button fills with the scope's action scale unless `secondary` is
* passed; outline edges and labels are primary roles.
*/
export function ButtonColor() {
return (
<div className={styles.row}>
<Button variant="solid">Scope Action</Button>
<Button variant="solid" secondary="indigo">
Secondary Indigo
</Button>
<Button variant="outline" primary="plum">
Primary Plum
</Button>
<Button variant="text" secondary="orange" icon="arrow_forward" iconPosition="end">
Secondary Orange
</Button>
</div>
)
}
On grounds
On paper, forest and leaf
The same two buttons on three grounds. On forest the action stays amber; on leaf, a solid ground with one ink, it becomes the ink pill.
import { Button } from '@fairgarden-private/design/components/Button'
import { PresetGround } from '@/components/PresetGround'
import styles from './grounds.module.css'
const presets = ['paper', 'forest', 'leaf'] as const
/** Same props, three grounds: the action becomes the ink pill on leaf. */
export function ButtonGrounds() {
return (
<div className={styles.row}>
{presets.map((preset) => (
<PresetGround key={preset} preset={preset} className={styles.face}>
<span className={styles.name}>{preset}</span>
<div className={styles.actions}>
<Button variant="solid">Join Us</Button>
<Button variant="outline">Visit</Button>
</div>
</PresetGround>
))}
</div>
)
}
API Reference
A Base UI Button. A navigating action renders an anchor through render
(with nativeButton={false}), keeping link semantics. States come from
Base UI and ARIA attributes only: pass disabled (with
focusableWhenDisabled where the reason matters) or aria-busy together
with an authored “-ing…” label; a busy button holds its rest width and
ignores clicks.
| Prop | Type | Description |
|---|---|---|
butted | | Butts the button against an adjacent field on its |
icon | | One optional functional glyph (§6.10), inline tier, FILL 0. |
iconOnly | |
|
iconPosition | | Which side of the label the glyph sits on (a |
onMedia | | Only with |
onPress | | Called on click, after |
primary | | Primary Radix scale, from the primary roster: the outline edge, labels and focus ring. Never defaulted; omitted, it inherits the scope [D133]. |
secondary | | Secondary Radix scale: the |
size | | Fixed height: |
variant | |
|
children | | The label: verb plus object, authored in title case [D160]. |
button
ButtonProps
Specification: DESIGN-SYSTEM.md §9.2 (button) and §1.11.10 (the reference Button).