Back to Onyx

ContentAction

web/lib/opal/src/layouts/content-action/README.md

3.3.03.1 KB
Original Source

ContentAction

Import: import { ContentAction, type ContentActionProps } from "@opal/layouts";

A row layout that pairs a Content block with optional right-side action children (buttons, badges, icons, etc.).

Why ContentAction?

Content renders icon + title + description but has no slot for actions. When you need a settings row, card header, or list item with an action on the right you would typically wrap Content in a manual flex-row. ContentAction standardises that pattern and adds padding alignment with Interactive.Container and Button via the shared SizeVariant scale.

Props

Inherits all props from Content (same discriminated-union API) plus:

PropTypeDefaultDescription
rightChildrenReactNodeundefinedContent rendered on the right side. Wrapper stretches to the full height of the row.
paddingSizeVariant"lg"Padding preset applied around the Content area. Uses the shared size scale from @opal/shared.

padding reference

ValuePadding classEffective padding
lgp-20.5rem (8px)
mdp-10.25rem (4px)
smp-10.25rem (4px)
xsp-0.50.125rem (2px)
2xsp-0.50.125rem (2px)
fitp-00

These values are identical to the padding applied by Interactive.Container at each size, so ContentAction labels naturally align with adjacent buttons of the same size.

Layout Structure

[  Content (flex-1, padded)  ][  rightChildren (shrink-0, full height)  ]
  • The outer wrapper is flex flex-row items-stretch w-full.
  • Content sits inside a flex-1 min-w-0 div with padding from padding.
  • rightChildren is wrapped in flex items-stretch shrink-0 so it stretches vertically.

Usage Examples

Settings row with an edit button

tsx
import { ContentAction } from "@opal/layouts";
import { Button } from "@opal/components";
import SvgSettings from "@opal/icons/settings";

<ContentAction
  icon={SvgSettings}
  title="OpenAI"
  description="GPT"
  sizePreset="main-content"
  variant="section"
  tag={{ title: "Default", color: "blue" }}
  padding="lg"
  rightChildren={
    <Button icon={SvgSettings} prominence="tertiary" onClick={handleEdit} />
  }
/>

Card header with connect action

tsx
import { ContentAction } from "@opal/layouts";
import { Button } from "@opal/components";
import { SvgArrowExchange, SvgCloud } from "@opal/icons";

<ContentAction
  icon={SvgCloud}
  title="Google Cloud Vertex AI"
  description="Gemini"
  sizePreset="main-content"
  variant="section"
  padding="md"
  rightChildren={
    <Button rightIcon={SvgArrowExchange} prominence="tertiary">
      Connect
    </Button>
  }
/>

No right children (padding-only wrapper)

tsx
<ContentAction
  title="Section Header"
  sizePreset="main-content"
  variant="section"
  padding="lg"
/>

When rightChildren is omitted the component renders only the padded Content — useful for alignment consistency when some rows have actions and others don't.