You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React折叠面板中通过CSS Transform实现点击切换图标及背景色?

解决方案

1. 传递激活状态到样式组件

首先需要把组件内的isActive状态传递给Title、Icon和Content样式组件,让样式能根据状态动态调整:

修改后的React组件代码:

import { string, node, oneOf, bool } from "prop-types"
import * as Styled from "./Accordion.styled"
import Icon from "design-system/components/icon"
import React, { useState } from 'react'


const Accordion = ({ children, icon, text, button, color, activeColor }) => {
  const [isActive, setIsActive] = useState(false);
  return (
    <Styled.Accordion color={color}>
      <Styled.Title 
        onClick={() => setIsActive(!isActive)}
        color={isActive ? activeColor : color}
        isActive={isActive}
      > 
        {text}
        <Styled.Icon 
          color={isActive ? activeColor : color}
          isActive={isActive}
        >
          <Icon name={icon}/>
        </Styled.Icon> 
      </Styled.Title>
      {isActive && (
        <Styled.Content
          color={isActive ? activeColor : color}
          isActive={isActive}
        >
          {children} 
          {button}
        </Styled.Content>
      )}
    </Styled.Accordion>
  );
}

Accordion.propTypes = {
  text: string.isRequired,
  children: node.isRequired,
  icon: string,
  name: string,
  button: node,
  color: oneOf(["primary", "neutrals", "grey"]),
  activeColor: oneOf(["primary", "neutrals", "grey"]),
}

Accordion.defaultProps = {
  children: null,
  icon: null,
  name: null,
  button: null,
  color: "grey",
  activeColor: "primary",
}

export default Accordion

2. 实现图标旋转切换

在Icon样式组件中,通过transform结合isActive状态实现旋转效果,同时添加过渡动画让切换更平滑:

修改样式代码中的Icon部分:

export const Icon = styled.div`
  display: flex;
  align-items: center;
  width: auto;
  height: auto;
  transition: transform 0.3s ease-in-out;
  /* 可根据需求调整旋转角度,比如180度 */
  transform: ${({ isActive }) => isActive ? 'rotate(90deg)' : 'rotate(0deg)'};
`

3. 修正背景色与文字颜色的显示问题

你当前代码中文字颜色和背景色使用了同一个主题色值,导致文字无法看清。需要区分两者的颜色逻辑,比如背景色用指定主题色,文字用对比色:

修改Title和Content的样式:

export const Title = styled.div`
  width: auto;
  height: auto;
  display: inline-flex;
  gap: 161px;
  border-radius: 10px 10px 0px 0px;
  padding: 10px 10px 10px 10px;
  cursor: pointer;
  /* 文字用对比色 */
  color: ${({ color, theme }) => {
    switch (color) {
      case "grey":
        return theme.colors.white;
      case "neutrals":
        return theme.colors.neutrals[900];
      case "primary":
        return theme.colors.white;
      default:
        return theme.colors.white;
    };
  }};
  /* 背景用指定主题色 */
  background-color: ${({ color, theme }) => {
    switch (color) {
      case "grey":
        return theme.colors.grey[600];
      case "neutrals":
        return theme.colors.neutrals[100];
      case "primary":
        return theme.colors.primary[500];
      default:
        return theme.colors.grey[600];
    }
  }};
  transition: background-color 0.3s ease;
`

export const Content = styled.div`
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: start;
  width: auto;
  height: auto;
  border-radius: 0px 0px 10px 10px;
  padding: 10px 10px 10px 10px;
  /* 文字用对比色 */
  color: ${({ color, theme }) => {
    switch (color) {
      case "grey":
        return theme.colors.white;
      case "neutrals":
        return theme.colors.neutrals[900];
      case "primary":
        return theme.colors.white;
      default:
        return theme.colors.white;
    }
  }};
  /* 背景用指定主题色,可略浅于Title背景 */
  background-color: ${({ color, theme }) => {
    switch (color) {
      case "grey":
        return theme.colors.grey[500];
      case "neutrals":
        return theme.colors.neutrals[200];
      case "primary":
        return theme.colors.primary[400];
      default:
        return theme.colors.grey[500];
    }
  }};
  transition: background-color 0.3s ease;
`

4. 额外优化建议

为Content添加展开/收起的高度过渡动画,避免突然显示/隐藏:

export const Content = styled.div`
  /* 保留原有样式 */
  max-height: ${({ isActive }) => isActive ? '1000px' : '0'};
  overflow: hidden;
  transition: max-height 0.3s ease;
`

注意:添加此动画后,需要去掉原有的{isActive && ...}条件渲染,直接渲染Content组件,通过max-height控制显示。


内容的提问来源于stack exchange,提问作者Emilia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 06:55:16