控制多行文本展示,支持自定义传入行数

52 阅读1分钟

背景

最近实现一个需求,要求一个文本容器,支持输入字符串信息,要求超过8行则 显示 展开更多,不足8行则全部展示,也不显示 展开更多,基本的UI样式如下

image.png

image.png

代码实现

import React, { useState, useRef, useEffect } from 'react';
import { memo } from 'react';

const TextExpander = ({ text, lineClamp = 8 }) => {
  const [isExpanded, setIsExpanded] = useState(false);
  const [shouldShowToggle, setShouldShowToggle] = useState(false);
  const contentRef = useRef(null);

  useEffect(() => {
    if (contentRef.current) {
      const lineHeight = parseInt(
        getComputedStyle(contentRef.current).lineHeight,
        10
      );
      const maxHeight = lineHeight * lineClamp;
      const actualHeight = contentRef.current.scrollHeight;

      setShouldShowToggle(actualHeight > maxHeight);
    }
  }, [lineClamp, text]);

  const toggleExpand = () => {
    setIsExpanded(!isExpanded);
  };

  return (
    <div className="w-full">
      <div
        ref={contentRef}
        className="break-words font-sans text-[12px] text-base leading-relaxed"
        style={
          !isExpanded && shouldShowToggle
            ? {
                display: '-webkit-box',
                WebkitLineClamp: lineClamp,
                WebkitBoxOrient: 'vertical',
                overflow: 'hidden'
              }
            : {}
        }
      >
        {text}
      </div>
      {shouldShowToggle && (
        <button
          onClick={toggleExpand}
          className="mt-2 text-[#438DFB] transition-colors duration-200 focus:outline-none"
        >
          {isExpanded ? '收起' : '展开全部'}
        </button>
      )}
    </div>
  );
};

export default memo(TextExpander);

使用

<TextExpander text={item?.content}></TextExpander>}  不传则默认8行展示