arendjr / text-clipper

Fast and correct clip functions for HTML and plain text
MIT License
133 stars 13 forks source link

Option to return the text that gets clipped off #10

Closed Paul-Hebert closed 4 years ago

Paul-Hebert commented 4 years ago

Hey Arend!

This library looks awesome! Thanks for putting this together!

I was hoping to use this for a truncated excerpt with a Read More/Read Less toggle button.

This library will return the excerpt, but I don't see an easy way to get the rest of the text when a user clicks "Read More." (I'd prefer not to duplicate the truncated section.

I don't know if that fits with this project, but I figured I'd mention it, since if it did I would totally use this!

Thanks!

arendjr commented 4 years ago

Thanks! Could you elaborate a bit more on why you'd need this option exactly?

I have a use case that sounds pretty much the same as yours and using React I have solved it like this:

function TruncatedText({ text, maxLength}) {
    const [isExpanded, setExpanded] = useState(false);
    if (text.length <= maxLength || isExpanded) {
        return text;
    } 

    return <>
        {clip(text, maxLength)}
        <a onClick={() => setExpanded(true)>Show more</a>
    </>;
}

Even if you don't use React, you probably still have a reference to the original text around that you can use to replace the content of the element where you show the snippet with.

Paul-Hebert commented 4 years ago

Hey Arend!

That's a fair point. I would still have a copy of the full text stored in JS in most cases. There are a few scenarios where it would be handy to be able to split the text in two pieces. These may be edge cases though so I'm fine if you'd rather not bloat the library by adding this feature:

Accessibility and Screen Readers

This was the issue I was running into. If I were to replace the truncated text with the full text, as in your React example, it could lead to awkward experiences for screen readers.

Let's say I have this text:

This is the beginning of my text. And this is the end of my text.

And let's say I truncate it to this:

This is the beginning of my text... Read More...

A screen reader user comes along:

  1. The screen reader reads "This is the beginning of my text.."
  2. The screen reader reads "Read More..."
  3. The user clicks the read more button.
  4. The screen reader reads "This is the beginning of my text. And this is the end of my text."

This is a contrived example, but I'd prefer the screen reader to only read "And this is the end of my text." in step 4.

Alternatively, I could always display the full text to screen reader users, while hiding the end of the text for sighted users (this would also be simpler if I could easily split the text)

Animation

If I had the second chunk of text in a separate span in the DOM, then I could animate it in and out on user action, though this is definitely a "Nice to Have" and not a "Must Have"

Jamstack and Server Side Rendered sites

If I'm using React, or Vue, or one of the other popular JS frameworks I likely will have the full text already stored as a JS var. If I'm using something like Eleventy to statically render a site it may be trickier to have access to that text. I could stick the full text in a data attribute, or render it into a script tag, but it would be simpler to stick it in a hidden node in the DOM.

Again, this one is totally a "Nice to Have."


Let me know if that makes sense or if you'd like clarification on any of these points. I realize these are edge cases with work-arounds for the most part. For what it's worth I ended up using a CSS line-clamp solution so no longer need this library for this specific project.


Thanks again for the awesome library! It was the best option I found when researching JS solutions to this problem and I'll definitely keep it in mind for future use!

arendjr commented 4 years ago

Hi! Sorry for not getting back on this sooner. But as you mention, and I agree, these are edge cases, and work-arounds can be created relatively easily, so I'm closing this for now.