浮层组件
Dropdown Menu 下拉菜单
点击触发器后展开的下拉菜单,支持普通菜单项、分组、标签、复选框、单选组、子菜单和快捷键。
安装
bash
npx polyui add dropdown-menu基础
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuPortal } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
export function DropdownMenuBasic() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Basic</Button>} />
<DropdownMenuContent className="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuSub>
<DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>Email</DropdownMenuItem>
<DropdownMenuItem>Message</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>More...</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuItem>GitHub</DropdownMenuItem>
<DropdownMenuItem>Support</DropdownMenuItem>
<DropdownMenuItem disabled>API</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}用户切换
tsx
import { useState } from "react"
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel } from "@polyui/react/dropdown-menu"
import { Avatar, AvatarFallback, AvatarImage } from "@polyui/react/avatar"
import { CheckIcon } from "lucide-react"
export function DropdownMenuUserSwitcher() {
const [selectedUser, setSelectedUser] = useState(switchUsers[0])
return (
<DropdownMenu>
<DropdownMenuTrigger className="bg-secondary flex items-center gap-2 rounded-lg px-3 py-2.5">
<Avatar>
<AvatarImage src={selectedUser.src} alt={selectedUser.name} />
<AvatarFallback className="text-xs">{selectedUser.fallback}</AvatarFallback>
</Avatar>
<div className="flex flex-col gap-1 text-start leading-none">
<span className="max-w-[17ch] truncate text-sm font-semibold leading-none">{selectedUser.name}</span>
<span className="text-muted-foreground max-w-[20ch] truncate text-xs">{selectedUser.mail}</span>
</div>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="w-66">
<DropdownMenuGroup>
<DropdownMenuLabel>Task Assignment</DropdownMenuLabel>
{switchUsers.map((user) => (
<DropdownMenuItem key={user.id} onClick={() => setSelectedUser(user)}>
<div className="flex items-center gap-2">
<Avatar>
<AvatarImage src={user.src} alt={user.name} />
<AvatarFallback className="text-xs">{user.fallback}</AvatarFallback>
</Avatar>
<div className="flex flex-col gap-1 text-start leading-none">
<span className="max-w-[17ch] truncate text-sm font-semibold leading-none">{user.name}</span>
<span className="text-muted-foreground max-w-[20ch] truncate text-xs">{user.mail}</span>
</div>
</div>
{selectedUser.id === user.id && <CheckIcon className="ml-auto" />}
</DropdownMenuItem>
))}
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}聊天列表
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
import { Avatar, AvatarFallback, AvatarImage } from "@polyui/react/avatar"
import { Badge } from "@polyui/react/badge"
export function DropdownMenuChatList() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Chat List</Button>} />
<DropdownMenuContent className="w-91">
<DropdownMenuGroup>
<DropdownMenuLabel>Chat List</DropdownMenuLabel>
<DropdownMenuGroup>
{chatItems.map((item, index) => (
<DropdownMenuItem key={index} className="justify-between">
<Avatar>
<AvatarImage src={item.src} alt={item.name} />
<AvatarFallback className="text-xs">{item.fallback}</AvatarFallback>
</Avatar>
<div className="flex flex-1 flex-col">
<span className="text-popover-foreground">{item.name}</span>
<span className="text-muted-foreground text-xs">{item.message}</span>
</div>
{item.newMessages ? (
<div className="flex flex-col items-end gap-1">
<span className="text-muted-foreground text-xs">{item.time}</span>
<Badge className="h-5 min-w-5 bg-green-600 px-1 dark:bg-green-400">{item.newMessages}</Badge>
</div>
) : (
<span className="text-muted-foreground text-xs">{item.time}</span>
)}
</DropdownMenuItem>
))}
</DropdownMenuGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}联系人列表
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
import { Avatar, AvatarFallback, AvatarImage } from "@polyui/react/avatar"
export function DropdownMenuContactList() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Contact List</Button>} />
<DropdownMenuContent className="w-91">
<DropdownMenuGroup>
<DropdownMenuLabel>Contact List</DropdownMenuLabel>
<DropdownMenuGroup>
{contactItems.map((item, index) => (
<DropdownMenuItem key={index} className="justify-between">
<Avatar>
<AvatarImage src={item.src} alt={item.name} />
<AvatarFallback className="text-xs">{item.fallback}</AvatarFallback>
</Avatar>
<div className="flex flex-1 flex-col">
<span className="text-popover-foreground">{item.name}</span>
<span className="text-muted-foreground text-xs">{item.mail}</span>
</div>
<Button variant="secondary" className="h-7 cursor-pointer rounded-md px-2">
Send
</Button>
</DropdownMenuItem>
))}
<DropdownMenuItem>
<Button className="grow">Add Contact</Button>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}会议日程
tsx
import { useState } from "react"
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
import { Avatar, AvatarFallback, AvatarImage } from "@polyui/react/avatar"
import { Switch } from "@polyui/react/switch"
export function DropdownMenuMeetingSchedule() {
const [firstMeeting, setFirstMeeting] = useState(false)
const [secondMeeting, setSecondMeeting] = useState(true)
const [thirdMeeting, setThirdMeeting] = useState(false)
const [forthMeeting, setForthMeeting] = useState(true)
const [fifthMeeting, setFifthMeeting] = useState(false)
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Meetings Schedule</Button>} />
<DropdownMenuContent className="sm:w-124">
<DropdownMenuGroup>
<DropdownMenuLabel>Today's meetings</DropdownMenuLabel>
<DropdownMenuGroup>
<DropdownMenuItem className="justify-between gap-3.5" onSelect={(event) => event.preventDefault()}>
<span className="text-popover-foreground font-medium">08:30</span>
<div className="flex flex-1 flex-col">
<span className="text-popover-foreground">Daily Project Review</span>
<span className="text-muted-foreground text-xs">Team organization</span>
</div>
<Avatar className="max-sm:hidden">
<AvatarImage src="https://cdn.shadcnstudio.com/ss-assets/avatar/avatar-11.png" alt="Hallie Richards" />
<AvatarFallback className="text-xs">Angel</AvatarFallback>
</Avatar>
<div className="flex items-center gap-2">
<span className="text-popover-foreground text-sm">Privacy</span>
<Switch checked={firstMeeting} onCheckedChange={setFirstMeeting} />
</div>
</DropdownMenuItem>
<DropdownMenuItem className="justify-between gap-3.5" onSelect={(event) => event.preventDefault()}>
<span className="text-popover-foreground font-medium">09:00</span>
<div className="flex flex-1 flex-col">
<span className="text-popover-foreground">Sprint Surge</span>
<span className="text-muted-foreground text-xs">Daily Boost for Agile Progress</span>
</div>
<div className="flex -space-x-3 max-sm:hidden">
{meetingAvatars.map((avatar, index) => (
<Avatar key={index} className="ring-background ring-2">
<AvatarImage src={avatar.src} alt={avatar.name} />
<AvatarFallback className="text-xs">{avatar.fallback}</AvatarFallback>
</Avatar>
))}
</div>
<div className="flex items-center gap-2">
<span className="text-popover-foreground text-sm">Privacy</span>
<Switch checked={secondMeeting} onCheckedChange={setSecondMeeting} />
</div>
</DropdownMenuItem>
<DropdownMenuItem className="justify-between gap-3.5" onSelect={(event) => event.preventDefault()}>
<span className="text-popover-foreground font-medium">11:45</span>
<div className="flex flex-1 flex-col">
<span className="text-popover-foreground">Project Status Update</span>
<span className="text-muted-foreground text-xs">Progress Overview Update</span>
</div>
<Avatar className="max-sm:hidden">
<AvatarImage src="https://cdn.shadcnstudio.com/ss-assets/avatar/avatar-12.png" alt="Hallie Richards" />
<AvatarFallback className="text-xs">Angel</AvatarFallback>
</Avatar>
<div className="flex items-center gap-2">
<span className="text-popover-foreground text-sm">Privacy</span>
<Switch checked={thirdMeeting} onCheckedChange={setThirdMeeting} />
</div>
</DropdownMenuItem>
<DropdownMenuItem className="justify-between gap-3.5" onSelect={(event) => event.preventDefault()}>
<span className="text-popover-foreground font-medium">06:30</span>
<div className="flex flex-1 flex-col">
<span className="text-popover-foreground">Team Performance</span>
<span className="text-muted-foreground text-xs">Team Metrics Evaluation</span>
</div>
<div className="flex -space-x-3 max-sm:hidden">
{meetingAvatars.map((avatar, index) => (
<Avatar key={index} className="ring-background ring-2">
<AvatarImage src={avatar.src} alt={avatar.name} />
<AvatarFallback className="text-xs">{avatar.fallback}</AvatarFallback>
</Avatar>
))}
</div>
<div className="flex items-center gap-2">
<span className="text-popover-foreground text-sm">Privacy</span>
<Switch checked={forthMeeting} onCheckedChange={setForthMeeting} />
</div>
</DropdownMenuItem>
<DropdownMenuItem className="justify-between gap-3.5" onSelect={(event) => event.preventDefault()}>
<span className="text-popover-foreground font-medium">10:50</span>
<div className="flex flex-1 flex-col">
<span className="text-popover-foreground">Stakeholder Feedback</span>
<span className="text-muted-foreground text-xs">Feedback from Stakeholders</span>
</div>
<Avatar className="max-sm:hidden">
<AvatarImage src="https://cdn.shadcnstudio.com/ss-assets/avatar/avatar-14.png" alt="Hallie Richards" />
<AvatarFallback className="text-xs">Angel</AvatarFallback>
</Avatar>
<div className="flex items-center gap-2">
<span className="text-popover-foreground text-sm">Privacy</span>
<Switch checked={fifthMeeting} onCheckedChange={setFifthMeeting} />
</div>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}编辑菜单
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
import { PencilIcon } from "lucide-react"
export function DropdownMenuEditMenu() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="ghost" size="icon" className="rounded-full" />}>
<PencilIcon />
<span className="sr-only">Edit menu</span>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>Edit text</DropdownMenuLabel>
<DropdownMenuGroup>
{editItemDefs.map((item, index) => (
<DropdownMenuItem key={index}>
<span className="flex items-center justify-center rounded-md border p-2">
<item.icon className="size-4" />
</span>
<div className="flex flex-col">
<span className="text-popover-foreground">{item.property}</span>
<span className="text-muted-foreground text-xs">{item.description}</span>
</div>
</DropdownMenuItem>
))}
</DropdownMenuGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}用户菜单
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
export function DropdownMenuUserMenu() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="secondary" size="icon" className="overflow-hidden rounded-full" />}>
<img src="https://cdn.shadcnstudio.com/ss-assets/avatar/avatar-5.png" alt="Hallie Richards" />
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuGroup>
{accountItemDefs.map((item, index) => (
<DropdownMenuItem key={index}>
<item.icon />
<span className="text-popover-foreground">{item.label}</span>
</DropdownMenuItem>
))}
</DropdownMenuGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}用户资料
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuPortal } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
import { Avatar, AvatarFallback, AvatarImage } from "@polyui/react/avatar"
export function DropdownMenuUserProfile() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">User Profile</Button>} />
<DropdownMenuContent className="w-56">
<DropdownMenuLabel className="flex items-center gap-2">
<Avatar>
<AvatarImage src="https://cdn.shadcnstudio.com/ss-assets/avatar/avatar-1.png" alt="Phillip George" />
<AvatarFallback className="text-xs">PG</AvatarFallback>
</Avatar>
<div className="flex flex-1 flex-col">
<span className="text-popover-foreground">Phillip George</span>
<span className="text-muted-foreground text-xs font-normal">phillip@example.com</span>
</div>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuSub>
<DropdownMenuSubTrigger>Invite users</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>Email</DropdownMenuItem>
<DropdownMenuItem>Message</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>More...</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuItem>GitHub</DropdownMenuItem>
<DropdownMenuItem>Support</DropdownMenuItem>
<DropdownMenuItem disabled>API</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}含危险操作
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
import { UploadIcon, Trash2Icon, PencilLineIcon } from "lucide-react"
export function DropdownMenuWithDestructive() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Align Start</Button>} />
<DropdownMenuContent align="start" className="w-34">
<DropdownMenuGroup>
<DropdownMenuItem>
<PencilLineIcon />
Edit
</DropdownMenuItem>
<DropdownMenuItem>
<UploadIcon />
Share
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive">
<Trash2Icon />
<span>Delete</span>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}带快捷键
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuShortcut } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
export function DropdownMenuWithShortcuts() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Align End</Button>} />
<DropdownMenuContent align="end" className="w-66">
<DropdownMenuGroup>
<DropdownMenuItem>
New Tab<DropdownMenuShortcut>⌘ + T</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
New Window <DropdownMenuShortcut>⌘ + N</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
New Incognito Window <DropdownMenuShortcut>⌘ + ⇧ + N</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
History <DropdownMenuShortcut>⌘ + Y</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Downloads <DropdownMenuShortcut>⌥ + ⇧ + L</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}优先级
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
export function DropdownMenuPriority() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Bordered Menu</Button>} />
<DropdownMenuContent className="w-56 shadow-none">
<DropdownMenuGroup>
<DropdownMenuLabel>Task priority</DropdownMenuLabel>
<DropdownMenuGroup>
{priorityItemDefs.map((item, index) => (
<DropdownMenuItem key={index}>
<item.icon className={item.color} />
{item.label}
</DropdownMenuItem>
))}
</DropdownMenuGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}带图标
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
import { UserIcon, SettingsIcon, DollarSignIcon, CircleHelpIcon, ReceiptIcon } from "lucide-react"
export function DropdownMenuWithIcons() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Menu item with icon</Button>} />
<DropdownMenuContent className="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>User Profile</DropdownMenuLabel>
<DropdownMenuGroup>
<DropdownMenuItem>
<UserIcon />
Profile
</DropdownMenuItem>
<DropdownMenuItem>
<SettingsIcon />
Settings
</DropdownMenuItem>
<DropdownMenuItem>
<ReceiptIcon />
Billing Plans
</DropdownMenuItem>
<DropdownMenuItem>
<DollarSignIcon />
Pricing
</DropdownMenuItem>
<DropdownMenuItem>
<CircleHelpIcon />
FAQ
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}复选框
tsx
import { useState } from "react"
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuCheckboxItem } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
export function DropdownMenuCheckboxes() {
const [showStatusBar, setShowStatusBar] = useState(true)
const [showActivityBar, setShowActivityBar] = useState(false)
const [showPanel, setShowPanel] = useState(false)
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">With checkbox</Button>} />
<DropdownMenuContent className="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>Appearance</DropdownMenuLabel>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem checked={showStatusBar} onCheckedChange={setShowStatusBar}>
Status Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem checked={showActivityBar} onCheckedChange={setShowActivityBar} disabled>
API
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem checked={showPanel} onCheckedChange={setShowPanel}>
Invite users
</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>
)
}单选
tsx
import { useState } from "react"
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuRadioGroup, DropdownMenuRadioItem } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
export function DropdownMenuRadio() {
const [position, setPosition] = useState("bottom")
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">With radio</Button>} />
<DropdownMenuContent className="w-56">
<DropdownMenuGroup>
<DropdownMenuLabel>Panel Position</DropdownMenuLabel>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuRadioGroup value={position} onValueChange={setPosition}>
<DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="right" disabled>
Right
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}向左滑入
tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
export function DropdownMenuSlideLeft() {
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Slide Left Animation</Button>} />
<DropdownMenuContent
align="start"
className="data-[state=closed]:slide-out-to-left-20 data-[state=open]:slide-in-from-left-20 data-[state=closed]:zoom-out-100 data-[state=open]:zoom-in-100 w-56 duration-400"
>
<DropdownMenuGroup>
<DropdownMenuLabel>Settings</DropdownMenuLabel>
<DropdownMenuGroup>
<DropdownMenuItem>My Profile</DropdownMenuItem>
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
<DropdownMenuItem>FAQs</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuLabel>Contact</DropdownMenuLabel>
<DropdownMenuGroup>
<DropdownMenuItem>Call Support</DropdownMenuItem>
<DropdownMenuItem>Chat with us</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}向上滑入
tsx
import { useState } from "react"
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel } from "@polyui/react/dropdown-menu"
import { Button } from "@polyui/react/button"
import { Switch } from "@polyui/react/switch"
export function DropdownMenuSlideUp() {
const [googleSwitch, setGoogleSwitch] = useState(false)
const [twitterSwitch, setTwitterSwitch] = useState(false)
const [linkedinSwitch, setLinkedinSwitch] = useState(false)
const [dribbbleSwitch, setDribbbleSwitch] = useState(false)
const [behanceSwitch, setBehanceSwitch] = useState(false)
return (
<DropdownMenu>
<DropdownMenuTrigger render={<Button variant="outline">Slide Up Animation</Button>} />
<DropdownMenuContent className="data-[state=closed]:slide-out-to-left-0 data-[state=open]:slide-in-from-left-0 data-[state=closed]:slide-out-to-bottom-20 data-[state=open]:slide-in-from-bottom-20 data-[state=closed]:zoom-out-100 w-56 duration-400">
<DropdownMenuGroup>
<DropdownMenuLabel>Apps notification</DropdownMenuLabel>
<DropdownMenuGroup>
<DropdownMenuItem className="justify-between" onSelect={(event) => event.preventDefault()}>
<img
src="https://cdn.shadcnstudio.com/ss-assets/components/dropdown/google.png"
alt="google"
className="size-4"
/>
<span className="flex-1">Google</span>
<Switch checked={googleSwitch} onCheckedChange={setGoogleSwitch} />
</DropdownMenuItem>
<DropdownMenuItem className="justify-between" onSelect={(event) => event.preventDefault()}>
<img
src="https://cdn.shadcnstudio.com/ss-assets/components/dropdown/twitter.png"
alt="twitter"
className="size-4"
/>
<span className="flex-1">Twitter</span>
<Switch checked={twitterSwitch} onCheckedChange={setTwitterSwitch} />
</DropdownMenuItem>
<DropdownMenuItem className="justify-between" onSelect={(event) => event.preventDefault()}>
<img
src="https://cdn.shadcnstudio.com/ss-assets/components/dropdown/linkedin.png"
alt="linkedin"
className="size-4"
/>
<span className="flex-1">Linkedin</span>
<Switch checked={linkedinSwitch} onCheckedChange={setLinkedinSwitch} />
</DropdownMenuItem>
<DropdownMenuItem className="justify-between" onSelect={(event) => event.preventDefault()}>
<img
src="https://cdn.shadcnstudio.com/ss-assets/components/dropdown/dribbble.png"
alt="dribbble"
className="size-4"
/>
<span className="flex-1">Dribbble</span>
<Switch checked={dribbbleSwitch} onCheckedChange={setDribbbleSwitch} />
</DropdownMenuItem>
<DropdownMenuItem className="justify-between" onSelect={(event) => event.preventDefault()}>
<img
src="https://cdn.shadcnstudio.com/ss-assets/components/dropdown/behance.png"
alt="behance"
className="size-4"
/>
<span className="flex-1">Behance</span>
<Switch checked={behanceSwitch} onCheckedChange={setBehanceSwitch} />
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
DropdownMenuContent › side | "top" | "right" | "bottom" | "left" | "bottom" | 菜单相对触发器的弹出方向。 |
DropdownMenuContent › align | "start" | "center" | "end" | "start" | 菜单相对触发器的对齐方式。 |
DropdownMenuContent › sideOffset | number | 4 | 菜单与触发器之间的间距(px)。 |
DropdownMenuItem › variant | "default" | "destructive" | "default" | 菜单项的视觉变体,destructive 显示为红色。 |
DropdownMenuItem › inset | boolean | false | 添加左侧内边距,与带图标的菜单项对齐。 |