Split Button

Primary action plus dropdown actions.

html

<div class="split-btn" style="--bg:#241430;border-radius:8px">
  <button type="button" class="split-btn__main">Save</button>
  <button type="button" class="split-btn__caret" aria-label="More save options" aria-haspopup="menu" aria-expanded="false">
    <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M6 9l6 6 6-6"/></svg>
  </button>
</div>
<style>
.split-btn { display: inline-flex; overflow: hidden; }
.split-btn__main, .split-btn__caret {
  font: 600 15px/1 system-ui, sans-serif;
  border: none;
  background: var(--bg);
  color: #FAF7F2;
  cursor: pointer;
}
.split-btn__main { padding: 11px 18px; }
.split-btn__caret { padding: 11px 12px; border-left: 1px solid rgba(250,247,242,.3); display: inline-flex; align-items: center; }
.split-btn__main:hover:not(:disabled), .split-btn__caret:hover:not(:disabled) { filter: brightness(1.12); }
.split-btn__caret[aria-expanded="true"] { filter: brightness(0.85); }
.split-btn__main:focus-visible, .split-btn__caret:focus-visible { outline:2px solid #241430;outline-offset:2px; position: relative; z-index: 1; }
.split-btn__main:disabled, .split-btn__caret:disabled { opacity: .45; cursor: not-allowed; }
</style>

tailwind

<div class="inline-flex overflow-hidden split-btn-tw" style="border-radius:8px">
  <button type="button" class="px-4.5 py-2.75 text-sm font-semibold text-[#FAF7F2] border-none cursor-pointer disabled:opacity-45 disabled:cursor-not-allowed hover:brightness-110" style="background:#241430">Save</button>
  <button type="button" class="inline-flex items-center px-3 py-2.75 text-[#FAF7F2] border-none cursor-pointer disabled:opacity-45 disabled:cursor-not-allowed hover:brightness-110 split-btn-tw__caret" style="background:#241430;border-left:1px solid rgba(250,247,242,.3)" aria-label="More save options" aria-haspopup="menu" aria-expanded="false">
    <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M6 9l6 6 6-6"/></svg>
  </button>
</div>
<style>
.split-btn-tw__caret[aria-expanded="true"] { filter: brightness(0.85); }
.split-btn-tw button:focus-visible { outline:2px solid #241430;outline-offset:2px; position: relative; z-index: 1; }
</style>

react

export function SplitButton({
  label = "Save",
  open = false,
  bg = "#241430",
  radius = 8,
  disabled = false,
}) {
  const base = {
    border: "none",
    background: bg,
    color: "#FAF7F2",
    font: "600 15px/1 system-ui, sans-serif",
    cursor: disabled ? "not-allowed" : "pointer",
    opacity: disabled ? 0.45 : 1,
  };
  return (
    <div style={{ display: "inline-flex", overflow: "hidden", borderRadius: radius }}>
      <button type="button" disabled={disabled} style={{ ...base, padding: "11px 18px" }}>
        {label}
      </button>
      <button
        type="button"
        disabled={disabled}
        aria-label="More save options"
        aria-haspopup="menu"
        aria-expanded={open}
        style={{
          ...base,
          padding: "11px 12px",
          borderLeft: "1px solid rgba(250,247,242,.3)",
          filter: open ? "brightness(0.85)" : "none",
        }}
      >
        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
          <path d="M6 9l6 6 6-6" />
        </svg>
      </button>
    </div>
  );
}