省略文字,动态行,查看更多显示全部 组件

备注:

  1. 使用 TypeScriptReact的函数式组件语法。此组件的目的是显示文本,如果文本内容超出了指定的行数,它将显示一个“查看更多”的按钮。
  2. 当用户点击这个按钮时,将展示全部的文本内容。组件使用了自定义的钩子
    useBoundingClientRect 来确定是否需要显示这个按钮
//index.tsx文件
import type { FC, JSX } from 'react';
import { Fragment, useState } from 'react';
import type { StandardProps } from '@tarojs/components';
import { Image, Text, View } from '@tarojs/components';

import iconDropDown from '@/assets/icons/icon-dorpdown-primary.svg';
import useBoundingClientRect from '@/hooks/useBoundingClientRect';

import './index.less';

interface EllipsisProps {
  rows?: number;
  /**
   * 收起节点
   */
  foldRender?: JSX.Element;
  /**
   * 是否显示收取按钮
   */
  showFold?: boolean;
  /**
   * 展开节点
   */
  unfoldRender?: JSX.Element;
  /**
   * 是否显示展开按钮
   */
  showUnfold?: boolean;
  onChange?: (val: boolean) => void;
}

const Ellipsis: FC<EllipsisProps & StandardProps> = ({
  rows = 1,
  children,
  className,
  showUnfold,
  unfoldRender,
}) => {
  const [show, setShow] = useState(false);
  const [rectAssist] = useBoundingClientRect('#rectAssist', [children]);
  const [rectActual] = useBoundingClientRect('#rectActual', [children]);

  const style = {
    lineClamp: rows,
    webkitLineClamp: rows,
  };

  const showMoreBtn =
    !show &&
    showUnfold &&
    rectActual?.height &&
    rectAssist?.height &&
    Number(rectActual?.height) !== Number(rectAssist?.height);

  return (
    <Fragment>
      <View
        style={{ position: 'absolute', left: 0, top: -999999, opacity: 0 }}
        className={className}
        id="rectAssist"
      >
        {children}
      </View>

      <View
        className={`lineClamp__1 ${className}`}
        style={!show ? style : { display: 'block' }}
        id="rectActual"
      >
        {children}
        {!!showMoreBtn && (
          <View className="unfold-wrap" id="unfoldWrap" onClick={() => setShow(true)}>
            {unfoldRender || (
              <View className="unfold-btn">
                <Text>查看更多</Text>
                <Image src={iconDropDown} />
              </View>
            )}
          </View>
        )}
      </View>
    </Fragment>
  );
};

export default Ellipsis;

css样式index.less

.lineClamp(@row) {
  display: -webkit-box;
  overflow: hidden;
  line-clamp: @row;
  -webkit-line-clamp: @row;
  -webkit-box-orient: vertical;
  position: relative;
}

.lineClamp__1 {
  .lineClamp(1);

  &::after {
    color: red;
    position: absolute;
    right: 0;
    bottom: 5px;
  }
}

.lineClamp__2 {
  .lineClamp(2);
}

.lineClamp__3 {
  .lineClamp(3);
}

.unfold-wrap {
  position: absolute;
  right: 0;
  bottom: 0;
  display: flex;
  background: linear-gradient(to left, #fff, #fff, #fff, rgba(255, 255, 255, 0.4));
}

.unfold-btn {
  display: flex;
  flex-direction: row;
  align-items: center;
  min-width: 32px;
  padding: 4px 10px 4px 30px;
  line-height: 1;

  text {
    color: #b89962;
    font-size: 12px;
    font-style: normal;
    font-weight: 400;
    line-height: 12px; /* 100% */
  }

  image {
    width: 13px;
    height: 12px;
  }
}

使用组件

<View>
   <Ellipsis className={styles.name}>{'未知文字文字文字'}</Ellipsis> 
</View>

你可能感兴趣的:(javascript,前端)