Добавление многоточия и всплывающей подсказки после двух строк текста - React - PullRequest
0 голосов
/ 01 января 2019

Можно ли создать компонент React, который может добавить многоточие после двух строк и отображать всплывающую подсказку, только если текст обернут?

Я пробовал , настраивая пользовательский интерфейс материалаТипографский компонент со свойством «noWrap» и дополнительным CSS-кодом, но не выполнен.

Пожалуйста, помогите, я хочу получить что-то вроде этого экрана: enter image description here

Ответы [ 2 ]

0 голосов
/ 01 января 2019

Эта проблема имеет два основных аспекта:

  • Показать многоточие для переполнения текста на основе вертикального переполнения, чтобы разрешить более одной строки, но не без ограничений
  • Обнаружить вертикальноепереполнение и включение функции всплывающей подсказки в этом случае

Я не верю, что решение FrankerZ покажет многоточие.Насколько я могу судить, text-overflow: ellipsis работает только для горизонтального переполнения, которое требует ограничения текста одной строкой.

Я нашел решение для выполнения многоточия при вертикальном переполнении здесь , но этоможет потребоваться значительная доработка, как только вы начнете оборачивать это в компоненты пользовательского интерфейса материалов (например, ListItem), которые вносят дополнительный CSS в смесь, и это может стать достаточно сложным, чтобы не стоить этого.Это решение позволяет зарезервировать место для многоточия в конце каждой строки текста, что не кажется идеальным.Кажется, есть некоторые другие решения этой проблемы, но я сам не использовал ни одного из них (включая этот, кроме сегодняшнего).

Вторая часть (обнаружение переполнения) кажется более простой.и обрабатывается divRef.current.scrollHeight > divRef.current.offsetHeight.Я пришел к этому решению, найдя много ссылок на выполнение аналогичных условий на основе ширины.Я лично не использовал эту технику за пределами сегодняшнего дня при работе над этим ответом, поэтому кто-то с более глубокими знаниями CSS может вмешаться с «вы никогда не должны делать это из-за ...», но, похоже, работает (я не сделаллюбое серьезное тестирование браузера - пробовал только на Chrome).

В моем примере я использую хуки для удобства синтаксиса, поэтому, если вы не используете альфа, вам нужно перевести состояние,Ref, и эффект работы в соответствующих классах.Это также в настоящее время не касается изменения размера окна, что потребовало бы переоценки того, должна ли подсказка действовать.С этими предостережениями, надеюсь, это даст вам несколько шагов к работоспособному решению.

Вот код:

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

0 голосов
/ 01 января 2019

Вы можете просто использовать CSS для этого:

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

Вы также можете увидеть это для некоторых других ресурсов / альтернативных маршрутов.

...