Split Button

One default action with a caret that opens the close alternatives beside it.

chose: send

Build a split button: one default action plus a caret that opens close alternatives. Structure: an inline-flex group with overflow hidden and one shared border, holding a text button, a one-pixel divider, and a caret button. The panel is absolutely positioned under the group, right-aligned. The rule that defines the control: THE DEFAULT STAYS ONE CLICK. The main action is a real button, never the first row of the menu. Fold it in and the common case costs two clicks instead of one, which is the only reason this control exists rather than a plain menu. The panel: transformOrigin top right, aligned to the CARET, entering with opacity, y -6 and scale 0.97 over 180ms on ease [0.22, 1, 0.36, 1]. Grow it from the centre of the whole control and the alternatives look like they belong to the default action rather than to the arrow that opened them. Rotate the caret 180 degrees on open. It is the only piece of state this control has, and without it the arrow is a mystery button. Stagger the rows 30ms apart, entering 4px from the left. Enough to read as a list unfolding, short enough that the third row is not late. Draw the divider between the two halves from your ink token at about 18 percent alpha. Without it the caret reads as part of the label and nobody ever finds the menu. Closing: outside mousedown AND Escape, both removed on cleanup. A menu that only closes by choosing something traps anyone who opened it by accident. Accessibility: aria-expanded on the caret, a real aria-label on it ("More send options"), and the panel as a list of buttons. Under prefers-reduced-motion, fade the panel in with no scale and no stagger, and leave the caret unrotated. Colors as tokens: accent and on-primary ink for the control, surface and border for the panel. Build the component, not this demo of it. - Ambient motion that IS the component may loop: a drifting background, a marquee, a spinner while something is genuinely loading. - Do not add any timer, interval, loop or script that performs a person's action by itself. No auto-hover, no auto-click, no cycling through states, no pretend submitting, no replaying the interaction on a schedule. - Every state that answers a person waits for a real event from that person. - Placeholder copy and sample content are welcome. Simulated behaviour is not.

Rate it
0
0

We'd like to measure how the site gets used, with Google Analytics. It sets cookies. Everything the site needs to work runs either way. How we handle data