Button

A button for triggering actions, with options for icons, intent, variant, size, and busy or pressed states.

Installation

import { Button } from "@o/pipeline/experimental/components/button";

Default

Icons

Don’t pass icons as children. Pass them to the button through these props:

  1. iconStart (or the icon alias)
  2. iconEnd

Give icon-only buttons an aria-label on the SVG element for accessibility.

intent

Change the button’s color scheme to signal the nature of the action.

  • none (default): for neutral actions without a strong emphasis
  • success: for actions that are positive or confirmatory in nature
  • danger: for destructive or potentially negative actions

Combine with the variant prop to adjust the button’s appearance.

variant

Changes the aesthetics of the button to blend accordingly with the context of its usage.

variant="solid"

intent="none"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
intent="success"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
intent="danger"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"

variant="ghost"

intent="none"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
intent="success"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
intent="danger"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"

choice

Used for actions that display a value you choose, such as a Choice.

Note

Currently, the choice prop only supports intent="none".

See OP-3633: Button Clean-up: Extend choice variants.

When a value isn’t set, also supply a placeholder attribute.

variant="ghost" choice placeholder
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
variant="ghost" choice
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"

shape

Sets the button’s geometry along two independent axes: corner rounding and width.

Defaults to "square" for icon-only buttons (a single icon/iconEnd/collapsible, no other content) and "rectangle" otherwise.

The pinned shapes ("square"/"circle") lock width to height, so their content must fit a square box. They’re intended for a single icon. Adding text to one keeps the 1:1 lock and truncates rather than growing. For an elongated fully-rounded button, use "pill". The width pin also wins over stretch: a stretched "square"/"circle" stays 1:1, while a stretched "rectangle"/"pill" fills its container.

shape="rectangle"
shape="square"
shape="circle"
shape="pill"

size

disabled

Prevent user interaction

Note

For elements that don’t support the disabled attribute, such as <a> elements, we mimic disabled behavior by disabling pointer events completely.

pending

Indicate a busy or loading state, blocking interaction and replacing the content with a spinner.

pressed

Indicate an active or pressed state, such as a Menu trigger when its menu is open.

Note

For flexibility, this isn’t applied automatically when combined with collapsible and an open state.

stretch

Fill the button to the width of its container

shrink

Allows the button to shrink smaller than its content if necessary to avoid overflow (true by default)

collapsible

Indicate to the user that the button toggles another element’s visibility with a visual cue (e.g. a caret that rotates when open).

Accepts either true (alias for { weight: "bold", transition: "right-down" }) or a config object:

  • weight: "bold" (default) or "fill", the caret icon’s Phosphor weight.
  • transition: "right-down" (default) or "down-up", the rotation the caret animates through when toggled between closed and open.

This can be combined with pressed where relevant.

collapsible(default, alias for bold)
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
collapsible={{"weight":"bold"}}
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
collapsible={{"weight":"fill"}}
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
collapsible={{"weight":"fill","transition":"down-up"}}
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"

render

Customize the underlying element to your needs

e.g. a link:

render={<a href="#" />}

bleed

Allow the button to extend beyond its normal bounds via negative margins.

Note

bleed works on square/circle buttons: the offset is the glyph frame inset, (height - glyph-frame) / 2 (the same distance an icon-only button bleeds), rather than the text-button padding a square doesn’t have. A bled square button’s content therefore lines up flush with its surroundings.

bleed={false} (default)
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
bleed (all sides)
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
bleed="top"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
bleed="bottom"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
bleed="y"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
bleed="start"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
bleed="end"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"
bleed="x"
    • size="sm"
    • size="md"
    • stretchsize="sm"
    • stretchsize="md"