edbnedbn/ui
Get Started
WelcomeChoosing a VariantChangelogLicense
Components
OverviewButtonAlert DialogPopoverDropdown MenuPull Down Menu
Sheet
Motion Utilities
Motion ProviderSpring PresetsHooks
0installs
Components
BlocksMaps
HomeDocsComponentsAnimatedPull Down

On this page

Pull Down Menu

A pull down menu with morphing animations. The trigger morphs into the menu container, creating a fluid, native-feeling interaction with spring physics. Features submenus, directional expansion, and full keyboard navigation.

Credits & Attribution

Inspired by and adapted from bloom-menu by Josh Puckett. Licensed under MIT.

Usage

import { PullDown } from "@/components/ui/animated/pull-down"
<PullDown direction="top" anchor="start">
  <PullDown.Container
    buttonSize={40}
    menuWidth={160}
    menuRadius={12}
    className="bg-white dark:bg-neutral-800"
  >
    <PullDown.Trigger>
      <DotsThreeIcon className="h-5 w-5" weight="bold" />
    </PullDown.Trigger>
    <PullDown.Content className="p-1">
      <PullDown.Item onSelect={() => {}}>Edit</PullDown.Item>
      <PullDown.Item onSelect={() => {}}>Copy</PullDown.Item>
      <PullDown.Item onSelect={() => {}}>Share</PullDown.Item>
      <PullDown.Separator />
      <PullDown.Item onSelect={() => {}}>Archive</PullDown.Item>
    </PullDown.Content>
  </PullDown.Container>
</PullDown>

Installation

Examples

Basic Menu

The simplest pull down menu with icon trigger and items.

With Icons

Add leading icons to menu items for better visual context.

Text Trigger

Use a rectangular button with text as the trigger by providing a buttonSize object with width and height.

Menu

Submenus

Create nested navigation using SubMenu, SubMenuTrigger, and SubMenuContent. The submenu morphs from the trigger position with a scaled container effect.

API Reference

PullDown (Root)

Root container that provides state and configuration context.

PropTypeDefaultDescription
openboolean—Controlled open state
defaultOpenbooleanfalseDefault open state (uncontrolled)
onOpenChange(open: boolean) => void—Callback when open state changes
direction"top" | "bottom" | "left" | "right""top"Direction the menu expands from trigger
anchor"start" | "center" | "end""start"Anchor alignment. For left/right directions, only 'center' is supported.
closeOnClickOutsidebooleantrueClose when clicking outside the menu
closeOnEscapebooleantrueClose when pressing Escape key
modalbooleanfalseEnable modal behavior with focus trapping
visualDurationnumber0.25Spring animation duration in seconds
bouncenumber0.2Spring animation bounce amount

PullDown.Container

The morphing container that transitions from button to menu.

PropTypeDefaultDescription
buttonSizenumber | { width: number; height: number }40Size of the closed button state
menuWidthnumber200Width when open
menuRadiusnumber24Border radius when open
buttonRadiusnumber—Border radius when closed (defaults to pill shape)

PullDown.Trigger

The trigger element that opens the menu. Fades out when menu opens.

PropTypeDefaultDescription
disabledbooleanfalseDisable the trigger

PullDown.Content

Container for menu items with animated entrance.

PropTypeDefaultDescription
onAnimationComplete() => void—Callback when entrance animation completes

PullDown.Item

Interactive menu item with hover highlighting.

PropTypeDefaultDescription
onSelect() => void—Callback when selected
disabledbooleanfalseDisable the item
closeOnSelectbooleantrueClose menu after selection

PullDown.SubMenu

Wrapper for nested submenu functionality.

PropTypeDefaultDescription
idstring—Unique identifier for this submenu (required)

PullDown.SubMenuTrigger

The item that opens a submenu. Supports render prop for active state.

PropTypeDefaultDescription
childrenReactNode | (isActive: boolean) => ReactNode—Content or render prop for active state
disabledbooleanfalseDisable the trigger

Accessibility

Full keyboard navigation and ARIA support for accessible menu interactions.

Keyboard

Open/close menu
EnterSpace
Open menuArrowDown
Close menuEscape
Open submenuArrowRight
Close submenu
ArrowLeftEscape

ARIA Attributes

  • • Trigger has role="button", aria-expanded, and aria-haspopup="menu"
  • • Content has role="menu"
  • • Items have role="menuitem" with aria-disabled
  • • Respects prefers-reduced-motion media query