Animated Dropdown

A composable, fully accessible dropdown menu built on Base UI with a spring-driven shared hover highlight and origin-aware scale/fade animations. No hardcoded items — compose your own content.

Features

  • Composable APIAnimatedDropdown / Trigger / Content / Item / Separator, shadcn-style.
  • Spring hover highlight — shared layoutId glides between items as you move the mouse.
  • Per-instance isolationuseId() scopes the layout group so multiple dropdowns on the same page never conflict.
  • Origin-aware animation — popup scales in from the trigger position using Base UI's --transform-origin.
  • Icon-agnostic — pass any ReactNode as the icon prop.
  • Danger variant — red-tinted destructive items.
  • Controlled or uncontrolled — use open/onOpenChange or defaultOpen as needed.
  • Full accessibility — keyboard nav, typeahead, focus trap, and portal via Base UI.
  • Reduced-motion safe — instant transitions when the OS prefers reduced motion.

Playground

Try different side and align positions.

Controls
Controls

Installation

Usage

Examples

Danger variant

Use variant="danger" on destructive items — they get a red tint and are visually separated.

Controlled open state

Pass open and onOpenChange to fully control the dropdown from external state.

Dropdown is: closed

Code Examples

Basic usage

TypeScript
my-dropdown.tsx

Controlled state

TypeScript
controlled-dropdown.tsx

Side and alignment

TypeScript
positioned-dropdown.tsx

Props

PropertyTypeDefaultDescription
childrenReactNoderequired
openbooleanControlled open state.
defaultOpenbooleanfalseInitial open state for uncontrolled usage.
onOpenChange(open: boolean) => voidCallback when open state changes.
disabledbooleanfalseWhether the menu ignores user interaction.
modalbooleantrueWhether the open menu limits interaction to the menu.