1.安装react-spring
npm install react-spring@9.7.3
npm install react-use-measure@2.1.1
2.html部分
import React, { useState, useEffect } from "react";
import { useSpring, animated } from "react-spring";
import useMeasure from 'react-use-measure';
import ArrowIcon from '@/assets/arrow.png';
import keyUpgradesIcon from '@/assets/14.png';
import "./index.less";
const CollapsablePanel = ({ title, content, activeId, coll, onChange, currentClick, className,headClassName,arrowAnimial=true,englishHeader, arrow, showArrow=true, keyUpgrades }) => {
const currentClickId = currentClick?.id;
const [isCollapsed, setIsCollapsed] = useState(true);
const [ref, bounds] = useMeasure();
useEffect(() => {
console.log(coll,'content====')
if((activeId && activeId == coll.id)){
setIsCollapsed(false);
}else {
setIsCollapsed(true);
}
},[activeId]);
const togglePanel = () => {
setIsCollapsed((prevState) => !prevState);
if(onChange){
onChange(coll);
}
};
const panelContentAnimatedStyle = useSpring({
height: isCollapsed ? 0 : bounds.height,
});
const toggleWrapperAnimatedStyle = useSpring({
transform: isCollapsed ? "rotate(0deg)" : "rotate(180deg)",
});
const showBac = isCollapsed && currentClick?.parentKey == coll.key;
return (
<div className={`${className || 'pannel'} ${isCollapsed || title == '新手入门'?'':'active-panel'}`} >
<div onClick={togglePanel} className={`heading ${headClassName} ${(currentClickId && currentClickId == coll.id) || showBac?'active-header':''}`}>
{
englishHeader?(
<div className="en-header-con" >
<div className="collapse-header-text cn-text" >{title}</div>
<div className="en-text" >Getting started</div>
</div>
): (
<span className="collapse-header-text" >
{title}
{keyUpgrades && <img alt="" src={keyUpgradesIcon} />}
</span>
)
}
{
showArrow? arrowAnimial?(
<animated.div className='arrow' style={toggleWrapperAnimatedStyle}>
<img alt="" src={ArrowIcon} />
</animated.div>
):(
<div className={`arrow ${arrow}`} >
<img alt="" src={ArrowIcon} />
</div>
):null
}
</div>
{
content?(
<animated.div
style={panelContentAnimatedStyle}
className="content"
>
<div ref={ref} className="contentInner" >
{content}
</div>
</animated.div>
):null
}
</div>
);
};
export default CollapsablePanel;
3.css部分
.pannel {
width: 100%;
text-align: left;
padding: 4px;
border-radius: 10px;
border-bottom: 0px;
box-sizing: border-box;
margin-bottom: 4px;
}
.active-panel{
background: rgba(0,0,0,0.04);
}
.heading {
line-height: 15px;
padding: 9.5px 14px 9.5px 10px;
color: rgba(0,0,0,0.86);
font-size: 12px;
border-radius: 8px;
align-items: center;
user-select: none;
cursor: pointer;
display: flex;
justify-content: space-between;
font-weight: bold;
.ant-collapse-arrow{
font-size: 11px;
}
.collapse-header-text{
white-space: normal;
word-wrap: break-word;
word-break: break-all;
display: flex;
align-items: center;
>img{
width: 26px;
margin-left: 5px;
}
}
.en-header-con{
padding: 14px 0px;
.cn-text{
height: 14px;
line-height: 14px;
}
.en-text{
color: rgba(0,0,0,0.46);
font-size: 10px;
height: 12px;
line-height: 12px;
margin-top: 4px;
}
}
.arrow{
min-width: 16px;
height: 16px;
margin-left: 24px;
display: flex;
img{
width: 16px;
height: 16px;
}
}
.to-right{
transform: rotate(-90deg);
}
}
.active-header{
background: linear-gradient(90deg,rgba(0,0,0,0.08), rgba(0,0,0,0.00));
}
.content {
font-size: 10px;
border-top: none;
color: #000000;
overflow: hidden;
.coll-item {
padding: 0 16px;
}
}
.coll-item-con{
padding: 4px 0px;
cursor: pointer;
}
.coll-item{
box-sizing: border-box;
line-height: 28px;
font-size: 12px;
color: rgba(0,0,0,0.86);
border-radius: 7px;
}
.active-item-con{
.coll-item{
background: linear-gradient(90deg,rgba(0,0,0,0.08), rgba(0,0,0,0.00));
}
}
.white-coll{
background-color: #fff;
margin-bottom: 10px;
border-radius: 14px;
padding: 21.5px 4px;
.heading{
padding: 0px 14px 0px 10px;
background-color: #fff;
color: rgba(0,0,0,0.86);
font-weight: bold;
font-size: 14px;
line-height: 17px;
}
.content {
padding: 0 16px;
}
.contentInner {
padding-top: 20px;
padding-bottom: 20px;
}
}