AZMARA PLATFORM
Components

SplitButton

A primary action with a menu of related actions attached. Button plus DropdownMenu.

Usage

import { SplitButton } from "@azmr/ui/split-button";
import { DropdownMenuItem } from "@azmr/ui/menu";
Preview theme
Preview density

Nothing saved yet

"use client";

import { DropdownMenuItem, DropdownMenuSeparator } from "@azmr/ui/menu";
import { SplitButton } from "@azmr/ui/split-button";
import { useState } from "react";

export default function SplitButtonBasic() {
  const [last, setLast] = useState("Nothing saved yet");
  return (
    <div className="flex items-center gap-4">
      <SplitButton
        menuLabel="More save options"
        onClick={() => setLast("Saved")}
        menu={
          <>
            <DropdownMenuItem onClick={() => setLast("Saved as a new file")}>
              Save as…
            </DropdownMenuItem>
            <DropdownMenuItem onClick={() => setLast("Saved a copy")}>Save a copy</DropdownMenuItem>
            <DropdownMenuSeparator />
            <DropdownMenuItem onClick={() => setLast("Saved and closed")}>
              Save and close
            </DropdownMenuItem>
          </>
        }
      >
        Save
      </SplitButton>
      <SplitButton
        variant="outline"
        menuLabel="More export options"
        menu={<DropdownMenuItem>PDF</DropdownMenuItem>}
      >
        Export
      </SplitButton>
      <p className="text-sm text-muted-foreground" aria-live="polite">
        {last}
      </p>
    </div>
  );
}
<SplitButton
  menuLabel="More save options"
  onClick={save}
  menu={
    <>
      <DropdownMenuItem onClick={saveAs}>Save as…</DropdownMenuItem>
      <DropdownMenuItem onClick={saveCopy}>Save a copy</DropdownMenuItem>
    </>
  }
>
  Save
</SplitButton>

The main button runs the common action. The arrow opens a menu of alternatives, so the common case stays one click. menu takes any DropdownMenu parts: items, separators, groups, even checkbox items.

menuLabel is required. The arrow button has no text, so it needs a name ("More save options"), and the types enforce it. The arrow also announces that it opens a menu (aria-haspopup, aria-expanded).

Props

variant and size apply to both halves, so the pair stays level; filled variants get a divider between them and outline shares one border.

  • loading shows a spinner on the main button and ignores it, while the menu stays usable: a slow "Save" should not stop someone choosing "Save as…". loadingText and startIcon work as on Button.
  • disabled disables both halves.

Everything else a Button accepts (onClick, type, aria-*) goes to the main button.

Keyboard

Keyboard interactions
KeyAction
TabMoves to the main button, then to the arrow button.
EnterorSpaceOn the main button: runs the primary action. On the arrow: opens the menu.
ArrowDownOn the arrow button: opens the menu on its first item.
EscapeCloses the menu and returns focus to the arrow button.

Once the menu is open it follows the DropdownMenu keys.

Size

The menu is loaded with the split button, so this entry carries the menu's cost (about the same as @azmr/ui/menu). If a page only needs a plain Button, import that instead.

On this page