鼠标离开时自动折叠Shadcn-UI手风琴的实现问题
解决思路与代码修改
问题根源
你当前用纯CSS hover 伪类控制侧边栏宽度,但手风琴的展开状态是独立管理的——鼠标离开侧边栏时,宽度收缩但手风琴仍保持展开,导致内容被挤压出现显示异常;且之前尝试的onMouseLeave未联动手风琴的状态控制,所以没效果。
解决方案步骤
- 改用React状态管理侧边栏的展开/收缩状态,替代纯CSS hover,实现状态与样式、手风琴的联动
- 监听侧边栏的
onMouseEnter/onMouseLeave事件,同步更新侧边栏宽度与手风琴折叠状态 - 通过Shadcn-ui Accordion的
value属性,控制手风琴的展开/折叠
修改后的完整代码
"use client"; // NextJS 13.4+ App Router 需添加该指令 import { useState } from "react"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "@/components/ui/accordion"; import Link from "next/link"; import { MdLock, MdCorporateFare, MdDashboard, MdDevices } from "react-icons/md"; export default function Sidebar() { // 侧边栏展开状态 const [sidebarExpanded, setSidebarExpanded] = useState(false); // 手风琴选中项(single类型下,null代表全部折叠) const [accordionValue, setAccordionValue] = useState<string | null>(null); return ( <div className={`fixed left-0 bg-primary h-full shadow-lg w-fit transition-all duration-300 ${ sidebarExpanded ? "md:w-[20%] w-[50%]" : "md:w-[5%] w-[15%]" }`} onMouseEnter={() => setSidebarExpanded(true)} onMouseLeave={() => { setSidebarExpanded(false); // 侧边栏收缩时自动折叠所有手风琴 setAccordionValue(null); }} > <Accordion type="single" collapsible className="w-full" value={accordionValue} onValueChange={setAccordionValue} > <AccordionItem value="item-1" className="sidebarItem"> <AccordionTrigger className="p-5"> <MdDashboard /> </AccordionTrigger> <AccordionContent> <ul> <li className="hover:bg-tertiary p-5"> <Link href="/page">an item</Link> </li> <li className="text-secondary p-5 hover:bg-tertiary"> <Link href="/page">an item</Link> </li> </ul> </AccordionContent> </AccordionItem> <AccordionItem value="item-2" className="sidebarItem"> <AccordionTrigger className="p-5"> <MdCorporateFare /> </AccordionTrigger> <AccordionContent> <ul> <li className="hover:bg-tertiary p-5"> <Link href="/page" className="text-ellipsis">an item</Link> </li> <li className="text-secondary p-5 hover:bg-tertiary"> <Link href="/page">an item</Link> </li> </ul> </AccordionContent> </AccordionItem> <AccordionItem value="item-3" className="sidebarItem"> <AccordionTrigger className="p-5"> <MdDevices /> </AccordionTrigger> <AccordionContent> <ul> <li className="hover:bg-tertiary p-5"> <Link href="/page">an item</Link> </li> <li className="text-secondary p-5 hover:bg-tertiary "> <Link href="/page" className="text-ellipsis">an item</Link> </li> </ul> </AccordionContent> </AccordionItem> <AccordionItem value="item-4" className="sidebarItem"> <AccordionTrigger className="p-5"> <MdLock className="text-secondary " /> </AccordionTrigger> <AccordionContent> <ul> <li className="text-secondary p-5 hover:bg-tertiary easing text-ellipsis w-fit"> <Link href="/page">an item</Link> </li> <li className="text-secondary p-5 hover:bg-tertiary easing text-ellipsis"> <Link href="/page">an item</Link> </li> </ul> </AccordionContent> </AccordionItem> </Accordion> </div> ); }
关键修改点说明
- 状态管理:新增
sidebarExpanded控制侧边栏宽度,accordionValue控制手风琴展开项 - 事件绑定:给侧边栏容器添加
onMouseEnter/onMouseLeave,鼠标离开时同时收缩侧边栏并折叠手风琴 - 样式切换:用模板字符串根据状态切换宽度类,替代纯CSS hover,确保状态与样式同步
- Accordion联动:将
Accordion的value与accordionValue绑定,通过onValueChange更新选中状态,离开时重置为null实现全折叠
内容的提问来源于stack exchange,提问作者Winter
相关产品推荐
相关产品推荐

