# Button.Split

A split button that groups a primary action with a dropdown trigger for secondary actions. Supports two modes: **custom** (arbitrary button children) and **strict** (declarative action list with built-in menu).

## When to Use

- Present a default action alongside alternative actions in a compact control
- Allow users to switch between related operations (e.g., deploy targets, save modes)
- Group two or more buttons visually as a single connected unit

## Component

---

## Properties

### Base Properties

Supports [Base properties](../../tasty/tasty.md)

### Styling Properties

#### styles

Customises the root wrapper element of the split button.

### Style Properties

These properties allow direct styling without using the `styles` prop: `width`, `height`.

### Context Inheritance

`type`, `theme`, `size`, and `isDisabled` set on `Button.Split` are inherited by all child `Button` components via context. Explicitly passed props on individual buttons always take precedence.

## Modes

### Strict Mode

Pass an `actions` array to automatically render an action button and a trigger button with a dropdown menu. The trigger displays a `DirectionIcon` pointing down.

Each action object requires `key` and `label`, and inherits all other props from `Menu.Item` (`icon`, `rightIcon`, `description`, `descriptionPlacement`, `prefix`, `suffix`, `hotkeys`, `textValue`, `isDisabled`, `qa`, `styles`, etc.).

```jsx
import { Button } from '@cube-dev/ui-kit';

const actions = [
  { key: 'deploy', label: 'Deploy', icon: <IconSend />, hotkeys: 'Mod+D' },
  { key: 'deploy-staging', label: 'Deploy to Staging', icon: <IconSend />, description: 'Preview environment' },
  { key: 'deploy-preview', label: 'Deploy Preview', icon: <IconPlayerPlay /> },
];

<Button.Split
  actions={actions}
  defaultActionKey="deploy"
  type="primary"
  onAction={(key) => console.log('Executed:', key)}
  onActionChange={(key) => console.log('Switched to:', key)}
/>
```

#### Controlled

Use `actionKey` and `onActionChange` for controlled state.

```jsx
const [currentKey, setCurrentKey] = useState('deploy');

<Button.Split
  actions={actions}
  actionKey={currentKey}
  type="primary"
  onAction={(key) => console.log('Executed:', key)}
  onActionChange={setCurrentKey}
/>
```

### Custom Mode

Pass `children` to render arbitrary buttons with split-group styling (joined radius, collapsed borders). Set `type` and `theme` on the wrapper -- child buttons inherit them via context.

```jsx
import { Button, Menu } from '@cube-dev/ui-kit';
import { DirectionIcon } from '@cube-dev/ui-kit';

<Button.Split type="primary">
  <Button onPress={() => console.log('Save')}>Save</Button>
  <Menu.Trigger placement="bottom end">
    <Button
      aria-label="More save options"
      icon={({ pressed }) => <DirectionIcon to={pressed ? 'up' : 'down'} />}
    />
    <Menu onAction={(key) => console.log(key)}>
      <Menu.Item key="save-draft">Save as Draft</Menu.Item>
      <Menu.Item key="save-publish">Save & Publish</Menu.Item>
    </Menu>
  </Menu.Trigger>
</Button.Split>
```

### Multiple Buttons

More than two buttons are supported. Middle buttons have no border radius.

```jsx
<Button.Split type="outline">
  <Button icon={<IconPlus />}>Add</Button>
  <Button icon={<IconCopy />}>Copy</Button>
  <Button icon={<IconDownload />}>Export</Button>
</Button.Split>
```

## Examples

### Variants

Different types and themes can be applied. All child buttons inherit the styling.

```jsx
<Button.Split actions={actions} defaultActionKey="copy" type="primary" />
<Button.Split actions={actions} defaultActionKey="copy" type="secondary" />
<Button.Split actions={actions} defaultActionKey="copy" type="outline" />
<Button.Split actions={actions} defaultActionKey="copy" type="primary" theme="danger" />
<Button.Split actions={actions} defaultActionKey="copy" type="primary" isDisabled />
```

### Customizing Sub-Components

Use `actionProps`, `triggerProps`, and `menuProps` to customise individual parts in strict mode.

```jsx
<Button.Split
  actions={actions}
  defaultActionKey="deploy"
  type="primary"
  actionProps={{ size: 'large' }}
  triggerProps={{ 'aria-label': 'Select deploy target' }}
  menuProps={{ placement: 'bottom start' }}
/>
```

## Accessibility

### Keyboard Navigation

- `Tab` -- Moves focus between the action button and the trigger button.
- `Space` / `Enter` -- Activates the focused button. On the trigger, opens the dropdown menu.
- `Arrow Down` -- When the menu is open, navigates menu items.
- `Escape` -- Closes the dropdown menu and returns focus to the trigger.

### Screen Reader Support

- The action button announces its label.
- The trigger button has `aria-label="More options"` by default (override via `triggerProps`).
- The dropdown menu announces selection changes.

### ARIA Properties

- `aria-label` -- Provide on the trigger for context (e.g., "Select deploy target").
- Menu items support `aria-disabled` via the `isDisabled` property on actions.

## Best Practices

1. **Do**: Use strict mode for standard action+trigger patterns.
   ```jsx
   <Button.Split actions={actions} defaultActionKey="deploy" type="primary" />
   ```

2. **Do**: Set `type` and `theme` on the wrapper instead of repeating on each child.
   ```jsx
   <Button.Split type="primary">
     <Button>Save</Button>
     <Button icon={<DirectionIcon to="down" />} aria-label="Options" />
   </Button.Split>
   ```

3. **Don't**: Mix `actions` prop with `children`. Use one mode or the other.

4. **Accessibility**: Always provide `aria-label` on icon-only trigger buttons.

## Suggested Improvements

- Support `isLoading` on the action button in strict mode.
- Add keyboard shortcut display in menu items via `hotkeys` prop.

## Related Components

- [Button](./Button.md) -- Standalone action button.
- [Menu](./Menu.md) -- Dropdown menu for action lists.
- Button.Group -- Layout wrapper for spacing multiple buttons.
