Git Product home page Git Product logo

react-dotdotdot's Introduction

React-dotdotdot

Cross-browser multiline text ellipsis for react

Inspired by: https://github.com/BeSite/jQuery.dotdotdot

Internally uses: https://www.npmjs.com/package/clamp-js

Installation

npm install --save react-dotdotdot

Sample usage

import React from 'react'
import Dotdotdot from 'react-dotdotdot'

...

render() {
	return (
		<div>
			<Dotdotdot clamp={3}>
				<p>
					Long, long <br />
					content,<br />
					3 lines <br />
					will be shown.
				</p>
			</Dotdotdot>
		</div>
	)
}

Dotdotdot props:

clamp (Number | String | 'auto'). This controls where and when to clamp the text of an element. Submitting a number controls the number of lines that should be displayed. Second, you can submit a CSS value (in px or em) that controls the height of the element as a String. Finally, you can submit the word 'auto' as a string. Auto will try to fill up the available space with the content and then automatically clamp once content no longer fits. This last option should only be set if a static height is being set on the element elsewhere (such as through CSS) otherwise no clamping will be done.

useNativeClamp: [default: false] Use -webkit-line-clamp available in Webkit (Chrome, Safari) only.

splitOnChars: [default: ['.', '-', '–', '—', ' ']] Split on sentences (periods), hypens, en-dashes, em-dashes, and words (spaces).

animate: [default: false] animated clamp

truncationChar: The character to insert at the end of the HTML element after truncation is performed. This defaults to an ellipsis (…). useNativeClamp overrides it to default.

truncationHTML: String of HTML to use instead of truncationChar

tagName: [default: div] (String). The type of HTML tag which will wrap the component's content.

Notes

React-dotdotdot is simple plugin, if you need more functionality, consider using react-truncate https://www.npmjs.com/package/react-truncate

Known issues:

  • react-dotdotdot does not work with text containers with nested markup.
  • padding-bottom CSS rule breaks clamp
  • line-height units might be important for React-dotdotdot. We recommend px over em

Changelog

1.3.1

  • Update TypeScript definition to add missing props (thanks @tuxracer)
  • round line-height value from computed float value - IE11 fix (thanks @YoonjiJang)

1.3.0

  • useNativeClamp prop is set to false by default, it was causing some issues.
  • Comments are not counted as a text anymore
  • Remove Github's potential security vulnerability with react-dom

1.2.4

  • Added TypeScript typings (thanks @vojty and @feimosi)

1.2.3

  • Add the option to choose a tag other than div (thanks @Kalita-Roman)
  • Fix demo on Firefox
  • Added .npmignore to limit package size

1.2.2

  • Revert: Fix break word for long text
  • Update documentation

1.2.1

  • Update documentation
  • Re-trigger clamp on window.load
  • Allow for all params to passed to clamp-js (splitOnChars, animate, etc)

1.2.0

  • Fix word breaking for long text (issues #21 and #15; Thanks @krzysztofczernek).
  • calculate correct height for many childs + clamp: 'auto' (thanks @rurquia)
  • Update dependencies to support react 16 (thanks @emersonbroga)

1.0.17

  • Support for IE11, Edge and Firefox (thanks, @kkwiatkowski)

1.0.16

  • Remove clamp-js from package.json dependencies, as it's not maintained anymore.
  • Bugfix for TypeError: elem.lastChild is null in Firefox.

react-dotdotdot's People

Contributors

bstream avatar bxt avatar cezarydanielnowak avatar cooya avatar emersonbroga avatar kkwiatkowski avatar krzysztofczernek avatar nucleartide avatar rurquia avatar thinkkevin avatar tuxracer avatar v-honcharenko avatar yoonjijang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

react-dotdotdot's Issues

When page load, the full description flashes before getting resized

We are using NextJs in our React application for SSR (Server Side Rendering). When the page loads initially, it flashes the full description, causing the page to jump a bit (even leaving the text on top of some other elements). Is there any solution for SSR? Thanks :)

Ellipsis does not work for long text

Hello Mr CezaryDanielNowak,

I have tried to use your Dotdotdot component like this

<Dotdotdot clamp={2}>
  hello everyonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRR
</Dotdotdot>

And I got:

Capture d’écran 2021-02-17 à 21 58 23

So, I did the following changes:

const ClampedText = styled(Box)`
  overflow: hidden;
  text-overflow: ellipsis;
  -webkit-box-orient: vertical;
  display: inline-block;
  white-space: nowrap;
  -webkit-line-clamp: ${(props) => props.clamp ?? 1};
`;

And I used it like that:

<ClampedText clamp={2}>
  hello everyonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRReveryonFRRRRRRRRRRRRRRRR
</ClampedText>

And it worked for me:

Capture d’écran 2021-02-17 à 22 00 21

I only have changed the value of display and have added white-space.

Could you confirm if it is a bug in the component please?

Thx in advance.

useNativeClamp documentation is out of date

The documentation states that useNativeClamp defaults to true but I believe this was changed in version 1.3.0 (based on the changelogs). I think the correct fix here would be to simply update the documentation?

Error: Only a ReactOwner can have refs

I am having the following error when importing your library into my project:

addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's render method, or you have multiple copies of React loaded.

It seems to be due to this line:
https://github.com/CezaryDanielNowak/React-dotdotdot/blob/master/src/index.js#L47 where you have:

Dotdotdot.prototype.render = function() {
   return React.createElement(
   "div",
   { ref: "container", className: this.props.className },
   this.props.children
  );
 };

Once I change ref to id, the error disappears, but I guess it is not the most elegant solution:

Dotdotdot.prototype.render = function() {
  return React.createElement(
    "div",
    { id: "dotdotdot-container", className: this.props.className },
    this.props.children
  );
};

Breaks in Firefox when using white-space: pre-wrap

Miscalculates where to truncate (often truncating the entire text) in Firefox if using white-space: pre-wrap to display multiline text.

Works fine on Chrome.

Repro:

Style:

.formatted-text {
   white-space: pre-wrap;
}

Component:

<Dotdotdot
   className="formatted-text"
   clamp={2}>
   {children}
</Dotdotdot>

with .formatted-text in Firefox (empty):
image

with .formatted-text in Chrome (works):
image

without .formatted-text in Firefox (works, but no pre-wrap):
image

TypeError: Cannot read property 'length' of null

getting this error as react Dotdotdot not able to access container ref in case of snapshot testing this.dotdotdot(ReactDOM.findDOMNode(this.refs.container));.

 FAIL  src/scripts/Plp/tests/snapshot/Product.jsx
  ● Component: Product snapshot tests › renders correctly.

    TypeError: Cannot read property 'length' of null
      
      at ReactComponent.Object.<anonymous>.Dotdotdot.dotdotdot (node_modules/react-dotdotdot/src/index.js:29:18)
      at ReactComponent.Object.<anonymous>.Dotdotdot.componentDidMount (node_modules/react-dotdotdot/src/index.js:17:8)
      at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:265:25
      at measureLifeCyclePerf (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:75:12)
      at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:264:11
      at CallbackQueue.notifyAll (node_modules/react-test-renderer/lib/CallbackQueue.js:76:22)
      at ReactTestReconcileTransaction.close (node_modules/react-test-renderer/lib/ReactTestReconcileTransaction.js:36:26)
      at ReactTestReconcileTransaction.closeAll (node_modules/react-test-renderer/lib/Transaction.js:206:25)
      at ReactTestReconcileTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:153:16)
      at batchedMountComponentIntoNode (node_modules/react-test-renderer/lib/ReactTestMount.js:69:27)
      at ReactDefaultBatchingStrategyTransaction.perform (node_modules/react-test-renderer/lib/Transaction.js:140:20)
      at Object.batchedUpdates (node_modules/react-test-renderer/lib/ReactDefaultBatchingStrategy.js:62:26)
      at Object.batchedUpdates (node_modules/react-test-renderer/lib/ReactUpdates.js:97:27)
      at Object.render (node_modules/react-test-renderer/lib/ReactTestMount.js:125:18)
      at getComponent (src/scripts/Plp/tests/snapshot/Product.jsx:27:71)
      at Object.<anonymous> (src/scripts/Plp/tests/snapshot/Product.jsx:41:16)
      at process._tickCallback (internal/process/next_tick.js:103:7)

some of my finding:-
1> https://facebook.github.io/react/blog/2016/11/16/react-v15.4.0.html#mocking-refs-for-snapshot-testing
2> facebook/react#7371

not working with preact

I am trying to replace react with preact using preact-compat.
Then I got issue in console that hard to find any clue:

preact.esm.js:212 Uncaught (in promise) TypeError: value is not a function
    at setAccessor (preact.esm.js:212)
    at diffAttributes (preact.esm.js:555)
    at idiff (preact.esm.js:401)
    at diff (preact.esm.js:306)
    at renderComponent (preact.esm.js:727)
    at renderComponent (preact.esm.js:712)
    at setComponentProps (preact.esm.js:634)
    at buildComponentFromVNode (preact.esm.js:814)
    at idiff (preact.esm.js:355)
    at innerDiffNode (preact.esm.js:474)
    at idiff (preact.esm.js:397)
    at innerDiffNode (preact.esm.js:474)
    at idiff (preact.esm.js:397)
    at innerDiffNode (preact.esm.js:474)
    at idiff (preact.esm.js:397)
    at innerDiffNode (preact.esm.js:474)
    at idiff (preact.esm.js:397)
    at diff (preact.esm.js:306)
    at renderComponent (preact.esm.js:727)
    at setComponentProps (preact.esm.js:634)
    at buildComponentFromVNode (preact.esm.js:814)
    at idiff (preact.esm.js:355)
    at innerDiffNode (preact.esm.js:474)
    at idiff (preact.esm.js:397)
    at diff (preact.esm.js:306)
    at renderComponent (preact.esm.js:727)
    at setComponentProps (preact.esm.js:634)
    at buildComponentFromVNode (preact.esm.js:814)
    at idiff (preact.esm.js:355)
    at innerDiffNode (preact.esm.js:474)
    at idiff (preact.esm.js:397)
    at innerDiffNode (preact.esm.js:474)
    at idiff (preact.esm.js:397)
    at innerDiffNode (preact.esm.js:474)
    at idiff (preact.esm.js:397)
    at diff (preact.esm.js:306)
    at renderComponent (preact.esm.js:727)
    at renderComponent (preact.esm.js:712)
    at renderComponent (preact.esm.js:712)
    at setComponentProps (preact.esm.js:634)
    at buildComponentFromVNode (preact.esm.js:814)
    at idiff (preact.esm.js:355)
    at innerDiffNode (preact.esm.js:474)
    at idiff (preact.esm.js:397)
    at diff (preact.esm.js:306)
    at renderComponent (preact.esm.js:727)
    at setComponentProps (preact.esm.js:634)
    at buildComponentFromVNode (preact.esm.js:814)
    at idiff (preact.esm.js:355)
    at innerDiffNode (preact.esm.js:474)

After trying to add/remove kinds of component, I found this module is the cause.

The reason for it, either ref="container" , or this.refs.container doesn't work.
I tried to change the code like:

//...
Dotdotdot.prototype.componentDidMount = function() {
  this.dotdotdot(ReactDOM.findDOMNode(this.container));
  window.addEventListener('resize', this.update, false);
};
//...
Dotdotdot.prototype.componentDidUpdate = function() {
  this.dotdotdot(ReactDOM.findDOMNode(this.container));
};
//...
Dotdotdot.prototype.render = function() {
  var _ref = function (container) {
    this.container = container;
  }.bind(this);
  return React.createElement(
    "div",
    { ref: _ref,
    className: this.props.className },
    this.props.children
  );
};


Then it worked.

Doesn't rerender when available space increases

I wonder if this is a some sort of design choice, but it seems that the element doesn't recalculate the correct text amount when the available space increases. It can only shrink the text, not show more. It'd be really useful for responsive designs to also add back some of the text, if the room for it has increased.

React 16 support?

Error in ./LinkedValueUtils
Module not found: Error: Can't resolve 'react/lib/React' in '/project/node_modules/react-dotdotdot/node_modules/react-dom/lib'

Tooltip when truncated

I guess this is somewhat complicated given that children can not only be strings but also html but a nice feature to have would be to have a tooltip on hover when the text is truncated.

Clamp does not rerender on state change

I am passing the number of lines to clamp which is stateful. Clamp does not rerender when the state changes

  const [ lines, setLines ] = useState(3);
  return (
      <Dotdotdot clamp={lines}>
          <Bio onClick={() => setLines(ln => (ln === 3 ? 0 : 3))}>
             {bio}
          </Bio>
      </Dotdotdot>

clamp: auto in parent elements with many childs

When the vertical ellipse is placed in an element with a parent with many childs the 'auto' clamp dont works. Its unable to calculate the correct height.

If you replace the line 92 of clamp.js (in the function getMaxLines) with this other one it ill do it well
var availHeight = height || (element.parentNode.clientHeight-element.offsetTop),

Take in clamp as an npm module?

You have clamp.js in your source repo. It'd be helpful for users of bundle loaders such as Rollup and Webpack if you referenced an npm module instead. That way our bundle loaders can intelligently deduplicate packages such as clamp.

truncationChar causes child text to be malformed.

When I set truncationChar=" ", the first line of my text is rendered with all spaces missing.

My setup:

<Dotdotdot
    tagName="p"
    clamp={3}
    truncationChar=" "
    truncationHTML={`...<a class="color" href="/path">Read More</a>`}>
    {article.description}
</Dotdotdot>

Result:
Screen Shot 2020-11-16 at 3 04 13 PM

Using truncationHTML without truncationChar set leads to both the native truncation char and the truncationHTML prop being rendered.

Typescript integration

Would the maintainer(s) of thid repo be open to creating and maintaining the type definitions for seamless integration in typescript?

Amount of lines shown in IE/Firefox is 1 less than clamp prop value

This component is working well for me in Chrome/Safari, but when I test in Firefox (for Mac) or IE11, it is truncating after 1 line instead of 2 when I have a clamp set to 2. In the meantime, I am using browser detection to add 1 to the clamp value when in either of those two browsers, but a fix would be ideal.

Different behavior in Chrome and Firefox

I noticed that if depending on the number of child it behaves differently in chrome and firefox.

In the example below, dotdotdot has a p with 2 span.

<Dotdotdot
              clamp={ 3 }
              useNativeClamp={ false }
            >
              <p>
                <span>Either 2 the well was very deep, or she fell very slowly, </span>
                <span>for she had plenty of time as she went down to look about her and to wonder what was going to happen next. First, she tried to look down and make out what she was coming to, but it was too dark to see anything; then she looked at the sides of the well, and noticed that they were filled with cupboards and book-shelves; here and there she saw maps and pictures hung upon pegs. She took down a jar from one of the shelves as she passed; it was labelled `ORANGE MARMALADE', but to her great disappointment it was empty: she did not like to drop the jar for fear of killing somebody, so managed to put it into one of the cupboards as she fell past it.</span>
              </p>
</Dotdotdot>

running it in chrome you get the 3 lines as expected, but in firefox just 2.

Chrome and Firefox

Doesn't clamp the text. Inserts only dots at the end of the text

import Dotdotdot from 'react-dotdotdot';
           <Dotdotdot clamp={3}>
                <a href="/notification" key={index}>
                  <span className="alert-heading">{notificationItem.subject}</span>
                  <span className="alert-content"> - {notificationItem.messageBody}</span>
                </a>
              </Dotdotdot>

tooltip

Why return a div instead of a span?

otherwise I get errors like this <div> cannot appear as a descendant of <p> why wouldn't a span be more semantically correct? it could even take a prop of block for those who need it to behave like a block instead.

Typescript props and propTypes mismatched

https://github.com/CezaryDanielNowak/React-dotdotdot/blob/master/src/index.js#L70

Dotdotdot.propTypes = {
  children: PropTypes.node,
  clamp: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.bool
  ]).isRequired,
  truncationChar: PropTypes.string,
  useNativeClamp: PropTypes.bool,
  className: PropTypes.string,
  tagName: PropTypes.string
};

https://github.com/CezaryDanielNowak/React-dotdotdot/blob/master/src/index.d.ts#L3

export interface DotdotdotProps extends React.HTMLProps<Dotdotdot> {
  clamp: string | number | 'auto';
  useNativeClamp?: boolean;
  splitOnChars?: string[];
  animate?: boolean;
  truncationChar?: string;
  truncationHTML?: string;
  tagName?: string;

Differences that I could see (TS = TypeScript):

  • clamp in propTypes has bool, but TS does not. It has 'auto' instead.
  • className is missing in TS.
  • truncationHTML is missing in propTypes
  • animate is missing in propTypes.
  • children is missing in TS (I don't know whether we should specify children in TS).

Might miss something, but you get the idea.

important: hidden bug window resize cannot work well

precondition: useNativeClamp = false ; it clamp the container content with ..., when window is small

steps: enlarge the window , thus the container become large, but the it still clamps content event it do not need to clamp

reason: reason is that in dotdotdot function, it always clamps the content with the 'container', event the container content is already clamped in last render.

npm file is not the theme with master

image

in clamp.js line 276, npm file has sty.wordBreak = 'break-all'; but the master doesnot;

the master should be right, and in fact i didnot want this style

Add classname when clamped

I want to add a "more" link only when text is clamped..

It would be nice I could do something like this:

.dotdotdot-clamped-text link {
display:none;
}

Just needs a class to the container to know if text is clamped or not, it will be helpful

text-align: justify

Don't seems to work with a justified text
captura
The strange dark gray square is the ellipsis

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.