Skip to content

No.527 · Micro-animations· New

Reaction Pill

A reaction button that opens a pill of six coloured reactions. The discs swell like a dock as you move along them, each names itself, and picking one pops it into the button while the count beside it updates — all optimistic, and put back if saving fails.

The prompt

Copy this text

Automatic copying is unavailable. Copy the selected text using your device’s copy command.

Written for the variant you picked above: Night

Build a reaction picker. Props: reactions [{id, label, color, icon}] (default six: Like blue, Cheer green, Support violet, Love red, Insight amber, Laugh teal, each a white line icon), counts, value (the viewer's reaction), onChange (a promise) and theme. A 54px rounded-square trigger shows the first reaction's icon in a muted colour, or the viewer's reaction in its colour; beside it, up to three overlapping 22px discs of the most used reactions and the total. Clicking the trigger toggles the first reaction. Pointing at it for 380ms, a long press on touch (420ms, without the context menu) or ↑ on the keyboard opens the pill above it: a dark capsule with 52px discs (each a radial gradient of its colour with a white icon) that springs open from the trigger's corner and pops its discs in with a 30ms stagger. While the pointer moves along the pill, each disc scales by 1 + 0.42 × a Gaussian of its distance from the pointer (64px reach), growing from its base and lifting, like a dock; a dark label pill appears above the disc under the pointer or focus. The viewer's current reaction has a small dot under it. Picking a reaction (or picking the current one again to remove it) closes the pill, pops the new icon into the trigger with a slight overshoot and rotation, and updates the counts at once: the old reaction loses one and the new one gains one. onChange runs afterwards; if it rejects, the reaction and counts go back and a status line says so. The pill is a menu of menuitemradio buttons with arrow-key navigation, Home and End, and Escape (which returns focus to the trigger); the trigger has aria-haspopup, aria-expanded and aria-keyshortcuts. Leaving the pill closes it after 260ms. Reduced motion keeps only fades. Selected variant — Night (night): Palette for this theme (Night): --rpill-btn #1c1c1e; --rpill-edge rgba(255, 255, 255, 0.08); --rpill-ink #f2f2f0; --rpill-muted #a5a5a0; --rpill-pill #1a1a1b. Treat these as the root colour tokens, one value per role, and name them to suit your code. Select it with the theme option set to "night". Keep every dimension, spacing value, state and motion from the brief unchanged, and keep text at 4.5:1 contrast or better on these surfaces. This selection takes precedence over references to other themes or options in the general brief. Implement this selected appearance; do not add a variant picker or alternative appearances unless requested. Implementation requirements: Use React and TypeScript. Keep the component self-contained, with uniquely scoped CSS and no animation libraries. Include required imports, styles and font setup in the result. Interaction: Click the button to like; point at it, long-press, or press ↑ to open the reactions; move along them and pick one. Arrow keys move between reactions, Escape closes. Motion: Pill springs open over 360ms with discs popping in 30ms apart; discs magnify instantly with the pointer; the chosen icon pops into the trigger over 420ms. Reduced motion: fades only. Accessibility: The trigger is a button with aria-haspopup, aria-expanded and aria-keyshortcuts; reactions are menuitemradio buttons with labels and aria-checked; changes and rollbacks are announced in a status line. Responsive behavior: Fixed-size control; the pill opens upward from the trigger and needs about 80px above it. Touch: Tap to like; long-press the button to open the reactions, then tap one. Preserve keyboard access, visible focus and reduced-motion behavior. Keep fictional demo data and simulated service calls in a separate usage example; expose callbacks for real actions and recover from rejected requests. Keep usage-example links inside the demo: use local buttons or prevent navigation. Demonstration links must not navigate to Vitrine routes or open other pages; preserve real URL support in the reusable component itself. Verify the result at narrow and wide viewport sizes, with keyboard input and reduced motion enabled.

Notes

Interaction
Click the button to like; point at it, long-press, or press ↑ to open the reactions; move along them and pick one. Arrow keys move between reactions, Escape closes.
Motion
Pill springs open over 360ms with discs popping in 30ms apart; discs magnify instantly with the pointer; the chosen icon pops into the trigger over 420ms. Reduced motion: fades only.
Accessibility
The trigger is a button with aria-haspopup, aria-expanded and aria-keyshortcuts; reactions are menuitemradio buttons with labels and aria-checked; changes and rollbacks are announced in a status line.
Responsive
Fixed-size control; the pill opens upward from the trigger and needs about 80px above it.
On touch
Tap to like; long-press the button to open the reactions, then tap one.

Loading components…