SplitButton from @prepared911/ui-core is a primary action paired with a menu trigger in a single visual cluster. The component renders two separate controls; your job is to keep their accessible names distinct and ensure the menu behavior handles focus correctly on open and close.
What the component handles
- Two focusable controls. The primary button and the menu trigger each receive focus on Tab.
- Menu wiring. The chevron trigger opens a Radix-based menu with listbox semantics, focus management, and Escape-to-close.
- Active-item state. Menu items follow the underlying
Menu contract for roving focus.
- Accessible name on the menu trigger. The chevron needs an explicit label ("More save options", "Other actions"). Its name should be distinct from the primary button's label—"Save" and "More save options" aren't confusable.
- Clear primary label. The primary button's label describes its single outcome ("Save draft", "Send reply").
- Destructive items in the menu. Any destructive item in the menu uses destructive styling and hands off to a
Modal confirmation.
- Tab reaches the primary button, then the menu trigger.
- Enter / Space activates the focused control; on the menu trigger, it opens the menu.
- Arrow keys navigate menu items; Escape closes the menu and returns focus to the trigger.
- Primary control → native
<button>.
- Menu trigger → native
<button> with aria-haspopup and aria-expanded reflecting menu state.
- Menu →
role="menu" with role="menuitem" children.
- Visual grouping vs. semantic count. The two controls look like one cluster but behave as two. Don't label only the group; each needs its own name.
- Ambiguity with
Menu alone. If the primary action isn't important enough to warrant a dedicated button, use a plain Menu and promote the primary item inside it.