diff --git a/README.md b/README.md index 41c2229d..19401926 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Hint: (Generally with React) if you want to preserve newlines from plain text, y | children | string, React node | | The text to be truncated. Anything that can be evaluated as text. | `'Some text'`, `

Some paragraph with other text-based inline elements

`, `Somesiblings` | | 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 })` | | trimWhitespace | boolean | false | If `true`, whitespace will be removed from before the ellipsis (e.g. `words ...` will become `words...` instead) | `{longText}` | +| breakAll | boolean | false | If `true`, lines will break at any place, not only on spaces (useful for example for truncating multiline URLs). | `{longText}` | ## Known issues - Text exceeding horizontal boundaries when "viewport" meta tag is not set accordingly for mobile devices (font boosting leads to wrong calculations). See [issue](https://github.com/One-com/react-truncate/issues/4#issuecomment-226703499) diff --git a/src/Truncate.js b/src/Truncate.js index f4ce134f..69cd2330 100644 --- a/src/Truncate.js +++ b/src/Truncate.js @@ -10,6 +10,7 @@ export default class Truncate extends Component { PropTypes.number ]), trimWhitespace: PropTypes.bool, + breakAll: PropTypes.bool, onTruncate: PropTypes.func }; @@ -17,7 +18,8 @@ export default class Truncate extends Component { children: '', ellipsis: '…', lines: 1, - trimWhitespace: false + trimWhitespace: false, + breakAll: false }; state = {}; @@ -175,7 +177,8 @@ export default class Truncate extends Component { props: { lines: numLines, ellipsis, - trimWhitespace + trimWhitespace, + breakAll }, state: { targetWidth @@ -188,7 +191,8 @@ export default class Truncate extends Component { const lines = []; const text = innerText(elements.text); - const textLines = text.split('\n').map(line => line.split(' ')); + const wordSeparator = breakAll ? '' : ' '; + const textLines = text.split('\n').map(line => line.split(wordSeparator)); let didTruncate = true; const ellipsisWidth = this.ellipsisWidth(this.elements.ellipsis); @@ -203,7 +207,7 @@ export default class Truncate extends Component { continue; } - let resultLine = textWords.join(' '); + let resultLine = textWords.join(wordSeparator); if (measureWidth(resultLine) <= targetWidth) { if (textLines.length === 1) { @@ -217,7 +221,7 @@ export default class Truncate extends Component { if (line === numLines) { // Binary search determining the longest possible line inluding truncate string - const textRest = textWords.join(' '); + const textRest = textWords.join(wordSeparator); let lower = 0; let upper = textRest.length - 1; @@ -256,7 +260,7 @@ export default class Truncate extends Component { while (lower <= upper) { const middle = Math.floor((lower + upper) / 2); - const testLine = textWords.slice(0, middle + 1).join(' '); + const testLine = textWords.slice(0, middle + 1).join(wordSeparator); if (measureWidth(testLine) <= targetWidth) { lower = middle + 1; @@ -272,7 +276,7 @@ export default class Truncate extends Component { continue; } - resultLine = textWords.slice(0, lower).join(' '); + resultLine = textWords.slice(0, lower).join(wordSeparator); textLines[0].splice(0, lower); } @@ -336,6 +340,7 @@ export default class Truncate extends Component { delete spanProps.onTruncate; delete spanProps.trimWhitespace; + delete spanProps.breakAll; return ( { this.elements.target = targetEl; }}>