UNPKG

use-truncate-from-middle

Version:

React hook which dynamically calculates the maximum number of characters that fit into an HTML element and truncates the text from middle with given middle chars.

3 lines (2 loc) 2.86 kB
function ___$insertStyle(e){if(e&&"undefined"!=typeof window){const t=document.createElement("style");return t.setAttribute("type","text/css"),t.innerHTML=e,document.head.appendChild(t),e}}Object.defineProperty(exports,"__esModule",{value:!0});var react=require("react"),useIsomorphicLayoutEffect="undefined"!=typeof window?react.useLayoutEffect:react.useEffect;function getTargetElement(e,t){if("undefined"!=typeof window){if("ResizeObserver"in window){if(!e)return t;t="function"==typeof e?e():"current"in e?e.current:e;return t}console.error("Your browser doesn't support Resize Observer, please use polyfill")}}var useElementWidth=function(t){var e=react.useState(0),n=e[0],o=e[1],r=new ResizeObserver(function(e){for(var t=0,n=e;t<n.length;t++){var r=n[t];r.contentBoxSize&&o(r.contentRect.width)}});return useIsomorphicLayoutEffect(function(){var e=getTargetElement(t);if(e)return r.observe(e),function(){r.disconnect()}},[]),n},getContext$1=function(){var e=document.createDocumentFragment(),t=document.createElement("canvas");return e.appendChild(t),t.getContext("2d")},useFitCharacterNumber=function(e){var s=e.target,f=e.maxWidth,m=e.middleChars;return react.useMemo(function(){var e=getTargetElement(s);if(!e)return{charNumber:void 0};if(e.textContent&&f){var t=getContext$1(),n=window.getComputedStyle(e);if(t){t.font=n.font||"".concat(n.fontSize,'" "').concat(n.fontFamily);for(var r,o=e.textContent.length,u="",i="",a=0,c=o-1,d=m||"...";a<c;){if(u+=e.textContent.charAt(a),t.measureText(r=u+m+i).width>f){o=d.length;break}if(d=r,i=e.textContent.charAt(c)+i,t.measureText(r=u+m+i).width>f){o=d.length;break}d=r,a++,c--}return{charNumber:o}}}return{charNumber:void 0}},[f,m])},truncateFromMiddle=function(e,t,n){if((e=void 0===e?"":e).length<=t)return e;var t=t-(n=void 0===n?"...":n).length,r=Math.ceil(t/2),t=Math.floor(t/2);return e.substr(0,r)+n+e.substr(e.length-t)},getContext=function(){var e=document.createDocumentFragment(),t=document.createElement("canvas");return e.appendChild(t),t.getContext("2d")},useTextWidth=function(n){var r=getContext();return react.useMemo(function(){var e=getTargetElement(n);if(null!=e&&e.textContent){var t=window.getComputedStyle(e);if(r)return r.font=t.font||"".concat(t.fontSize,'" "').concat(t.fontFamily),r.measureText(e.textContent).width}},[r])},useTruncateFromMiddle=function(e){var t=e.ref,n=e.originalText,e=e.middleChars,r=react.useState(n||""),o=r[0],u=r[1],i=useElementWidth(t),a=useTextWidth(t),c=useFitCharacterNumber({target:t,maxWidth:i,middleChars:e}).charNumber;return useIsomorphicLayoutEffect(function(){i&&c&&a&&u(i<a?truncateFromMiddle(n,c):n)},[i,c,a,n]),{truncatedText:o,contentWidth:i,textWidth:a}};exports.useElementWidth=useElementWidth,exports.useFitCharacterNumber=useFitCharacterNumber,exports.useTruncateFromMiddle=useTruncateFromMiddle; //# sourceMappingURL=index.js.map