Skip to content
NewService Map: 30 components for hosts, ports and routes
<hf-split>Custom elementInputsFree

Split button

Split button with a primary action and a menu of alternatives; choosing an item rolls its label into the main button.

View as Markdown
<hf-split>

Tryopen the menu and pick “Create preview”.

Playground

Change a prop and the component updates. Props marked live animate to the new value; the others rebuild the element.

Loading <hf-split>
Props
itemsremounts
<HfSplit
  items="Deploy to production|Ships to everyone after checks;Deploy to staging|Internal testers only;Create preview|A unique URL for this branch;Schedule deploy…|Pick a time tonight"
/>

Installation

pnpm dlx shadcn@latest add @lumesec/hf-split
First timeRegister the @lumesec registry once, or install by URL+

Adds @lumesec to your components.json:

pnpm dlx shadcn@latest registry add @lumesec=https://elements.lumesec.ai/r/{name}.json

Or skip the setup and install by URL:

npx shadcn@latest add https://elements.lumesec.ai/r/hf-split.json

Usage

import { HfSplit } from "@/components/lumesec/hf-split";

export function Example() {
  return (
    <HfSplit items="Deploy to production|Ships to everyone;Deploy to staging|Internal testers only" />
  );
}

Behaviour

A primary action with a menu of alternatives. Rows sweep in, a highlight springs between them, and choosing one rolls it into the main button.

API reference

Attributes

itemsReact propitemsTypestringDefaultDeploy to production|Ships to everyone after checks;Deploy to staging|Internal testers only;Create preview|A unique URL for this branch;Schedule deploy…|Pick a time tonight

Menu entries separated by ;, each Label|Description with an optional description. The first entry starts selected. The menu is built once on connect.

Events

Events bubble and cross the shadow boundary unless the description says otherwise.

actionReact proponActionDetail{ value: string }

Fires when the main button is clicked. value is the selected item's label.

selectReact proponSelectDetail{ value: string }

Fires when an item is chosen from the menu. value is its label.

Methods

Call them on the element, for example through a React ref.

toggle(force?: boolean)

Opens or closes the menu: true opens, false closes, no argument toggles. Opening focuses the selected item.

Properties

items (read-only)Type{ label: string; desc: string }[]

The parsed items.

Keyboard

KeysAction
ArrowDownOn the caret button: open the menu and focus the selected item.
ArrowDown / ArrowUpIn the menu: move focus to the next or previous item, wrapping.
EscapeIn the menu: close it and return focus to the caret button.
TabIn the menu: close it and move focus on.

Accessibility

  • The caret button has aria-haspopup="menu", aria-expanded and a fixed aria-label="More deploy options".
  • The menu has role="menu"; items are buttons with role="menuitemradio", aria-checked on the current choice and tabindex="-1".
  • Choosing an item closes the menu and returns focus to the caret button. A pointer press outside the element also closes the menu.
  • Effects are drawn on an aria-hidden canvas.
  • Reduced motion: the button's drifting noise stops, menu rows appear without the sweep, the highlight jumps between rows and the label changes without rolling.

Theming

The element reads your shadcn theme tokens through its shadow root, so light and dark follow your theme. The accent comes from --lumesec. See Theming.

This component reads --border, --card, --foreground, --lumesec and --muted-foreground.

To restyle only LumeSec elements, set the matching --ui-* overrides: --ui-accent, --ui-border, --ui-fg, --ui-muted and --ui-surface.

Notes

  • The host carries an open attribute while the menu is open, usable for styling. Setting it yourself does not open the menu; call toggle().
  • The menu is absolutely positioned below the button, up to 320px wide, and overlaps the content that follows.
  • The main button is at least 200px wide and 46px tall.

Was this page helpful?