Agent docs

OptionCards

A small set of weighty choices shown as cards, each with a title and a sentence, where exactly one is picked.

A radio group drawn as cards. Each card carries an optional icon, a title and a sentence saying what picking it means. The column count follows the number of options, so four cards sit two by two and never three plus an orphan.

When to reach for it#

Five or fewer choices that each need a sentence to explain: a run mode, a plan, a connection type. If the options are one word each, or there are more than five, use Select. If the choices switch panels of content, use Tabs.

SchemaForm renders the same component for x-widget: "mode-chooser"; this is that widget, exported.

Contract#

  • options: { value, label?, description?, icon?, disabled? }[]. label defaults to value.
  • value and onChange(value): controlled, one value or none.
  • label: required, names the group for assistive tech.
  • id, disabled, className.
  • invalid and warned: an error or warning edge around the group, with a little padding so the edge does not touch the cards.
  • Columns: 2 or 4 options use two columns from sm, everything else uses three from lg; one column on a phone. The count is not a prop.
  • Keyboard and roles: a radiogroup of radio buttons; each card is a tab stop and Space or Enter picks it.

Laws it enforces#

  • Every action answers. Every enabled card shows the pointer, the picked card shows a primary border and ring, and a disabled card shows the refusal cursor.
  • Fit, then truncate, never clip. Cards share a grid whose columns follow the count, so no card is left alone on a row.

Sanctioned combinations#

  • Inside a form Card or a FormModal, above the fields the choice controls.
  • With Field-style captions above it: put the caption in the surrounding layout and repeat it as label for assistive tech.

Banned combinations#

  • More than five options. The grid stops reading as a choice; use Select.
  • Cards that only differ by a word. Without a sentence each, a Select or Segmented control is smaller and clearer.
  • Using it as navigation. Cards pick a value; they do not switch panels. Use Tabs.

Before you adopt this#

  • Does every option have a sentence that says what picking it changes?
  • Are there five options or fewer?
  • Is exactly one always the answer, or is "none yet" a valid state you show with an empty value?

Travels with#

Card (a form block), FormModal, SchemaForm (the mode-chooser widget).

Snippet#

<OptionCards
label="Run mode"
value={mode}
onChange={setMode}
options={[
{ value: "manual", label: "Manual", description: "You start every run." },
{ value: "scheduled", label: "Scheduled", description: "Runs on a timer." },
{ value: "push", label: "On push", description: "Runs when code lands." },
{ value: "hybrid", label: "Hybrid", description: "Timer plus push." },
]}
/>
@versable-git/ui · reference, canon, and method, read in place