Components / Actions
SplitButton
A primary action with a menu of nearby alternatives.
Install
npx shadcn@latest add https://irisui.dev/r/split-button.jsonimport { SplitButton } from "@/components/iris/split-button/split-button";Preview
SplitButton
A primary action joined to a chevron that opens a menu of nearby alternatives, such as Publish with "Schedule for later".
When to use
- One action is clearly the default, but a few close variants should stay one click away (publish now / schedule / publish to staging).
- When the main label changes after a press ("Copy page" to "Copied"): shared letters stay put and only the changed ones morph.
- For unrelated actions with no default, use
DropdownMenu. For several equal-weight actions in a row, useButtonGroup.
Usage
import { SplitButton } from "@/components/iris/split-button/split-button";
<SplitButton
label="Publish"
icon={<SendIcon size={16} />}
onClick={publish}
actions={[
{ label: "Schedule for 14:00", icon: <ClockIcon size={16} />, onSelect: schedule },
{ label: "Send back to review", onSelect: sendToReview },
{ label: "Discard draft", destructive: true, onSelect: discard },
]}
/>;
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label |
string |
— | Main action label (required). Changing it morphs letter by letter. |
actions |
SplitButtonAction[] |
— | Menu items (required): { label, onSelect?, disabled?, destructive?, icon? }. |
onClick |
() => void |
— | Runs the main action. |
icon |
ReactNode |
— | Icon before the label; swapping to a different icon element crossfades it. |
variant |
"primary" | "secondary" |
"primary" |
Filled or outlined surface. |
disabled |
boolean |
— | Disables both halves. |
Notes
- The menu is a Radix dropdown: it opens on press or Enter/Space/ArrowDown, loops with the arrow keys, closes on Escape, and returns focus to the chevron. The chevron is labelled "
{label}more actions". - The main label is mirrored into a polite live region, so a morph such as "Copied" is announced.
- The menu portals to
<body>, aligns to the group's end edge with a 4px offset, and keeps 12px from the viewport edge. - The chevron half never scales on press, so the menu always anchors to a still trigger. Reduced motion turns the glyph morph into instant fades.