react truncation

by AntowaKartowa

CSS

.truncate {
  position: relative;
  max-height: inherit;
  word-wrap: break-word;
  overflow: hidden;

  &__measure {
    position: absolute;
    display: inline-block;
    opacity: 0;
    top: -1000px;
    z-index: -1;
  }
}

JavaScript

import React, {Component} from "react";
import BEM from "helpers/BEM";

if (process.env.BROWSER) {
  require("./Truncate.less");
}

const bTruncate = new BEM.b("truncate");

/**
 * Class representing a functionality for Truncate component.
 * Takes two parameters: text and rows. Text should be plain without any
 * html markup.
 *
 * For better experience and avoiding blinking and shifting, wrapping element
 * should have defined font-size, line-height, max-height and overflow-hidden
 * css properties. max-height better set in em in relation to line-height and
 * rows propety value. Lets say you set line-height to 1.3em and visible rows
 * to 3 so max-height should be 1.3em * 3 = 3.9em.
 *
 * <caption>Default usage</caption>
 * @example
 * <Truncate
 *   text={ "Text that should be truncated" }
 *   rows={ 3 } />
 *
 * @extends {React.Component}
 * @see https://facebook.github.io/react/docs/component-api.html#react.component
 */
export default class Truncate extends Component {

  /**
   * DefaultProps
   * @type {Object}
   */
  static defaultProps = {
    text: " ",
    rows: 2
  };

  /**
   * @param {String}  props.text    - Text that should be truncated in case it
   *                                  exceeds defined row limitation.
   * @param {Number}  props.rows    - rows quantity that could be visible
   */

  /**
   * Container width to follow changes on shouldComponentUpdate
   */
  __width = 0;

  /**
   * Font (m letter) line height. Measured for counting rows
   */
  __mHeight = null;

  /**
   * Font (m letter) doubled width. Used to calc enough space for ellipsis
   */
  __m2Width = null;

  /**
   * Text with additional markup for tracing optimal place for truncation
   */
  __markedup = "";

  /**
   * Lifecycle method   componentDidMount() {
   * @see https://facebook.github.io/react/docs/react-component.html#mounting-componentdidmount
   */
  componentDidMount() {
    this.__addFontMeasure();
    this.__saveFontMeasures();
   ...