Skip to content

HySplitButton ​

Usage examples on this page are written for Lit / plain HTML (<hy-split-button>). The same component ships as HySplitButton in @whitespaceux/harmony-react (native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.

A main action and a chevron that opens a menu of related actions, joined into one control ("Save ▾" — Save as…, Save a copy). Composes two hy-buttons and an hy-menu-button; it adds the joined geometry, the seam between the segments and one variant / emphasis / size / disabled for both.

Key Features ​

  • Two real buttons, two Tab stops: the main action and a menu button named by menu-label ("More save options")
  • Inner corners square, outer corners the design system's button corners
  • The seam is geometry: a shared border when outlined, a hairline gap otherwise
  • The menu takes hy-menu-button's items, actions, select / change, show / hide
  • Inside hy-toolbar both segments are arrow stops of the toolbar

Split button or menu button? ​

A split button when one action is the usual choice and the menu holds its variations; hy-menu-button when no action is the default, so nobody runs the wrong one by habit. Keep destructive actions off the main segment.

Events ​

The main action fires activate — a plain click on the host can't tell the two segments apart. Menu items fire select (and change for radio groups).

When to use

  • A main action that has a few variations people sometimes need: Save, with Save as… and Save a copy.
  • A default choice most people take, with the alternatives one click away.

Do

  • Put the most used variation on the main part.
  • Keep the menu to variations of the same action.

When not to use

  • Only one action: hy-button.
  • Actions that are not variations of one another, such as Save and Delete: separate hy-buttons, or a button and a hy-menu-button.
  • Picking a value a form reads, such as a format: hy-select or hy-combobox.

Examples ​

Save with more save options ​

html
<hy-split-button label="Save" menu-label="More save options" variant="brand">
  <hy-menu-item value="save-as" label="Save as…"></hy-menu-item>
  <hy-menu-item value="save-copy" label="Save a copy"></hy-menu-item>
</hy-split-button>

API ​

Properties ​

PropertyAttributeTypeDefaultDescription
labellabelstring''The main action's visible text. Required.
menuLabelmenu-labelstring'More options'The chevron segment's accessible name — name the action ("More save options").
variantvariant'neutral' | 'brand' | 'success' | 'warning' | 'danger' | 'info' | 'highlight''neutral'Semantic role of both segments — hy-button's role set.
emphasisemphasis'solid' | 'soft' | 'outlined' | 'tinted''solid'Visual chrome weight of both segments. No plain (it renders outlined, with a dev warning).
sizesize'small' | 'medium' | 'large''medium'Size of both segments; the menu takes small or medium.
disableddisabledbooleanfalseDisables both segments.
loadingloadingbooleanfalseThe main action is busy: its spinner shows, and both segments are inert.
loadingTextloading-textstring'Loading'Text announced while loading — passed to the main action's hy-button loading-text. Use for internationalization.
typetype'button' | 'submit' | 'reset''button'What the main action does in a form. The chevron never submits.
formformstring | undefined—The id of the form a submit or reset main action acts on when the split button sits outside it — a dialog footer, a toolbar — as hy-button's form. Unset, the main action acts on the form it is inside. The host is form-associated, so the browser resolves it (internals.form).
placementplacement'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'right' | 'right-start' | 'right-end''bottom-end'Where the menu opens, relative to the chevron.
widthwidthstring''Fixed menu-panel width (any CSS length).
minWidthmin-widthstring''Minimum menu-panel width.
openopenbooleanfalseControlled menu state.
actions—MenuAction[][]Items from data, when the default slot is empty — slotted items win.
fullWidthfull-widthbooleanfalseThe main segment grows to fill the host; the chevron keeps its width.

Events ​

EventDetailDescription
activate—The main action was clicked or pressed. Detail: HyClickDetail
select—A menu item was chosen (relayed from the menu). Detail: MenuSelectDetail
change—A menu radio group changed (relayed). Detail: MenuChangeDetail
show—The menu opened (does not bubble)
hide—The menu closed (does not bubble)

Slots ​

SlotDescription
defaulthy-menu-item / hy-menu-item-checkbox / hy-menu-item-radio / hy-menu-group / hy-divider children
prefixAn icon before the main action's label

CSS Parts ​

PartDescription
baseThe wrapper around the two segments
primaryThe main action (hy-button)
triggerThe chevron segment (hy-button)

CSS Custom Properties ​

The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.

PropertyDefaultDescription
--hy-split-button-stroke-smvar(--hy-stroke-sm)The seam: the gap between the segments (solid, soft, tinted) or their shared border (outlined)
--hy-split-button-effect-glowonThe glow around the whole control (solid brand and highlight); the segments draw none
--hy-split-button-radius-action-md-top-startvar(--hy-radius-action-md-top-start)The control's outer corner the glow follows (top-start; also top-end, bottom-start, bottom-end)

Methods ​

focus() ​

Focuses the main action.

Built with Lit. Documented with VitePress.