Skip to content

nosferatu500/react-truncate

 
 

Repository files navigation

React-Truncate

![NPM version][npm-image] ![Downloads][downloads-image]

Install

$ yarn add @nosferatu500/react-truncate

Usage

import Truncate from '@nosferatu500/react-truncate'

// ...

class Foo extends Component {
  render() {
    return (
      <Truncate
        lines={3}
        ellipsis={
          <span>
            ... <a href="/link/to/article">Read more</a>
          </span>
        }>
        {longText}
      </Truncate>
    )
  }
}

Hint: (Generally with React) if you want to preserve newlines from plain text, you need to do as follows:

//...
{
  text.split('\n').map((line, i, arr) => {
    const line = <span key={i}>{line}</span>

    if (i === arr.length - 1) {
      return line
    } else {
      return [line, <br key={i + 'br'} />]
    }
  })
}
//...

API

Prop Type Default Description Example
lines integer, boolean {false} 1 Specifies how many lines of text should be preserved until it gets truncated. false and any integer < 1 will result in the text not getting clipped at all. (false, -1, 0), 1, ...
ellipsis string, React node '…' An ellipsis that is added to the end of the text in case it is truncated. '...', <span>...</span>, <span>... <a href='#' onClick={someHandler}>Read more</a></span>, [<span key='some'>Some</span>, <span key='siblings'>siblings<span>]
children string, React node The text to be truncated. Anything that can be evaluated as text. 'Some text', <p>Some paragraph <a/>with other text-based inline elements<a></p>, <span>Some</span><span>siblings</span>
trimWhitespace boolean false If true, whitespace will be removed from before the ellipsis (e.g. words ... will become words... instead)
width number 0 If not 0, the calculation of the content will be based on this number.
onTruncate function Gets invoked on each render. Gets called with true when text got truncated and ellipsis was injected, and with false otherwise. isTruncated => isTruncated !== this.state.isTruncated && this.setState({ isTruncated })
breakAll boolean false If true, lines will break at any place, not only on spaces (useful for example for truncating multiline URLs). <Truncate breakAll lines={3}>{longText}</Truncate>

Known issues

  • Resize content when the size of parent container changed (use the width property or call ref.onResize()). See issue
  • Text exceeding horizontal boundaries when "viewport" meta tag is not set accordingly for mobile devices (font boosting leads to wrong calculations). See issue
  • Output in plain text only - no support for markup/HTML. See issue
  • Wrong line breaks when custom font is loading after the component has rendered. See issue
  • No support for letter spacing / word spacing. See issue

Integrated example for toggling "read more" text

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Truncate from '@nosferatu500/react-truncate'

class ReadMore extends Component {
  constructor(...args) {
    super(...args)

    this.state = {
      expanded: false,
      truncated: false,
    }

    this.handleTruncate = this.handleTruncate.bind(this)
    this.toggleLines = this.toggleLines.bind(this)
  }

  handleTruncate(truncated) {
    if (this.state.truncated !== truncated) {
      this.setState({
        truncated,
      })
    }
  }

  toggleLines(event) {
    event.preventDefault()

    this.setState({
      expanded: !this.state.expanded,
    })
  }

  render() {
    const { children, more, less, lines } = this.props

    const { expanded, truncated } = this.state

    return (
      <div>
        <Truncate
          lines={!expanded && lines}
          ellipsis={
            <span>
              ...{' '}
              <a href="#" onClick={this.toggleLines}>
                {more}
              </a>
            </span>
          }
          onTruncate={this.handleTruncate}>
          {children}
        </Truncate>
        {!truncated && expanded && (
          <span>
            {' '}
            <a href="#" onClick={this.toggleLines}>
              {less}
            </a>
          </span>
        )}
      </div>
    )
  }
}

ReadMore.defaultProps = {
  lines: 3,
  more: 'Read more',
  less: 'Show less',
}

ReadMore.propTypes = {
  children: PropTypes.node.isRequired,
  lines: PropTypes.number,
  less: PropTypes.string,
  more: PropTypes.string,
}

export default ReadMore

Developing

Install system libraries needed for development dependencies

Install development dependencies

$ npm install

Run tests

$ npm test

Run code linter

$ npm run lint

Compile to ES5 from /src to /lib

$ npm run compile

About

React component for truncating multi-line spans and adding an ellipsis.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 72.9%
  • TypeScript 27.1%