Expand Menu
unlumen-ui/expand-menuFreeComponent
An animated expanding menu that reveals items from a trigger button, with configurable direction, layout, and alignment.
Install it
npx shadcn@latest add https://ui.unlumen.com/r/expand-menu.jsonSource
1"use client";23import * as React from "react";4import { motion, AnimatePresence } from "motion/react";5import { cn } from "@/lib/utils";67export type ExpandMenuItemType = {8 icon: React.ReactNode;9 label: string;10 onClick?: () => void;11};1213export type ExpandMenuProps = {14 items: ExpandMenuItemType[];15 direction?: "up" | "down" | "left" | "right";16 showLabels?: boolean;17 triggerIcon?: React.ReactNode;18 className?: string;19};2021// anchor so the trigger stays in place while items expand away from it22const anchorStyle: Record<string, React.CSSProperties> = {23 down: { top: 0, left: 0 },24 right: { top: 0, left: 0 },25 up: { bottom: 0, left: 0 },26 left: { top: 0, right: 0 },27};2829// "up" / "left" need the trigger last so it stays at the anchor corner30const triggerLast = (d: string) => d === "up" || d === "left";3132const flexDirMap: Record<string, React.CSSProperties["flexDirection"]> = {33 down: "column",34 up: "column",35 right: "row",36 left: "row",37};3839function TriggerButton({40 open,41 triggerIcon,42 onClick,43}: {44 open: boolean;45 triggerIcon?: React.ReactNode;46 onClick: () => void;47}) {48 return (49 <motion.button50 layout51 onClick={onClick}52 aria-expanded={open}53 style={{ borderRadius: 9999, flexShrink: 0 }}54 className="flex items-center justify-center w-9 h-9 hover:bg-gray-100 active:bg-gray-200 transition-colors cursor-pointer"55 >56 <motion.span57 animate={{ rotate: open ? 45 : 0 }}58 transition={{ type: "spring", stiffness: 400, damping: 28 }}59 className="flex items-center justify-center"60 >61 {triggerIcon ?? (62 <svg63 width="16"64 height="16"65 viewBox="0 0 16 16"66 fill="currentColor"67 className="text-gray-700"68 >69 <path d="M8 2a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm0 4.5a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm0 4.5a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3z" />70 </svg>71 )}72 </motion.span>73 </motion.button>74 );75}7677function MenuItem({78 icon,79 label,80 onClick,81 index,82 showLabels,83}: ExpandMenuItemType & { index: number; showLabels: boolean }) {84 return (85 <motion.button86 layout87 initial={{ opacity: 0, scale: 0.7 }}88 animate={{ opacity: 1, scale: 1 }}89 exit={{ opacity: 0, scale: 0.7 }}90 transition={{91 delay: index * 0.04,92 type: "spring",93 stiffness: 400,94 damping: 28,95 }}96 onClick={onClick}97// … truncated
What it pulls in
npm packages
Files it writes
More from Unlumen Ui
All 233 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| AI Chatai-chat | Unlumen Ui | Components | Paid | 2 deps | |
| Vercel Animate Countanimate-count | Unlumen Ui | Components | Free | 1 dep | |
| Animate Digitsanimate-digits | Unlumen Ui | Components | Free | 1 dep | |
| Animated Inputanimate-text-input-typing | Unlumen Ui | Components | Paid | 1 dep | |
| Animated Listanimated-list | Unlumen Ui | Components | Free | 1 dep | |
| Apple Switchapple-switch | Unlumen Ui | Components | Free | 1 dep | |
| Aurora Barsaurora-bars | Unlumen Ui | Components | Free | 1 dep | |
| Aurora Bluraurora-blur | Unlumen Ui | Components | Free | 2 deps |
