Navigation
SplitButton
Primary action button with an attached toggle that opens a menu of secondary actions.
Import
import { SplitButton } from "@zephora/react";Examples
Basic
`onClick` fires the primary action; `onSelect` receives a menu value.
Last: none
const [last, setLast] = React.useState("none");
<SplitButton
onClick={() => setLast("save")}
onSelect={setLast}
actions={[
{ label: "Save as draft", value: "draft" },
{ label: "Duplicate", value: "duplicate" },
{ label: "Delete", value: "delete", danger: true },
]}
>
Save
</SplitButton>
<p>Last: {last}</p>Variants and sizes
Both buttons share the Button `variant` and `size` scales.
<SplitButton variant="outline" size="sm" actions={[{ label: "Export CSV", value: "csv" }]}>
Export
</SplitButton>
<SplitButton variant="soft" size="lg" actions={[{ label: "Publish later", value: "later" }]}>
Publish
</SplitButton>API
SplitButton props
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | — | Primary button label. |
onClick | MouseEventHandler<HTMLButtonElement> | — | Primary action. |
actions * | Array<{ label: string; value: string; disabled?: boolean; danger?: boolean }> | — | Entries of the dropdown action menu. |
onSelect | (value: string) => void | — | Called with the picked action's value. |
variant | ButtonVariant | "solid" | Visual style of both buttons. |
size | "sm" | "md" | "lg" | "md" | Size of both buttons. |
disabled | boolean | false | Disables the primary button and the menu toggle. |
placement | Placement | "bottom-end" | Menu placement relative to the group. |
unstyled | boolean | false | Headless mode — skips Zephora styling. |
Keyboard
| Key | Action |
|---|---|
ArrowDown | On the toggle: opens the menu and focuses the first action. |
ArrowDown / ArrowUp | Move between enabled actions inside the menu. |
Home / End | Jump to the first / last enabled action. |
Enter / Space | Picks the active action and closes the menu. |
Escape / Tab | Closes the menu and refocuses the toggle. |