简体   繁体   中英

ReactJS multiline textarea with ellipsis

I'm trying to build a component with multiline textfield. If the text entered exceeds 2 lines, then I'd like to add the ellipsis (...) for text-overflow.

How can I achieve this by just manipulating the css to show the ellipsis in display only but not modify the actual text that will be stored to contain '...'?

I'm using this React component link

Thanks

I just figured out how to solve this for React.

As Khodor mentioned, line-clamp is what you want. However, it's not currently supported by the official CSS spec. So, you can use -webkit-line-clamp as a sort of workaround. However, I struggled to figure out the exact syntax needed for React. I eventually figured out it out by peeking at the source code for this NPM package react-lines-ellipses and searching for 'webkit' in his github repo.

The React-specific CSS

const textStyle = {
    maxWidth: '100%',
    display: '-webkit-box',
    WebkitBoxOrient: 'vertical',
    WebkitLineClamp: 3,
    overflow: 'hidden',
    textOverflow: 'ellipsis',
  };

I set the maxWidth to ensure the text filled the whole width of the display element. This is optional.

overflow: 'hidden' hides the extra text beyond the 3 lines (I chose 3 at random).

textOverflow: 'ellipses' adds an ellipses (...) to the end of the line, where it gets cut off.

The JSX

<div
    onClick={toggleTruncate}
    style={calculateTextStyle()}
>
This is where my long text goes.
</div>


// This function returns the correct style to the above div.
 function calculateTextStyle() {
    return truncate ? textStyle : null;
  }

// I used React Hooks to create a variable in state to manage if the text should be truncated or not.
  const [truncate, setToggleTruncate] = React.useState(true);

// This function toggles the state variable 'truncate', thereby expanding and truncating the text every time the user clicks the div.
  function toggleTruncate() {
    setToggleTruncate(!truncate);
  }

for CSS only, you can use line-clamp, though it doesn't have the best browser support

Check this codepen for implementation.

  display: block; /* Fallback for non-webkit */
  display: -webkit-box;
  max-width: 400px;
  height: $font-size*$line-height*$lines-to-show; /* Fallback for non-webkit */
  margin: 0 auto;
  font-size: $font-size;
  line-height: $line-height;
  -webkit-line-clamp: $lines-to-show;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;

The javascript for this could look something like below. You take the value, split it into lines, and if there's more than one line, you wrap the following lines in parentheses.

The React component your using appears to take in an onChange prop, which could use a similar function.

 const textAreaElement = document.getElementById('t') textAreaElement.addEventListener('keyup', () => { const value = textAreaElement.value.replace(/[\\(\\)]/g, '') const splitLines = value.split(/(?:\\r\\n|\\r|\\n)/) const newValue = splitLines.length > 1 ? `${splitLines[0]}\\n(${splitLines.slice(1, splitLines.length).join('\\n')})` : splitLines[0] textAreaElement.value = newValue; });
 <textarea id="t"></textarea>

An easy implementation for multi-line ellipsis will be using antd typography component . You can provide a prop called ellipsis with the value of number of rows after which it should be truncated.

<Paragraph ellipsis={{ rows: 3, expandable: true }}>
  Ant Design, a design language for background applications, is refined by Ant UED Team.
  Ant Design, a design language for background applications, is refined by Ant UED Team.
  Ant Design, a design language for background applications, is refined by Ant UED Team.
  Ant Design, a design language for background applications, is refined by Ant UED Team.
  Ant Design, a design language for background applications, is refined by Ant UED Team.
  Ant Design, a design language for background applications, is refined by Ant UED Team.
</Paragraph>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM