Skip to the solution
MediumMachine Coding9 min read

Build a Speed Dial Menu

668 views

The problem

Question presented to candidate: "Our mobile web app has a round floating action button in the bottom-right corner. Tapping it should fan out a short column of secondary actions (Share, Print, Copy link, Download) with a little staggered animation, and collapse again when you pick one, tap elsewhere or press Escape. Build it."

Requirements:

  • A floating action button (FAB) fixed to the bottom-right that toggles a vertical column of action buttons above it; the "+" icon rotates into a "ร—".
  • Staggered animation: on open the action nearest the FAB appears first; on close the farthest disappears first.
  • Choosing an action reports it and closes; Escape closes; a press outside closes; focus returns to the FAB.
  • Keyboard: from the open FAB, ArrowUp moves into the actions and up the column, ArrowDown moves back down to the FAB; Tab reaches the actions only while open.
  • Each action has a visible text label as well as an icon; respects prefers-reduced-motion.

What a strong answer should cover:

  • Keeping the actions mounted so the close animation can play, and making them inert while closed so they are unreachable.
  • Computing per-item transition-delay from the index and the direction (open vs close).
  • Outside-press detection with contains() and listener cleanup, and focus return to the FAB.
  • ARIA for the FAB (aria-expanded, aria-controls, an accessible name) and why icon-only actions need labels.
  • Reduced motion and touch target sizes (at least 44 px).

Clarifying questions expected:

  • "Vertical or radial layout? Which direction does it open?"
  • "Should it also open on hover on desktop?"
  • "Is it a primary action plus extras, or only a launcher?"

Code / implementation expected: Yes. One component plus a demo; CSS transitions, no animation library.

  • React
  • Menu
  • Animation

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

9 min read ยท 9 sections

React solution

Every file of the working solution. Open it in the playground to run and change it.

ReactComplete solution
import { useState } from "react";
import SpeedDial from "./src/components/SpeedDial";

const ACTIONS = [
  { id: "share", label: "Share", icon: "โ†—", done: "Link shared" },
  { id: "print", label: "Print", icon: "โŽ™", done: "Sent to printer" },
  { id: "copy", label: "Copy link", icon: "โง‰", done: "Link copied" },
  { id: "download", label: "Download", icon: "โ†“", done: "Download started" },
];

export default function App() {
  const [status, setStatus] = useState("Pick an action");
  return (
    <main className="page">
      <h1>Speed dial</h1>
      <p className="hint">
        Click the round button, or focus it and use the arrow keys. Escape or a
        click outside closes it.
      </p>
      <p data-testid="status" aria-live="polite">
        {status}
      </p>
      <SpeedDial actions={ACTIONS} onAction={(a) => setStatus(a.done)} />
    </main>
  );
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 49 of 107 in Machine coding

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

Up nextMedium

Build a Star Rating component

Continue