# Split Button

Main action joined to a menu of alternatives. Used as a picker, choosing an option swaps the main label in place, and a finished state fuses both halves into one pill with a check.

> Composed · Pro · Actions — React Native, Expo Go compatible.

## Install

```bash
npx @lumioui/cli add pro/split-button
```

## Import

```tsx
import { SplitButton } from "@/components/ui/split-button/split-button";
```

## Variants

- `export` — Export: `npx @lumioui/cli add pro/split-button-export`
- `merge` — Merge: `npx @lumioui/cli add pro/split-button-merge`
- `send` — Schedule send: `npx @lumioui/cli add pro/split-button-send`

## Props

| Prop | Type | Notes |
| --- | --- | --- |
| `label?` | `string` | Primary label (actions mode, or select mode before anything is picked). |
| `icon?` | `React.ReactNode` | Leading icon element for the primary segment. |
| `options` | `SplitButtonOption[]` | Menu options. |
| `value?` | `string` | Controlled selected option — turns on select mode. |
| `defaultValue?` | `string` | Uncontrolled initial selection — turns on select mode. |
| `onValueChange?` | `(value: string) => void` | Fires when an option is picked in select mode. |
| `onSelect?` | `(value: string) => void` | Fires when a menu item is picked in actions mode. |
| `onPress?` | `(value: string | undefined) => void | Promise<unknown>` | Primary action. Receives the selected value in select mode. Return a promise for a loading state. |
| `variant?` | `"default" | "secondary" | "outline"` | Visual style. Default "default" (accent/ink fill). |
| `size?` | `"sm" | "md" | "lg"` | sm 36 · md 44 · lg 56. Default "md". |
| `fullWidth?` | `boolean` | Stretch the primary segment to fill the row. |
| `loading?` | `boolean` | Force the primary segment into its loading state. |
| `disabled?` | `boolean` | — |
| `menuLabel?` | `string` | Accessibility label for the menu segment. Default "More options". |
| `open?` | `boolean` | Controlled menu open state. |
| `onOpenChange?` | `(open: boolean) => void` | — |
| `sealed?` | `boolean` | Commit performed on the object: the segments fuse into one pill, a check draws and the label swaps to `sealedLabel`, one sheen crosses, then a 700ms hold before `onSettled`. Presses are blocked while sealed. |
| `sealedLabel?` | `string` | Label on the fused pill. Default "Done". |
| `settledLabel?` | `string` | After the hold, the pill dims to a quiet secondary fill reading this  (e.g. "Merged · squash · just now"). Omit to stay on `sealedLabel`. |
| `onSettled?` | `() => void` | Fires once the sealed result has held. |
| `className?` | `string` | — |

## Icons rendered

- `check` — /icons.html?i=check
- `chevron-down` — /icons.html?i=chevron-down

Source: https://lumioui.com/components/split-button