在两行文字之后添加省略号和工具提示-React

时间:2019-01-01 16:10:53

标签: reactjs material-ui

是否可以创建一个React组件,该组件可以在两行之后添加省略号,并且仅在文本被换行时显示工具提示?

我已经tried使用“ noWrap”属性和附加的CSS自定义了Material UI的Typography组件,但是失败了。

请协助,我要实现以下屏幕: enter image description here

2 个答案:

答案 0 :(得分:1)

此问题有两个主要方面:

  • 基于垂直溢出显示省略号以显示文本溢出,以允许多于一行但不是无限行
  • 检测垂直溢出并在这种情况下包括工具提示功能

我不相信FrankerZ的解决方案会显示省略号。据我所知,text-overflow: ellipsis仅适用于水平溢出,这需要将文本限制为一行。

我找到了一种在垂直溢出here上执行省略号的解决方案,但是一旦将其包装在Material UI组件(例如ListItem)中,可能需要进行大量调整,从而将其他CSS引入混合,并且可能复杂到不值得。这种解决方案的效果是在每行文本的末尾保留省略号的空间,这似乎并不理想。对于这个问题,似乎还有其他解决方案,但是我本人(包括今天在内)还没有使用过它们。

第二部分(检测溢出)似乎更简单,由divRef.current.scrollHeight > divRef.current.offsetHeight处理。我通过找到许多参考文献来做这种解决方案,这些参考文献基于宽度来做类似的条件。在解决此问题时,我今天还没有亲自使用此技术,因此具有更深的CSS专业知识的人可能会为“您永远不要因为...而这么做”而感到困惑,但是它似乎有效(我尚未完成)任何重要的浏览器测试-仅在Chrome上进行过尝试。

为了方便语法,我在示例中使用了钩子,因此,如果您不使用alpha,则需要将状态,引用和效果工作转换为对应的类。当前,这也不在调整窗口大小,这需要重新评估工具提示是否应生效。有了这些警告,希望这将使您朝着可行的解决方案迈出几步。

代码如下:

import React, { useRef, useState, useEffect } from "react";
import ReactDOM from "react-dom";
import Tooltip from "@material-ui/core/Tooltip";
import { withStyles } from "@material-ui/core/styles";
/* 
CSS from http://hackingui.com/front-end/a-pure-css-solution-for-multiline-text-truncation/ 
Additional syntax help from https://stackoverflow.com/questions/40965977/cant-target-before-pseudo-selector-in-jss
*/
const styles = theme => ({
  listItem: {
    maxWidth: "20rem",
    overflow: "hidden",
    position: "relative",
    lineHeight: "1.2em",
    maxHeight: "2.4em",
    textAlign: "justify",
    marginRight: "-1em",
    paddingRight: "1em",
    borderBottom: "1px solid",
    marginBottom: "0.5em",
    "&&:before": {
      content: '"..."',
      position: "absolute",
      right: 0,
      bottom: 0
    },
    "&&:after": {
      content: '""',
      position: "absolute",
      right: 0,
      width: "1em",
      height: "1em",
      marginTop: "0.2em",
      background: "white"
    }
  }
});
const data = [
  "Some short text",
  "Some text that is a little bit longer",
  "Some text that will need to wrap but still fits on two lines",
  "Some text that will overflow because it is more than just two lines worth when the maxWidth is set at 20rem.",
  "A massive range of hammer drill machines and rotary hammers for SDS-plus accessory tools, designed for higher performance drilling and longer life - for easy drilling in concrete and other materials."
];
const TooltipDiv = props => {
  const divRef = useRef(null);
  const [allowTooltip, setAllowTooltip] = useState(false);
  useEffect(() => {
    if (
      !allowTooltip &&
      divRef.current.scrollHeight > divRef.current.offsetHeight
    ) {
      setAllowTooltip(true);
    }
  }, []);
  if (allowTooltip) {
    return (
      <Tooltip title={props.text}>
        <div ref={divRef} className={props.className}>
          {props.text}
        </div>
      </Tooltip>
    );
  }
  return (
    <div ref={divRef} className={props.className}>
      {props.text}
    </div>
  );
};
function App(props) {
  return (
    <>
      {data.map(text => {
        return (
          <>
            <TooltipDiv text={text} className={props.classes.listItem} />
          </>
        );
      })}
    </>
  );
}
const StyledApp = withStyles(styles)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<StyledApp />, rootElement);

您可以在此处查看其运行情况:

Edit 4xn3386z6x

答案 1 :(得分:0)

您可以简单地使用CSS来完成此任务:

.tooltip {
    overflow: hidden;
    text-overflow: ellipsis;
    height: /* Just enough to show 2 lines */
}

您还可以在this中看到更多资源/替代路线。