DropdownMenu with motion: it springs out of its trigger, its items rise in one after another, and one highlight glides from item to item after the pointer or the arrow keys.
$ pnpm dlx shadcn@latest add https://dashral.com/r/motion-dropdown-menu.jsonInstallation
$ pnpm dlx shadcn@latest add https://dashral.com/r/motion-dropdown-menu.jsonAdds components/dashral/motion/dropdown-menu.tsx, the Dropdown Menu it builds on (in components/dashral/), motion and the motion files every motion component shares. With the registry in your components.json:
$ pnpm dlx shadcn@latest add @dashral/motion-dropdown-menuUsage
The same as Dropdown Menu, imported from components/dashral/motion/: swap the import and it moves.
import { DropdownMenu } from "@/components/dashral/motion/dropdown-menu"
<DropdownMenu
trigger={<Button variant="outline">Open menu</Button>}
items={[
{ label: "Profile", icon: <User /> },
{ label: "Sign out", icon: <LogOut />, color: "destructive" },
]}
/>Examples
Row actions
Each ⋯ menu springs out of its button. Duplicate slides a copy in, Move to opens a submenu, Delete folds the row away with Undo.
Compared with Default
Fades and zooms in from 95%; the highlight jumps from item to item.
Motion
Springs out of its trigger with its items rising in one after another; one highlight glides from item to item; ticks draw, radio dots spring in, submenus slide out.
How the two editions differ in general, and which to use where: Motion.
API reference
Every prop of Dropdown Menu, and every attribute of the element it renders. The Motion edition adds no props of its own.
DropdownMenu
Also takes every prop of Radix Dropdown Menu(opens in a new tab).
| Prop | Type | Default |
|---|---|---|
trigger | ReactElementWhat opens it. Required. | — |
items | MenuItem[]Required. A MenuItem is { label, icon?, shortcut?, color?: "destructive", onSelect?, href?, external?, active?, disabled? }, or a { type } of "checkbox", "radio" (a group with options), "row" (small items side by side), "label", "separator" or "submenu" (with items). | — |
linkAs | ElementTypeYour router's link, for items with href. From a client component. | "a" |
side / align / sideOffset | Where it opens. | "bottom" / "center" / 4 |
open / onOpenChange | Control it yourself. | — |
className | stringThe menu panel's classes, e.g. a width. | — |
Motion
- It springs out of its trigger from the side it opens on (--duration-standard, a hint of overshoot), from 94% and 6px back toward the trigger; it leaves quickly (--duration-fast, --ease-exit).
- Its items rise 4px as they fade in, one after another, 25ms apart.
- The highlight is one pill per panel gliding from item to item, after the pointer or the arrow keys, instead of jumping; on a destructive item it's red.
- A checkbox item's tick draws itself and back out; a radio's dot springs into the picked one and shrinks out of the one left; a reaction in a row grows under the pointer; a submenu slides out from its side.
- With reduced motion it only fades, and the highlight moves at once.