use-fit-text
Version:
React hook used to fit text in a div
3 lines (2 loc) • 1.87 kB
JavaScript
import{useCallback as n,useRef as e,useState as t,useEffect as r,useLayoutEffect as i}from"react";import o from"resize-observer-polyfill";function c(){return(c=Object.assign||function(n){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=t[r])}return n}).apply(this,arguments)}var f="undefined"!=typeof window&&window.document&&window.document.createElement?i:r;export default function(i){var u=void 0===i?{}:i,a=u.maxFontSize,l=void 0===a?100:a,z=u.minFontSize,S=void 0===z?20:z,d=u.onFinish,s=u.onStart,v=u.resolution,m=void 0===v?5:v,w=n(function(){return{calcKey:0,fontSize:l,fontSizePrev:S,fontSizeMax:l,fontSizeMin:S}},[l,S]),h=e(null),M=e(),y=e(!1),p=t(w),x=p[0],F=p[1],K=x.calcKey,b=x.fontSize,P=x.fontSizeMax,g=x.fontSizeMin,H=x.fontSizePrev,O=null,j=t(function(){return new o(function(){O=window.requestAnimationFrame(function(){y.current||(s&&s(),y.current=!0,F(c({},w(),{calcKey:K+1})))})})})[0];r(function(){return h.current&&j.observe(h.current),function(){O&&window.cancelAnimationFrame(O),j.disconnect()}},[O,j]);var A=h.current&&h.current.innerHTML;return r(function(){0===K||y.current||(A!==M.current&&(s&&s(),F(c({},w(),{calcKey:K+1}))),M.current=A)},[K,w,A,s]),f(function(){if(0!==K){var n=Math.abs(b-H)<=m,e=!!h.current&&(h.current.scrollHeight>h.current.offsetHeight||h.current.scrollWidth>h.current.offsetWidth),t=b>H;if(n)e&&b===H?(y.current=!1,console.error("Failed to fit text with `minFontSize = "+S+"`. To fix, reduce `minFontSize`.")):e?F({fontSize:t?H:g,fontSizeMax:P,fontSizeMin:g,fontSizePrev:H,calcKey:K}):(y.current=!1,d&&d(b));else{var r,i=P,o=g;e?(r=t?H-b:g-b,i=Math.min(P,b)):(r=t?P-b:H-b,o=Math.max(g,b)),F({calcKey:K,fontSize:b+r/2,fontSizeMax:i,fontSizeMin:o,fontSizePrev:b})}}},[K,b,P,g,H,d,h,m]),{fontSize:b+"%",ref:h}}
//# sourceMappingURL=index.esm.js.map