RoadieRoadie
  • Home
  • Foundations
  • Tokens
  • Components
  • Charts
  • Widgets
  • Appearance
HomeFoundationsComponents
Appearance

Components

  • Navigation

    • Breadcrumb
    • Navigator
    • Steps
    • Tabs
  • Layout

    • Pane
    • ScrollArea
    • Separator
  • Actions

    • Button
    • IconButton
    • Toggle
    • Toggle group
  • Forms

    • Forms overview
    • Autocomplete
    • Checkbox
    • Combobox
    • Field
    • Fieldset
    • Input
    • Label
    • Number field
    • OTP field
    • Radio group
    • Select
    • Slider
    • Switch
    • Textarea
  • Overlays

    • Dialog
    • Drawer
    • Menu
    • Popover
    • Toast
    • Tooltip
  • Collections

    • Accordion
    • Card
    • Carousel
    • Collapsible
    • DataTable
    • List
    • Marquee
    • Table
  • Status

    • Badge
    • Callout
    • Countdown
    • Empty state
    • Meter
    • Progress
    • Skeleton
    • Sparkline
    • StatTile
  • Media & brand

    • Avatar
    • Icon Tile
    • Image
    • Logo
    • QR code
    • SpotIllustration
  • Text

    • CalendarTile
    • Code
    • DateTime
    • Duration
    • Highlight
    • Mark
    • Prose

Toggle

A button that stays pressed or unpressed, such as favourite or bold.

Import

import { Toggle } from '@oztix/roadie-components/toggle'

Examples

Default

<Toggle>Notify me</Toggle>

Emphasis

emphasis sets the look at rest. Pressed steps one rung up: normal and subtle become strong. A pressed subtler toggle takes a soft fill with no border and a strong icon or label, and an unpressed one rests in subtle text. The subtler selected state relies on the fill and the icon together and doesn't meet 3:1 on the fill alone, so it's for quiet controls. Use subtle or normal when the state must stand out.

<div className='grid gap-4'>
  <div className='flex flex-wrap items-center gap-2'>
    <Toggle>Normal</Toggle>
    <Toggle defaultPressed>Normal, pressed</Toggle>
  </div>
  <div className='flex flex-wrap items-center gap-2'>
    <Toggle emphasis='subtle'>Subtle</Toggle>
    <Toggle emphasis='subtle' defaultPressed>Subtle, pressed</Toggle>
  </div>
  <div className='flex flex-wrap items-center gap-2'>
    <Toggle emphasis='subtler'>Subtler</Toggle>
    <Toggle emphasis='subtler' defaultPressed>Subtler, pressed</Toggle>
  </div>
</div>

Sizes

The same sizes as Button. A toggle whose only child is an icon renders square.

<div className='grid gap-4'>
  <div className='flex flex-wrap items-center gap-2'>
    <Toggle size='xs'>Extra small</Toggle>
    <Toggle size='sm'>Small</Toggle>
    <Toggle size='md'>Medium</Toggle>
    <Toggle size='lg'>Large</Toggle>
  </div>
  <div className='flex flex-wrap items-center gap-2'>
    <Toggle size='xs' aria-label='Bold'><TextBIcon weight='bold' /></Toggle>
    <Toggle size='sm' aria-label='Bold'><TextBIcon weight='bold' /></Toggle>
    <Toggle size='md' aria-label='Bold'><TextBIcon weight='bold' /></Toggle>
    <Toggle size='lg' aria-label='Bold'><TextBIcon weight='bold' /></Toggle>
  </div>
</div>

Intents

The intent colours the pressed state most.

<div className='flex flex-wrap items-center gap-2'>
  <Toggle intent='accent' defaultPressed>Accent</Toggle>
  <Toggle intent='brand' defaultPressed>Brand</Toggle>
  <Toggle intent='danger' defaultPressed>Danger</Toggle>
</div>

States

<div className='grid gap-4'>
  <div className='grid gap-2'>
    <p className='text-sm text-subtle'>Unpressed</p>
    <Toggle>Notify me</Toggle>
  </div>
  <div className='grid gap-2'>
    <p className='text-sm text-subtle'>Pressed</p>
    <Toggle defaultPressed>Notify me</Toggle>
  </div>
  <div className='grid gap-2'>
    <p className='text-sm text-subtle'>Disabled</p>
    <Toggle disabled>Notify me</Toggle>
  </div>
</div>

With a pressed icon

Control pressed to swap the icon. Icons take fill only when pressed.

function Favourite() {
  const [pressed, setPressed] = useState(false)
  return (
    <Toggle
      aria-label='Favourite'
      intent='danger'
      pressed={pressed}
      onPressedChange={setPressed}
    >
      <HeartIcon weight={pressed ? 'fill' : 'bold'} />
    </Toggle>
  )
}

render(<Favourite />)

Guidelines

  • Use a Toggle for a state that stays on, such as following an artist or muting alerts. For a one-off action, use Button.
  • Keep the label the same when pressed. The pressed style already says it is on. Changing "Follow" to "Following" as well reads as two different controls to a screen reader.
  • Choose one option from a set with ToggleGroup, not a row of Toggles.

Accessibility

  • Renders a <button> with aria-pressed, so screen readers announce it as a toggle button and read its state.
  • Space and Enter toggle it.
  • Give an icon-only toggle an aria-label.

API reference

Toggle

Base UI
pressedboolean

Whether the toggle button is currently pressed. This is the controlled counterpart of `defaultPressed`.

defaultPressedboolean

Whether the toggle button is currently pressed. This is the uncontrolled counterpart of `pressed`.

Defaults to false.

disabledboolean

Whether the component should ignore user interaction.

Defaults to false.

onPressedChange((pressed: boolean, eventDetails: { reason: "none"; event: Event; cancel: () => void; allowPropagation: () => void; isCanceled: boolean; isPropagationAllowed: boolean; trigger: Element; }) => void)

Callback fired when the pressed state is changed.

valuestring

A unique string that identifies the toggle when used inside a toggle group.

classNamestring | ((state: ToggleState) => 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" | "accent" | "danger" | "success" | "warning" | "info"

Sets the colour palette. Inherits from the surrounding intent when unset.

emphasis"normal" | "subtle" | "subtler"

Emphasis at rest. Pressed steps up: `normal` and `subtle` to `strong`, `subtler` to a soft fill with a strong icon or label.

Defaults to 'normal'.

size"xs" | "sm" | "md" | "lg"

Button sizes. A toggle whose only child is an icon renders square.

Defaults to 'md'.

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← IconButtonNext pageToggle group →