> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# SplitButton

Pairs one action with a menu of related ones, for when a second action matters enough that burying it in a `DropdownMenu` would hide it. Both halves are ordinary `Button`s, so they must share a variant, colour and size — the group only joins their facing corners.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/SplitButton) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/actions-splitbutton--overview)

```tsx
import { Button } from '@wallarm-org/design-system/Button';
import { ChevronDown } from '@wallarm-org/design-system/icons';
import { SplitButton } from '@wallarm-org/design-system/SplitButton';

export const Default = () => (
  <SplitButton data-testid='split-button'>
    <Button variant='primary' color='brand'>
      Button
    </Button>
    <Button variant='primary' color='brand'>
      <ChevronDown />
    </Button>
  </SplitButton>
);
```

## Usage

```tsx
import { Button } from '@wallarm-org/design-system/Button';
import { ChevronDown } from '@wallarm-org/design-system/icons';
import { SplitButton } from '@wallarm-org/design-system/SplitButton';
```

## Examples

### Variants

Every sanctioned pairing, and the reason the pair must match: outline buttons drop the
gap and overlap their borders into a single hairline, which only looks right when both halves
carry the same variant.

```tsx
import { Button } from '@wallarm-org/design-system/Button';
import { ChevronDown } from '@wallarm-org/design-system/icons';
import { SplitButton } from '@wallarm-org/design-system/SplitButton';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const Variants = () => (
  <VStack>
    <HStack>
      <SplitButton>
        <Button variant='primary' color='brand'>
          Button
        </Button>
        <Button variant='primary' color='brand'>
          <ChevronDown />
        </Button>
      </SplitButton>
    </HStack>
    <HStack>
      <SplitButton>
        <Button variant='outline' color='neutral'>
          Button
        </Button>
        <Button variant='outline' color='neutral'>
          <ChevronDown />
        </Button>
      </SplitButton>
    </HStack>
    <HStack>
      <SplitButton>
        <Button variant='secondary' color='neutral'>
          Button
        </Button>
        <Button variant='secondary' color='neutral'>
          <ChevronDown />
        </Button>
      </SplitButton>
    </HStack>
    <HStack>
      <SplitButton>
        <Button variant='ghost' color='neutral'>
          Button
        </Button>
        <Button variant='ghost' color='neutral'>
          <ChevronDown />
        </Button>
      </SplitButton>
    </HStack>
    <HStack>
      <SplitButton>
        <Button variant='secondary' color='brand'>
          Button
        </Button>
        <Button variant='secondary' color='brand'>
          <ChevronDown />
        </Button>
      </SplitButton>
    </HStack>
    <HStack>
      <SplitButton>
        <Button variant='ghost' color='brand'>
          Button
        </Button>
        <Button variant='ghost' color='brand'>
          <ChevronDown />
        </Button>
      </SplitButton>
    </HStack>
    <div className='flex flex-col gap-16 rounded-lg bg-component-tooltip-bg p-8'>
      <HStack>
        <SplitButton>
          <Button variant='ghost' color='neutral-alt'>
            Button
          </Button>
          <Button variant='ghost' color='neutral-alt'>
            <ChevronDown />
          </Button>
        </SplitButton>
      </HStack>
    </div>
    <div className='flex flex-col gap-16 rounded-lg bg-component-tooltip-bg p-8'>
      <HStack>
        <SplitButton>
          <Button variant='secondary' color='neutral-alt'>
            Button
          </Button>
          <Button variant='secondary' color='neutral-alt'>
            <ChevronDown />
          </Button>
        </SplitButton>
      </HStack>
    </div>
  </VStack>
);
```

### Sizes

Both halves take the same `size`, since the group aligns them rather than sizing them.

```tsx
import { Button } from '@wallarm-org/design-system/Button';
import { ChevronDown } from '@wallarm-org/design-system/icons';
import { SplitButton } from '@wallarm-org/design-system/SplitButton';
import { HStack } from '@wallarm-org/design-system/Stack';

export const Sizes = () => (
  <HStack align='end' justify='center'>
    <SplitButton>
      <Button variant='primary' color='brand' size='small'>
        Small
      </Button>
      <Button variant='primary' color='brand' size='small'>
        <ChevronDown />
      </Button>
    </SplitButton>
    <SplitButton>
      <Button variant='primary' color='brand' size='medium'>
        Medium
      </Button>
      <Button variant='primary' color='brand' size='medium'>
        <ChevronDown />
      </Button>
    </SplitButton>
    <SplitButton>
      <Button variant='primary' color='brand' size='large'>
        Large
      </Button>
      <Button variant='primary' color='brand' size='large'>
        <ChevronDown />
      </Button>
    </SplitButton>
  </HStack>
);
```

### Content

Text, icon-and-text, and icon-only leading halves. The trailing half stays a bare
chevron — giving it a label doubles the width and makes the menu look like a second action.

```tsx
import { Button } from '@wallarm-org/design-system/Button';
import { ChevronDown, CircleDashed } from '@wallarm-org/design-system/icons';
import { NumericBadge } from '@wallarm-org/design-system/NumericBadge';
import { SplitButton } from '@wallarm-org/design-system/SplitButton';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const Content = () => (
  <VStack>
    <HStack align='end'>
      <SplitButton>
        <Button variant='primary' color='brand' size='large'>
          Large
        </Button>
        <Button variant='primary' color='brand' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
      <SplitButton>
        <Button variant='outline' color='neutral' size='large'>
          Large
        </Button>
        <Button variant='outline' color='neutral' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
      <SplitButton>
        <Button variant='secondary' color='neutral' size='large'>
          Large
        </Button>
        <Button variant='secondary' color='neutral' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
    </HStack>
    <HStack align='end'>
      <SplitButton>
        <Button variant='primary' color='brand' size='large'>
          <CircleDashed />
          Large
        </Button>
        <Button variant='primary' color='brand' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
      <SplitButton>
        <Button variant='outline' color='neutral' size='large'>
          <CircleDashed />
          Large
        </Button>
        <Button variant='outline' color='neutral' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
      <SplitButton>
        <Button variant='secondary' color='neutral' size='large'>
          <CircleDashed />
          Large
        </Button>
        <Button variant='secondary' color='neutral' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
    </HStack>
    <HStack align='end'>
      <SplitButton>
        <Button variant='primary' color='brand' size='large'>
          <CircleDashed />
          Large
          <NumericBadge type='outline'>1</NumericBadge>
        </Button>
        <Button variant='primary' color='brand' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
      <SplitButton>
        <Button variant='outline' color='neutral' size='large'>
          <CircleDashed />
          Large
          <NumericBadge type='outline'>1</NumericBadge>
        </Button>
        <Button variant='outline' color='neutral' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
      <SplitButton>
        <Button variant='secondary' color='neutral' size='large'>
          <CircleDashed />
          Large
          <NumericBadge type='outline'>1</NumericBadge>
        </Button>
        <Button variant='secondary' color='neutral' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
    </HStack>
    <HStack align='end'>
      <SplitButton>
        <Button variant='primary' color='brand' size='large'>
          <CircleDashed />
        </Button>
        <Button variant='primary' color='brand' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
      <SplitButton>
        <Button variant='outline' color='neutral' size='large'>
          <CircleDashed />
        </Button>
        <Button variant='outline' color='neutral' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
      <SplitButton>
        <Button variant='secondary' color='neutral' size='large'>
          <CircleDashed />
        </Button>
        <Button variant='secondary' color='neutral' size='large'>
          <ChevronDown />
        </Button>
      </SplitButton>
    </HStack>
  </VStack>
);
```

### With dropdown menu

The real shape: the leading half performs the default action, and only the chevron opens
the menu. Repeat the default inside the menu only if its wording differs there.

```tsx
import { Button } from '@wallarm-org/design-system/Button';
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@wallarm-org/design-system/DropdownMenu';
import { ChevronDown } from '@wallarm-org/design-system/icons';
import { SplitButton } from '@wallarm-org/design-system/SplitButton';

export const WithDropdownMenu = () => (
  <DropdownMenu>
    <SplitButton data-testid='split-button-dropdown'>
      <Button variant='primary' color='brand'>
        Save
      </Button>
      <DropdownMenuTrigger asChild>
        <Button variant='primary' color='brand'>
          <ChevronDown />
        </Button>
      </DropdownMenuTrigger>
    </SplitButton>
    <DropdownMenuContent>
      <DropdownMenuItem value='draft'>Save as draft</DropdownMenuItem>
      <DropdownMenuItem value='publish'>Save and publish</DropdownMenuItem>
      <DropdownMenuItem value='template'>Save as template</DropdownMenuItem>
    </DropdownMenuContent>
  </DropdownMenu>
);
```

## Props

| Prop           | Type                                                 | Default | Description |
| -------------- | ---------------------------------------------------- | ------- | ----------- |
| defaultChecked | `boolean \| undefined`                               |         |             |
| defaultValue   | `string \| number \| readonly string[] \| undefined` |         |             |
| autoFocus      | `boolean \| undefined`                               |         |             |
| id             | `string \| undefined`                                |         |             |
| tabIndex       | `number \| undefined`                                |         |             |
| title          | `string \| undefined`                                |         |             |
| rel            | `string \| undefined`                                |         |             |
| onChange       | `ChangeEventHandler<T, Element> \| undefined`        |         |             |
| data-testid    | `string \| undefined`                                |         |             |
