Responsive Menu

A menu that adapts to the viewport — a Dropdown Menu on desktop, a bottom Drawer menu on mobile — since a hover-triggered dropdown doesn't translate to touch.

Last updated August 8, 2026

CreditsModifiedPublished

Copied from shadcn/ui.

  • Not a shadcn/ui component — this composition (switch between Dropdown Menu and a Drawer menu by viewport width, behind one shared API) is original to this registry, built on top of this registry's own Dropdown Menu and Drawer
  • Added variant="destructive" support to Dropdown Menu's item so it matches Context Menu and Menubar, and so a destructive action looks the same on both the desktop and mobile surface here

Overview

Resize the browser window to see the preview switch between a dropdown and a drawer menu.

"use client"
 
import { Button } from "@/components/ui/button"
import {
  ResponsiveMenu,
  ResponsiveMenuContent,
  ResponsiveMenuItem,
  ResponsiveMenuSeparator,
  ResponsiveMenuTrigger,
} from "@/components/ui/responsive-menu"
 
export function ResponsiveMenuDemoExample() {
  return (
    <ResponsiveMenu>
      <ResponsiveMenuTrigger
        render={<Button variant="outline">Open menu</Button>}
      />
      <ResponsiveMenuContent groupLabel="My Account">
        <ResponsiveMenuItem onClick={() => {}}>Profile</ResponsiveMenuItem>
        <ResponsiveMenuItem onClick={() => {}}>Billing</ResponsiveMenuItem>
        <ResponsiveMenuSeparator />
        <ResponsiveMenuItem variant="destructive" onClick={() => {}}>
          Log out
        </ResponsiveMenuItem>
      </ResponsiveMenuContent>
    </ResponsiveMenu>
  )
}

Installation

$ npx shadcn@latest add https://ui.persian-labs.ir/r/responsive-menu.json

Usage

import {
  ResponsiveMenu,
  ResponsiveMenuContent,
  ResponsiveMenuItem,
  ResponsiveMenuSeparator,
  ResponsiveMenuTrigger,
} from "@/components/ui/responsive-menu"
 
export function Example() {
  return (
    <ResponsiveMenu>
      <ResponsiveMenuTrigger render={<Button variant="outline">Open menu</Button>} />
      <ResponsiveMenuContent groupLabel="My Account">
        <ResponsiveMenuItem onClick={() => {}}>Profile</ResponsiveMenuItem>
        <ResponsiveMenuItem onClick={() => {}}>Billing</ResponsiveMenuItem>
        <ResponsiveMenuSeparator />
        <ResponsiveMenuItem variant="destructive" onClick={() => {}}>
          Log out
        </ResponsiveMenuItem>
      </ResponsiveMenuContent>
    </ResponsiveMenu>
  )
}

RTL

"use client"
 
import { Button } from "@/components/ui/button"
import {
  ResponsiveMenu,
  ResponsiveMenuContent,
  ResponsiveMenuItem,
  ResponsiveMenuSeparator,
  ResponsiveMenuTrigger,
} from "@/components/ui/responsive-menu"
 
export function ResponsiveMenuRtlExample() {
  return (
    <ResponsiveMenu>
      <ResponsiveMenuTrigger
        render={<Button variant="outline">باز کردن منو</Button>}
      />
      <ResponsiveMenuContent groupLabel="حساب من">
        <ResponsiveMenuItem onClick={() => {}}>پروفایل</ResponsiveMenuItem>
        <ResponsiveMenuItem onClick={() => {}}>صورتحساب</ResponsiveMenuItem>
        <ResponsiveMenuSeparator />
        <ResponsiveMenuItem variant="destructive" onClick={() => {}}>
          خروج از حساب
        </ResponsiveMenuItem>
      </ResponsiveMenuContent>
    </ResponsiveMenu>
  )
}

API Reference

ResponsiveMenu

ResponsiveMenuContent