Speed Dial React component
A floating action button that opens into a short menu of actions: the plus turns into a close cross while actions spring out one after another in a line or a quarter-circle fan, each with a label, with an optional dimmed backdrop and full keyboard control.
About the Speed Dial component
Speed Dial is a floating action button that opens a short list of related actions, each a round button with a label. The actions spring out one after another, up, down, left, right or fanned over a quarter circle, and the plus on the main button turns into a close icon. Labels sit on the side facing into the screen.
actions takes objects with label, icon and onClick, and the icon can be one of eight built-in names (edit, camera, upload, link, share, folder, mic, calendar) or your own element. direction sets the way it opens, corner the corner it sits in, and contained places it inside the nearest positioned parent instead of fixed to the screen. openOnHover opens it on hover as well as on click, backdrop dims the page while it is open, and picking an action closes it.
When to use it
Use Speed Dial on mobile-first screens and canvases where one floating button should lead to a few related actions: create note / photo / file, share options, quick tools.
Keep it to three to six actions; for more, open a menu or a sheet instead.
Installation
Add the Speed Dial component to your project with the shadcn CLI. It lands in components/speed-dial.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add @reactframe/speed-dialOr copy the source by hand and install its dependencies:
npm install motion clsx tailwind-mergeProps
<SpeedDial /> accepts 9 props, all optional.
| Prop | Type | Default |
|---|---|---|
| actions | { label: string; icon: SpeedDialIcon | React.ReactNode; onClick?: () => void }[] | DEFAULT_ACTIONS |
| direction Which way the actions open. radial fans them over a quarter circle. | "up" | "down" | "left" | "right" | "radial" | "up" |
| openOnHover Open on hover as well as on click. | boolean | false |
| backdrop Dim everything behind while open. | boolean | false |
| corner Corner of the positioned parent (or the screen) to sit in. | "bottom-right" | "bottom-left" | "top-right" | "top-left" | "bottom-right" |
| contained Place it inside the nearest positioned ancestor instead of fixed on the screen. | boolean | false |
| label | string | "Quick actions" |
| theme | "dark" | "light" | "dark" |
| className | string | — |
- actions{ label: string; icon: SpeedDialIcon | React.ReactNode; onClick?: () => void }[]Default: DEFAULT_ACTIONS
- direction
Which way the actions open. radial fans them over a quarter circle.
"up" | "down" | "left" | "right" | "radial"Default: "up" - openOnHover
Open on hover as well as on click.
booleanDefault: false - backdrop
Dim everything behind while open.
booleanDefault: false - corner
Corner of the positioned parent (or the screen) to sit in.
"bottom-right" | "bottom-left" | "top-right" | "top-left"Default: "bottom-right" - contained
Place it inside the nearest positioned ancestor instead of fixed on the screen.
booleanDefault: false - labelstringDefault: "Quick actions"
- theme"dark" | "light"Default: "dark"
- classNamestring
npm dependencies
Installed for you by the shadcn CLI.
Speed Dial FAQ
- Which direction should it open?
- Up for a bottom corner, left or right along an edge, and the fan when there's room diagonally. Labels automatically sit on the side facing into the screen.
- Can it be used with a keyboard?
- Yes. It's a menu button: arrow keys move from the main button into the actions and between them, Enter runs one, and Escape closes and returns focus.
- Does it cover the page?
- Only if you set backdrop, which dims everything behind and closes on click. Without it the page stays usable around the open menu.
- How do I keep it inside a card or a preview?
- Set contained and give the parent position: relative. It then sits in that box's corner with position: absolute instead of in the corner of the screen.