@liiift-studio/magnettype 1.1.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const M=require("react"),K=require("react/jsx-runtime"),G={i:3,l:3,1:3,I:3,r:2,n:1,m:1,0:2,O:2,o:1,b:1,d:1,p:1,q:1,c:1,e:1},R={word:"mt-word",char:"mt-char",probe:"mt-probe"},$={axes:{wght:[300,500]},radius:120,falloff:"quadratic",magnetMode:"attract",wdthBoost:6,scope:"document"};function _(t,o=[]){return t.nodeType===Node.TEXT_NODE?o.push(t):t.childNodes.forEach(r=>_(r,o)),o}function H(t,o,r){if(!t||t==="normal")return`"${o}" ${r}`;const l=new RegExp(`(["'])${o}\\1\\s+[\\d.eE+-]+`),c=`"${o}" ${r}`;return l.test(t)?t.replace(l,c):`${t}, ${c}`}function J(t,o){let r=t;for(const[l,c]of Object.entries(o))r=H(r,l,c);return r}function U(t,o,r){if(o.opacity!==void 0){const[l,c]=o.opacity;t.style.opacity=String(l+(c-l)*r)}o.italic===!0&&(t.style.fontStyle=r>.5?"italic":"")}function P(t,o){o.opacity!==void 0&&(t.style.opacity=String(o.opacity[0])),o.italic===!0&&(t.style.fontStyle="")}function z(t){const o=t.cloneNode(!0),r=o.querySelectorAll(`.${R.word}, .${R.char}`);return Array.from(r).reverse().forEach(c=>{const a=c.parentNode;if(a){for(;c.firstChild;)a.insertBefore(c.firstChild,c);a.removeChild(c)}}),o.innerHTML}function ot(t,o){t.innerHTML=o}function Q(t,o,r={}){if(typeof window>"u")return()=>{};if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return t.innerHTML=o,()=>{};const l=r.wdthBoost??$.wdthBoost,c=r.radius??$.radius,a=r.falloff??$.falloff,T=r.scope??$.scope,v=r.props,d=r.transitionMs??0,S=window.scrollY;t.innerHTML=o;const L=getComputedStyle(t).fontVariationSettings,b=L.match(/"wdth"\s+([\d.eE+-]+)/),y=b?parseFloat(b[1]):100,A=_(t),w=[];for(const n of A){const e=n.textContent??"";if(!e||!e.split("").some(m=>m in G))continue;const h=document.createDocumentFragment();for(const m of e){const B=G[m];if(B===void 0){const E=h.lastChild;E&&E.nodeType===Node.TEXT_NODE?E.textContent+=m:h.appendChild(document.createTextNode(m))}else{const E=document.createElement("span");E.className=R.char,E.style.fontVariationSettings=H(L,"wdth",y),E.textContent=m,h.appendChild(E),w.push({span:E,riskLevel:B})}}n.parentNode.replaceChild(h,n)}if(requestAnimationFrame(()=>{typeof window<"u"&&Math.abs(window.scrollY-S)>2&&window.scrollTo({top:S,behavior:"instant"})}),w.length===0)return()=>{};v&&w.forEach(({span:n})=>P(n,v));let p=-9999,q=-9999,g=!1,i=0,V=!0,s=null;function f(){if(!V)return;if(!g){w.forEach(({span:e})=>{d>0&&(e.style.transition=`font-variation-settings ${d}ms ease`),e.style.fontVariationSettings=H(L,"wdth",y),v&&P(e,v)}),d>0&&(s!==null&&clearTimeout(s),s=setTimeout(()=>{w.forEach(({span:e})=>{e.style.transition=""}),s=null},d)),i=0;return}const n=w.map(({span:e})=>e.getBoundingClientRect());w.forEach(({span:e,riskLevel:x},h)=>{e.style.transition="";const m=n[h],B=m.left+m.width/2,E=m.top+m.height/2,j=Math.sqrt((p-B)**2+(q-E)**2),O=Math.max(0,1-j/c),Y=a==="quadratic"?O*O:O,X=l*(x/3)*Y;e.style.fontVariationSettings=H(L,"wdth",y+X),v&&U(e,v,Y)}),i=requestAnimationFrame(f)}function N(n){p=n.clientX,q=n.clientY,g||(g=!0),i===0&&(i=requestAnimationFrame(f))}function C(){g=!1,i===0&&(i=requestAnimationFrame(f))}function F(n){n.touches.length!==0&&(p=n.touches[0].clientX,q=n.touches[0].clientY,g||(g=!0),i===0&&(i=requestAnimationFrame(f)))}function k(){g=!1,i===0&&(i=requestAnimationFrame(f))}const u=T==="document"?document:t;return u.addEventListener("mousemove",N),u.addEventListener("mouseleave",C),u.addEventListener("touchmove",F,{passive:!0}),u.addEventListener("touchend",k),()=>{V=!1,cancelAnimationFrame(i),s!==null&&clearTimeout(s),u.removeEventListener("mousemove",N),u.removeEventListener("mouseleave",C),u.removeEventListener("touchmove",F),u.removeEventListener("touchend",k),t.innerHTML=o}}function Z(t,o,r={}){if(typeof window>"u")return()=>{};if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return t.innerHTML=o,()=>{};const l=r.axes??$.axes,c=r.radius??$.radius,a=r.falloff??$.falloff,T=r.magnetMode??$.magnetMode,v=r.scope??$.scope,d=r.props,S=r.transitionMs??0,L=window.scrollY;t.innerHTML=o;const b=_(t),y=[];for(const n of b){const e=n.textContent??"";if(!e.trim())continue;const x=e.split(/(\S+)/),h=document.createDocumentFragment();for(let m=0;m<x.length;m+=2){const B=x[m],E=x[m+1];if(!E)continue;const O=x[m+3]===void 0?x[m+2]??"":"",Y=document.createElement("span");Y.className=R.word,Y.textContent=B+E+O,h.appendChild(Y),y.push(Y)}n.parentNode.replaceChild(h,n)}if(requestAnimationFrame(()=>{typeof window<"u"&&Math.abs(window.scrollY-L)>2&&window.scrollTo({top:L,behavior:"instant"})}),y.length===0)return()=>{};const A=getComputedStyle(t).fontVariationSettings,w=J(A,Object.fromEntries(Object.entries(l).map(([n,[e]])=>[n,e])));y.forEach(n=>{n.style.fontVariationSettings=w,d&&P(n,d)});let p=-9999,q=-9999,g=!1,i=0,V=!0,s=null;function f(){if(!V)return;if(!g){y.forEach(e=>{S>0&&(e.style.transition=`font-variation-settings ${S}ms ease`),e.style.fontVariationSettings=w,d&&P(e,d)}),S>0&&(s!==null&&clearTimeout(s),s=setTimeout(()=>{y.forEach(e=>{e.style.transition=""}),s=null},S)),i=0;return}const n=y.map(e=>e.getBoundingClientRect());y.forEach((e,x)=>{e.style.transition="";const h=n[x],m=h.left+h.width/2,B=h.top+h.height/2,E=Math.sqrt((p-m)**2+(q-B)**2),j=Math.max(0,1-E/c),O=a==="quadratic"?j*j:j,Y=T==="repel"?1-O:O,X={};for(const D of Object.keys(l)){const[I,nt]=l[D]??[300,500];X[D]=I+(nt-I)*Y}e.style.fontVariationSettings=J(A,X),d&&U(e,d,O)}),i=requestAnimationFrame(f)}function N(n){p=n.clientX,q=n.clientY,g||(g=!0),i===0&&(i=requestAnimationFrame(f))}function C(){g=!1,i===0&&(i=requestAnimationFrame(f))}function F(n){n.touches.length!==0&&(p=n.touches[0].clientX,q=n.touches[0].clientY,g||(g=!0),i===0&&(i=requestAnimationFrame(f)))}function k(){g=!1,i===0&&(i=requestAnimationFrame(f))}const u=v==="document"?document:t;return u.addEventListener("mousemove",N),u.addEventListener("mouseleave",C),u.addEventListener("touchmove",F,{passive:!0}),u.addEventListener("touchend",k),()=>{V=!1,cancelAnimationFrame(i),s!==null&&clearTimeout(s),u.removeEventListener("mousemove",N),u.removeEventListener("mouseleave",C),u.removeEventListener("touchmove",F),u.removeEventListener("touchend",k),t.innerHTML=o}}function W(t){const o=M.useRef(null),r=M.useRef(null),l=M.useRef(t);l.current=t;const c=M.useRef(null),a=t.mode??"field",{axes:T,radius:v,falloff:d,magnetMode:S,wdthBoost:L,scope:b}=t,y=T?JSON.stringify(T):void 0,A=t.props?JSON.stringify(t.props):void 0,w=M.useCallback(()=>{const p=o.current;if(!p)return;r.current===null&&(r.current=z(p)),c.current&&(c.current(),c.current=null),(l.current.mode??"field")==="field"?c.current=Z(p,r.current,l.current):c.current=Q(p,r.current,l.current)},[a,y,v,d,S,L,b,A]);return M.useLayoutEffect(()=>(w(),()=>{c.current&&(c.current(),c.current=null)}),[w]),M.useEffect(()=>{document.fonts.ready.then(w)},[w]),o}const tt=M.forwardRef(function({children:o,as:r="p",className:l,style:c,...a},T){const v=W(a),d=M.useCallback(S=>{v.current=S,typeof T=="function"?T(S):T&&(T.current=S)},[T]);return K.jsx(r,{ref:d,className:l,style:c,children:o})});tt.displayName="MagnetTypeText";const et=M.forwardRef(function({children:o,as:r="p",className:l,style:c,minWeight:a=300,maxWeight:T=600,proximityRadius:v,spreadRadius:d,fixedAxes:S={}},L){const b=M.useRef(null),y=M.useRef(null),A=M.useRef([]),w=M.useCallback(s=>{b.current=s,typeof L=="function"?L(s):L&&(L.current=s)},[L]);function p(s){const f=[`'wght' ${s.toFixed(0)}`];for(const[N,C]of Object.entries(S))f.push(`'${N}' ${C}`);return f.join(", ")}M.useEffect(()=>{var k;if(!d)return;const s=b.current;if(!s)return;const f=[],N=document.createTreeWalker(s,NodeFilter.SHOW_TEXT),C=[];let F;for(;F=N.nextNode();)C.push(F);for(const u of C){const n=u.textContent??"";if(!n)continue;const e=document.createDocumentFragment();for(const x of n)if(/\s/.test(x))e.appendChild(document.createTextNode(x));else{const h=document.createElement("span");h.style.fontVariationSettings=p(a),h.textContent=x,f.push(h),e.appendChild(h)}(k=u.parentNode)==null||k.replaceChild(e,u)}A.current=f},[]);function q(s,f){const N=b.current;if(!N)return;const C=N.getBoundingClientRect(),F=Math.max(C.left-s,0,s-C.right),k=Math.max(C.top-f,0,f-C.bottom),u=Math.sqrt(F*F+k*k);if(v!==void 0&&!d){const e=1-(1-Math.max(0,1-u/v))**2;N.style.fontVariationSettings=p(a+(T-a)*e);return}if(d){if(v!==void 0&&u>v){N.style.fontVariationSettings=p(a);for(const n of A.current)n.style.fontVariationSettings=p(a);return}for(const n of A.current){const e=n.getBoundingClientRect(),x=(e.left+e.right)/2,h=(e.top+e.bottom)/2,m=Math.sqrt((s-x)**2+(f-h)**2),E=1-(1-Math.max(0,1-m/d))**2;n.style.fontVariationSettings=p(a+(T-a)*E)}}}const g=M.useCallback(s=>{y.current={x:s.clientX,y:s.clientY},q(s.clientX,s.clientY)},[a,T,v,d]),i=M.useCallback(()=>{y.current&&q(y.current.x,y.current.y)},[a,T,v,d]),V=M.useCallback(()=>{y.current=null;const s=b.current;s&&(s.style.fontVariationSettings=p(a));for(const f of A.current)f.style.fontVariationSettings=p(a)},[a]);return M.useEffect(()=>(window.addEventListener("mousemove",g,{passive:!0}),window.addEventListener("scroll",i,{passive:!0,capture:!0}),document.documentElement.addEventListener("mouseleave",V),()=>{window.removeEventListener("mousemove",g),window.removeEventListener("scroll",i,{capture:!0}),document.documentElement.removeEventListener("mouseleave",V)}),[g,i,V]),K.jsx(r,{ref:w,className:l,style:{fontVariationSettings:p(a),...c},children:o})});et.displayName="MagnetBlock";exports.MAGNET_TYPE_CLASSES=R;exports.MagnetBlock=et;exports.MagnetTypeText=tt;exports.applyMagnetType=Q;exports.getCleanHTML=z;exports.removeMagnetType=ot;exports.startMagnetType=Z;exports.useMagnetType=W;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("react"),H=require("react/jsx-runtime"),G={i:3,l:3,1:3,I:3,r:2,n:1,m:1,0:2,O:2,o:1,b:1,d:1,p:1,q:1,c:1,e:1},R={word:"mt-word",char:"mt-char",probe:"mt-probe"},$={axes:{wght:[300,500]},radius:120,falloff:"quadratic",magnetMode:"attract",wdthBoost:6,scope:"document"};function D(t,n=[]){return t.nodeType===Node.TEXT_NODE?n.push(t):t.childNodes.forEach(o=>D(o,n)),n}function P(t,n,o){if(!t||t==="normal")return`"${n}" ${o}`;const u=new RegExp(`(["'])${n}\\1\\s+[\\d.eE+-]+`),c=`"${n}" ${o}`;return u.test(t)?t.replace(u,c):`${t}, ${c}`}function K(t,n){let o=t;for(const[u,c]of Object.entries(n))o=P(o,u,c);return o}function U(t,n,o){if(n.opacity!==void 0){const[u,c]=n.opacity;t.style.opacity=String(u+(c-u)*o)}n.italic===!0&&(t.style.fontStyle=o>.5?"italic":"")}function _(t,n){n.opacity!==void 0&&(t.style.opacity=String(n.opacity[0])),n.italic===!0&&(t.style.fontStyle="")}function z(t){const n=t.cloneNode(!0),o=n.querySelectorAll(`.${R.word}, .${R.char}`);return Array.from(o).reverse().forEach(c=>{const a=c.parentNode;if(a){for(;c.firstChild;)a.insertBefore(c.firstChild,c);a.removeChild(c)}}),n.innerHTML}function ot(t,n){t.innerHTML=n}function Q(t,n,o={}){if(typeof window>"u")return()=>{};if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return t.innerHTML=n,()=>{};const u=o.wdthBoost??$.wdthBoost,c=o.radius??$.radius,a=o.falloff??$.falloff,T=o.scope??$.scope,y=o.props,l=o.transitionMs??0,C=window.scrollY;t.innerHTML=n;const N=getComputedStyle(t).fontVariationSettings,F=N.match(/"wdth"\s+([\d.eE+-]+)/),g=F?parseFloat(F[1]):100,q=D(t),w=[];for(const r of q){const e=r.textContent??"";if(!e||!e.split("").some(m=>m in G))continue;const A=document.createDocumentFragment();for(const m of e){const k=G[m];if(k===void 0){const L=A.lastChild;L&&L.nodeType===Node.TEXT_NODE?L.textContent+=m:A.appendChild(document.createTextNode(m))}else{const L=document.createElement("span");L.className=R.char,L.style.fontVariationSettings=P(N,"wdth",g),L.textContent=m,A.appendChild(L),w.push({span:L,riskLevel:k})}}r.parentNode.replaceChild(A,r)}if(requestAnimationFrame(()=>{typeof window<"u"&&Math.abs(window.scrollY-C)>2&&window.scrollTo({top:C,behavior:"instant"})}),w.length===0)return()=>{};y&&w.forEach(({span:r})=>_(r,y));let h=-9999,V=-9999,E=!1,i=0,B=!0,S=null;function s(){if(!B)return;if(!E){w.forEach(({span:e})=>{l>0&&(e.style.transition=`font-variation-settings ${l}ms ease`),e.style.fontVariationSettings=P(N,"wdth",g),y&&_(e,y)}),l>0&&(S!==null&&clearTimeout(S),S=setTimeout(()=>{w.forEach(({span:e})=>{e.style.transition=""}),S=null},l)),i=0;return}const r=w.map(({span:e})=>e.getBoundingClientRect());w.forEach(({span:e,riskLevel:x},A)=>{e.style.transition="";const m=r[A],k=m.left+m.width/2,L=m.top+m.height/2,j=Math.sqrt((h-k)**2+(V-L)**2),O=Math.max(0,1-j/c),Y=a==="quadratic"?O*O:O,X=u*(x/3)*Y;e.style.fontVariationSettings=P(N,"wdth",g+X),y&&U(e,y,Y)}),i=requestAnimationFrame(s)}function M(r){h=r.clientX,V=r.clientY,E||(E=!0),i===0&&(i=requestAnimationFrame(s))}function v(){E=!1,i===0&&(i=requestAnimationFrame(s))}function f(r){r.touches.length!==0&&(h=r.touches[0].clientX,V=r.touches[0].clientY,E||(E=!0),i===0&&(i=requestAnimationFrame(s)))}function b(){E=!1,i===0&&(i=requestAnimationFrame(s))}const d=T==="document"?document:t;return d.addEventListener("mousemove",M),d.addEventListener("mouseleave",v),d.addEventListener("touchmove",f,{passive:!0}),d.addEventListener("touchend",b),()=>{B=!1,cancelAnimationFrame(i),S!==null&&clearTimeout(S),d.removeEventListener("mousemove",M),d.removeEventListener("mouseleave",v),d.removeEventListener("touchmove",f),d.removeEventListener("touchend",b),t.innerHTML=n}}function Z(t,n,o={}){if(typeof window>"u")return()=>{};if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return t.innerHTML=n,()=>{};const u=o.axes??$.axes,c=o.radius??$.radius,a=o.falloff??$.falloff,T=o.magnetMode??$.magnetMode,y=o.scope??$.scope,l=o.props,C=o.transitionMs??0,N=window.scrollY;t.innerHTML=n;const F=D(t),g=[];for(const r of F){const e=r.textContent??"";if(!e.trim())continue;const x=e.split(/(\S+)/),A=document.createDocumentFragment();for(let m=0;m<x.length;m+=2){const k=x[m],L=x[m+1];if(!L)continue;const O=x[m+3]===void 0?x[m+2]??"":"",Y=document.createElement("span");Y.className=R.word,Y.textContent=k+L+O,A.appendChild(Y),g.push(Y)}r.parentNode.replaceChild(A,r)}if(requestAnimationFrame(()=>{typeof window<"u"&&Math.abs(window.scrollY-N)>2&&window.scrollTo({top:N,behavior:"instant"})}),g.length===0)return()=>{};const q=getComputedStyle(t).fontVariationSettings,w=K(q,Object.fromEntries(Object.entries(u).map(([r,[e]])=>[r,e])));g.forEach(r=>{r.style.fontVariationSettings=w,l&&_(r,l)});let h=-9999,V=-9999,E=!1,i=0,B=!0,S=null;function s(){if(!B)return;if(!E){g.forEach(e=>{C>0&&(e.style.transition=`font-variation-settings ${C}ms ease`),e.style.fontVariationSettings=w,l&&_(e,l)}),C>0&&(S!==null&&clearTimeout(S),S=setTimeout(()=>{g.forEach(e=>{e.style.transition=""}),S=null},C)),i=0;return}const r=g.map(e=>e.getBoundingClientRect());g.forEach((e,x)=>{e.style.transition="";const A=r[x],m=A.left+A.width/2,k=A.top+A.height/2,L=Math.sqrt((h-m)**2+(V-k)**2),j=Math.max(0,1-L/c),O=a==="quadratic"?j*j:j,Y=T==="repel"?1-O:O,X={};for(const I of Object.keys(u)){const[J,nt]=u[I]??[300,500];X[I]=J+(nt-J)*Y}e.style.fontVariationSettings=K(q,X),l&&U(e,l,O)}),i=requestAnimationFrame(s)}function M(r){h=r.clientX,V=r.clientY,E||(E=!0),i===0&&(i=requestAnimationFrame(s))}function v(){E=!1,i===0&&(i=requestAnimationFrame(s))}function f(r){r.touches.length!==0&&(h=r.touches[0].clientX,V=r.touches[0].clientY,E||(E=!0),i===0&&(i=requestAnimationFrame(s)))}function b(){E=!1,i===0&&(i=requestAnimationFrame(s))}const d=y==="document"?document:t;return d.addEventListener("mousemove",M),d.addEventListener("mouseleave",v),d.addEventListener("touchmove",f,{passive:!0}),d.addEventListener("touchend",b),()=>{B=!1,cancelAnimationFrame(i),S!==null&&clearTimeout(S),d.removeEventListener("mousemove",M),d.removeEventListener("mouseleave",v),d.removeEventListener("touchmove",f),d.removeEventListener("touchend",b),t.innerHTML=n}}function W(t){const n=p.useRef(null),o=p.useRef(null),u=p.useRef(t);u.current=t;const c=p.useRef(null),a=t.mode??"field",{axes:T,radius:y,falloff:l,magnetMode:C,wdthBoost:N,scope:F}=t,g=T?JSON.stringify(T):void 0,q=t.props?JSON.stringify(t.props):void 0,w=p.useCallback(()=>{const h=n.current;if(!h)return;o.current===null&&(o.current=z(h)),c.current&&(c.current(),c.current=null),(u.current.mode??"field")==="field"?c.current=Z(h,o.current,u.current):c.current=Q(h,o.current,u.current)},[a,g,y,l,C,N,F,q]);return p.useLayoutEffect(()=>(w(),()=>{c.current&&(c.current(),c.current=null)}),[w]),p.useEffect(()=>{document.fonts.ready.then(w)},[w]),n}const tt=p.forwardRef(function({children:n,as:o="p",className:u,style:c,...a},T){const y=W(a),l=p.useCallback(C=>{y.current=C,typeof T=="function"?T(C):T&&(T.current=C)},[T]);return H.jsx(o,{ref:l,className:u,style:c,children:n})});tt.displayName="MagnetTypeText";const et=p.forwardRef(function({children:n,as:o="p",className:u,style:c,minWeight:a=300,maxWeight:T=600,proximityRadius:y,spreadRadius:l,fixedAxes:C={}},N){const F=p.useRef(null),g=p.useRef(null),q=p.useRef([]),w=p.useCallback(s=>{F.current=s,typeof N=="function"?N(s):N&&(N.current=s)},[N]);function h(s){const M=[`'wght' ${s.toFixed(0)}`];for(const[v,f]of Object.entries(C))M.push(`'${v}' ${f}`);return M.join(", ")}const V=p.useMemo(()=>{if(!l)return n;q.current=[];let s=0;function M(v){if(typeof v=="string")return[...v].map(f=>{if(/\s/.test(f))return f;const b=s++;return H.jsx("span",{ref:d=>{q.current[b]=d},style:{fontVariationSettings:h(a)},children:f},b)});if(Array.isArray(v))return v.map((f,b)=>H.jsx(p.Fragment,{children:M(f)},b));if(p.isValidElement(v)){const f=v;if(f.props.children!==void 0)return p.cloneElement(f,{},M(f.props.children))}return v}return M(n)},[n,l,a,JSON.stringify(C)]);function E(s,M){const v=F.current;if(!v)return;const f=v.getBoundingClientRect(),b=Math.max(f.left-s,0,s-f.right),d=Math.max(f.top-M,0,M-f.bottom),r=Math.sqrt(b*b+d*d);if(y!==void 0&&!l){const x=1-(1-Math.max(0,1-r/y))**2;v.style.fontVariationSettings=h(a+(T-a)*x);return}if(l){if(y!==void 0&&r>y){v.style.fontVariationSettings=h(a);for(const e of q.current)e&&(e.style.fontVariationSettings=h(a));return}for(const e of q.current){if(!e)continue;const x=e.getBoundingClientRect(),A=(x.left+x.right)/2,m=(x.top+x.bottom)/2,k=Math.sqrt((s-A)**2+(M-m)**2),j=1-(1-Math.max(0,1-k/l))**2;e.style.fontVariationSettings=h(a+(T-a)*j)}}}const i=p.useCallback(s=>{g.current={x:s.clientX,y:s.clientY},E(s.clientX,s.clientY)},[a,T,y,l]),B=p.useCallback(()=>{g.current&&E(g.current.x,g.current.y)},[a,T,y,l]),S=p.useCallback(()=>{g.current=null;const s=F.current;s&&(s.style.fontVariationSettings=h(a));for(const M of q.current)M&&(M.style.fontVariationSettings=h(a))},[a]);return p.useEffect(()=>(window.addEventListener("mousemove",i,{passive:!0}),window.addEventListener("scroll",B,{passive:!0,capture:!0}),document.documentElement.addEventListener("mouseleave",S),()=>{window.removeEventListener("mousemove",i),window.removeEventListener("scroll",B,{capture:!0}),document.documentElement.removeEventListener("mouseleave",S)}),[i,B,S]),H.jsx(o,{ref:w,className:u,style:{fontVariationSettings:h(a),...c},children:V})});et.displayName="MagnetBlock";exports.MAGNET_TYPE_CLASSES=R;exports.MagnetBlock=et;exports.MagnetTypeText=tt;exports.applyMagnetType=Q;exports.getCleanHTML=z;exports.removeMagnetType=ot;exports.startMagnetType=Z;exports.useMagnetType=W;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,4 @@
1
1
  import { default as default_2 } from 'react';
2
- import { ForwardRefExoticComponent } from 'react';
3
- import { RefAttributes } from 'react';
4
2
  import { RefObject } from 'react';
5
3
 
6
4
  /**
@@ -42,22 +40,23 @@ export declare const MAGNET_TYPE_CLASSES: {
42
40
 
43
41
  /**
44
42
  * Drop-in block element with cursor-proximity variable font weight variation.
45
- * Accepts any ReactNode use spreadRadius for per-word spread, proximityRadius
46
- * for a whole-element proximity gate, or combine both.
43
+ * Accepts any ReactNode. When spreadRadius is set, string children are split into
44
+ * per-character spans rendered as React elements no DOM manipulation required.
45
+ * Use proximityRadius for a whole-element gate, or combine both.
47
46
  */
48
- export declare const MagnetBlock: ForwardRefExoticComponent<MagnetBlockProps & RefAttributes<HTMLElement>>;
47
+ export declare const MagnetBlock: default_2.ForwardRefExoticComponent<MagnetBlockProps & default_2.RefAttributes<HTMLElement>>;
49
48
 
50
49
  export declare interface MagnetBlockProps {
51
- children: React.ReactNode;
50
+ children: default_2.ReactNode;
52
51
  /** HTML element to render. Default: 'p' */
53
- as?: React.ElementType;
52
+ as?: default_2.ElementType;
54
53
  className?: string;
55
- style?: React.CSSProperties;
54
+ style?: default_2.CSSProperties;
56
55
  minWeight?: number;
57
56
  maxWeight?: number;
58
57
  /** Pixel distance from the element edge within which the whole-element effect activates */
59
58
  proximityRadius?: number;
60
- /** Pixel distance from the cursor within which each word's weight rises to max */
59
+ /** Pixel distance from the cursor within which each character's weight rises to max */
61
60
  spreadRadius?: number;
62
61
  fixedAxes?: Record<string, number>;
63
62
  }
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { useRef as k, useCallback as j, useLayoutEffect as tt, useEffect as _, forwardRef as z } from "react";
2
- import { jsx as Q } from "react/jsx-runtime";
3
- const G = {
1
+ import J, { useRef as j, useCallback as X, useLayoutEffect as et, useEffect as Q, forwardRef as Z, useMemo as nt } from "react";
2
+ import { jsx as D } from "react/jsx-runtime";
3
+ const R = {
4
4
  i: 3,
5
5
  l: 3,
6
6
  1: 3,
@@ -22,7 +22,7 @@ const G = {
22
22
  c: 1,
23
23
  e: 1
24
24
  // similar bowls
25
- }, I = {
25
+ }, P = {
26
26
  /** Applied to each word span in field mode */
27
27
  word: "mt-word",
28
28
  /** Applied to each character span in legibility mode */
@@ -37,320 +37,329 @@ const G = {
37
37
  wdthBoost: 6,
38
38
  scope: "document"
39
39
  };
40
- function J(t, o = []) {
41
- return t.nodeType === Node.TEXT_NODE ? o.push(t) : t.childNodes.forEach((r) => J(r, o)), o;
40
+ function K(t, n = []) {
41
+ return t.nodeType === Node.TEXT_NODE ? n.push(t) : t.childNodes.forEach((o) => K(o, n)), n;
42
42
  }
43
- function D(t, o, r) {
44
- if (!t || t === "normal") return `"${o}" ${r}`;
45
- const f = new RegExp(`(["'])${o}\\1\\s+[\\d.eE+-]+`), c = `"${o}" ${r}`;
46
- return f.test(t) ? t.replace(f, c) : `${t}, ${c}`;
43
+ function I(t, n, o) {
44
+ if (!t || t === "normal") return `"${n}" ${o}`;
45
+ const u = new RegExp(`(["'])${n}\\1\\s+[\\d.eE+-]+`), c = `"${n}" ${o}`;
46
+ return u.test(t) ? t.replace(u, c) : `${t}, ${c}`;
47
47
  }
48
- function R(t, o) {
49
- let r = t;
50
- for (const [f, c] of Object.entries(o))
51
- r = D(r, f, c);
52
- return r;
48
+ function z(t, n) {
49
+ let o = t;
50
+ for (const [u, c] of Object.entries(n))
51
+ o = I(o, u, c);
52
+ return o;
53
53
  }
54
- function Z(t, o, r) {
55
- if (o.opacity !== void 0) {
56
- const [f, c] = o.opacity;
57
- t.style.opacity = String(f + (c - f) * r);
54
+ function W(t, n, o) {
55
+ if (n.opacity !== void 0) {
56
+ const [u, c] = n.opacity;
57
+ t.style.opacity = String(u + (c - u) * o);
58
58
  }
59
- o.italic === !0 && (t.style.fontStyle = r > 0.5 ? "italic" : "");
59
+ n.italic === !0 && (t.style.fontStyle = o > 0.5 ? "italic" : "");
60
60
  }
61
- function P(t, o) {
62
- o.opacity !== void 0 && (t.style.opacity = String(o.opacity[0])), o.italic === !0 && (t.style.fontStyle = "");
61
+ function _(t, n) {
62
+ n.opacity !== void 0 && (t.style.opacity = String(n.opacity[0])), n.italic === !0 && (t.style.fontStyle = "");
63
63
  }
64
- function et(t) {
65
- const o = t.cloneNode(!0), r = o.querySelectorAll(
66
- `.${I.word}, .${I.char}`
64
+ function ot(t) {
65
+ const n = t.cloneNode(!0), o = n.querySelectorAll(
66
+ `.${P.word}, .${P.char}`
67
67
  );
68
- return Array.from(r).reverse().forEach((c) => {
68
+ return Array.from(o).reverse().forEach((c) => {
69
69
  const a = c.parentNode;
70
70
  if (a) {
71
71
  for (; c.firstChild; ) a.insertBefore(c.firstChild, c);
72
72
  a.removeChild(c);
73
73
  }
74
- }), o.innerHTML;
74
+ }), n.innerHTML;
75
75
  }
76
- function ut(t, o) {
77
- t.innerHTML = o;
76
+ function lt(t, n) {
77
+ t.innerHTML = n;
78
78
  }
79
- function nt(t, o, r = {}) {
79
+ function rt(t, n, o = {}) {
80
80
  if (typeof window > "u") return () => {
81
81
  };
82
82
  if (window.matchMedia("(prefers-reduced-motion: reduce)").matches)
83
- return t.innerHTML = o, () => {
83
+ return t.innerHTML = n, () => {
84
84
  };
85
- const f = r.wdthBoost ?? Y.wdthBoost, c = r.radius ?? Y.radius, a = r.falloff ?? Y.falloff, w = r.scope ?? Y.scope, v = r.props, d = r.transitionMs ?? 0, x = window.scrollY;
86
- t.innerHTML = o;
87
- const L = getComputedStyle(t).fontVariationSettings, N = L.match(/"wdth"\s+([\d.eE+-]+)/), y = N ? parseFloat(N[1]) : 100, A = J(t), M = [];
88
- for (const n of A) {
89
- const e = n.textContent ?? "";
90
- if (!e || !e.split("").some((m) => m in G)) continue;
91
- const p = document.createDocumentFragment();
85
+ const u = o.wdthBoost ?? Y.wdthBoost, c = o.radius ?? Y.radius, a = o.falloff ?? Y.falloff, M = o.scope ?? Y.scope, v = o.props, f = o.transitionMs ?? 0, x = window.scrollY;
86
+ t.innerHTML = n;
87
+ const N = getComputedStyle(t).fontVariationSettings, F = N.match(/"wdth"\s+([\d.eE+-]+)/), y = F ? parseFloat(F[1]) : 100, q = K(t), w = [];
88
+ for (const r of q) {
89
+ const e = r.textContent ?? "";
90
+ if (!e || !e.split("").some((m) => m in R)) continue;
91
+ const C = document.createDocumentFragment();
92
92
  for (const m of e) {
93
- const B = G[m];
94
- if (B === void 0) {
95
- const E = p.lastChild;
96
- E && E.nodeType === Node.TEXT_NODE ? E.textContent += m : p.appendChild(document.createTextNode(m));
93
+ const V = R[m];
94
+ if (V === void 0) {
95
+ const S = C.lastChild;
96
+ S && S.nodeType === Node.TEXT_NODE ? S.textContent += m : C.appendChild(document.createTextNode(m));
97
97
  } else {
98
- const E = document.createElement("span");
99
- E.className = I.char, E.style.fontVariationSettings = D(L, "wdth", y), E.textContent = m, p.appendChild(E), M.push({ span: E, riskLevel: B });
98
+ const S = document.createElement("span");
99
+ S.className = P.char, S.style.fontVariationSettings = I(N, "wdth", y), S.textContent = m, C.appendChild(S), w.push({ span: S, riskLevel: V });
100
100
  }
101
101
  }
102
- n.parentNode.replaceChild(p, n);
102
+ r.parentNode.replaceChild(C, r);
103
103
  }
104
104
  if (requestAnimationFrame(() => {
105
105
  typeof window < "u" && Math.abs(window.scrollY - x) > 2 && window.scrollTo({ top: x, behavior: "instant" });
106
- }), M.length === 0) return () => {
106
+ }), w.length === 0) return () => {
107
107
  };
108
- v && M.forEach(({ span: n }) => P(n, v));
109
- let h = -9999, q = -9999, g = !1, i = 0, V = !0, s = null;
110
- function l() {
111
- if (!V) return;
112
- if (!g) {
113
- M.forEach(({ span: e }) => {
114
- d > 0 && (e.style.transition = `font-variation-settings ${d}ms ease`), e.style.fontVariationSettings = D(L, "wdth", y), v && P(e, v);
115
- }), d > 0 && (s !== null && clearTimeout(s), s = setTimeout(() => {
116
- M.forEach(({ span: e }) => {
108
+ v && w.forEach(({ span: r }) => _(r, v));
109
+ let p = -9999, b = -9999, E = !1, i = 0, B = !0, T = null;
110
+ function s() {
111
+ if (!B) return;
112
+ if (!E) {
113
+ w.forEach(({ span: e }) => {
114
+ f > 0 && (e.style.transition = `font-variation-settings ${f}ms ease`), e.style.fontVariationSettings = I(N, "wdth", y), v && _(e, v);
115
+ }), f > 0 && (T !== null && clearTimeout(T), T = setTimeout(() => {
116
+ w.forEach(({ span: e }) => {
117
117
  e.style.transition = "";
118
- }), s = null;
119
- }, d)), i = 0;
118
+ }), T = null;
119
+ }, f)), i = 0;
120
120
  return;
121
121
  }
122
- const n = M.map(({ span: e }) => e.getBoundingClientRect());
123
- M.forEach(({ span: e, riskLevel: T }, p) => {
122
+ const r = w.map(({ span: e }) => e.getBoundingClientRect());
123
+ w.forEach(({ span: e, riskLevel: L }, C) => {
124
124
  e.style.transition = "";
125
- const m = n[p], B = m.left + m.width / 2, E = m.top + m.height / 2, X = Math.sqrt((h - B) ** 2 + (q - E) ** 2), O = Math.max(0, 1 - X / c), $ = a === "quadratic" ? O * O : O, H = f * (T / 3) * $;
126
- e.style.fontVariationSettings = D(L, "wdth", y + H), v && Z(e, v, $);
127
- }), i = requestAnimationFrame(l);
125
+ const m = r[C], V = m.left + m.width / 2, S = m.top + m.height / 2, k = Math.sqrt((p - V) ** 2 + (b - S) ** 2), O = Math.max(0, 1 - k / c), $ = a === "quadratic" ? O * O : O, H = u * (L / 3) * $;
126
+ e.style.fontVariationSettings = I(N, "wdth", y + H), v && W(e, v, $);
127
+ }), i = requestAnimationFrame(s);
128
128
  }
129
- function C(n) {
130
- h = n.clientX, q = n.clientY, g || (g = !0), i === 0 && (i = requestAnimationFrame(l));
129
+ function g(r) {
130
+ p = r.clientX, b = r.clientY, E || (E = !0), i === 0 && (i = requestAnimationFrame(s));
131
131
  }
132
- function S() {
133
- g = !1, i === 0 && (i = requestAnimationFrame(l));
132
+ function h() {
133
+ E = !1, i === 0 && (i = requestAnimationFrame(s));
134
134
  }
135
- function F(n) {
136
- n.touches.length !== 0 && (h = n.touches[0].clientX, q = n.touches[0].clientY, g || (g = !0), i === 0 && (i = requestAnimationFrame(l)));
135
+ function l(r) {
136
+ r.touches.length !== 0 && (p = r.touches[0].clientX, b = r.touches[0].clientY, E || (E = !0), i === 0 && (i = requestAnimationFrame(s)));
137
137
  }
138
- function b() {
139
- g = !1, i === 0 && (i = requestAnimationFrame(l));
138
+ function A() {
139
+ E = !1, i === 0 && (i = requestAnimationFrame(s));
140
140
  }
141
- const u = w === "document" ? document : t;
142
- return u.addEventListener("mousemove", C), u.addEventListener("mouseleave", S), u.addEventListener("touchmove", F, { passive: !0 }), u.addEventListener("touchend", b), () => {
143
- V = !1, cancelAnimationFrame(i), s !== null && clearTimeout(s), u.removeEventListener("mousemove", C), u.removeEventListener("mouseleave", S), u.removeEventListener("touchmove", F), u.removeEventListener("touchend", b), t.innerHTML = o;
141
+ const d = M === "document" ? document : t;
142
+ return d.addEventListener("mousemove", g), d.addEventListener("mouseleave", h), d.addEventListener("touchmove", l, { passive: !0 }), d.addEventListener("touchend", A), () => {
143
+ B = !1, cancelAnimationFrame(i), T !== null && clearTimeout(T), d.removeEventListener("mousemove", g), d.removeEventListener("mouseleave", h), d.removeEventListener("touchmove", l), d.removeEventListener("touchend", A), t.innerHTML = n;
144
144
  };
145
145
  }
146
- function ot(t, o, r = {}) {
146
+ function st(t, n, o = {}) {
147
147
  if (typeof window > "u") return () => {
148
148
  };
149
149
  if (window.matchMedia("(prefers-reduced-motion: reduce)").matches)
150
- return t.innerHTML = o, () => {
150
+ return t.innerHTML = n, () => {
151
151
  };
152
- const f = r.axes ?? Y.axes, c = r.radius ?? Y.radius, a = r.falloff ?? Y.falloff, w = r.magnetMode ?? Y.magnetMode, v = r.scope ?? Y.scope, d = r.props, x = r.transitionMs ?? 0, L = window.scrollY;
153
- t.innerHTML = o;
154
- const N = J(t), y = [];
155
- for (const n of N) {
156
- const e = n.textContent ?? "";
152
+ const u = o.axes ?? Y.axes, c = o.radius ?? Y.radius, a = o.falloff ?? Y.falloff, M = o.magnetMode ?? Y.magnetMode, v = o.scope ?? Y.scope, f = o.props, x = o.transitionMs ?? 0, N = window.scrollY;
153
+ t.innerHTML = n;
154
+ const F = K(t), y = [];
155
+ for (const r of F) {
156
+ const e = r.textContent ?? "";
157
157
  if (!e.trim()) continue;
158
- const T = e.split(/(\S+)/), p = document.createDocumentFragment();
159
- for (let m = 0; m < T.length; m += 2) {
160
- const B = T[m], E = T[m + 1];
161
- if (!E) continue;
162
- const O = T[m + 3] === void 0 ? T[m + 2] ?? "" : "", $ = document.createElement("span");
163
- $.className = I.word, $.textContent = B + E + O, p.appendChild($), y.push($);
158
+ const L = e.split(/(\S+)/), C = document.createDocumentFragment();
159
+ for (let m = 0; m < L.length; m += 2) {
160
+ const V = L[m], S = L[m + 1];
161
+ if (!S) continue;
162
+ const O = L[m + 3] === void 0 ? L[m + 2] ?? "" : "", $ = document.createElement("span");
163
+ $.className = P.word, $.textContent = V + S + O, C.appendChild($), y.push($);
164
164
  }
165
- n.parentNode.replaceChild(p, n);
165
+ r.parentNode.replaceChild(C, r);
166
166
  }
167
167
  if (requestAnimationFrame(() => {
168
- typeof window < "u" && Math.abs(window.scrollY - L) > 2 && window.scrollTo({ top: L, behavior: "instant" });
168
+ typeof window < "u" && Math.abs(window.scrollY - N) > 2 && window.scrollTo({ top: N, behavior: "instant" });
169
169
  }), y.length === 0) return () => {
170
170
  };
171
- const A = getComputedStyle(t).fontVariationSettings, M = R(
172
- A,
173
- Object.fromEntries(Object.entries(f).map(([n, [e]]) => [n, e]))
171
+ const q = getComputedStyle(t).fontVariationSettings, w = z(
172
+ q,
173
+ Object.fromEntries(Object.entries(u).map(([r, [e]]) => [r, e]))
174
174
  );
175
- y.forEach((n) => {
176
- n.style.fontVariationSettings = M, d && P(n, d);
175
+ y.forEach((r) => {
176
+ r.style.fontVariationSettings = w, f && _(r, f);
177
177
  });
178
- let h = -9999, q = -9999, g = !1, i = 0, V = !0, s = null;
179
- function l() {
180
- if (!V) return;
181
- if (!g) {
178
+ let p = -9999, b = -9999, E = !1, i = 0, B = !0, T = null;
179
+ function s() {
180
+ if (!B) return;
181
+ if (!E) {
182
182
  y.forEach((e) => {
183
- x > 0 && (e.style.transition = `font-variation-settings ${x}ms ease`), e.style.fontVariationSettings = M, d && P(e, d);
184
- }), x > 0 && (s !== null && clearTimeout(s), s = setTimeout(() => {
183
+ x > 0 && (e.style.transition = `font-variation-settings ${x}ms ease`), e.style.fontVariationSettings = w, f && _(e, f);
184
+ }), x > 0 && (T !== null && clearTimeout(T), T = setTimeout(() => {
185
185
  y.forEach((e) => {
186
186
  e.style.transition = "";
187
- }), s = null;
187
+ }), T = null;
188
188
  }, x)), i = 0;
189
189
  return;
190
190
  }
191
- const n = y.map((e) => e.getBoundingClientRect());
192
- y.forEach((e, T) => {
191
+ const r = y.map((e) => e.getBoundingClientRect());
192
+ y.forEach((e, L) => {
193
193
  e.style.transition = "";
194
- const p = n[T], m = p.left + p.width / 2, B = p.top + p.height / 2, E = Math.sqrt((h - m) ** 2 + (q - B) ** 2), X = Math.max(0, 1 - E / c), O = a === "quadratic" ? X * X : X, $ = w === "repel" ? 1 - O : O, H = {};
195
- for (const K of Object.keys(f)) {
196
- const [U, W] = f[K] ?? [300, 500];
197
- H[K] = U + (W - U) * $;
194
+ const C = r[L], m = C.left + C.width / 2, V = C.top + C.height / 2, S = Math.sqrt((p - m) ** 2 + (b - V) ** 2), k = Math.max(0, 1 - S / c), O = a === "quadratic" ? k * k : k, $ = M === "repel" ? 1 - O : O, H = {};
195
+ for (const U of Object.keys(u)) {
196
+ const [G, tt] = u[U] ?? [300, 500];
197
+ H[U] = G + (tt - G) * $;
198
198
  }
199
- e.style.fontVariationSettings = R(A, H), d && Z(e, d, O);
200
- }), i = requestAnimationFrame(l);
199
+ e.style.fontVariationSettings = z(q, H), f && W(e, f, O);
200
+ }), i = requestAnimationFrame(s);
201
201
  }
202
- function C(n) {
203
- h = n.clientX, q = n.clientY, g || (g = !0), i === 0 && (i = requestAnimationFrame(l));
202
+ function g(r) {
203
+ p = r.clientX, b = r.clientY, E || (E = !0), i === 0 && (i = requestAnimationFrame(s));
204
204
  }
205
- function S() {
206
- g = !1, i === 0 && (i = requestAnimationFrame(l));
205
+ function h() {
206
+ E = !1, i === 0 && (i = requestAnimationFrame(s));
207
207
  }
208
- function F(n) {
209
- n.touches.length !== 0 && (h = n.touches[0].clientX, q = n.touches[0].clientY, g || (g = !0), i === 0 && (i = requestAnimationFrame(l)));
208
+ function l(r) {
209
+ r.touches.length !== 0 && (p = r.touches[0].clientX, b = r.touches[0].clientY, E || (E = !0), i === 0 && (i = requestAnimationFrame(s)));
210
210
  }
211
- function b() {
212
- g = !1, i === 0 && (i = requestAnimationFrame(l));
211
+ function A() {
212
+ E = !1, i === 0 && (i = requestAnimationFrame(s));
213
213
  }
214
- const u = v === "document" ? document : t;
215
- return u.addEventListener("mousemove", C), u.addEventListener("mouseleave", S), u.addEventListener("touchmove", F, { passive: !0 }), u.addEventListener("touchend", b), () => {
216
- V = !1, cancelAnimationFrame(i), s !== null && clearTimeout(s), u.removeEventListener("mousemove", C), u.removeEventListener("mouseleave", S), u.removeEventListener("touchmove", F), u.removeEventListener("touchend", b), t.innerHTML = o;
214
+ const d = v === "document" ? document : t;
215
+ return d.addEventListener("mousemove", g), d.addEventListener("mouseleave", h), d.addEventListener("touchmove", l, { passive: !0 }), d.addEventListener("touchend", A), () => {
216
+ B = !1, cancelAnimationFrame(i), T !== null && clearTimeout(T), d.removeEventListener("mousemove", g), d.removeEventListener("mouseleave", h), d.removeEventListener("touchmove", l), d.removeEventListener("touchend", A), t.innerHTML = n;
217
217
  };
218
218
  }
219
- function rt(t) {
220
- const o = k(null), r = k(null), f = k(t);
221
- f.current = t;
222
- const c = k(null), a = t.mode ?? "field", { axes: w, radius: v, falloff: d, magnetMode: x, wdthBoost: L, scope: N } = t, y = w ? JSON.stringify(w) : void 0, A = t.props ? JSON.stringify(t.props) : void 0, M = j(() => {
223
- const h = o.current;
224
- if (!h) return;
225
- r.current === null && (r.current = et(h)), c.current && (c.current(), c.current = null), (f.current.mode ?? "field") === "field" ? c.current = ot(h, r.current, f.current) : c.current = nt(h, r.current, f.current);
226
- }, [a, y, v, d, x, L, N, A]);
227
- return tt(() => (M(), () => {
219
+ function ct(t) {
220
+ const n = j(null), o = j(null), u = j(t);
221
+ u.current = t;
222
+ const c = j(null), a = t.mode ?? "field", { axes: M, radius: v, falloff: f, magnetMode: x, wdthBoost: N, scope: F } = t, y = M ? JSON.stringify(M) : void 0, q = t.props ? JSON.stringify(t.props) : void 0, w = X(() => {
223
+ const p = n.current;
224
+ if (!p) return;
225
+ o.current === null && (o.current = ot(p)), c.current && (c.current(), c.current = null), (u.current.mode ?? "field") === "field" ? c.current = st(p, o.current, u.current) : c.current = rt(p, o.current, u.current);
226
+ }, [a, y, v, f, x, N, F, q]);
227
+ return et(() => (w(), () => {
228
228
  c.current && (c.current(), c.current = null);
229
- }), [M]), _(() => {
230
- document.fonts.ready.then(M);
231
- }, [M]), o;
229
+ }), [w]), Q(() => {
230
+ document.fonts.ready.then(w);
231
+ }, [w]), n;
232
232
  }
233
- const st = z(
234
- function({ children: o, as: r = "p", className: f, style: c, ...a }, w) {
235
- const v = rt(a), d = j(
233
+ const it = Z(
234
+ function({ children: n, as: o = "p", className: u, style: c, ...a }, M) {
235
+ const v = ct(a), f = X(
236
236
  (x) => {
237
- v.current = x, typeof w == "function" ? w(x) : w && (w.current = x);
237
+ v.current = x, typeof M == "function" ? M(x) : M && (M.current = x);
238
238
  },
239
239
  // eslint-disable-next-line react-hooks/exhaustive-deps
240
- [w]
240
+ [M]
241
241
  );
242
- return /* @__PURE__ */ Q(r, { ref: d, className: f, style: c, children: o });
242
+ return /* @__PURE__ */ D(o, { ref: f, className: u, style: c, children: n });
243
243
  }
244
244
  );
245
- st.displayName = "MagnetTypeText";
246
- const ct = z(
245
+ it.displayName = "MagnetTypeText";
246
+ const at = Z(
247
247
  function({
248
- children: o,
249
- as: r = "p",
250
- className: f,
248
+ children: n,
249
+ as: o = "p",
250
+ className: u,
251
251
  style: c,
252
252
  minWeight: a = 300,
253
- maxWeight: w = 600,
253
+ maxWeight: M = 600,
254
254
  proximityRadius: v,
255
- spreadRadius: d,
255
+ spreadRadius: f,
256
256
  fixedAxes: x = {}
257
- }, L) {
258
- const N = k(null), y = k(null), A = k([]), M = j(
257
+ }, N) {
258
+ const F = j(null), y = j(null), q = j([]), w = X(
259
259
  (s) => {
260
- N.current = s, typeof L == "function" ? L(s) : L && (L.current = s);
260
+ F.current = s, typeof N == "function" ? N(s) : N && (N.current = s);
261
261
  },
262
262
  // eslint-disable-next-line react-hooks/exhaustive-deps
263
- [L]
263
+ [N]
264
264
  );
265
- function h(s) {
266
- const l = [`'wght' ${s.toFixed(0)}`];
267
- for (const [C, S] of Object.entries(x)) l.push(`'${C}' ${S}`);
268
- return l.join(", ");
265
+ function p(s) {
266
+ const g = [`'wght' ${s.toFixed(0)}`];
267
+ for (const [h, l] of Object.entries(x)) g.push(`'${h}' ${l}`);
268
+ return g.join(", ");
269
269
  }
270
- _(() => {
271
- var b;
272
- if (!d) return;
273
- const s = N.current;
274
- if (!s) return;
275
- const l = [], C = document.createTreeWalker(s, NodeFilter.SHOW_TEXT), S = [];
276
- let F;
277
- for (; F = C.nextNode(); ) S.push(F);
278
- for (const u of S) {
279
- const n = u.textContent ?? "";
280
- if (!n) continue;
281
- const e = document.createDocumentFragment();
282
- for (const T of n)
283
- if (/\s/.test(T))
284
- e.appendChild(document.createTextNode(T));
285
- else {
286
- const p = document.createElement("span");
287
- p.style.fontVariationSettings = h(a), p.textContent = T, l.push(p), e.appendChild(p);
288
- }
289
- (b = u.parentNode) == null || b.replaceChild(e, u);
270
+ const b = nt(() => {
271
+ if (!f) return n;
272
+ q.current = [];
273
+ let s = 0;
274
+ function g(h) {
275
+ if (typeof h == "string")
276
+ return [...h].map((l) => {
277
+ if (/\s/.test(l)) return l;
278
+ const A = s++;
279
+ return /* @__PURE__ */ D(
280
+ "span",
281
+ {
282
+ ref: (d) => {
283
+ q.current[A] = d;
284
+ },
285
+ style: { fontVariationSettings: p(a) },
286
+ children: l
287
+ },
288
+ A
289
+ );
290
+ });
291
+ if (Array.isArray(h)) return h.map((l, A) => /* @__PURE__ */ D(J.Fragment, { children: g(l) }, A));
292
+ if (J.isValidElement(h)) {
293
+ const l = h;
294
+ if (l.props.children !== void 0)
295
+ return J.cloneElement(l, {}, g(l.props.children));
296
+ }
297
+ return h;
290
298
  }
291
- A.current = l;
292
- }, []);
293
- function q(s, l) {
294
- const C = N.current;
295
- if (!C) return;
296
- const S = C.getBoundingClientRect(), F = Math.max(S.left - s, 0, s - S.right), b = Math.max(S.top - l, 0, l - S.bottom), u = Math.sqrt(F * F + b * b);
297
- if (v !== void 0 && !d) {
298
- const e = 1 - (1 - Math.max(0, 1 - u / v)) ** 2;
299
- C.style.fontVariationSettings = h(a + (w - a) * e);
299
+ return g(n);
300
+ }, [n, f, a, JSON.stringify(x)]);
301
+ function E(s, g) {
302
+ const h = F.current;
303
+ if (!h) return;
304
+ const l = h.getBoundingClientRect(), A = Math.max(l.left - s, 0, s - l.right), d = Math.max(l.top - g, 0, g - l.bottom), r = Math.sqrt(A * A + d * d);
305
+ if (v !== void 0 && !f) {
306
+ const L = 1 - (1 - Math.max(0, 1 - r / v)) ** 2;
307
+ h.style.fontVariationSettings = p(a + (M - a) * L);
300
308
  return;
301
309
  }
302
- if (d) {
303
- if (v !== void 0 && u > v) {
304
- C.style.fontVariationSettings = h(a);
305
- for (const n of A.current) n.style.fontVariationSettings = h(a);
310
+ if (f) {
311
+ if (v !== void 0 && r > v) {
312
+ h.style.fontVariationSettings = p(a);
313
+ for (const e of q.current) e && (e.style.fontVariationSettings = p(a));
306
314
  return;
307
315
  }
308
- for (const n of A.current) {
309
- const e = n.getBoundingClientRect(), T = (e.left + e.right) / 2, p = (e.top + e.bottom) / 2, m = Math.sqrt((s - T) ** 2 + (l - p) ** 2), E = 1 - (1 - Math.max(0, 1 - m / d)) ** 2;
310
- n.style.fontVariationSettings = h(a + (w - a) * E);
316
+ for (const e of q.current) {
317
+ if (!e) continue;
318
+ const L = e.getBoundingClientRect(), C = (L.left + L.right) / 2, m = (L.top + L.bottom) / 2, V = Math.sqrt((s - C) ** 2 + (g - m) ** 2), k = 1 - (1 - Math.max(0, 1 - V / f)) ** 2;
319
+ e.style.fontVariationSettings = p(a + (M - a) * k);
311
320
  }
312
321
  }
313
322
  }
314
- const g = j(
323
+ const i = X(
315
324
  (s) => {
316
- y.current = { x: s.clientX, y: s.clientY }, q(s.clientX, s.clientY);
325
+ y.current = { x: s.clientX, y: s.clientY }, E(s.clientX, s.clientY);
317
326
  },
318
- [a, w, v, d]
319
- ), i = j(
327
+ [a, M, v, f]
328
+ ), B = X(
320
329
  () => {
321
- y.current && q(y.current.x, y.current.y);
330
+ y.current && E(y.current.x, y.current.y);
322
331
  },
323
- [a, w, v, d]
324
- ), V = j(
332
+ [a, M, v, f]
333
+ ), T = X(
325
334
  () => {
326
335
  y.current = null;
327
- const s = N.current;
328
- s && (s.style.fontVariationSettings = h(a));
329
- for (const l of A.current) l.style.fontVariationSettings = h(a);
336
+ const s = F.current;
337
+ s && (s.style.fontVariationSettings = p(a));
338
+ for (const g of q.current) g && (g.style.fontVariationSettings = p(a));
330
339
  },
331
340
  [a]
332
341
  );
333
- return _(() => (window.addEventListener("mousemove", g, { passive: !0 }), window.addEventListener("scroll", i, { passive: !0, capture: !0 }), document.documentElement.addEventListener("mouseleave", V), () => {
334
- window.removeEventListener("mousemove", g), window.removeEventListener("scroll", i, { capture: !0 }), document.documentElement.removeEventListener("mouseleave", V);
335
- }), [g, i, V]), /* @__PURE__ */ Q(
336
- r,
342
+ return Q(() => (window.addEventListener("mousemove", i, { passive: !0 }), window.addEventListener("scroll", B, { passive: !0, capture: !0 }), document.documentElement.addEventListener("mouseleave", T), () => {
343
+ window.removeEventListener("mousemove", i), window.removeEventListener("scroll", B, { capture: !0 }), document.documentElement.removeEventListener("mouseleave", T);
344
+ }), [i, B, T]), /* @__PURE__ */ D(
345
+ o,
337
346
  {
338
- ref: M,
339
- className: f,
340
- style: { fontVariationSettings: h(a), ...c },
341
- children: o
347
+ ref: w,
348
+ className: u,
349
+ style: { fontVariationSettings: p(a), ...c },
350
+ children: b
342
351
  }
343
352
  );
344
353
  }
345
354
  );
346
- ct.displayName = "MagnetBlock";
355
+ at.displayName = "MagnetBlock";
347
356
  export {
348
- I as MAGNET_TYPE_CLASSES,
349
- ct as MagnetBlock,
350
- st as MagnetTypeText,
351
- nt as applyMagnetType,
352
- et as getCleanHTML,
353
- ut as removeMagnetType,
354
- ot as startMagnetType,
355
- rt as useMagnetType
357
+ P as MAGNET_TYPE_CLASSES,
358
+ at as MagnetBlock,
359
+ it as MagnetTypeText,
360
+ rt as applyMagnetType,
361
+ ot as getCleanHTML,
362
+ lt as removeMagnetType,
363
+ st as startMagnetType,
364
+ ct as useMagnetType
356
365
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liiift-studio/magnettype",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Cursor-field per-word variable font axis variation and per-character legibility mode",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",