Button
Button presents a finished action or emphasized native link. Brick owns its visual recipes and styling; the public Atom Button owns semantics, interaction, form behavior, unavailable/loading behavior, and composition.
Built from the published package
Know when Button is the right part
Use it when
Use Button for immediate actions such as saving, submitting, confirming,
cancelling, continuing, opening another surface, or retrying work. Supply
href when an emphasized call to action navigates instead of performing an
action.
Choose another path when
- Use an ordinary link when navigation should read as navigation rather than a prominent action.
- Use
IconButtonfor an icon-only action. - Use
Togglefor persistent pressed/unpressed state. - Use a component with more specific semantics for menu items, tabs, or arbitrary interactive surfaces.
- Use variants for normal hierarchy. Reserve
info,success,warning, anddangertones for actions with that actual meaning.
Button intentionally has no label, iconOnly, loadingText,
loadingIndicator, icon registry, arbitrary radius/color, gradient, or
translucent prop.
Installation and imports
Import Button from the package root or its stable subpath, then load Brick's compiled stylesheet once in the application:
The complete stylesheet above is the recommended default. For a measured route-aware build, replace it with the shared foundation and this component's stylesheet:
Add the modular stylesheet for every other Brick component the route renders.
Do not combine modular styles with styles.css or tokens.css.
Brick currently requires React 18 or newer and the package's exact released Atom dependency.
Quick start
The defaults are variant="solid", tone="accent", size="md",
shape="rounded", and fullWidth={false}.
Visual recipes and states
Variants
| Variant | Intended hierarchy |
|---|---|
solid | Highest local emphasis |
soft | Quieter filled treatment |
outline | Secondary transparent treatment with a visible border |
ghost | Lowest standalone emphasis with a transparent rest border |
Tones
neutral supports secondary and cancel actions. accent is the normal product
action. info, success, warning, and danger communicate genuine semantic
meaning; they are not decorative palette choices.
Sizes and shapes
| Size | Minimum block size |
|---|---|
xs | 28px |
sm | 36px |
md | 44px |
lg | 52px |
xl | 60px |
sharp, rounded, and pill change radius only. fullWidth changes inline
width only and is independent of size or shape.
Every recipe supports rest, capability-gated hover, active/pressed, focus-visible, disabled, loading, light/dark appearance, forced colors, and reduced motion. Disabled and loading block activation through Atom. Loading remains focusable and overlays a centered visual spinner without resizing the Button.
Examples
API
Start with the public parts and root options below. Components with multiple parts separate each area into its own named subsection.
Exports
Brick visual props
| Prop | Allowed values | Default |
|---|---|---|
variant | "solid", "soft", "outline", "ghost" | "solid" |
tone | "neutral", "accent", "info", "success", "warning", "danger" | "accent" |
size | "xs", "sm", "md", "lg", "xl" | "md" |
shape | "sharp", "rounded", "pill" | "rounded" |
fullWidth | boolean | false |
startIcon | ReactNode | none |
endIcon | ReactNode | none |
Inherited Atom and native props
Button preserves the applicable public Atom Button contract:
| Prop | Contract |
|---|---|
children | Visible content and accessible name on the normal path |
href | Renders a native anchor when present |
target, rel | Native anchor behavior; Atom preserves safe new-tab relationships |
disabled | Blocks activation and exposes the unavailable state |
loading | Blocks activation, remains focusable, and exposes aria-busy |
onPress | MouseEventHandler<HTMLElement> normalized by Atom |
onClick, onKeyDown | Native-compatible handlers composed by Atom |
type | "button", "submit", or "reset"; defaults to "button" |
asChild | Uses one child element as the host; defaults to false |
render | Uses an Atom render element or callback as the host |
data-slot | Defaults to "button" and may be overridden |
| native/global props | Applicable form, ARIA, data-*, event, className, and style props |
The native color attribute is intentionally omitted because Brick uses
semantic tone.
asChild and render are mutually exclusive. When asChild is true,
children must be one ReactElement, and startIcon/endIcon are rejected
by the public type. Put any icon inside that child instead.
Accessibility
Provide meaningful visible children for the accessible name. Use the default
button path for actions and href for navigation.
Atom owns the native role, keyboard activation, form behavior, unavailable and loading guards, safe anchor behavior, event composition, and ref forwarding. Brick supplies visible focus, recipe contrast, minimum target geometry, forced-color presentation, and reduced-motion styling.
startIcon and endIcon are decorative. Do not rely on them as the only
source of meaning. Loading retains the original accessible name; put detailed
asynchronous status in adjacent live feedback and connect it with
aria-describedby when useful.
The md default supplies a 44 CSS pixel minimum block size. If using xs or
sm on touch interfaces, the application must provide adequate surrounding
target spacing.
Responsive behavior
Button is intrinsic and mobile-first. Labels may wrap, block size grows with zoom or localization, padding and icon order use logical directions, and the root remains constrained by its container. It never becomes full width automatically.
Use fullWidth for unconditional width. Breakpoint-dependent width, placement,
visibility, or grouping remains application layout:
Brick does not mirror icon artwork. Supply the correct directional arrow or chevron for the current writing direction.
Styling and tokens
Customization
Prefer customization in this order:
- Button props for supported recipes;
- Brick semantic tokens on an application scope;
- the public Button tokens above;
classNameandstylefor a local escape hatch.
When overriding colors, verify rest, hover, pressed, focus, disabled, loading, light/dark appearance, and forced colors.
Tokens and CSS hooks
Stable styling surface
- root class:
.brick-button - default overridable slot:
data-slot="button" - visual attributes:
data-variant,data-tone,data-size,data-shape - conditional layout attribute:
data-full-width - Atom state attributes:
data-disabled,data-loading - native
classNameandstyle
Brick targets .brick-button; changing data-slot does not remove its styles.
The private content/icon classes and loading pseudo-element are not public
customization contracts.
Public Button tokens
Internal tone-mapping and spinner variables used by the stylesheet are not
public tokens. The typography variables default to the matching
control-xs–control-xl semantic recipes.
Advanced reference
Open these details only when you need to inspect DOM ownership, native forwarding, or lower-level composition.