Button
Installation
import { Button } from "@o/pipeline/experimental/components/button";
Default
Icons
Icons should not be supplied as children, and should be supplied to the button via the following props:
iconStart(or theiconalias)iconEnd
Icon-only buttons must have an aria-label specified on the SVG element for accessibility.
intent
Change the color scheme of a button to visually cue the user on the nature of the action.
none(default): for neutral actions without a strong emphasissuccess: for actions that are positive or confirmatory in naturedanger: for destructive or potentially negative actions
Combine with the variant prop…
variant
Changes the aesthetics of the button to blend accordingly with the context of its usage.
variant="solid"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
variant="ghost"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
rounded
Applies fully rounded corners to the button, creating a circle or pill shape.
Currently only intended for use with icon-only buttons.
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, preventing interaction and providing feedback to the user — replacing content with a spinner.
pressed
Indicate an active or pressed state, such as a DropdownMenu trigger when its menu is open.
Note
This is not applied automatically when combined with collapsible and an open state to provide additional flexibility.
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).
This can be combined with pressed where relevant.
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
render
Customize the underlying element to your needs
e.g. a link:
bleed
Allow the button to extend beyond its normal bounds via negative margins.
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
- size="sm"
- size="md"
- size="lg"
- size="sm"
- stretchsize="sm"
- stretchsize="md"
- stretchsize="lg"
- stretchsize="sm"
Migration Guide
When migrating from @o/pipeline/legacy/components/button to @o/pipeline/experimental/components/button, follow these steps:
-
variantvariant="primary"→variant="solid"variant="secondary"→variant="solid"variant="outline"→variant="solid"variant="success"→variant="solid" intent="success"variant="danger"→variant="solid" intent="danger"variant="ghost"→variant="ghost"variant="dashed"→ no equivalent, only adjust anydefaultsizes tosmfor consistency with new button sizing.
-
sizedefault→mdsm→mdxs→sm
-
fluid→stretch -
Icons
icon+iconPosition="start"→iconStarticon+iconPosition="end"→iconEnd
-
asChild→render(see render for details) -
Usage with
PendingText→ usependingprop instead with the same content rather than changing based onpendingstate. -
Changing the button background based on the trigger’s active state (e.g. opening a dropdown menu) → use the
pressedprop on the button and control it based on the trigger’s state (e.g.openor not) -
Collapsible triggers (e.g. for an accordion) → use the
collapsibleprop on the button and control it based on the trigger’s state (e.g.openor not). Only usepressedif the background was previously changing based on the trigger’s active state. -
className="rounded-full"→rounded
Implementation Notes
-
We’ve deliberately decided to omit the
classNameandstyleprops from a component- This is the first time we’re doing this
- We’re hoping it acts as a mechanism for design feedback — forcing us to choose from existing variants or adjust accordingly.
-
Safari doesn’t handle
0.5pxshadows too well on SVGs, but we’re happy to accept this trade-off and fallback to no shadow for these cases.