nanoclamp
Version:
Responsive text clamping component for React
3 lines (2 loc) • 1.02 kB
JavaScript
import{useRef as t,useMemo as e,useCallback as r,useLayoutEffect as n,createElement as l}from"react";const i=({accessibility:i=!0,debounce:u=300,ellipsis:c="…",is:o="div",lines:s=3,text:f,...d})=>{const v=t(null),a=t("."),m={ref:v,...i?{title:f}:{},...d},b=e((()=>"string"==typeof f&&f.length>0),[f]),g=r((()=>{if(!b)return;const t=t=>{a.current=t,null!=v.current&&(v.current.textContent=t)},e=()=>{var t,e;return null!==(e=null===(t=v.current)||void 0===t?void 0:t.clientHeight)&&void 0!==e?e:0};t(".");const r=(e()+1)*s+1;if(t(f),e()<=r)return;let n=0,l=0,i=f.length;for(;n<=i;){l=Math.floor((n+i)/2);t(f.slice(0,l).trim()+c),e()<=r?n=l+1:i=l-1}t(f.slice(0,l-1).trim()+c)}),[c,b,s,f]);return n((()=>{if(g(),null==v.current)return;const t=new ResizeObserver(((t,e)=>{let r;const n=()=>{r=void 0,t()};return()=>{const l=null==r;clearTimeout(r),r=setTimeout(n,e),l&&t()}})(g,u));return t.observe(v.current),()=>t.disconnect()}),[g,u]),b?l(o,m,a.current):null};export{i as default};
//# sourceMappingURL=nanoclamp.mjs.map