Back to Onyx

LineItemButton

web/lib/opal/src/components/buttons/line-item-button/README.md

3.3.03.2 KB
Original Source

LineItemButton

Import: import { LineItemButton, type LineItemButtonProps } from "@opal/components";

A composite component that wraps Interactive.Stateful > Interactive.Container > ContentAction into a single API. Use it for selectable list rows such as model pickers, menu items, or any row that acts like a button.

Architecture

Interactive.Stateful         <- selectVariant, state, interaction, onClick, href, ref
  └─ Interactive.Container   <- type, width, rounding
       └─ ContentAction      <- withInteractive, padding="lg"
            ├─ Content       <- icon, title, description, sizePreset, variant, ...
            └─ rightChildren

padding is hardcoded to "lg" and withInteractive is always true. These are not exposed as props.

Props

Interactive surface

PropTypeDefaultDescription
selectVariant"select-light" | "select-heavy""select-light"Interactive select variant
stateInteractiveStatefulState"empty"Value state ("empty", "filled", "selected")
interactionInteractiveStatefulInteraction"rest"JS-controlled interaction state override
onClickMouseEventHandler<HTMLElement>Click handler
hrefstringRenders an anchor instead of a div
targetstringAnchor target (e.g. "_blank")
groupstringInteractive group key
refReact.Ref<HTMLElement>Forwarded ref

Sizing

PropTypeDefaultDescription
roundingInteractiveContainerRoundingVariant"md"Corner rounding preset (height is content-driven)
widthWidthVariant"full"Container width
type"submit" | "button" | "reset""button"HTML button type
tooltipstringTooltip text shown on hover
tooltipSideTooltipSide"top"Tooltip side

Content (pass-through to ContentAction)

PropTypeDefaultDescription
titlestring(required)Row label
iconIconFunctionComponentLeft icon
descriptionstringDescription below the title
sizePresetSizePreset"headline"Content size preset
variantContentVariant"heading"Content layout variant
rightChildrenReactNodeContent after the label (e.g. action button)

All other ContentAction / Content props (editable, onTitleChange, optional, auxIcon, tag, etc.) are also passed through. Note: withInteractive is always true inside LineItemButton and cannot be overridden.

Usage

tsx
import { LineItemButton } from "@opal/components";

// Simple selectable row
<LineItemButton
  selectVariant="select-heavy"
  state={isSelected ? "selected" : "empty"}
  rounding="sm"
  onClick={handleClick}
  title="gpt-4o"
  sizePreset="main-ui"
  variant="section"
/>

// With right-side action
<LineItemButton
  selectVariant="select-heavy"
  state={isSelected ? "selected" : "empty"}
  onClick={handleClick}
  title="claude-opus-4"
  sizePreset="main-ui"
  variant="section"
  rightChildren={<Tag title="Default" color="blue" />}
/>