Button group
A set of actions, drawn three ways: one pair of parentheses with hairlines between, a narrow column with a dash hung in the margin, or a list written into the sentence around it.
Report an issue with Button groupExample
Halden is ready to share. You can .
Rest
Pointed at
Disabled
Column
Pointed at
Disabled
SentenceThen .
Pointed atThen .
DisabledThen .
Install
Run it in a project that has the shadcn CLI set up. It brings the 0nlyType base and button along.
npx shadcn@latest add https:// thedirectors.agency/ ui/ r/button-group.jsonUsage
import { Button } from "@/components/ui/button"import { ButtonGroup } from "@/components/ui/button-group"export default function Example() {return (<div className="grid justify-items-start gap-(--ot-space-8)"><ButtonGroup aria-label="Share Halden"><Button>Copy link</Button><Button>Email</Button><Button>Export PDF</Button></ButtonGroup><ButtonGroup variant="column" aria-label="Halden"><Button>Open</Button><Button>Rename</Button><Button>Duplicate</Button><Button>Move to archive</Button></ButtonGroup><p className="ot-mp max-w-[34ch] text-(--ot-graphite)">Halden is ready to share. You can{" "}<ButtonGroup variant="sentence" aria-label="Share Halden"><Button>copy the link</Button><Button>email it</Button><Button>export a PDF</Button></ButtonGroup>.</p></div>)}Contract
- Underneath: native.
- Anatomy:
<div class="ot-btn-group" role="group" data-variant="parentheses | column | sentence" aria-label="Name">ofot-btnbuttons (no variant). The sentence is a<span>, since it sits inside a paragraph, and writes.ot-btn-group-sep(aria-hidden) between its buttons. - Parentheses: one pair holds the set, after 20(25), and hairlines stand between the actions. Pointing draws a line under one; it passes through.
- Column: after "Less is more." and Healthy habits, the actions stacked as a narrow ragged column at tight leading, with no rules between. Pointing hangs the poster's short heavy dash in the margin beside the action; it grows out from the word and goes back into it, and a press lengthens it. It hangs into the inline-start margin, mirrored right to left.
- Sentence: the actions written into running text as a list, the way prose names choices: "copy the link, email it, or export a PDF". The group takes the text's size; each action is ink on a pencil hairline, and pointing passes an ink line through it.
conjunctionsets the last word between ("or" by default). - Keyboard: Tab between buttons.
Props
| Prop | Type | Default | What it does |
|---|---|---|---|
aria-label | string | Names the set for a screen reader, such as Share Halden. The group is role=group. | |
variant | "parentheses" | "column" | "sentence" | "parentheses" | Parentheses hold the set and hairlines stand between. Column stacks the actions as a narrow ragged column; pointing hangs a short heavy dash in the margin beside one. Sentence writes them into running text as a list (copy the link, email it, or export a PDF), each on a pencil hairline that the ink passes through. |
conjunction | string | "or" | In a sentence, the word before the last action. Use and, or the page's own language. |
children | Button[] | The actions. Each Button gives up its own brackets inside the group. |
Craft
Where its move comes from
| Component | Reference | Move |
|---|---|---|
| Button group | 20(25) | Parentheses hold the set; hairlines stand between |
| Column group | "Less is more." corner column; Healthy habits | A ragged column; a heavy dash hung in the margin |
| Sentence group | Healthy habits → (one line of thought); the written list | The actions written into the sentence |
How it moves
| Component | Articulation | What moves |
|---|---|---|
| Button group | Pass-through | The line under an action leaves the way it was heading |
| Column group | Hang | The dash grows out of the word into the margin and goes back into it |