import React, { useRef, useState } from 'react'; import './Collapse.css'; /* 折叠面板(移动端)— 规格 §25 标题行是原生 button(整行热区、键盘可达)+ aria-expanded / aria-controls; 内容区收起时用 hidden 属性(而不是只靠 CSS 高度),读屏也不会读到收起的内容。 accordion=true 时展开新面板会收起当前展开项,其余模式互不影响。 本端不发明展开动画(内容区直接切 hidden):面板高度本由浏览器决定,不做高度换算。 */ /* 面板标题 / 内容区的 id:同页多实例不撞号(模块级自增即可) */ let seq = 0; export default function Collapse({ items = [], accordion = false, bordered = true, value = [], onChange, children = null, }) { const idRef = useRef(null); if (idRef.current === null) { seq += 1; idRef.current = 'kole-m-collapse-' + seq; } const base = idRef.current; /* null = 跟随 value 属性;点击后本地记账(与 DatePicker 同一约定) */ const [open, setOpen] = useState(null); const expanded = open || value; function toggle(key) { const has = expanded.indexOf(key) >= 0; const next = accordion ? has ? [] : [key] : has ? expanded.filter((k) => k !== key) : expanded.concat([key]); setOpen(next); if (onChange) onChange(key, !has); } return (
{items.map((it, i) => { const key = it && it.key !== undefined ? it.key : i; const isOpen = expanded.indexOf(key) >= 0; const headerId = `${base}-header-${key}`; const panelId = `${base}-panel-${key}`; return (
); })} {children}
); }