RoadieRoadie
  • Home
  • Brand
  • Foundations
  • Content
  • Tokens
  • Components
  • Charts
  • Widgets
  • Appearance
HomeBrandFoundations
Appearance

Components

  • Navigation

    • Breadcrumb
    • LinkBeta
    • NavigatorAlpha
    • Steps
    • Tabs
  • Layout

    • Accordion
    • CollapsibleBeta
    • PaneAlpha
    • ScrollArea
    • Separator
  • Actions

    • Button
    • IconButton
    • ToggleBeta
    • Toggle groupBeta
    • ToolbarBeta
  • Fields

    • EditorAlpha
    • Field
    • Fieldset
    • Input
    • Label
    • Number fieldBeta
    • OTP fieldBeta
    • Query fieldAlpha
    • Textarea
  • Choices

    • Autocomplete
    • CheckboxBeta
    • Combobox
    • Radio group
    • Select
    • SliderBeta
    • SwitchBeta
  • Date and time

    • CalendarBeta
    • CalendarTile
    • Countdown
    • Dashboard periodBeta
    • Date fieldBeta
    • Date pickerBeta
    • Date range pickerBeta
    • DateTime
    • Duration
    • Time fieldBeta
  • Collections

    • Card
    • Carousel
    • DataTableBeta
    • ListAlpha
    • Marquee
    • RecordGridAlpha
    • RecordTableAlpha
    • SortableAlpha
    • TableBeta
  • Overlays

    • Dialog
    • Drawer
    • MenuBeta
    • Popover
    • ToastBeta
    • Tooltip
  • Status

    • Badge
    • CalloutBeta
    • DeltaBeta
    • Empty state
    • MeterBeta
    • ProgressBeta
    • SkeletonBeta
    • SparklineBeta
    • StatTileBeta
  • Media & brand

    • AvatarBeta
    • Icon Tile
    • Image
    • Logo
    • PatternBeta
    • QR codeBeta
    • SpotIllustration
  • Text

    • Code
    • Highlight
    • KbdBeta
    • Mark
    • Prose

Button

Status
Stable
Added
Components 0.1.03 Jan 2025
Updated
Components 2.16.020 Oct 2026
Docs updated
19 Oct 2026

An interactive control that triggers an action when pressed.

Import

import { Button } from '@oztix/roadie-components'

Examples

Default

<Button>Button</Button>

Emphasis

<Button emphasis='strong'>Strong</Button>
<Button emphasis='normal'>Normal</Button>
<Button emphasis='subtle'>Subtle</Button>
<Button emphasis='subtler'>Subtler</Button>

Sizes

<Button size='xs'>Extra small</Button>
<Button size='sm'>Small</Button>
<Button size='md'>Medium</Button>
<Button size='lg'>Large</Button>

Full width

A button is as wide as its label and takes its parent's alignment. Add w-full to fill the space. A parent's items-stretch or self-stretch won't widen it. To go back to the label's width at a breakpoint, use w-fit, not w-auto.

<div className='grid max-w-sm gap-2'>
<Button emphasis='strong' className='w-full'>Checkout</Button>
<Button className='w-full sm:w-fit'>Keep browsing</Button>
</div>

Intents

Neutral is the default intent. Each intent communicates a different purpose: accent for primary actions, danger for destructive actions, and so on. Hover and focus states adapt automatically.

{/* Strong */}
<Button emphasis='strong' intent='neutral'>Neutral</Button>
<Button emphasis='strong' intent='accent'>Accent</Button>
<Button emphasis='strong' intent='brand'>Brand</Button>
<Button emphasis='strong' intent='info'>Info</Button>
<Button emphasis='strong' intent='success'>Success</Button>

States

Hover and focus states use the intent color scale automatically via is-interactive.

{/* Default */}
<Button>Button</Button>
{/* Disabled */}
<Button disabled>Button</Button>

Href

Pass href to render the button as a routed anchor. Roadie picks the right element + safety attributes based on the href shape: internal routes go through your configured RoadieLinkProvider; external hrefs (https://…, //…) auto-render with target='_blank' rel='noopener noreferrer'; protocol hrefs (mailto: / tel: / sms:) render plain anchors.

{/* Internal */}
<Button href='/foundations/linking' emphasis='strong' intent='accent'>
Read about linking
</Button>
{/* External */}
<Button href='https://oztix.com.au' emphasis='normal'>

Hover each button. The browser status bar shows the resolved href exactly as Roadie rendered it. See Linking for the full reference: provider setup, the external/internal/protocol decision tree, and the external/target/rel overrides.

Download

Add download to an href button to save the file instead of opening it, optionally under a filename. A file isn't a route, so the button renders a plain <a> and skips the provider's Link, which would otherwise prefetch the file as a page. That also means it gets no base path: if your app has one, add it to the href yourself.

<Button href='/roadie-logo.png' download='roadie-logo.png'>
<DownloadIcon weight='bold' className='size-4' />
Download logo
</Button>

Escape hatch

For full element control, or anchor props href doesn't cover (hreflang, referrerPolicy), use Base UI's render prop. It keeps Base UI's button semantics, which are role='button' and Space activation. The element you pass is yours to make accessible. Passing both href and render triggers a one-shot dev warning. render wins, and provider routing is silently disabled.

Guidelines

Write labels with Interface copy.

Accessibility

  • Keyboard: Enter or Space activates the button. With href it is a link, so Enter follows it and Space scrolls the page. Focus is indicated by a semi-transparent ring via is-interactive.
  • ARIA: Renders a native <button>, or an <a> with href. A disabled link gets aria-disabled, leaves the tab order and doesn't navigate.
  • IconButton: Requires an aria-label prop (enforced by TypeScript) since there is no visible text.

API reference

Button

Base UI
focusableWhenDisabledboolean

Whether the button should be focusable when disabled.

Defaults to false.

classNamestring | ((state: ButtonState) => string)

CSS class applied to the element, or a function that returns a class based on the component's state.

intent"neutral" | "brand" | "brand-secondary" | "brand-blue" | "brand-orange" | "brand-purple" | "accent" | "danger" | "success" | "warning" | "info" | null
emphasis"strong" | "normal" | "subtle" | "subtler" | null
size"xs" | "sm" | "md" | "lg" | "icon-xs" | "icon-sm" | "icon-md" | "icon-lg" | null
hrefstring

Pass a URL to render the button as a routed anchor instead of a `<button>`. Internal hrefs route through the configured `RoadieLinkProvider` (or fall back to plain `<a>`); external hrefs (`http(s)://`, `//…`) render as `<a target='_blank' rel='noopener noreferrer'>`; `mailto:` / `tel:` / `sms:` render as plain `<a>`. Pair with `external`, `target`, or `rel` to override the defaults.

externalboolean

Force external-link treatment regardless of `href` shape. Useful for first-party URLs that should still open in a new tab, or for an `https://` URL that should route internally through the provider.

targetstring

Override the auto `target='_blank'` default on external hrefs.

downloadstring | boolean

Download the `href` instead of navigating, optionally as this filename.

Inherited from NativeButtonProps

nativeButtonboolean

Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`).

Defaults to true.

Inherited from HTMLAttributes

relstring

Override the auto `rel='noopener noreferrer'` default on external hrefs.

IconButton

intent"neutral" | "brand" | "brand-secondary" | "brand-blue" | "brand-orange" | "brand-purple" | "accent" | "danger" | "success" | "warning" | "info" | null
emphasis"strong" | "normal" | "subtle" | "subtler" | null
classNamestring | ((state: ButtonState) => string)

CSS class applied to the element, or a function that returns a class based on the component's state.

hrefstring

Pass a URL to render the button as a routed anchor instead of a `<button>`. Internal hrefs route through the configured `RoadieLinkProvider` (or fall back to plain `<a>`); external hrefs (`http(s)://`, `//…`) render as `<a target='_blank' rel='noopener noreferrer'>`; `mailto:` / `tel:` / `sms:` render as plain `<a>`. Pair with `external`, `target`, or `rel` to override the defaults.

externalboolean

Force external-link treatment regardless of `href` shape. Useful for first-party URLs that should still open in a new tab, or for an `https://` URL that should route internally through the provider.

targetstring

Override the auto `target='_blank'` default on external hrefs.

downloadstring | boolean

Download the `href` instead of navigating, optionally as this filename.

aria-labelstring
Required
size"xs" | "sm" | "md" | "lg" | "icon-xs" | "icon-sm" | "icon-md" | "icon-lg"

Icon-button sizing. Use `'xs' | 'sm' | 'md' | 'lg'` (plain) — the `'icon-*'` aliases are accepted for backwards compatibility but discouraged.

Defaults to md.

Inherited from HTMLAttributes

relstring

Override the auto `rel='noopener noreferrer'` default on external hrefs.

Inherited from ButtonProps

focusableWhenDisabledboolean

Whether the button should be focusable when disabled.

Defaults to false.

Inherited from NativeButtonProps

nativeButtonboolean

Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`).

Defaults to true.

Previous page← SeparatorNext pageIconButton →