react-truncate

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

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
react-truncate
2.4.06 years ago8 years agoMinified + gzip package size for react-truncate in KB

Readme

React-Truncate
!NPM versionnpm-imagenpm-url !Downloadsdownloads-imagenpm-url !Build statustravis-imagetravis-url !Coverage statuscoveralls-imagecoveralls-url !Dependency statusdavid-dm-imagedavid-dm-url !Dev dependency statusdavid-dm-dev-imagedavid-dm-dev-url

Install

$ npm install react-truncate

Usage

import Truncate from '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) | <Truncate trimWhitespace>{longText}</Truncate> | | width | number | 0 | If not 0, the calculation of the content will be based on this number. | <Truncate trimWhitespace>{longText}</Truncate> | | 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 }) |

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 '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
  • https://github.com/Automattic/node-canvas#installation

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