Split Button
A compound button with a primary action and a dropdown trigger for secondary options
Playground
Installation
pnpm add @tessinaui/uiUsage
import { SplitButton } from "@tessinaui/ui";<SplitButton label="Create project">
<SplitButton.Item>Blank project</SplitButton.Item>
<SplitButton.Item>Use a template</SplitButton.Item>
</SplitButton>Examples
Default
A basic split button with a primary action and a dropdown of secondary options.
Variants
Four visual styles — primary, secondary, ghost, and outline.
Intents
Semantic color intents for the primary action — error, warning, success, and info.
Sizes
Five sizes from xs to xl; xs through lg shown here.
With Icon
A leading icon rendered before the label.
States
Disabled and loading states applied to both the action and the dropdown trigger.
API Reference
SplitButton Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Text label for the primary action button |
variant | "primary" | "secondary" | "ghost" | "outline" | "on-color" | "primary" | Visual style variant |
intent | "none" | "error" | "warning" | "success" | "info" | "none" | Semantic color intent |
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | Size of the button |
rounded | "full" | "lg" | "md" | "sm" | "none" | "full" | Border radius style |
leadingIcon | React.ReactNode | — | Icon rendered before the label |
trailingIcon | React.ReactNode | — | Icon rendered after the label |
onClick | MouseEventHandler | — | Handler for the primary action click |
disabled | boolean | false | Disables both action and dropdown trigger |
loading | boolean | false | Shows a spinner in the action section |
open | boolean | — | Controlled open state of the dropdown |
onOpenChange | (open: boolean) => void | — | Called when dropdown open state changes |
dropdownAlign | "start" | "center" | "end" | "end" | Alignment of the dropdown menu |
children | React.ReactNode | — | Dropdown menu items |
SplitButton.Item Props
Extends @radix-ui/react-dropdown-menu Item props.
| Prop | Type | Description |
|---|---|---|
disabled | boolean | Disables the menu item |
onSelect | (event: Event) => void | Called when item is selected |
SplitButton.Separator
A horizontal line divider between menu items. No additional props.
SplitButton.Label
A non-interactive label for grouping items.
Sizes
| Size | Height | Use case |
|---|---|---|
xs | 32px | Compact toolbars |
sm | 40px | Secondary actions |
md | 48px | Default, most use cases |
lg | 56px | Prominent actions |
xl | 96px | Hero / landing page CTAs |
Accessibility
The Split Button component:
- Two focusable buttons — action button and dropdown trigger — each with their own
Tabstop - Dropdown trigger has
aria-label="More options" - Uses Radix UI's
DropdownMenuprimitive for full keyboard navigation (arrow keys,Enter,Escape) - Focus ring on both buttons (
focus-visible:ring-2) meets WCAG 2.1 AA disabledpropagates to both sections and setspointer-events-nonearia-disabledis set automatically by Radix when the trigger is disabled
Spinner
Animated loading indicators with ring, dots, and pulse variants, five sizes, intent colors including brand primary, optional track, label positions, and LTR/RTL support.
Stack
A flex-based layout primitive for arranging items in a row or column. Configurable direction, gap, alignment, justification, wrapping, reversal, dividers, inline display, polymorphic rendering, and LTR/RTL support. Ships with HStack and VStack convenience wrappers.