Next.js中实现仅点击箭头图标折叠Accordion的需求
解决react-accessible-accordion仅点击箭头触发折叠的问题
基于react-accessible-accordion的修改方案
该包默认让AccordionItemButton包裹的整个区域都可触发折叠,要实现仅箭头触发,需调整组件结构,将AccordionItemButton仅包裹箭头图标,标题文字放在按钮外部,同时保证无障碍特性:
- 调整组件层级,把标题文字和箭头按钮放在同一容器内,仅箭头作为触发按钮:
import { Accordion, AccordionItem, AccordionItemHeading, AccordionItemButton, AccordionItemPanel } from 'react-accessible-accordion'; import Chevron from './Chevron'; const MyAccordion = () => { return ( <Accordion> <AccordionItem> <AccordionItemHeading> <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '1rem' }}> {/* 标题文字,点击不触发折叠 */} <span aria-labelledby="accordion-btn-1">这是折叠面板标题</span> {/* 仅箭头作为触发按钮 */} <AccordionItemButton id="accordion-btn-1" style={{ background: 'none', border: 'none', padding: 0, cursor: 'pointer' }}> <Chevron /> </AccordionItemButton> </div> </AccordionItemHeading> <AccordionItemPanel> <p>折叠面板内容区域,点击标题不会展开/收起,只有点击箭头才会触发</p> </AccordionItemPanel> </AccordionItem> </Accordion> ); }; export default MyAccordion;
- 无障碍优化:给按钮添加唯一
id,标题文字通过aria-labelledby关联按钮,确保屏幕阅读器能正确关联标题和触发控件。
自定义Accordion替代方案
如果觉得现有包限制较多,完全可以用React Hooks实现一个简易折叠组件,精准控制触发区域:
import { useState } from 'react'; import Chevron from './Chevron'; const CustomAccordion = ({ items = [] }) => { const [activeIdx, setActiveIdx] = useState(null); const togglePanel = (idx) => { setActiveIdx(prev => prev === idx ? null : idx); }; return ( <div className="accordion-container"> {items.map(({ title, content }, idx) => ( <div key={idx} className="accordion-item"> <div className="accordion-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '1rem', borderBottom: '1px solid #eee' }}> <h3 className="accordion-title">{title}</h3> {/* 仅箭头按钮触发折叠 */} <button onClick={() => togglePanel(idx)} aria-expanded={activeIdx === idx} className="accordion-toggle-btn" style={{ background: 'transparent', border: 'none', cursor: 'pointer' }} > <Chevron isOpen={activeIdx === idx} /> </button> </div> {activeIdx === idx && ( <div className="accordion-panel" style={{ padding: '1rem' }}> {content} </div> )} </div> ))} </div> ); }; export default CustomAccordion;
使用方式:
<CustomAccordion items={[ { title: '标题1', content: '内容1' }, { title: '标题2', content: '内容2' } ]} />
这个自定义方案完全由你控制触发逻辑,只有点击箭头按钮才会展开/收起面板,同时保留了aria-expanded等无障碍属性,满足基础的无障碍要求。
内容的提问来源于stack exchange,提问作者Ram Chander
相关产品推荐
相关产品推荐

