Next.js14中Shadcn.ui Popover内嵌Command无法鼠标点击求助
问题:shadcn/ui中Popover内的Command组件无法鼠标点击交互
我正在评估shadcn.ui组件库的易用性,尝试复刻Demo中「tasks」示例的交互逻辑——结合Popover与Command组件。当前实现能正常打开Popover,也可通过键盘选择Command元素,但无法用鼠标点击或选中任何Command组件,仿佛被禁用。
PopoverDemo组件代码
import { Button } from "@/components/ui/button"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from "@/components/ui/command"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { CalendarIcon, EnvelopeClosedIcon, FaceIcon, GearIcon, PersonIcon, RocketIcon } from "@radix-ui/react-icons"; export function PopoverDemo() { return ( <Popover> <PopoverTrigger asChild> <Button variant="outline">Open popover</Button> </PopoverTrigger> <PopoverContent className="w-80"> <Command className="rounded-lg border shadow-md"> <CommandInput placeholder="Type a command or search..." /> <CommandList> <CommandEmpty>No results found.</CommandEmpty> <CommandGroup heading="Suggestions"> <CommandItem> <CalendarIcon className="mr-2 h-4 w-4" /> <span>Calendar</span> </CommandItem> <CommandItem> <FaceIcon className="mr-2 h-4 w-4" /> <span>Search Emoji</span> </CommandItem> <CommandItem> <RocketIcon className="mr-2 h-4 w-4" /> <span>Launch</span> </CommandItem> </CommandGroup> <CommandSeparator /> <CommandGroup heading="Settings"> <CommandItem> <PersonIcon className="mr-2 h-4 w-4" /> <span>Profile</span> </CommandItem> <CommandItem> <EnvelopeClosedIcon className="mr-2 h-4 w-4" /> <span>Mail</span> </CommandItem> <CommandItem> <GearIcon className="mr-2 h-4 w-4" /> <span>Settings</span> </CommandItem> </CommandGroup> </CommandList> </Command> </PopoverContent> </Popover> ); }
主页面代码
import { PopoverDemo } from "@/components/PopoverDemo"; export default function Home() { return ( <div> <PopoverDemo></PopoverDemo> </div> ); }
组件显示效果

解决方案
问题根源在于shadcn/ui的PopoverContent默认启用焦点陷阱(focus trap),拦截了鼠标点击事件,导致无法传递给内部的Command组件。只需两步修改即可解决:
1. 关闭Popover的焦点陷阱
给PopoverContent添加focusTrap={false}属性,解除事件拦截:
<PopoverContent className="w-80" focusTrap={false}> {/* 内部Command组件代码保持不变 */} </PopoverContent>
2. 为CommandItem添加点击回调(可选但推荐)
按照shadcn Demo的标准做法,给每个CommandItem绑定onSelect回调,确保交互逻辑完整:
<CommandItem onSelect={() => console.log("Calendar selected")}> <CalendarIcon className="mr-2 h-4 w-4" /> <span>Calendar</span> </CommandItem>
完整修改后的PopoverDemo代码
import { Button } from "@/components/ui/button"; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from "@/components/ui/command"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { CalendarIcon, EnvelopeClosedIcon, FaceIcon, GearIcon, PersonIcon, RocketIcon } from "@radix-ui/react-icons"; export function PopoverDemo() { return ( <Popover> <PopoverTrigger asChild> <Button variant="outline">Open popover</Button> </PopoverTrigger> <PopoverContent className="w-80" focusTrap={false}> <Command className="rounded-lg border shadow-md"> <CommandInput placeholder="Type a command or search..." /> <CommandList> <CommandEmpty>No results found.</CommandEmpty> <CommandGroup heading="Suggestions"> <CommandItem onSelect={() => console.log("Calendar selected")}> <CalendarIcon className="mr-2 h-4 w-4" /> <span>Calendar</span> </CommandItem> <CommandItem onSelect={() => console.log("Search Emoji selected")}> <FaceIcon className="mr-2 h-4 w-4" /> <span>Search Emoji</span> </CommandItem> <CommandItem onSelect={() => console.log("Launch selected")}> <RocketIcon className="mr-2 h-4 w-4" /> <span>Launch</span> </CommandItem> </CommandGroup> <CommandSeparator /> <CommandGroup heading="Settings"> <CommandItem onSelect={() => console.log("Profile selected")}> <PersonIcon className="mr-2 h-4 w-4" /> <span>Profile</span> </CommandItem> <CommandItem onSelect={() => console.log("Mail selected")}> <EnvelopeClosedIcon className="mr-2 h-4 w-4" /> <span>Mail</span> </CommandItem> <CommandItem onSelect={() => console.log("Settings selected")}> <GearIcon className="mr-2 h-4 w-4" /> <span>Settings</span> </CommandItem> </CommandGroup> </CommandList> </Command> </PopoverContent> </Popover> ); }
内容的提问来源于stack exchange,提问作者BlackLabrador
相关产品推荐
相关产品推荐

