<TruncateMarkup /> Examples

Without truncating

User roles: Admin, Editor, Collaborator, User
const userRoles = ['Admin', 'Editor', 'Collaborator', 'User'];

<div style={{ border: '1px dashed #c7c7c7', width: '250px' }}>
  <strong>User roles: </strong>
  {userRoles.join(', ')}
</div>

1 line truncating

User roles: Admin, Editor, Col...
const userRoles = ['Admin', 'Editor', 'Collaborator', 'User'];

<TruncateMarkup>
  <div style={{ border: '1px dashed #c7c7c7', width: '250px' }}>
    <strong>User roles: </strong>
    {userRoles.join(', ')}
  </div>
</TruncateMarkup>

3 line truncating

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididun...
<TruncateMarkup lines={3}>
  <div style={{ border: '1px dashed #c7c7c7', width: '250px' }}>
    {'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ' +
      'eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ' +
      'ad minim veniam, quis nostrud exercitation ullamco laboris nisi ' +
      'ut aliquip ex ea commodo consequat.'}
  </div>
</TruncateMarkup>

With custom ellipsis

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod temp... read more
const longText =
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ' +
  'eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ' +
  'ad minim veniam, quis nostrud exercitation ullamco laboris nisi ' +
  'ut aliquip ex ea commodo consequat.';

const readMoreEllipsis = (
  <span>
    ...{' '}
    <span onClick={this.toggleTruncate} style={link}>
      read more
    </span>
  </span>
);

{this.state.shouldTruncate ? (
  <TruncateMarkup lines={3} ellipsis={readMoreEllipsis}>
    <div style={{ border: '1px dashed #c7c7c7', width: '250px' }}>
      {longText}
    </div>
  </TruncateMarkup>
) : (
  <div style={{ border: '1px dashed #c7c7c7', width: '250px' }}>
    {longText}
    <span onClick={this.toggleTruncate} style={link}>
      {' show less'}
    </span>
  </div>
)}

With ellipsis callback

User roles: Admin,... (+3 roles)
const userRoles = ['Admin', 'Editor', 'Collaborator', 'User'];

const rolesLeftEllipsis = node => {
  const displayedRoles = node.props.children[1];

  const originalRolesCount = userRoles.length;
  const displayedRolesCount = displayedRoles
    ? displayedRoles.split(', ').filter(Boolean).length
    : 0;

  return `... (+${originalRolesCount - displayedRolesCount} roles)`;
};

<TruncateMarkup lines={1} ellipsis={rolesLeftEllipsis}>
  <div style={{ border: '1px dashed #c7c7c7', width: '250px' }}>
    <strong>User roles: </strong>
    {userRoles.join(', ')}
  </div>
</TruncateMarkup>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tem... (+24 words)
const longText =
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ' +
  'eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ' +
  'ad minim veniam, quis nostrud exercitation ullamco laboris nisi ' +
  'ut aliquip ex ea commodo consequat.';

const wordCountEllipsis = node => {
  const originalWordCount = longText.match(/\S+/g).length;
  const currentWordCount = node.props.children.match(/\S+/g).length;

  return `... (+${originalWordCount - currentWordCount} words)`;
};

<TruncateMarkup lines={3} ellipsis={wordCountEllipsis}>
  <div style={{ border: '1px dashed #c7c7c7', width: '250px' }}>
    {longText}
  </div>
</TruncateMarkup>

More markup

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incid...
<TruncateMarkup lines={3}>
  <div style={{ border: '1px dashed #c7c7c7', width: '250px' }}>
    <span style={{ color: 'tomato' }}>
      Lorem ipsum dolor sit amet,{' '}
    </span>
    <span style={{ color: 'royalblue', fontWeight: 'bold' }}>
      consectetur adipiscing elit,{' '}
    </span>
    <span style={{ color: 'tomato' }}>
      sed do eiusmod tempor incididunt{' '}
    </span>
    <span style={{ color: 'royalblue', fontWeight: 'bold' }}>
      ut labore et dolore magna aliqua.{' '}
    </span>
    <span style={{ color: 'tomato' }}>
      Ut enim ad minim veniam, quis nostrud exercitation ullamco
    </span>
  </div>
</TruncateMarkup>

In resizable box

User roles: Admi... (+3 roles)
const userRoles = ['Admin', 'Editor', 'Collaborator', 'User'];

const rolesLeftEllipsis = node => {
  const displayedRoles = node.props.children[1];

  const originalRolesCount = userRoles.length;
  const displayedRolesCount = displayedRoles
    ? displayedRoles.split(', ').filter(Boolean).length
    : 0;

  return `... (+${originalRolesCount - displayedRolesCount} roles)`;
};

<TruncateMarkup lines={1} ellipsis={rolesLeftEllipsis}>
  <div>
    <strong>User roles: </strong>
    {userRoles.join(', ')}
  </div>
</TruncateMarkup>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmo... (+25 words)
const longText =
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ' +
  'eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ' +
  'ad minim veniam, quis nostrud exercitation ullamco laboris nisi ' +
  'ut aliquip ex ea commodo consequat.';

const wordCountEllipsis = node => {
  const originalWordCount = longText.match(/\S+/g).length;
  const currentWordCount = node.props.children.match(/\S+/g).length;

  return `... (+${originalWordCount - currentWordCount} words)`;
};

<TruncateMarkup lines={3} ellipsis={wordCountEllipsis}>
  <div>{longText}</div>
</TruncateMarkup>

onTruncate callback

User roles: Admin, Editor, C...
onTruncate called: 1x
Did truncate? Yes
const userRoles = ['Admin', 'Editor', 'Collaborator', 'User'];

<TruncateMarkup
  lines={1}
  onTruncate={wasTruncated => {
    this.setState(state => ({
      onTruncateCalledCount:
        state.onTruncateCalledCount + 1,
      lastWasTruncated: wasTruncated,
    }));
  }}
>
  <div>
    <strong>User roles: </strong>
    {userRoles.join(', ')}
  </div>
</TruncateMarkup>

<div>
  onTruncate called: {this.state.onTruncateCalledCount}x
  Did truncate? {this.state.lastWasTruncated ? 'Yes' : 'No'}
</div>

Tokenize: words

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do... (+26 words)
const longText =
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do ' +
  'eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ' +
  'ad minim veniam, quis nostrud exercitation ullamco laboris nisi ' +
  'ut aliquip ex ea commodo consequat.';

const wordCountEllipsis = node => {
  const originalWordCount = longText.match(/\S+/g).length;
  const currentWordCount = node.props.children.match(/\S+/g).length;

  return `... (+${originalWordCount - currentWordCount} words)`;
};

<TruncateMarkup lines={3} tokenize="words" ellipsis={wordCountEllipsis}>
  <div>{longText}</div>
</TruncateMarkup>
  

TruncateMarkup.Atom

(NORMAL text - splittable anywhere) (atomic, not splittable) ...
<TruncateMarkup lines={3}>
  <div>
    <b>
      (<i>NORMAL</i> text - splittable anywhere)
    </b>

    <TruncateMarkup.Atom>
      <i> (atomic, not splittable) </i>
    </TruncateMarkup.Atom>

    <TruncateMarkup.Atom>
      <Foo>
        <b>(Foo Component that can be used, not splittable)</b>
      </Foo>
    </TruncateMarkup.Atom>
  </div>
</TruncateMarkup>

Avatars example

Patrik Piskay
Patrik Piskay
Patrik Piskay
+3 more
const user = {
  name: 'Patrik Piskay',
  image:
    'https://avatars2.githubusercontent.com/u/966953?s=460&u=6e5b5f2a85a02ace66548f5cf1a105a22f73fc71',
};

const users = Array(6)
  .fill(user)
  .map((user, index) => ({ ...user, id: index }));

const usersLeftEllipsis = (node) => {
  const usersRendered = node.props.children;

  return `+${users.length - usersRendered.length} more`;
};

<TruncateMarkup lines={1} lineHeight="38px" ellipsis={usersLeftEllipsis}>
  <div
    style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center' }}
  >
    {users.map((user) => (
      <TruncateMarkup.Atom key={user.id}>
        <Avatar user={user} />
      </TruncateMarkup.Atom>
    ))}
  </div>
</TruncateMarkup>