Smooth Dropdown
uselayouts/smooth-dropdownFreeComponent
A dropdown menu with premium layout transitions.
Live preview
live · rendered by the registry
Rendered by uselayouts on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://uselayouts.com/r/smooth-dropdown.jsonSource
1"use client";23import { useState, useRef, useEffect } from "react";4import { motion } from "motion/react";5import { HugeiconsIcon } from "@hugeicons/react";6import useMeasure from "react-use-measure";7import {8 UserIcon,9 CreditCardIcon,10 FolderIcon,11 File01Icon,12 SettingsIcon,13 HelpCircleIcon,14 LogoutIcon,15 MoreHorizontalCircle01Icon,16} from "@hugeicons/core-free-icons";1718// Change Here19const menuItems = [20 { id: "profile", label: "Profile", icon: UserIcon },21 { id: "upgrade", label: "Upgrade", icon: CreditCardIcon },22 { id: "projects", label: "Projects", icon: FolderIcon },23 { id: "documentation", label: "Documentation", icon: File01Icon },24 { id: "divider", label: "", icon: null },25 { id: "settings", label: "Settings", icon: SettingsIcon },26 { id: "help", label: "Get Help", icon: HelpCircleIcon },27 { id: "logout", label: "Logout", icon: LogoutIcon },28];2930const easeOutQuint: [number, number, number, number] = [0.23, 1, 0.32, 1];3132export default function TwentyTwelveOne() {33 const [isOpen, setIsOpen] = useState(false);34 const [activeItem, setActiveItem] = useState("profile");35 const [hoveredItem, setHoveredItem] = useState<string | null>(null);36 const containerRef = useRef<HTMLDivElement>(null);3738 const [contentRef, contentBounds] = useMeasure();3940 useEffect(() => {41 const handleClickOutside = (event: MouseEvent) => {42 if (43 containerRef.current &&44 !containerRef.current.contains(event.target as Node)45 ) {46 setIsOpen(false);47 }48 };4950 if (isOpen) {51 document.addEventListener("mousedown", handleClickOutside);52 }53 return () => document.removeEventListener("mousedown", handleClickOutside);54 }, [isOpen]);5556 const openHeight = Math.max(40, Math.ceil(contentBounds.height));57 return (58 <div ref={containerRef} className="relative h-10 w-10 not-prose">59 <motion.div60 layout61 initial={false}62 animate={{63 width: isOpen ? 220 : 40,64 height: isOpen ? openHeight : 40,65 borderRadius: isOpen ? 14 : 12,66 }}67 transition={{68 type: "spring" as const,69 damping: 34,70 stiffness: 380,71 mass: 0.8,72 }}73 className="absolute top-0 right-0 bg-popover border border-border shadow-lg overflow-hidden cursor-pointer origin-top-right "74 onClick={() => !isOpen && setIsOpen(true)}75 >76 <motion.div77 initial={false}78 animate={{79// … truncated
What it pulls in
npm packages
Files it writes
More from uselayouts
All 26 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| 3D Book3d-book | uselayouts | Components | Free | 3 deps | |
| Animated Collectionanimated-collection | uselayouts | Components | Free | 5 deps | |
| Bento Cardbento-card | uselayouts | Components | Free | 5 deps | |
| Bottom Menubottom-menu | uselayouts | Components | Free | 6 deps | |
| Bucketbucket | uselayouts | Components | Free | 5 deps · 2 files | |
| Day Pickerday-picker | uselayouts | Components | Free | 5 deps | |
| Delete Buttondelete-button | uselayouts | Components | Free | 5 deps | |
| Discover Buttondiscover-button | uselayouts | Components | Free | 5 deps |
