Back to Onyx

Button

web/lib/opal/src/components/buttons/button/README.md

3.3.02.8 KB
Original Source

Button

Import: import { Button, type ButtonProps } from "@opal/components";

A single component that handles both labeled buttons and icon-only buttons. Built on Interactive.Stateless > Interactive.Container.

Architecture

Interactive.Stateless          <- variant, prominence, interaction, disabled, href, onClick
  └─ Interactive.Container     <- height, rounding, padding (from `size`), border (auto for secondary)
       └─ div.opal-button.interactive-foreground
            ├─ div > Icon?       (interactive-foreground-icon)
            ├─ <span>?           .opal-button-label
            └─ div > RightIcon?  (interactive-foreground-icon)
  • Colors are not in the Button. Interactive.Stateless sets background-color, --interactive-foreground, and --interactive-foreground-icon per variant/prominence/state. Descendants opt in via the .interactive-foreground and .interactive-foreground-icon utility classes.
  • Icon-only buttons render as squares because Interactive.Container enforces min-width >= height.
  • Border is automatic for prominence="secondary". The Container receives border={prominence === "secondary"} internally.

Props

PropTypeDefaultDescription
variant"default" | "action" | "danger" | "none""default"Color variant
prominence"primary" | "secondary" | "tertiary" | "internal""primary"Color prominence
interaction"rest" | "hover" | "active""rest"JS-controlled interaction override
iconIconFunctionComponentLeft icon
childrenstringLabel text. Omit for icon-only buttons
rightIconIconFunctionComponentRight icon
responsiveHideTextbooleanfalseHides label on small screens
sizeSizeVariant"lg"Size preset
type"submit" | "button" | "reset""button"HTML button type
widthWidthVariantWidth preset
tooltipstringTooltip text
tooltipSideTooltipSide"top"Tooltip placement
disabledbooleanfalseDisables the button
hrefstringURL; renders as a link

Usage

tsx
import { Button } from "@opal/components";
import { SvgPlus, SvgArrowRight } from "@opal/icons";

// Primary button with label
<Button variant="default" onClick={handleClick}>Save changes</Button>

// Icon-only button (renders as a square)
<Button icon={SvgPlus} prominence="tertiary" size="sm" />

// Secondary button (auto border)
<Button rightIcon={SvgArrowRight} prominence="secondary">Continue</Button>

// Interaction override (e.g. inside a popover trigger)
<Button icon={SvgFilter} prominence="tertiary" interaction={isOpen ? "hover" : "rest"} />