69 lines
2.5 KiB
JavaScript
69 lines
2.5 KiB
JavaScript
import { useState } from 'react'
|
||
import { UpOutlined, DownOutlined } from '@ant-design/icons'
|
||
import './ExtendInfoPanel.css'
|
||
|
||
/**
|
||
* 扩展信息面板组件
|
||
* @param {Object} props
|
||
* @param {Array} props.sections - 信息区块配置数组
|
||
* @param {string} props.sections[].key - 区块唯一键
|
||
* @param {string} props.sections[].title - 区块标题
|
||
* @param {ReactNode} props.sections[].icon - 标题图标
|
||
* @param {ReactNode} props.sections[].content - 区块内容
|
||
* @param {boolean} props.sections[].defaultCollapsed - 默认是否折叠
|
||
* @param {boolean} props.sections[].hideTitleBar - 是否隐藏该区块的标题栏(默认 false)
|
||
* @param {string} props.layout - 布局方式:'vertical'(垂直堆叠)| 'horizontal'(水平排列)
|
||
* @param {string} props.className - 自定义类名
|
||
*/
|
||
function ExtendInfoPanel({ sections = [], layout = 'vertical', className = '' }) {
|
||
const [collapsedSections, setCollapsedSections] = useState(() => {
|
||
const initial = {}
|
||
sections.forEach((section) => {
|
||
if (section.defaultCollapsed) {
|
||
initial[section.key] = true
|
||
}
|
||
})
|
||
return initial
|
||
})
|
||
|
||
const toggleSection = (key) => {
|
||
setCollapsedSections((prev) => ({
|
||
...prev,
|
||
[key]: !prev[key],
|
||
}))
|
||
}
|
||
|
||
return (
|
||
<div className={`extend-info-panel extend-info-panel-${layout} ${className}`}>
|
||
{sections.map((section) => {
|
||
const isCollapsed = collapsedSections[section.key]
|
||
const hideTitleBar = section.hideTitleBar === true
|
||
|
||
return (
|
||
<div key={section.key} className="extend-info-section">
|
||
{/* 区块头部 - 可配置隐藏 */}
|
||
{!hideTitleBar && (
|
||
<div className="extend-info-section-header" onClick={() => toggleSection(section.key)}>
|
||
<div className="extend-info-section-title">
|
||
{section.icon && <span className="extend-info-section-icon">{section.icon}</span>}
|
||
<span>{section.title}</span>
|
||
</div>
|
||
<button className="extend-info-section-toggle" type="button">
|
||
{isCollapsed ? <DownOutlined /> : <UpOutlined />}
|
||
</button>
|
||
</div>
|
||
)}
|
||
|
||
{/* 区块内容 - 如果隐藏标题栏则总是显示,否则根据折叠状态 */}
|
||
{(hideTitleBar || !isCollapsed) && (
|
||
<div className="extend-info-section-content">{section.content}</div>
|
||
)}
|
||
</div>
|
||
)
|
||
})}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default ExtendInfoPanel
|