动画抽屉效果展开和缩小效果

114 阅读1分钟

动画抽屉效果展开和缩小效果, 动画效果用css的transition来实现 单独只能打开一个用js的react的useState来实现

.content {
    max-height: 0;
    overflow: hidden;
    transition: all 0.6s ease-in-out 0s;

    &.expand {
      max-height: 900px;
      overflow: auto;
    }
}

单个展开效果

const ExpandContent = ({
  title,
  selected,
  children,
  className,
  maxHeight,
}: TabProps) => {
  const ref = useRef<HTMLDivElement>(null);
  const [expand, setExpand] = React.useState(false);
  const [hideReadMore, setHideReadMore] = useState(false);

  const toggleExpand = () => setExpand(!expand);

  useEffect(() => {
    if (ref) {
      const current = ref.current;
      if (current) {
        if (current.clientHeight < maxHeight && !hideReadMore) {
          setHideReadMore(true);
        }
      }
    }
  }, [hideReadMore, maxHeight]);

  useEffect(() => {
    if (ref) {
      const current = ref.current;
      if (current) {
        if (!expand) {
          current.scroll(0, 0);
        }
      }
    }
  }, [expand]);

  return (
    <div className={`content ${selected ? "expand" : ""}`}>
      <div
        ref={ref}
        id={title}
        className={`tabcontent rich-editor-content ${className} ${
          expand ? "expand" : ""
        }`}
      >
        {children}
      </div>
      {hideReadMore ? null : (
        <div className="more div_bgmore" onClick={toggleExpand}>
          <div className="btn btn-readmore">
            <ArrowDown />
          </div>
        </div>
      )}
    </div>
  );
};

多个tab展开

const Tabs = ({ tabs }: Props) => {
  const isDesktop = useIsDesktop();
  const [current, setCurrent] = React.useState<number | undefined>(0);
  const clickTab = (index: number) => {
    if (index === current) {
      setCurrent(undefined);
    } else {
      setCurrent(index);
    }
  };

  return isDesktop ? (
    <>
      <div className="tab">
        {tabs.map(({ title }, index) => (
          <button
            key={index}
            className={current === index ? "tablinks active" : "tablinks"}
            onClick={() => clickTab(index)}
          >
            {title}
          </button>
        ))}
      </div>

      {tabs.map(({ title, content, className }, index) => (
        <ExpandContent
          key={index}
          title={title}
          maxHeight={320}
          selected={current === index}
          content={content}
          className={className}
        >
          <div dangerouslySetInnerHTML={{ __html: content }} />
        </ExpandContent>
      ))}
    </>
  ) : (
    <div>
      {tabs.map(({ title, content, className }, index) => (
        <React.Fragment key={index}>
          <div className="tab">
            <button
              key={index}
              className={current === index ? "tablinks active" : "tablinks"}
              onClick={() => {
                clickTab(index);
              }}
            >
              {title}
              <ArrowDown />
            </button>
          </div>
          <ExpandContent
            key={index}
            title={title}
            maxHeight={320}
            selected={current === index}
            content={content}
            className={className}
          >
            <div dangerouslySetInnerHTML={{ __html: content }} />
          </ExpandContent>
        </React.Fragment>
      ))}
    </div>
  );
};