@liiift-studio/magnettype 1.1.6 → 1.2.1
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/README.md +18 -18
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +13 -7
- package/dist/index.js +339 -337
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ Per-word cursor-proximity weight variation driven by a continuous rAF loop.
|
|
|
30
30
|
import { MagnetTypeText } from '@liiift-studio/magnettype'
|
|
31
31
|
|
|
32
32
|
<MagnetTypeText
|
|
33
|
-
mode="
|
|
33
|
+
mode="word"
|
|
34
34
|
axes={{ wght: [300, 700] }}
|
|
35
35
|
radius={150}
|
|
36
36
|
falloff="quadratic"
|
|
@@ -40,43 +40,43 @@ import { MagnetTypeText } from '@liiift-studio/magnettype'
|
|
|
40
40
|
</MagnetTypeText>
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
### React — block mode (`
|
|
43
|
+
### React — block mode (`MagnetChar`)
|
|
44
44
|
|
|
45
45
|
Per-character cursor-proximity weight variation. Works with mixed content (inline elements, links, `<code>`, etc.) inside any block element. Characters are wrapped as React elements — no DOM mutation.
|
|
46
46
|
|
|
47
47
|
```tsx
|
|
48
|
-
import {
|
|
48
|
+
import { MagnetChar } from '@liiift-studio/magnettype'
|
|
49
49
|
|
|
50
50
|
// Per-character spread — each character responds to cursor distance
|
|
51
|
-
<
|
|
51
|
+
<MagnetChar
|
|
52
52
|
spreadRadius={200}
|
|
53
53
|
minWeight={300}
|
|
54
54
|
maxWeight={700}
|
|
55
55
|
>
|
|
56
56
|
Typography that responds to presence.
|
|
57
|
-
</
|
|
57
|
+
</MagnetChar>
|
|
58
58
|
|
|
59
59
|
// Whole-element gate — the effect only activates when the cursor is within proximityRadius of the element edge
|
|
60
|
-
<
|
|
60
|
+
<MagnetChar
|
|
61
61
|
proximityRadius={120}
|
|
62
62
|
minWeight={300}
|
|
63
63
|
maxWeight={700}
|
|
64
64
|
>
|
|
65
65
|
Weight rises when the cursor enters.
|
|
66
|
-
</
|
|
66
|
+
</MagnetChar>
|
|
67
67
|
|
|
68
68
|
// Both combined — proximity gates the spread effect
|
|
69
|
-
<
|
|
69
|
+
<MagnetChar
|
|
70
70
|
proximityRadius={200}
|
|
71
71
|
spreadRadius={120}
|
|
72
72
|
minWeight={300}
|
|
73
73
|
maxWeight={700}
|
|
74
74
|
>
|
|
75
75
|
Only spreads when the cursor is close.
|
|
76
|
-
</
|
|
76
|
+
</MagnetChar>
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
**`
|
|
79
|
+
**`MagnetChar` props:**
|
|
80
80
|
|
|
81
81
|
| Prop | Default | Description |
|
|
82
82
|
|------|---------|-------------|
|
|
@@ -97,7 +97,7 @@ import { MagnetBlock } from '@liiift-studio/magnettype'
|
|
|
97
97
|
```tsx
|
|
98
98
|
import { useMagnetType } from '@liiift-studio/magnettype'
|
|
99
99
|
|
|
100
|
-
const ref = useMagnetType({ mode: '
|
|
100
|
+
const ref = useMagnetType({ mode: 'word', axes: { wght: [300, 700] }, radius: 150 })
|
|
101
101
|
return <p ref={ref}>{children}</p>
|
|
102
102
|
```
|
|
103
103
|
|
|
@@ -120,7 +120,7 @@ import { startMagnetType, removeMagnetType, getCleanHTML } from '@liiift-studio/
|
|
|
120
120
|
|
|
121
121
|
const el = document.querySelector('p')
|
|
122
122
|
const original = getCleanHTML(el)
|
|
123
|
-
const opts = { mode: '
|
|
123
|
+
const opts = { mode: 'word', axes: { wght: [300, 700] }, radius: 150 }
|
|
124
124
|
|
|
125
125
|
let stop
|
|
126
126
|
|
|
@@ -163,10 +163,10 @@ ro.observe(el)
|
|
|
163
163
|
### TypeScript
|
|
164
164
|
|
|
165
165
|
```ts
|
|
166
|
-
import type { MagnetTypeOptions, FalloffType, MagnetModeType,
|
|
166
|
+
import type { MagnetTypeOptions, FalloffType, MagnetModeType, MagnetCharProps } from '@liiift-studio/magnettype'
|
|
167
167
|
|
|
168
168
|
const fieldOpts: MagnetTypeOptions = {
|
|
169
|
-
mode: '
|
|
169
|
+
mode: 'word',
|
|
170
170
|
axes: { wght: [300, 700], wdth: [90, 110] },
|
|
171
171
|
radius: 120,
|
|
172
172
|
falloff: 'quadratic' as FalloffType,
|
|
@@ -185,7 +185,7 @@ const legibilityOpts: MagnetTypeOptions = {
|
|
|
185
185
|
|
|
186
186
|
| Option | Default | Description |
|
|
187
187
|
|--------|---------|-------------|
|
|
188
|
-
| `mode` | `'
|
|
188
|
+
| `mode` | `'word'` | `'word'` — cursor proximity drives per-word `font-variation-settings` via a continuous rAF loop. `'legibility'` — static per-character `wdth` boost on visually confusable characters |
|
|
189
189
|
| `axes` | `{ wght: [300, 500] }` | *(field mode)* Map of axis tag → `[restValue, peakValue]` |
|
|
190
190
|
| `radius` | `120` | *(field mode)* Pixel radius over which the field effect fades from each word's centre |
|
|
191
191
|
| `falloff` | `'quadratic'` | *(field mode)* `'linear'` or `'quadratic'` falloff curve |
|
|
@@ -209,9 +209,9 @@ strength = normalised² (quadratic) or normalised (linear)
|
|
|
209
209
|
|
|
210
210
|
Each word's `font-variation-settings` interpolates between `restValue` and `peakValue` at that strength. Reads are batched before writes on every frame to avoid layout thrashing. When the cursor leaves, one final frame resets all words to `restValue`.
|
|
211
211
|
|
|
212
|
-
### Block mode (`
|
|
212
|
+
### Block mode (`MagnetChar`)
|
|
213
213
|
|
|
214
|
-
`
|
|
214
|
+
`MagnetChar` splits string children into per-character `<span>` elements during the React render pass using `useMemo` — no DOM mutation. Callback refs collect each span element. On `mousemove` (and on `scroll`, using the stored last position), the component reads each span's `getBoundingClientRect`, computes cursor-to-character-centre distance, and sets `font-variation-settings` directly on the span's style. This is passive and batched per frame via the event handler.
|
|
215
215
|
|
|
216
216
|
`proximityRadius` measures cursor distance to the element **edge** (not its centre) — useful as an outer gate so the effect only fires when the cursor is actually near the block. `spreadRadius` measures cursor distance to each **character centre** — controls how wide the weight gradient spreads around the cursor within the block. Both are independent and combinable.
|
|
217
217
|
|
|
@@ -247,4 +247,4 @@ The package itself has zero runtime dependencies. Do not remove this entry.
|
|
|
247
247
|
|
|
248
248
|
---
|
|
249
249
|
|
|
250
|
-
Current version: 1.
|
|
250
|
+
Current version: 1.2.0
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("react"),W=require("react/jsx-runtime"),rt={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},z={word:"mt-word",char:"mt-char",probe:"mt-probe"},K={axes:{wght:[300,500]},radius:120,falloff:"quadratic",magnetMode:"attract",wdthBoost:6,scope:"document"};function ot(t,n=[]){return t.nodeType===Node.TEXT_NODE?n.push(t):t.childNodes.forEach(o=>ot(o,n)),n}function tt(t,n,o){if(!t||t==="normal")return`"${n}" ${o}`;const E=new RegExp(`(["'])${n}\\1\\s+[\\d.eE+-]+`),y=`"${n}" ${o}`;return E.test(t)?t.replace(E,y):`${t}, ${y}`}function nt(t,n){let o=t;for(const[E,y]of Object.entries(n))o=tt(o,E,y);return o}function st(t,n,o){if(n.opacity!==void 0){const[E,y]=n.opacity;t.style.opacity=String(E+(y-E)*o)}n.italic===!0&&(t.style.fontStyle=o>.5?"italic":"")}function et(t,n){n.opacity!==void 0&&(t.style.opacity=String(n.opacity[0])),n.italic===!0&&(t.style.fontStyle="")}function ct(t){const n=t.cloneNode(!0),o=n.querySelectorAll(`.${z.word}, .${z.char}`);return Array.from(o).reverse().forEach(y=>{const d=y.parentNode;if(d){for(;y.firstChild;)d.insertBefore(y.firstChild,y);d.removeChild(y)}}),n.innerHTML}function mt(t,n){t.innerHTML=n}function it(t,n,o={}){var p,r;if(typeof window>"u")return()=>{};if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return t.innerHTML=n,()=>{};const E=o.wdthBoost??K.wdthBoost,y=o.radius??K.radius,d=o.falloff??K.falloff,L=o.scope??K.scope,F=o.props,m=o.transitionMs??0,S=o.cachePositions??!0,V=window.scrollY;t.innerHTML=n;const j=getComputedStyle(t).fontVariationSettings,N=j.match(/"wdth"\s+([\d.eE+-]+)/),k=N?parseFloat(N[1]):100,T=ot(t),g=[];for(const a of T){const C=a.textContent??"";if(!C||!C.split("").some(v=>v in rt))continue;const e=document.createDocumentFragment();for(const v of C){const i=rt[v];if(i===void 0){const u=e.lastChild;u&&u.nodeType===Node.TEXT_NODE?u.textContent+=v:e.appendChild(document.createTextNode(v))}else{const u=document.createElement("span");u.className=z.char,u.style.fontVariationSettings=tt(j,"wdth",k),u.textContent=v,e.appendChild(u),g.push({span:u,riskLevel:i})}}a.parentNode.replaceChild(e,a)}if(requestAnimationFrame(()=>{typeof window<"u"&&Math.abs(window.scrollY-V)>2&&window.scrollTo({top:V,behavior:"instant"})}),g.length===0)return()=>{};F&&g.forEach(({span:a})=>et(a,F));let A=[],H=!1;function _(){const a=window.scrollX,C=window.scrollY;A=g.map(({span:c})=>{const e=c.getBoundingClientRect();return{cx:(e.left+e.right)/2+a,cy:(e.top+e.bottom)/2+C}}),H=!0}let R=null;S&&(_(),R=new ResizeObserver(()=>{H=!1}),R.observe(t),(r=(p=document.fonts)==null?void 0:p.ready)==null||r.then(()=>{H=!1}));let q=-9999,B=-9999,$=!1,w=0,P=!0,b=null;function D(){if(!P)return;if(!$){g.forEach(({span:e})=>{m>0&&(e.style.transition=`font-variation-settings ${m}ms ease`),e.style.fontVariationSettings=tt(j,"wdth",k),F&&et(e,F)}),m>0&&(b!==null&&clearTimeout(b),b=setTimeout(()=>{g.forEach(({span:e})=>{e.style.transition=""}),b=null},m)),w=0;return}S&&!H&&_();const a=S?q+window.scrollX:q,C=S?B+window.scrollY:B,c=S?null:g.map(({span:e})=>e.getBoundingClientRect());g.forEach(({span:e,riskLevel:v},i)=>{e.style.transition="";let u,O;if(S)({cx:u,cy:O}=A[i]);else{const I=c[i];u=I.left+I.width/2,O=I.top+I.height/2}const M=Math.sqrt((a-u)**2+(C-O)**2),f=Math.max(0,1-M/y),x=d==="quadratic"?f*f:f,Y=E*(v/3)*x;e.style.fontVariationSettings=tt(j,"wdth",k+Y),F&&st(e,F,x)}),w=requestAnimationFrame(D)}function X(a){q=a.clientX,B=a.clientY,$||($=!0),w===0&&(w=requestAnimationFrame(D))}function J(){$=!1,w===0&&(w=requestAnimationFrame(D))}function Q(a){a.touches.length!==0&&(q=a.touches[0].clientX,B=a.touches[0].clientY,$||($=!0),w===0&&(w=requestAnimationFrame(D)))}function l(){$=!1,w===0&&(w=requestAnimationFrame(D))}const s=L==="document"?document:t;return s.addEventListener("mousemove",X),s.addEventListener("mouseleave",J),s.addEventListener("touchmove",Q,{passive:!0}),s.addEventListener("touchend",l),()=>{P=!1,cancelAnimationFrame(w),b!==null&&clearTimeout(b),R&&R.disconnect(),s.removeEventListener("mousemove",X),s.removeEventListener("mouseleave",J),s.removeEventListener("touchmove",Q),s.removeEventListener("touchend",l),t.innerHTML=n}}function lt(t,n,o={}){var a,C;if(typeof window>"u")return()=>{};if(window.matchMedia("(prefers-reduced-motion: reduce)").matches)return t.innerHTML=n,()=>{};const E=o.axes??K.axes,y=o.radius??K.radius,d=o.falloff??K.falloff,L=o.magnetMode??K.magnetMode,F=o.scope??K.scope,m=o.props,S=o.transitionMs??0,V=o.cachePositions??!0,j=o.stabilizeLayout??!0,N=window.scrollY;t.innerHTML=n;const k=ot(t),T=[];for(const c of k){const e=c.textContent??"";if(!e.trim())continue;const v=e.split(/(\S+)/),i=document.createDocumentFragment();for(let u=0;u<v.length;u+=2){const O=v[u],M=v[u+1];if(!M)continue;const x=v[u+3]===void 0?v[u+2]??"":"",Y=document.createElement("span");Y.className=z.word,Y.textContent=O+M+x,i.appendChild(Y),T.push(Y)}c.parentNode.replaceChild(i,c)}if(requestAnimationFrame(()=>{typeof window<"u"&&Math.abs(window.scrollY-N)>2&&window.scrollTo({top:N,behavior:"instant"})}),T.length===0)return()=>{};const g=getComputedStyle(t).fontVariationSettings,A=nt(g,Object.fromEntries(Object.entries(E).map(([c,[e]])=>[c,e])));let H=0;if(j){const c=nt(g,Object.fromEntries(Object.entries(E).map(([f,[,x]])=>[f,x]))),e=t.style.fontVariationSettings,v=t.style.whiteSpace,i=t.style.overflow;t.style.whiteSpace="nowrap",t.style.overflow="visible",t.style.fontVariationSettings=c;const u=t.scrollWidth;t.style.fontVariationSettings=A;const O=t.scrollWidth;t.style.fontVariationSettings=e,t.style.whiteSpace=v,t.style.overflow=i;const M=T.reduce((f,x)=>{var Y;return f+(((Y=x.textContent)==null?void 0:Y.replace(/\s+/g,"").length)??0)},0);M>0&&u>O&&(H=(u-O)/M)}T.forEach(c=>{c.style.fontVariationSettings=A,m&&et(c,m)});let _=[],R=!1;function q(){const c=window.scrollX,e=window.scrollY;_=T.map(v=>{const i=v.getBoundingClientRect();return{cx:(i.left+i.right)/2+c,cy:(i.top+i.bottom)/2+e}}),R=!0}let B=null;V&&(q(),B=new ResizeObserver(()=>{R=!1}),B.observe(t),(C=(a=document.fonts)==null?void 0:a.ready)==null||C.then(()=>{R=!1}));let $=-9999,w=-9999,P=!1,b=0,D=!0,X=null;function J(){if(!D)return;if(!P){T.forEach(i=>{S>0&&(i.style.transition=`font-variation-settings ${S}ms ease`),i.style.fontVariationSettings=A,j&&(i.style.letterSpacing=""),m&&et(i,m)}),S>0&&(X!==null&&clearTimeout(X),X=setTimeout(()=>{T.forEach(i=>{i.style.transition=""}),X=null},S)),b=0;return}V&&!R&&q();const c=V?$+window.scrollX:$,e=V?w+window.scrollY:w,v=V?null:T.map(i=>i.getBoundingClientRect());T.forEach((i,u)=>{i.style.transition="";let O,M;if(V)({cx:O,cy:M}=_[u]);else{const G=v[u];O=G.left+G.width/2,M=G.top+G.height/2}const f=Math.sqrt((c-O)**2+(e-M)**2),x=Math.max(0,1-f/y),Y=d==="quadratic"?x*x:x,I=L==="repel"?1-Y:Y,Z={};for(const G of Object.keys(E)){const[U,dt]=E[G]??[300,500];Z[G]=U+(dt-U)*I}i.style.fontVariationSettings=nt(g,Z),j&&H!==0&&(i.style.letterSpacing=`${(-H*I).toFixed(3)}px`),m&&st(i,m,Y)}),b=requestAnimationFrame(J)}function Q(c){$=c.clientX,w=c.clientY,P||(P=!0),b===0&&(b=requestAnimationFrame(J))}function l(){P=!1,b===0&&(b=requestAnimationFrame(J))}function s(c){c.touches.length!==0&&($=c.touches[0].clientX,w=c.touches[0].clientY,P||(P=!0),b===0&&(b=requestAnimationFrame(J)))}function p(){P=!1,b===0&&(b=requestAnimationFrame(J))}const r=F==="document"?document:t;return r.addEventListener("mousemove",Q),r.addEventListener("mouseleave",l),r.addEventListener("touchmove",s,{passive:!0}),r.addEventListener("touchend",p),()=>{D=!1,cancelAnimationFrame(b),X!==null&&clearTimeout(X),B&&B.disconnect(),r.removeEventListener("mousemove",Q),r.removeEventListener("mouseleave",l),r.removeEventListener("touchmove",s),r.removeEventListener("touchend",p),t.innerHTML=n}}function at(t){const n=h.useRef(null),o=h.useRef(null),E=h.useRef(t);E.current=t;const y=h.useRef(null),d=t.mode??"field",{axes:L,radius:F,falloff:m,magnetMode:S,wdthBoost:V,scope:j}=t,N=L?JSON.stringify(L):void 0,k=t.props?JSON.stringify(t.props):void 0,T=h.useCallback(()=>{const g=n.current;if(!g)return;o.current===null&&(o.current=ct(g)),y.current&&(y.current(),y.current=null),(E.current.mode??"field")==="field"?y.current=lt(g,o.current,E.current):y.current=it(g,o.current,E.current)},[d,N,F,m,S,V,j,k]);return h.useLayoutEffect(()=>(T(),()=>{y.current&&(y.current(),y.current=null)}),[T]),h.useEffect(()=>{var g,A;(A=(g=document.fonts)==null?void 0:g.ready)==null||A.then(T)},[T]),n}const ut=h.forwardRef(function({children:n,as:o="p",className:E,style:y,...d},L){const F=at(d),m=h.useCallback(S=>{F.current=S,typeof L=="function"?L(S):L&&(L.current=S)},[L]);return W.jsx(o,{ref:m,className:E,style:y,children:n})});ut.displayName="MagnetTypeText";const ft=h.forwardRef(function({children:n,as:o="p",className:E,style:y,minWeight:d=300,maxWeight:L=600,proximityRadius:F,spreadRadius:m,fixedAxes:S={},cachePositions:V=!0,rafThrottle:j=!0,stabilizeLayout:N=!0},k){const T=h.useRef(null),g=h.useRef(null),A=h.useRef([]),H=h.useRef([]),_=h.useRef(null),R=h.useRef(!1),q=h.useRef(null),B=h.useRef(0),$=h.useCallback(l=>{T.current=l,typeof k=="function"?k(l):k&&(k.current=l)},[k]);function w(l){const s=[`'wght' ${l.toFixed(0)}`];for(const[p,r]of Object.entries(S))s.push(`'${p}' ${r}`);return s.join(", ")}function P(){const l=T.current;if(!l)return;const s=window.scrollX,p=window.scrollY,r=l.getBoundingClientRect();_.current={top:r.top+p,left:r.left+s,right:r.right+s,bottom:r.bottom+p},H.current=A.current.map(a=>{if(!a)return{cx:0,cy:0};const C=a.getBoundingClientRect();return{cx:(C.left+C.right)/2+s,cy:(C.top+C.bottom)/2+p}}),R.current=!0}function b(l,s){const p=T.current;if(!p)return;V&&!R.current&&P();let r,a,C,c,e,v;if(V&&_.current)e=l+window.scrollX,v=s+window.scrollY,{top:r,left:a,right:C,bottom:c}=_.current;else{const M=p.getBoundingClientRect();e=l,v=s,r=M.top,a=M.left,C=M.right,c=M.bottom}const i=Math.max(a-e,0,e-C),u=Math.max(r-v,0,v-c),O=Math.sqrt(i*i+u*u);if(F!==void 0&&!m){const f=1-(1-Math.max(0,1-O/F))**2;p.style.fontVariationSettings=w(d+(L-d)*f);return}if(m){if(F!==void 0&&O>F){p.style.fontVariationSettings=w(d);for(const f of A.current)f&&(f.style.fontVariationSettings=w(d),N&&(f.style.letterSpacing=""));return}if(O>m){for(const f of A.current)f&&(f.style.fontVariationSettings=w(d),N&&(f.style.letterSpacing=""));return}const M=A.current;if(V&&H.current.length===M.length)for(let f=0;f<M.length;f++){const x=M[f];if(!x)continue;const{cx:Y,cy:I}=H.current[f],Z=Math.sqrt((e-Y)**2+(v-I)**2),U=1-(1-Math.max(0,1-Z/m))**2;x.style.fontVariationSettings=w(d+(L-d)*U),N&&B.current!==0&&(x.style.letterSpacing=`${(-B.current*U).toFixed(3)}px`)}else for(const f of M){if(!f)continue;const x=f.getBoundingClientRect(),Y=(x.left+x.right)/2,I=(x.top+x.bottom)/2,Z=Math.sqrt((l-Y)**2+(s-I)**2),U=1-(1-Math.max(0,1-Z/m))**2;f.style.fontVariationSettings=w(d+(L-d)*U),N&&B.current!==0&&(f.style.letterSpacing=`${(-B.current*U).toFixed(3)}px`)}}}const D=h.useCallback(l=>{g.current={x:l.clientX,y:l.clientY},j?q.current===null&&(q.current=requestAnimationFrame(()=>{q.current=null,g.current&&b(g.current.x,g.current.y)})):b(l.clientX,l.clientY)},[d,L,F,m,V,j,N,JSON.stringify(S)]),X=h.useCallback(()=>{g.current&&b(g.current.x,g.current.y)},[d,L,F,m,V,N,JSON.stringify(S)]),J=h.useCallback(()=>{g.current=null,q.current!==null&&(cancelAnimationFrame(q.current),q.current=null);const l=T.current;l&&(l.style.fontVariationSettings=w(d));for(const s of A.current)s&&(s.style.fontVariationSettings=w(d),N&&(s.style.letterSpacing=""))},[d,N,JSON.stringify(S)]);h.useEffect(()=>(window.addEventListener("mousemove",D,{passive:!0}),window.addEventListener("scroll",X,{passive:!0,capture:!0}),document.documentElement.addEventListener("mouseleave",J),()=>{window.removeEventListener("mousemove",D),window.removeEventListener("scroll",X,{capture:!0}),document.documentElement.removeEventListener("mouseleave",J),q.current!==null&&(cancelAnimationFrame(q.current),q.current=null)}),[D,X,J]),h.useEffect(()=>{var p,r;if(!V||!m)return;R.current=!1;const l=T.current;if(!l)return;const s=new ResizeObserver(()=>{R.current=!1});return s.observe(l),(r=(p=document.fonts)==null?void 0:p.ready)==null||r.then(()=>{R.current=!1}),()=>s.disconnect()},[V,m]),h.useEffect(()=>{R.current=!1},[n,m]),h.useEffect(()=>{var s,p;if(!N||!m){B.current=0;return}function l(){const r=T.current;if(!r)return;const a=r.textContent??"",C=a.replace(/\s/g,"").length;if(C===0)return;const c=getComputedStyle(r),e=document.createElement("span");e.style.cssText="position:fixed;top:-9999px;left:-9999px;visibility:hidden;white-space:nowrap;pointer-events:none;",e.style.fontFamily=c.fontFamily,e.style.fontSize=c.fontSize,e.style.fontWeight=c.fontWeight,e.style.lineHeight=c.lineHeight,e.style.letterSpacing=c.letterSpacing,e.textContent=a,document.body.appendChild(e);const v=O=>{const M=[`'wght' ${O.toFixed(0)}`];for(const[f,x]of Object.entries(S))M.push(`'${f}' ${x}`);return M.join(", ")};e.style.fontVariationSettings=v(L);const i=e.scrollWidth;e.style.fontVariationSettings=v(d);const u=e.scrollWidth;document.body.removeChild(e),B.current=i>u?(i-u)/C:0}l(),(p=(s=document.fonts)==null?void 0:s.ready)==null||p.then(l)},[N,m,d,L,n,JSON.stringify(S)]);const Q=h.useMemo(()=>{if(!m)return n;A.current=[];let l=0;function s(p){if(typeof p=="string")return[...p].map(r=>{if(/\s/.test(r))return r;const a=l++;return W.jsx("span",{ref:C=>{A.current[a]=C},style:{fontVariationSettings:w(d)},children:r},a)});if(Array.isArray(p))return p.map((r,a)=>W.jsx(h.Fragment,{children:s(r)},a));if(h.isValidElement(p)){const r=p;if(r.props.children!==void 0)return h.cloneElement(r,{},s(r.props.children))}return p}return s(n)},[n,m,d,JSON.stringify(S)]);return W.jsx(o,{ref:$,className:E,style:{fontVariationSettings:w(d),...y},children:Q})});ft.displayName="MagnetBlock";exports.MAGNET_TYPE_CLASSES=z;exports.MagnetBlock=ft;exports.MagnetTypeText=ut;exports.applyMagnetType=it;exports.getCleanHTML=ct;exports.removeMagnetType=mt;exports.startMagnetType=lt;exports.useMagnetType=at;
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("react"),tt=require("react/jsx-runtime"),it={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},W={word:"mt-word",char:"mt-char",probe:"mt-probe"},U={axes:{wght:[300,500]},radius:120,falloff:"quadratic",magnetMode:"attract",wdthBoost:6,scope:"document"};function rt(t,e=[]){return t.nodeType===Node.TEXT_NODE?e.push(t):t.childNodes.forEach(n=>rt(n,e)),e}function et(t,e,n){if(!t||t==="normal")return`"${e}" ${n}`;const E=new RegExp(`(["'])${e}\\1\\s+[\\d.eE+-]+`),y=`"${e}" ${n}`;return E.test(t)?t.replace(E,y):`${t}, ${y}`}function ot(t,e){let n=t;for(const[E,y]of Object.entries(e))n=et(n,E,y);return n}function lt(t,e,n){if(e.opacity!==void 0){const[E,y]=e.opacity;t.style.opacity=String(E+(y-E)*n)}e.italic===!0&&(t.style.fontStyle=n>.5?"italic":"")}function nt(t,e){e.opacity!==void 0&&(t.style.opacity=String(e.opacity[0])),e.italic===!0&&(t.style.fontStyle="")}function at(t){const e=t.cloneNode(!0),n=e.querySelectorAll(`.${W.word}, .${W.char}`);return Array.from(n).reverse().forEach(y=>{const f=y.parentNode;if(f){for(;y.firstChild;)f.insertBefore(y.firstChild,y);f.removeChild(y)}}),e.innerHTML}function ht(t,e){t.innerHTML=e}function ut(t,e,n={}){var m,r,L,N;if(typeof window>"u")return()=>{};if((r=(m=window.matchMedia)==null?void 0:m.call(window,"(prefers-reduced-motion: reduce)"))!=null&&r.matches)return t.innerHTML=e,()=>{};const E=n.wdthBoost??U.wdthBoost,y=n.radius??U.radius,f=n.falloff??U.falloff,b=n.scope??U.scope,F=n.props,d=n.transitionMs??0,M=n.cachePositions??!0,V=window.scrollY;t.innerHTML=e;const k=getComputedStyle(t).fontVariationSettings,A=k.match(/"wdth"\s+([\d.eE+-]+)/),H=A?parseFloat(A[1]):100,C=rt(t),g=[];for(const v of C){const p=v.textContent??"";if(!p||!p.split("").some(S=>S in it))continue;const s=document.createDocumentFragment();for(const S of p){const l=it[S];if(l===void 0){const o=s.lastChild;o&&o.nodeType===Node.TEXT_NODE?o.textContent+=S:s.appendChild(document.createTextNode(S))}else{const o=document.createElement("span");o.className=W.char,o.style.fontVariationSettings=et(k,"wdth",H),o.textContent=S,s.appendChild(o),g.push({span:o,riskLevel:l})}}v.parentNode.replaceChild(s,v)}if(requestAnimationFrame(()=>{typeof window<"u"&&Math.abs(window.scrollY-V)>2&&window.scrollTo({top:V,behavior:"instant"})}),g.length===0)return()=>{};F&&g.forEach(({span:v})=>nt(v,F));let O=[],D=!1;function G(){const v=window.scrollX,p=window.scrollY;O=g.map(({span:i})=>{const s=i.getBoundingClientRect();return{cx:(s.left+s.right)/2+v,cy:(s.top+s.bottom)/2+p}}),D=!0}let R=null;M&&(G(),R=new ResizeObserver(()=>{D=!1}),R.observe(t),(N=(L=document.fonts)==null?void 0:L.ready)==null||N.then(()=>{D=!1}));let q=-9999,$=-9999,j=!1,w=0,J=!0,T=null;function I(){if(!J)return;if(!j){g.forEach(({span:s})=>{d>0&&(s.style.transition=`font-variation-settings ${d}ms ease`),s.style.fontVariationSettings=et(k,"wdth",H),F&&nt(s,F)}),d>0&&(T!==null&&clearTimeout(T),T=setTimeout(()=>{g.forEach(({span:s})=>{s.style.transition=""}),T=null},d)),w=0;return}M&&!D&&G();const v=M?q+window.scrollX:q,p=M?$+window.scrollY:$,i=M?null:g.map(({span:s})=>s.getBoundingClientRect());g.forEach(({span:s,riskLevel:S},l)=>{s.style.transition="";let o,u;if(M)({cx:o,cy:u}=O[l]);else{const K=i[l];o=K.left+K.width/2,u=K.top+K.height/2}const x=Math.sqrt((v-o)**2+(p-u)**2),X=Math.max(0,1-x/y),B=f==="quadratic"?X*X:X,Y=E*(S/3)*B;s.style.fontVariationSettings=et(k,"wdth",H+Y),F&<(s,F,B)}),w=requestAnimationFrame(I)}function P(v){q=v.clientX,$=v.clientY,j||(j=!0),w===0&&(w=requestAnimationFrame(I))}function _(){j=!1,w===0&&(w=requestAnimationFrame(I))}function Z(v){v.touches.length!==0&&(q=v.touches[0].clientX,$=v.touches[0].clientY,j||(j=!0),w===0&&(w=requestAnimationFrame(I)))}function a(){j=!1,w===0&&(w=requestAnimationFrame(I))}const c=b==="document"?document:t;return c.addEventListener("mousemove",P),c.addEventListener("mouseleave",_),c.addEventListener("touchmove",Z,{passive:!0}),c.addEventListener("touchend",a),()=>{J=!1,cancelAnimationFrame(w),T!==null&&clearTimeout(T),R&&R.disconnect(),c.removeEventListener("mousemove",P),c.removeEventListener("mouseleave",_),c.removeEventListener("touchmove",Z),c.removeEventListener("touchend",a),t.innerHTML=e}}function ft(t,e,n={}){var L,N,v,p;if(typeof window>"u")return()=>{};if((N=(L=window.matchMedia)==null?void 0:L.call(window,"(prefers-reduced-motion: reduce)"))!=null&&N.matches)return t.innerHTML=e,()=>{};const E=n.axes??U.axes,y=n.radius??U.radius,f=n.falloff??U.falloff,b=n.magnetMode??U.magnetMode,F=n.scope??U.scope,d=n.props,M=n.transitionMs??0,V=n.cachePositions??!0,k=n.stabilizeLayout??!0,A=window.scrollY;t.innerHTML=e;const H=rt(t),C=[];for(const i of H){const s=i.textContent??"";if(!s.trim())continue;const S=s.split(/(\S+)/),l=document.createDocumentFragment();for(let o=0;o<S.length;o+=2){const u=S[o],x=S[o+1];if(!x)continue;const B=S[o+3]===void 0?S[o+2]??"":"",Y=document.createElement("span");Y.className=W.word,Y.textContent=u+x+B,l.appendChild(Y),C.push(Y)}i.parentNode.replaceChild(l,i)}if(requestAnimationFrame(()=>{typeof window<"u"&&Math.abs(window.scrollY-A)>2&&window.scrollTo({top:A,behavior:"instant"})}),C.length===0)return()=>{};const g=getComputedStyle(t).fontVariationSettings,O=ot(g,Object.fromEntries(Object.entries(E).map(([i,[s]])=>[i,s])));let D=0;if(k){const i=ot(g,Object.fromEntries(Object.entries(E).map(([X,[,B]])=>[X,B]))),s=t.style.fontVariationSettings,S=t.style.whiteSpace,l=t.style.overflow;t.style.whiteSpace="nowrap",t.style.overflow="visible",t.style.fontVariationSettings=i;const o=t.scrollWidth;t.style.fontVariationSettings=O;const u=t.scrollWidth;t.style.fontVariationSettings=s,t.style.whiteSpace=S,t.style.overflow=l;const x=C.reduce((X,B)=>{var Y;return X+(((Y=B.textContent)==null?void 0:Y.replace(/\s+/g,"").length)??0)},0);x>0&&o>u&&(D=(o-u)/x)}C.forEach(i=>{i.style.fontVariationSettings=O,d&&nt(i,d)});let G=[],R=!1;function q(){const i=window.scrollX,s=window.scrollY;G=C.map(S=>{const l=S.getBoundingClientRect();return{cx:(l.left+l.right)/2+i,cy:(l.top+l.bottom)/2+s}}),R=!0}let $=null;V&&(q(),$=new ResizeObserver(()=>{R=!1}),$.observe(t),(p=(v=document.fonts)==null?void 0:v.ready)==null||p.then(()=>{R=!1}));let j=-9999,w=-9999,J=!1,T=0,I=!0,P=null;function _(){if(!I)return;if(!J){C.forEach(l=>{M>0&&(l.style.transition=`font-variation-settings ${M}ms ease`),l.style.fontVariationSettings=O,k&&(l.style.letterSpacing=""),d&&nt(l,d)}),M>0&&(P!==null&&clearTimeout(P),P=setTimeout(()=>{C.forEach(l=>{l.style.transition=""}),P=null},M)),T=0;return}V&&!R&&q();const i=V?j+window.scrollX:j,s=V?w+window.scrollY:w,S=V?null:C.map(l=>l.getBoundingClientRect());C.forEach((l,o)=>{l.style.transition="";let u,x;if(V)({cx:u,cy:x}=G[o]);else{const z=S[o];u=z.left+z.width/2,x=z.top+z.height/2}const X=Math.sqrt((i-u)**2+(s-x)**2),B=Math.max(0,1-X/y),Y=f==="quadratic"?B*B:B,K=b==="repel"?1-Y:Y,Q={};for(const z of Object.keys(E)){const[ct,pt]=E[z]??[300,500];Q[z]=ct+(pt-ct)*K}l.style.fontVariationSettings=ot(g,Q),k&&D!==0&&(l.style.letterSpacing=`${(-D*K).toFixed(3)}px`),d&<(l,d,Y)}),T=requestAnimationFrame(_)}function Z(i){j=i.clientX,w=i.clientY,J||(J=!0),T===0&&(T=requestAnimationFrame(_))}function a(){J=!1,T===0&&(T=requestAnimationFrame(_))}function c(i){i.touches.length!==0&&(j=i.touches[0].clientX,w=i.touches[0].clientY,J||(J=!0),T===0&&(T=requestAnimationFrame(_)))}function m(){J=!1,T===0&&(T=requestAnimationFrame(_))}const r=F==="document"?document:t;return r.addEventListener("mousemove",Z),r.addEventListener("mouseleave",a),r.addEventListener("touchmove",c,{passive:!0}),r.addEventListener("touchend",m),()=>{I=!1,cancelAnimationFrame(T),P!==null&&clearTimeout(P),$&&$.disconnect(),r.removeEventListener("mousemove",Z),r.removeEventListener("mouseleave",a),r.removeEventListener("touchmove",c),r.removeEventListener("touchend",m),t.innerHTML=e}}function dt(t){const e=h.useRef(null),n=h.useRef(null),E=h.useRef(t);E.current=t;const y=h.useRef(null),f=t.mode??"word",{axes:b,radius:F,falloff:d,magnetMode:M,wdthBoost:V,scope:k}=t,A=b?JSON.stringify(b):void 0,H=t.props?JSON.stringify(t.props):void 0,C=h.useCallback(()=>{const g=e.current;if(!g)return;n.current===null&&(n.current=at(g)),y.current&&(y.current(),y.current=null),(E.current.mode??"word")==="word"?y.current=ft(g,n.current,E.current):y.current=ut(g,n.current,E.current)},[f,A,F,d,M,V,k,H]);return h.useLayoutEffect(()=>(C(),()=>{y.current&&(y.current(),y.current=null)}),[C]),h.useEffect(()=>{var g,O;(O=(g=document.fonts)==null?void 0:g.ready)==null||O.then(C)},[C]),e}const mt=h.forwardRef(function({children:e,as:n="p",className:E,style:y,...f},b){const F=dt(f),d=h.useCallback(M=>{F.current=M,typeof b=="function"?b(M):b&&(b.current=M)},[b]);return tt.jsx(n,{ref:d,className:E,style:y,children:e})});mt.displayName="MagnetTypeText";const st=h.forwardRef(function({children:e,as:n="p",className:E,style:y,minWeight:f=300,maxWeight:b=600,proximityRadius:F,spreadRadius:d,fixedAxes:M={},cachePositions:V=!0,rafThrottle:k=!0,stabilizeLayout:A=!0},H){const C=h.useRef(null),g=h.useRef(null),O=h.useRef([]),D=h.useRef([]),G=h.useRef(null),R=h.useRef(!1),q=h.useRef(null),$=h.useRef(0),j=h.useCallback(a=>{C.current=a,typeof H=="function"?H(a):H&&(H.current=a)},[H]);function w(a){const c=[`'wght' ${a.toFixed(0)}`];for(const[m,r]of Object.entries(M))c.push(`'${m}' ${r}`);return c.join(", ")}function J(){const a=C.current;if(!a)return;const c=window.scrollX,m=window.scrollY,r=a.getBoundingClientRect();G.current={top:r.top+m,left:r.left+c,right:r.right+c,bottom:r.bottom+m},D.current=O.current.map(L=>{if(!L)return{cx:0,cy:0};const N=L.getBoundingClientRect();return{cx:(N.left+N.right)/2+c,cy:(N.top+N.bottom)/2+m}}),R.current=!0}function T(a,c){const m=C.current;if(!m)return;V&&!R.current&&J();let r,L,N,v,p,i;if(V&&G.current)p=a+window.scrollX,i=c+window.scrollY,{top:r,left:L,right:N,bottom:v}=G.current;else{const o=m.getBoundingClientRect();p=a,i=c,r=o.top,L=o.left,N=o.right,v=o.bottom}const s=Math.max(L-p,0,p-N),S=Math.max(r-i,0,i-v),l=Math.sqrt(s*s+S*S);if(F!==void 0&&!d){const u=1-(1-Math.max(0,1-l/F))**2;m.style.fontVariationSettings=w(f+(b-f)*u);return}if(d){if(F!==void 0&&l>F){m.style.fontVariationSettings=w(f);for(const u of O.current)u&&(u.style.fontVariationSettings=w(f),A&&(u.style.letterSpacing=""));return}if(l>d){for(const u of O.current)u&&(u.style.fontVariationSettings=w(f),A&&(u.style.letterSpacing=""));return}const o=O.current;if(V&&D.current.length===o.length)for(let u=0;u<o.length;u++){const x=o[u];if(!x)continue;const{cx:X,cy:B}=D.current[u],Y=Math.sqrt((p-X)**2+(i-B)**2),Q=1-(1-Math.max(0,1-Y/d))**2;x.style.fontVariationSettings=w(f+(b-f)*Q),A&&$.current!==0&&(x.style.letterSpacing=`${(-$.current*Q).toFixed(3)}px`)}else for(const u of o){if(!u)continue;const x=u.getBoundingClientRect(),X=(x.left+x.right)/2,B=(x.top+x.bottom)/2,Y=Math.sqrt((a-X)**2+(c-B)**2),Q=1-(1-Math.max(0,1-Y/d))**2;u.style.fontVariationSettings=w(f+(b-f)*Q),A&&$.current!==0&&(u.style.letterSpacing=`${(-$.current*Q).toFixed(3)}px`)}}}const I=h.useCallback(a=>{g.current={x:a.clientX,y:a.clientY},k?q.current===null&&(q.current=requestAnimationFrame(()=>{q.current=null,g.current&&T(g.current.x,g.current.y)})):T(a.clientX,a.clientY)},[f,b,F,d,V,k,A,JSON.stringify(M)]),P=h.useCallback(()=>{g.current&&T(g.current.x,g.current.y)},[f,b,F,d,V,A,JSON.stringify(M)]),_=h.useCallback(()=>{g.current=null,q.current!==null&&(cancelAnimationFrame(q.current),q.current=null);const a=C.current;a&&(a.style.fontVariationSettings=w(f));for(const c of O.current)c&&(c.style.fontVariationSettings=w(f),A&&(c.style.letterSpacing=""))},[f,A,JSON.stringify(M)]);h.useEffect(()=>(window.addEventListener("mousemove",I,{passive:!0}),window.addEventListener("scroll",P,{passive:!0,capture:!0}),document.documentElement.addEventListener("mouseleave",_),()=>{window.removeEventListener("mousemove",I),window.removeEventListener("scroll",P,{capture:!0}),document.documentElement.removeEventListener("mouseleave",_),q.current!==null&&(cancelAnimationFrame(q.current),q.current=null)}),[I,P,_]),h.useEffect(()=>{var m,r;if(!V||!d)return;R.current=!1;const a=C.current;if(!a)return;const c=new ResizeObserver(()=>{R.current=!1});return c.observe(a),(r=(m=document.fonts)==null?void 0:m.ready)==null||r.then(()=>{R.current=!1}),()=>c.disconnect()},[V,d]),h.useEffect(()=>{R.current=!1},[e,d]),h.useEffect(()=>{var c,m;if(!A||!d){$.current=0;return}function a(){const r=C.current;if(!r)return;const L=r.textContent??"",N=L.replace(/\s/g,"").length;if(N===0)return;const v=getComputedStyle(r),p=document.createElement("span");p.style.cssText="position:fixed;top:-9999px;left:-9999px;visibility:hidden;white-space:nowrap;pointer-events:none;",p.style.fontFamily=v.fontFamily,p.style.fontSize=v.fontSize,p.style.fontWeight=v.fontWeight,p.style.lineHeight=v.lineHeight,p.style.letterSpacing=v.letterSpacing,p.textContent=L,document.body.appendChild(p);const i=l=>{const o=[`'wght' ${l.toFixed(0)}`];for(const[u,x]of Object.entries(M))o.push(`'${u}' ${x}`);return o.join(", ")};p.style.fontVariationSettings=i(b);const s=p.scrollWidth;p.style.fontVariationSettings=i(f);const S=p.scrollWidth;document.body.removeChild(p),$.current=s>S?(s-S)/N:0}a(),(m=(c=document.fonts)==null?void 0:c.ready)==null||m.then(a)},[A,d,f,b,e,JSON.stringify(M)]);const Z=h.useMemo(()=>{if(!d)return e;O.current=[];let a=0;function c(m){if(typeof m=="string")return[...m].map(r=>{if(/\s/.test(r))return r;const L=a++;return tt.jsx("span",{ref:N=>{O.current[L]=N},style:{fontVariationSettings:w(f)},children:r},L)});if(Array.isArray(m))return m.map((r,L)=>tt.jsx(h.Fragment,{children:c(r)},L));if(h.isValidElement(m)){const r=m;if(r.props.children!==void 0)return h.cloneElement(r,{},c(r.props.children))}return m}return c(e)},[e,d,f,JSON.stringify(M)]);return tt.jsx(n,{ref:j,className:E,style:{fontVariationSettings:w(f),...y},children:Z})});st.displayName="MagnetChar";const yt=st;exports.MAGNET_TYPE_CLASSES=W;exports.MagnetBlock=yt;exports.MagnetChar=st;exports.MagnetTypeText=mt;exports.applyMagnetType=ut;exports.getCleanHTML=at;exports.removeMagnetType=ht;exports.startMagnetType=ft;exports.useMagnetType=dt;
|
package/dist/index.d.ts
CHANGED
|
@@ -38,9 +38,15 @@ export declare const MAGNET_TYPE_CLASSES: {
|
|
|
38
38
|
readonly probe: "mt-probe";
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
/** @deprecated Use MagnetChar instead */
|
|
42
|
+
export declare const MagnetBlock: default_2.ForwardRefExoticComponent<MagnetCharProps & default_2.RefAttributes<HTMLElement>>;
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
/** @deprecated Use MagnetCharProps instead */
|
|
45
|
+
export declare type MagnetBlockProps = MagnetCharProps;
|
|
46
|
+
|
|
47
|
+
export declare const MagnetChar: default_2.ForwardRefExoticComponent<MagnetCharProps & default_2.RefAttributes<HTMLElement>>;
|
|
48
|
+
|
|
49
|
+
export declare interface MagnetCharProps {
|
|
44
50
|
children: default_2.ReactNode;
|
|
45
51
|
/** HTML element to render. Default: 'p' */
|
|
46
52
|
as?: default_2.ElementType;
|
|
@@ -87,7 +93,7 @@ export declare interface MagnetBlockProps {
|
|
|
87
93
|
export declare type MagnetModeType = 'attract' | 'repel';
|
|
88
94
|
|
|
89
95
|
/** Which mode magnetType operates in */
|
|
90
|
-
export declare type MagnetTypeModeType = '
|
|
96
|
+
export declare type MagnetTypeModeType = 'word' | 'legibility';
|
|
91
97
|
|
|
92
98
|
/**
|
|
93
99
|
* Options for the magnetType effect.
|
|
@@ -98,9 +104,9 @@ export declare type MagnetTypeModeType = 'field' | 'legibility';
|
|
|
98
104
|
*/
|
|
99
105
|
export declare interface MagnetTypeOptions {
|
|
100
106
|
/**
|
|
101
|
-
* Operating mode. Default: '
|
|
107
|
+
* Operating mode. Default: 'word'
|
|
102
108
|
*
|
|
103
|
-
* - **'
|
|
109
|
+
* - **'word'** — cursor proximity drives per-word font-variation-settings.
|
|
104
110
|
* - **'legibility'** — cursor-driven wdth boost for confusable characters; both return a stop function.
|
|
105
111
|
*/
|
|
106
112
|
mode?: MagnetTypeModeType;
|
|
@@ -249,13 +255,13 @@ export declare function startMagnetType(element: HTMLElement, originalHTML: stri
|
|
|
249
255
|
/**
|
|
250
256
|
* React hook that applies the magnetType effect to a ref'd element.
|
|
251
257
|
*
|
|
252
|
-
* For mode: '
|
|
258
|
+
* For mode: 'word' — starts the cursor proximity rAF loop via startMagnetType.
|
|
253
259
|
* For mode: 'legibility' — starts the cursor-driven wdth boost via applyMagnetType.
|
|
254
260
|
*
|
|
255
261
|
* Both modes return a stop function on mount and restart when options change.
|
|
256
262
|
* No ResizeObserver needed — the rAF loop reads live getBoundingClientRect each frame.
|
|
257
263
|
*
|
|
258
|
-
* Defaults to '
|
|
264
|
+
* Defaults to 'word' mode if mode is undefined.
|
|
259
265
|
*/
|
|
260
266
|
export declare function useMagnetType(options: MagnetTypeOptions): RefObject<HTMLElement | null>;
|
|
261
267
|
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import
|
|
3
|
-
import { jsx as
|
|
4
|
-
const
|
|
2
|
+
import st, { useRef as _, useCallback as W, useLayoutEffect as pt, useEffect as tt, forwardRef as ut, useMemo as ht } from "react";
|
|
3
|
+
import { jsx as et } from "react/jsx-runtime";
|
|
4
|
+
const at = {
|
|
5
5
|
i: 3,
|
|
6
6
|
l: 3,
|
|
7
7
|
1: 3,
|
|
@@ -23,14 +23,14 @@ const it = {
|
|
|
23
23
|
c: 1,
|
|
24
24
|
e: 1
|
|
25
25
|
// similar bowls
|
|
26
|
-
},
|
|
26
|
+
}, ot = {
|
|
27
27
|
/** Applied to each word span in field mode */
|
|
28
28
|
word: "mt-word",
|
|
29
29
|
/** Applied to each character span in legibility mode */
|
|
30
30
|
char: "mt-char",
|
|
31
31
|
/** Applied to measurement probe spans (never in final output) */
|
|
32
32
|
probe: "mt-probe"
|
|
33
|
-
},
|
|
33
|
+
}, G = {
|
|
34
34
|
axes: { wght: [300, 500] },
|
|
35
35
|
radius: 120,
|
|
36
36
|
falloff: "quadratic",
|
|
@@ -38,486 +38,488 @@ const it = {
|
|
|
38
38
|
wdthBoost: 6,
|
|
39
39
|
scope: "document"
|
|
40
40
|
};
|
|
41
|
-
function
|
|
42
|
-
return t.nodeType === Node.TEXT_NODE ?
|
|
41
|
+
function it(t, e = []) {
|
|
42
|
+
return t.nodeType === Node.TEXT_NODE ? e.push(t) : t.childNodes.forEach((n) => it(n, e)), e;
|
|
43
43
|
}
|
|
44
|
-
function
|
|
45
|
-
if (!t || t === "normal") return `"${
|
|
46
|
-
const M = new RegExp(`(["'])${
|
|
44
|
+
function nt(t, e, n) {
|
|
45
|
+
if (!t || t === "normal") return `"${e}" ${n}`;
|
|
46
|
+
const M = new RegExp(`(["'])${e}\\1\\s+[\\d.eE+-]+`), h = `"${e}" ${n}`;
|
|
47
47
|
return M.test(t) ? t.replace(M, h) : `${t}, ${h}`;
|
|
48
48
|
}
|
|
49
|
-
function
|
|
50
|
-
let
|
|
51
|
-
for (const [M, h] of Object.entries(
|
|
52
|
-
|
|
53
|
-
return
|
|
49
|
+
function ct(t, e) {
|
|
50
|
+
let n = t;
|
|
51
|
+
for (const [M, h] of Object.entries(e))
|
|
52
|
+
n = nt(n, M, h);
|
|
53
|
+
return n;
|
|
54
54
|
}
|
|
55
|
-
function
|
|
56
|
-
if (
|
|
57
|
-
const [M, h] =
|
|
58
|
-
t.style.opacity = String(M + (h - M) *
|
|
55
|
+
function ft(t, e, n) {
|
|
56
|
+
if (e.opacity !== void 0) {
|
|
57
|
+
const [M, h] = e.opacity;
|
|
58
|
+
t.style.opacity = String(M + (h - M) * n);
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
e.italic === !0 && (t.style.fontStyle = n > 0.5 ? "italic" : "");
|
|
61
61
|
}
|
|
62
|
-
function
|
|
63
|
-
|
|
62
|
+
function rt(t, e) {
|
|
63
|
+
e.opacity !== void 0 && (t.style.opacity = String(e.opacity[0])), e.italic === !0 && (t.style.fontStyle = "");
|
|
64
64
|
}
|
|
65
|
-
function
|
|
66
|
-
const
|
|
67
|
-
`.${
|
|
65
|
+
function yt(t) {
|
|
66
|
+
const e = t.cloneNode(!0), n = e.querySelectorAll(
|
|
67
|
+
`.${ot.word}, .${ot.char}`
|
|
68
68
|
);
|
|
69
|
-
return Array.from(
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
72
|
-
for (; h.firstChild; )
|
|
73
|
-
|
|
69
|
+
return Array.from(n).reverse().forEach((h) => {
|
|
70
|
+
const f = h.parentNode;
|
|
71
|
+
if (f) {
|
|
72
|
+
for (; h.firstChild; ) f.insertBefore(h.firstChild, h);
|
|
73
|
+
f.removeChild(h);
|
|
74
74
|
}
|
|
75
|
-
}),
|
|
75
|
+
}), e.innerHTML;
|
|
76
76
|
}
|
|
77
|
-
function
|
|
78
|
-
t.innerHTML =
|
|
77
|
+
function Ct(t, e) {
|
|
78
|
+
t.innerHTML = e;
|
|
79
79
|
}
|
|
80
|
-
function
|
|
81
|
-
var
|
|
80
|
+
function gt(t, e, n = {}) {
|
|
81
|
+
var m, r, b, V;
|
|
82
82
|
if (typeof window > "u") return () => {
|
|
83
83
|
};
|
|
84
|
-
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches)
|
|
85
|
-
return t.innerHTML =
|
|
84
|
+
if ((r = (m = window.matchMedia) == null ? void 0 : m.call(window, "(prefers-reduced-motion: reduce)")) != null && r.matches)
|
|
85
|
+
return t.innerHTML = e, () => {
|
|
86
86
|
};
|
|
87
|
-
const M =
|
|
88
|
-
t.innerHTML =
|
|
89
|
-
const
|
|
90
|
-
for (const
|
|
91
|
-
const
|
|
92
|
-
if (!
|
|
93
|
-
const
|
|
94
|
-
for (const
|
|
95
|
-
const
|
|
96
|
-
if (
|
|
97
|
-
const
|
|
98
|
-
|
|
87
|
+
const M = n.wdthBoost ?? G.wdthBoost, h = n.radius ?? G.radius, f = n.falloff ?? G.falloff, T = n.scope ?? G.scope, F = n.props, d = n.transitionMs ?? 0, S = n.cachePositions ?? !0, L = window.scrollY;
|
|
88
|
+
t.innerHTML = e;
|
|
89
|
+
const k = getComputedStyle(t).fontVariationSettings, N = k.match(/"wdth"\s+([\d.eE+-]+)/), H = N ? parseFloat(N[1]) : 100, E = it(t), y = [];
|
|
90
|
+
for (const g of E) {
|
|
91
|
+
const p = g.textContent ?? "";
|
|
92
|
+
if (!p || !p.split("").some((w) => w in at)) continue;
|
|
93
|
+
const s = document.createDocumentFragment();
|
|
94
|
+
for (const w of p) {
|
|
95
|
+
const l = at[w];
|
|
96
|
+
if (l === void 0) {
|
|
97
|
+
const o = s.lastChild;
|
|
98
|
+
o && o.nodeType === Node.TEXT_NODE ? o.textContent += w : s.appendChild(document.createTextNode(w));
|
|
99
99
|
} else {
|
|
100
|
-
const
|
|
101
|
-
|
|
100
|
+
const o = document.createElement("span");
|
|
101
|
+
o.className = ot.char, o.style.fontVariationSettings = nt(k, "wdth", H), o.textContent = w, s.appendChild(o), y.push({ span: o, riskLevel: l });
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
g.parentNode.replaceChild(s, g);
|
|
105
105
|
}
|
|
106
106
|
if (requestAnimationFrame(() => {
|
|
107
107
|
typeof window < "u" && Math.abs(window.scrollY - L) > 2 && window.scrollTo({ top: L, behavior: "instant" });
|
|
108
108
|
}), y.length === 0) return () => {
|
|
109
109
|
};
|
|
110
|
-
F && y.forEach(({ span:
|
|
111
|
-
let
|
|
112
|
-
function
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
return { cx: (
|
|
117
|
-
}),
|
|
110
|
+
F && y.forEach(({ span: g }) => rt(g, F));
|
|
111
|
+
let O = [], D = !1;
|
|
112
|
+
function K() {
|
|
113
|
+
const g = window.scrollX, p = window.scrollY;
|
|
114
|
+
O = y.map(({ span: i }) => {
|
|
115
|
+
const s = i.getBoundingClientRect();
|
|
116
|
+
return { cx: (s.left + s.right) / 2 + g, cy: (s.top + s.bottom) / 2 + p };
|
|
117
|
+
}), D = !0;
|
|
118
118
|
}
|
|
119
119
|
let Y = null;
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}), Y.observe(t), (
|
|
123
|
-
|
|
120
|
+
S && (K(), Y = new ResizeObserver(() => {
|
|
121
|
+
D = !1;
|
|
122
|
+
}), Y.observe(t), (V = (b = document.fonts) == null ? void 0 : b.ready) == null || V.then(() => {
|
|
123
|
+
D = !1;
|
|
124
124
|
}));
|
|
125
|
-
let A = -9999, $ = -9999,
|
|
126
|
-
function
|
|
127
|
-
if (!
|
|
128
|
-
if (!
|
|
129
|
-
y.forEach(({ span:
|
|
130
|
-
|
|
131
|
-
}),
|
|
132
|
-
y.forEach(({ span:
|
|
133
|
-
|
|
134
|
-
}),
|
|
135
|
-
},
|
|
125
|
+
let A = -9999, $ = -9999, X = !1, v = 0, J = !0, C = null;
|
|
126
|
+
function I() {
|
|
127
|
+
if (!J) return;
|
|
128
|
+
if (!X) {
|
|
129
|
+
y.forEach(({ span: s }) => {
|
|
130
|
+
d > 0 && (s.style.transition = `font-variation-settings ${d}ms ease`), s.style.fontVariationSettings = nt(k, "wdth", H), F && rt(s, F);
|
|
131
|
+
}), d > 0 && (C !== null && clearTimeout(C), C = setTimeout(() => {
|
|
132
|
+
y.forEach(({ span: s }) => {
|
|
133
|
+
s.style.transition = "";
|
|
134
|
+
}), C = null;
|
|
135
|
+
}, d)), v = 0;
|
|
136
136
|
return;
|
|
137
137
|
}
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
y.forEach(({ span:
|
|
141
|
-
|
|
142
|
-
let
|
|
143
|
-
if (
|
|
144
|
-
({ cx:
|
|
138
|
+
S && !D && K();
|
|
139
|
+
const g = S ? A + window.scrollX : A, p = S ? $ + window.scrollY : $, i = S ? null : y.map(({ span: s }) => s.getBoundingClientRect());
|
|
140
|
+
y.forEach(({ span: s, riskLevel: w }, l) => {
|
|
141
|
+
s.style.transition = "";
|
|
142
|
+
let o, u;
|
|
143
|
+
if (S)
|
|
144
|
+
({ cx: o, cy: u } = O[l]);
|
|
145
145
|
else {
|
|
146
|
-
const
|
|
147
|
-
|
|
146
|
+
const U = i[l];
|
|
147
|
+
o = U.left + U.width / 2, u = U.top + U.height / 2;
|
|
148
148
|
}
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
}), v = requestAnimationFrame(
|
|
149
|
+
const x = Math.sqrt((g - o) ** 2 + (p - u) ** 2), j = Math.max(0, 1 - x / h), B = f === "quadratic" ? j * j : j, q = M * (w / 3) * B;
|
|
150
|
+
s.style.fontVariationSettings = nt(k, "wdth", H + q), F && ft(s, F, B);
|
|
151
|
+
}), v = requestAnimationFrame(I);
|
|
152
152
|
}
|
|
153
|
-
function
|
|
154
|
-
A =
|
|
153
|
+
function R(g) {
|
|
154
|
+
A = g.clientX, $ = g.clientY, X || (X = !0), v === 0 && (v = requestAnimationFrame(I));
|
|
155
155
|
}
|
|
156
|
-
function
|
|
157
|
-
|
|
156
|
+
function P() {
|
|
157
|
+
X = !1, v === 0 && (v = requestAnimationFrame(I));
|
|
158
158
|
}
|
|
159
|
-
function
|
|
160
|
-
|
|
159
|
+
function Z(g) {
|
|
160
|
+
g.touches.length !== 0 && (A = g.touches[0].clientX, $ = g.touches[0].clientY, X || (X = !0), v === 0 && (v = requestAnimationFrame(I)));
|
|
161
161
|
}
|
|
162
|
-
function
|
|
163
|
-
|
|
162
|
+
function a() {
|
|
163
|
+
X = !1, v === 0 && (v = requestAnimationFrame(I));
|
|
164
164
|
}
|
|
165
|
-
const
|
|
166
|
-
return
|
|
167
|
-
|
|
165
|
+
const c = T === "document" ? document : t;
|
|
166
|
+
return c.addEventListener("mousemove", R), c.addEventListener("mouseleave", P), c.addEventListener("touchmove", Z, { passive: !0 }), c.addEventListener("touchend", a), () => {
|
|
167
|
+
J = !1, cancelAnimationFrame(v), C !== null && clearTimeout(C), Y && Y.disconnect(), c.removeEventListener("mousemove", R), c.removeEventListener("mouseleave", P), c.removeEventListener("touchmove", Z), c.removeEventListener("touchend", a), t.innerHTML = e;
|
|
168
168
|
};
|
|
169
169
|
}
|
|
170
|
-
function
|
|
171
|
-
var
|
|
170
|
+
function vt(t, e, n = {}) {
|
|
171
|
+
var b, V, g, p;
|
|
172
172
|
if (typeof window > "u") return () => {
|
|
173
173
|
};
|
|
174
|
-
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches)
|
|
175
|
-
return t.innerHTML =
|
|
174
|
+
if ((V = (b = window.matchMedia) == null ? void 0 : b.call(window, "(prefers-reduced-motion: reduce)")) != null && V.matches)
|
|
175
|
+
return t.innerHTML = e, () => {
|
|
176
176
|
};
|
|
177
|
-
const M =
|
|
178
|
-
t.innerHTML =
|
|
179
|
-
const
|
|
180
|
-
for (const
|
|
181
|
-
const
|
|
182
|
-
if (!
|
|
183
|
-
const
|
|
184
|
-
for (let
|
|
185
|
-
const
|
|
186
|
-
if (!
|
|
187
|
-
const
|
|
188
|
-
q.className =
|
|
177
|
+
const M = n.axes ?? G.axes, h = n.radius ?? G.radius, f = n.falloff ?? G.falloff, T = n.magnetMode ?? G.magnetMode, F = n.scope ?? G.scope, d = n.props, S = n.transitionMs ?? 0, L = n.cachePositions ?? !0, k = n.stabilizeLayout ?? !0, N = window.scrollY;
|
|
178
|
+
t.innerHTML = e;
|
|
179
|
+
const H = it(t), E = [];
|
|
180
|
+
for (const i of H) {
|
|
181
|
+
const s = i.textContent ?? "";
|
|
182
|
+
if (!s.trim()) continue;
|
|
183
|
+
const w = s.split(/(\S+)/), l = document.createDocumentFragment();
|
|
184
|
+
for (let o = 0; o < w.length; o += 2) {
|
|
185
|
+
const u = w[o], x = w[o + 1];
|
|
186
|
+
if (!x) continue;
|
|
187
|
+
const B = w[o + 3] === void 0 ? w[o + 2] ?? "" : "", q = document.createElement("span");
|
|
188
|
+
q.className = ot.word, q.textContent = u + x + B, l.appendChild(q), E.push(q);
|
|
189
189
|
}
|
|
190
|
-
|
|
190
|
+
i.parentNode.replaceChild(l, i);
|
|
191
191
|
}
|
|
192
192
|
if (requestAnimationFrame(() => {
|
|
193
|
-
typeof window < "u" && Math.abs(window.scrollY -
|
|
194
|
-
}),
|
|
193
|
+
typeof window < "u" && Math.abs(window.scrollY - N) > 2 && window.scrollTo({ top: N, behavior: "instant" });
|
|
194
|
+
}), E.length === 0) return () => {
|
|
195
195
|
};
|
|
196
|
-
const y = getComputedStyle(t).fontVariationSettings,
|
|
196
|
+
const y = getComputedStyle(t).fontVariationSettings, O = ct(
|
|
197
197
|
y,
|
|
198
|
-
Object.fromEntries(Object.entries(M).map(([
|
|
198
|
+
Object.fromEntries(Object.entries(M).map(([i, [s]]) => [i, s]))
|
|
199
199
|
);
|
|
200
|
-
let
|
|
201
|
-
if (
|
|
202
|
-
const
|
|
200
|
+
let D = 0;
|
|
201
|
+
if (k) {
|
|
202
|
+
const i = ct(
|
|
203
203
|
y,
|
|
204
|
-
Object.fromEntries(Object.entries(M).map(([
|
|
205
|
-
),
|
|
206
|
-
t.style.whiteSpace = "nowrap", t.style.overflow = "visible", t.style.fontVariationSettings =
|
|
204
|
+
Object.fromEntries(Object.entries(M).map(([j, [, B]]) => [j, B]))
|
|
205
|
+
), s = t.style.fontVariationSettings, w = t.style.whiteSpace, l = t.style.overflow;
|
|
206
|
+
t.style.whiteSpace = "nowrap", t.style.overflow = "visible", t.style.fontVariationSettings = i;
|
|
207
|
+
const o = t.scrollWidth;
|
|
208
|
+
t.style.fontVariationSettings = O;
|
|
207
209
|
const u = t.scrollWidth;
|
|
208
|
-
t.style.fontVariationSettings =
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
const S = x.reduce(
|
|
212
|
-
(f, C) => {
|
|
210
|
+
t.style.fontVariationSettings = s, t.style.whiteSpace = w, t.style.overflow = l;
|
|
211
|
+
const x = E.reduce(
|
|
212
|
+
(j, B) => {
|
|
213
213
|
var q;
|
|
214
|
-
return
|
|
214
|
+
return j + (((q = B.textContent) == null ? void 0 : q.replace(/\s+/g, "").length) ?? 0);
|
|
215
215
|
},
|
|
216
216
|
0
|
|
217
217
|
);
|
|
218
|
-
|
|
218
|
+
x > 0 && o > u && (D = (o - u) / x);
|
|
219
219
|
}
|
|
220
|
-
|
|
221
|
-
|
|
220
|
+
E.forEach((i) => {
|
|
221
|
+
i.style.fontVariationSettings = O, d && rt(i, d);
|
|
222
222
|
});
|
|
223
|
-
let
|
|
223
|
+
let K = [], Y = !1;
|
|
224
224
|
function A() {
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
const
|
|
228
|
-
return { cx: (
|
|
225
|
+
const i = window.scrollX, s = window.scrollY;
|
|
226
|
+
K = E.map((w) => {
|
|
227
|
+
const l = w.getBoundingClientRect();
|
|
228
|
+
return { cx: (l.left + l.right) / 2 + i, cy: (l.top + l.bottom) / 2 + s };
|
|
229
229
|
}), Y = !0;
|
|
230
230
|
}
|
|
231
231
|
let $ = null;
|
|
232
232
|
L && (A(), $ = new ResizeObserver(() => {
|
|
233
233
|
Y = !1;
|
|
234
|
-
}), $.observe(t), (
|
|
234
|
+
}), $.observe(t), (p = (g = document.fonts) == null ? void 0 : g.ready) == null || p.then(() => {
|
|
235
235
|
Y = !1;
|
|
236
236
|
}));
|
|
237
|
-
let
|
|
238
|
-
function
|
|
239
|
-
if (!
|
|
240
|
-
if (!
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}),
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}),
|
|
247
|
-
},
|
|
237
|
+
let X = -9999, v = -9999, J = !1, C = 0, I = !0, R = null;
|
|
238
|
+
function P() {
|
|
239
|
+
if (!I) return;
|
|
240
|
+
if (!J) {
|
|
241
|
+
E.forEach((l) => {
|
|
242
|
+
S > 0 && (l.style.transition = `font-variation-settings ${S}ms ease`), l.style.fontVariationSettings = O, k && (l.style.letterSpacing = ""), d && rt(l, d);
|
|
243
|
+
}), S > 0 && (R !== null && clearTimeout(R), R = setTimeout(() => {
|
|
244
|
+
E.forEach((l) => {
|
|
245
|
+
l.style.transition = "";
|
|
246
|
+
}), R = null;
|
|
247
|
+
}, S)), C = 0;
|
|
248
248
|
return;
|
|
249
249
|
}
|
|
250
250
|
L && !Y && A();
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
let
|
|
251
|
+
const i = L ? X + window.scrollX : X, s = L ? v + window.scrollY : v, w = L ? null : E.map((l) => l.getBoundingClientRect());
|
|
252
|
+
E.forEach((l, o) => {
|
|
253
|
+
l.style.transition = "";
|
|
254
|
+
let u, x;
|
|
255
255
|
if (L)
|
|
256
|
-
({ cx:
|
|
256
|
+
({ cx: u, cy: x } = K[o]);
|
|
257
257
|
else {
|
|
258
|
-
const
|
|
259
|
-
|
|
258
|
+
const z = w[o];
|
|
259
|
+
u = z.left + z.width / 2, x = z.top + z.height / 2;
|
|
260
260
|
}
|
|
261
|
-
const
|
|
262
|
-
for (const
|
|
263
|
-
const [
|
|
264
|
-
|
|
261
|
+
const j = Math.sqrt((i - u) ** 2 + (s - x) ** 2), B = Math.max(0, 1 - j / h), q = f === "quadratic" ? B * B : B, U = T === "repel" ? 1 - q : q, Q = {};
|
|
262
|
+
for (const z of Object.keys(M)) {
|
|
263
|
+
const [lt, mt] = M[z] ?? [300, 500];
|
|
264
|
+
Q[z] = lt + (mt - lt) * U;
|
|
265
265
|
}
|
|
266
|
-
|
|
267
|
-
}),
|
|
266
|
+
l.style.fontVariationSettings = ct(y, Q), k && D !== 0 && (l.style.letterSpacing = `${(-D * U).toFixed(3)}px`), d && ft(l, d, q);
|
|
267
|
+
}), C = requestAnimationFrame(P);
|
|
268
268
|
}
|
|
269
|
-
function
|
|
270
|
-
|
|
269
|
+
function Z(i) {
|
|
270
|
+
X = i.clientX, v = i.clientY, J || (J = !0), C === 0 && (C = requestAnimationFrame(P));
|
|
271
271
|
}
|
|
272
|
-
function
|
|
273
|
-
|
|
272
|
+
function a() {
|
|
273
|
+
J = !1, C === 0 && (C = requestAnimationFrame(P));
|
|
274
274
|
}
|
|
275
|
-
function
|
|
276
|
-
|
|
275
|
+
function c(i) {
|
|
276
|
+
i.touches.length !== 0 && (X = i.touches[0].clientX, v = i.touches[0].clientY, J || (J = !0), C === 0 && (C = requestAnimationFrame(P)));
|
|
277
277
|
}
|
|
278
|
-
function
|
|
279
|
-
|
|
278
|
+
function m() {
|
|
279
|
+
J = !1, C === 0 && (C = requestAnimationFrame(P));
|
|
280
280
|
}
|
|
281
281
|
const r = F === "document" ? document : t;
|
|
282
|
-
return r.addEventListener("mousemove",
|
|
283
|
-
|
|
282
|
+
return r.addEventListener("mousemove", Z), r.addEventListener("mouseleave", a), r.addEventListener("touchmove", c, { passive: !0 }), r.addEventListener("touchend", m), () => {
|
|
283
|
+
I = !1, cancelAnimationFrame(C), R !== null && clearTimeout(R), $ && $.disconnect(), r.removeEventListener("mousemove", Z), r.removeEventListener("mouseleave", a), r.removeEventListener("touchmove", c), r.removeEventListener("touchend", m), t.innerHTML = e;
|
|
284
284
|
};
|
|
285
285
|
}
|
|
286
|
-
function
|
|
287
|
-
const
|
|
286
|
+
function wt(t) {
|
|
287
|
+
const e = _(null), n = _(null), M = _(t);
|
|
288
288
|
M.current = t;
|
|
289
|
-
const h =
|
|
290
|
-
const y =
|
|
289
|
+
const h = _(null), f = t.mode ?? "word", { axes: T, radius: F, falloff: d, magnetMode: S, wdthBoost: L, scope: k } = t, N = T ? JSON.stringify(T) : void 0, H = t.props ? JSON.stringify(t.props) : void 0, E = W(() => {
|
|
290
|
+
const y = e.current;
|
|
291
291
|
if (!y) return;
|
|
292
|
-
|
|
293
|
-
}, [
|
|
294
|
-
return
|
|
292
|
+
n.current === null && (n.current = yt(y)), h.current && (h.current(), h.current = null), (M.current.mode ?? "word") === "word" ? h.current = vt(y, n.current, M.current) : h.current = gt(y, n.current, M.current);
|
|
293
|
+
}, [f, N, F, d, S, L, k, H]);
|
|
294
|
+
return pt(() => (E(), () => {
|
|
295
295
|
h.current && (h.current(), h.current = null);
|
|
296
|
-
}), [
|
|
297
|
-
var y,
|
|
298
|
-
(
|
|
299
|
-
}, [
|
|
296
|
+
}), [E]), tt(() => {
|
|
297
|
+
var y, O;
|
|
298
|
+
(O = (y = document.fonts) == null ? void 0 : y.ready) == null || O.then(E);
|
|
299
|
+
}, [E]), e;
|
|
300
300
|
}
|
|
301
|
-
const
|
|
302
|
-
function({ children:
|
|
303
|
-
const F =
|
|
304
|
-
(
|
|
305
|
-
F.current =
|
|
301
|
+
const St = ut(
|
|
302
|
+
function({ children: e, as: n = "p", className: M, style: h, ...f }, T) {
|
|
303
|
+
const F = wt(f), d = W(
|
|
304
|
+
(S) => {
|
|
305
|
+
F.current = S, typeof T == "function" ? T(S) : T && (T.current = S);
|
|
306
306
|
},
|
|
307
307
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
308
|
-
[
|
|
308
|
+
[T]
|
|
309
309
|
);
|
|
310
|
-
return /* @__PURE__ */
|
|
310
|
+
return /* @__PURE__ */ et(n, { ref: d, className: M, style: h, children: e });
|
|
311
311
|
}
|
|
312
312
|
);
|
|
313
|
-
|
|
314
|
-
const
|
|
313
|
+
St.displayName = "MagnetTypeText";
|
|
314
|
+
const dt = ut(
|
|
315
315
|
function({
|
|
316
|
-
children:
|
|
317
|
-
as:
|
|
316
|
+
children: e,
|
|
317
|
+
as: n = "p",
|
|
318
318
|
className: M,
|
|
319
319
|
style: h,
|
|
320
|
-
minWeight:
|
|
321
|
-
maxWeight:
|
|
320
|
+
minWeight: f = 300,
|
|
321
|
+
maxWeight: T = 600,
|
|
322
322
|
proximityRadius: F,
|
|
323
|
-
spreadRadius:
|
|
324
|
-
fixedAxes:
|
|
323
|
+
spreadRadius: d,
|
|
324
|
+
fixedAxes: S = {},
|
|
325
325
|
cachePositions: L = !0,
|
|
326
|
-
rafThrottle:
|
|
327
|
-
stabilizeLayout:
|
|
328
|
-
},
|
|
329
|
-
const
|
|
330
|
-
(
|
|
331
|
-
|
|
326
|
+
rafThrottle: k = !0,
|
|
327
|
+
stabilizeLayout: N = !0
|
|
328
|
+
}, H) {
|
|
329
|
+
const E = _(null), y = _(null), O = _([]), D = _([]), K = _(null), Y = _(!1), A = _(null), $ = _(0), X = W(
|
|
330
|
+
(a) => {
|
|
331
|
+
E.current = a, typeof H == "function" ? H(a) : H && (H.current = a);
|
|
332
332
|
},
|
|
333
333
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
334
|
-
[
|
|
334
|
+
[H]
|
|
335
335
|
);
|
|
336
|
-
function v(
|
|
337
|
-
const
|
|
338
|
-
for (const [
|
|
339
|
-
return
|
|
336
|
+
function v(a) {
|
|
337
|
+
const c = [`'wght' ${a.toFixed(0)}`];
|
|
338
|
+
for (const [m, r] of Object.entries(S)) c.push(`'${m}' ${r}`);
|
|
339
|
+
return c.join(", ");
|
|
340
340
|
}
|
|
341
|
-
function
|
|
342
|
-
const
|
|
343
|
-
if (!
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
top: r.top +
|
|
347
|
-
left: r.left +
|
|
348
|
-
right: r.right +
|
|
349
|
-
bottom: r.bottom +
|
|
350
|
-
},
|
|
351
|
-
if (!
|
|
352
|
-
const
|
|
341
|
+
function J() {
|
|
342
|
+
const a = E.current;
|
|
343
|
+
if (!a) return;
|
|
344
|
+
const c = window.scrollX, m = window.scrollY, r = a.getBoundingClientRect();
|
|
345
|
+
K.current = {
|
|
346
|
+
top: r.top + m,
|
|
347
|
+
left: r.left + c,
|
|
348
|
+
right: r.right + c,
|
|
349
|
+
bottom: r.bottom + m
|
|
350
|
+
}, D.current = O.current.map((b) => {
|
|
351
|
+
if (!b) return { cx: 0, cy: 0 };
|
|
352
|
+
const V = b.getBoundingClientRect();
|
|
353
353
|
return {
|
|
354
|
-
cx: (
|
|
355
|
-
cy: (
|
|
354
|
+
cx: (V.left + V.right) / 2 + c,
|
|
355
|
+
cy: (V.top + V.bottom) / 2 + m
|
|
356
356
|
};
|
|
357
357
|
}), Y.current = !0;
|
|
358
358
|
}
|
|
359
|
-
function
|
|
360
|
-
const
|
|
361
|
-
if (!
|
|
362
|
-
L && !Y.current &&
|
|
363
|
-
let r,
|
|
364
|
-
if (L &&
|
|
365
|
-
|
|
359
|
+
function C(a, c) {
|
|
360
|
+
const m = E.current;
|
|
361
|
+
if (!m) return;
|
|
362
|
+
L && !Y.current && J();
|
|
363
|
+
let r, b, V, g, p, i;
|
|
364
|
+
if (L && K.current)
|
|
365
|
+
p = a + window.scrollX, i = c + window.scrollY, { top: r, left: b, right: V, bottom: g } = K.current;
|
|
366
366
|
else {
|
|
367
|
-
const
|
|
368
|
-
|
|
367
|
+
const o = m.getBoundingClientRect();
|
|
368
|
+
p = a, i = c, r = o.top, b = o.left, V = o.right, g = o.bottom;
|
|
369
369
|
}
|
|
370
|
-
const
|
|
371
|
-
if (F !== void 0 && !
|
|
372
|
-
const
|
|
373
|
-
|
|
370
|
+
const s = Math.max(b - p, 0, p - V), w = Math.max(r - i, 0, i - g), l = Math.sqrt(s * s + w * w);
|
|
371
|
+
if (F !== void 0 && !d) {
|
|
372
|
+
const u = 1 - (1 - Math.max(0, 1 - l / F)) ** 2;
|
|
373
|
+
m.style.fontVariationSettings = v(f + (T - f) * u);
|
|
374
374
|
return;
|
|
375
375
|
}
|
|
376
|
-
if (
|
|
377
|
-
if (F !== void 0 &&
|
|
378
|
-
|
|
379
|
-
for (const
|
|
380
|
-
|
|
376
|
+
if (d) {
|
|
377
|
+
if (F !== void 0 && l > F) {
|
|
378
|
+
m.style.fontVariationSettings = v(f);
|
|
379
|
+
for (const u of O.current)
|
|
380
|
+
u && (u.style.fontVariationSettings = v(f), N && (u.style.letterSpacing = ""));
|
|
381
381
|
return;
|
|
382
382
|
}
|
|
383
|
-
if (
|
|
384
|
-
for (const
|
|
385
|
-
|
|
383
|
+
if (l > d) {
|
|
384
|
+
for (const u of O.current)
|
|
385
|
+
u && (u.style.fontVariationSettings = v(f), N && (u.style.letterSpacing = ""));
|
|
386
386
|
return;
|
|
387
387
|
}
|
|
388
|
-
const
|
|
389
|
-
if (L &&
|
|
390
|
-
for (let
|
|
391
|
-
const
|
|
392
|
-
if (!
|
|
393
|
-
const { cx:
|
|
394
|
-
|
|
388
|
+
const o = O.current;
|
|
389
|
+
if (L && D.current.length === o.length)
|
|
390
|
+
for (let u = 0; u < o.length; u++) {
|
|
391
|
+
const x = o[u];
|
|
392
|
+
if (!x) continue;
|
|
393
|
+
const { cx: j, cy: B } = D.current[u], q = Math.sqrt((p - j) ** 2 + (i - B) ** 2), Q = 1 - (1 - Math.max(0, 1 - q / d)) ** 2;
|
|
394
|
+
x.style.fontVariationSettings = v(f + (T - f) * Q), N && $.current !== 0 && (x.style.letterSpacing = `${(-$.current * Q).toFixed(3)}px`);
|
|
395
395
|
}
|
|
396
396
|
else
|
|
397
|
-
for (const
|
|
398
|
-
if (!
|
|
399
|
-
const
|
|
400
|
-
|
|
397
|
+
for (const u of o) {
|
|
398
|
+
if (!u) continue;
|
|
399
|
+
const x = u.getBoundingClientRect(), j = (x.left + x.right) / 2, B = (x.top + x.bottom) / 2, q = Math.sqrt((a - j) ** 2 + (c - B) ** 2), Q = 1 - (1 - Math.max(0, 1 - q / d)) ** 2;
|
|
400
|
+
u.style.fontVariationSettings = v(f + (T - f) * Q), N && $.current !== 0 && (u.style.letterSpacing = `${(-$.current * Q).toFixed(3)}px`);
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
403
|
}
|
|
404
|
-
const
|
|
405
|
-
(
|
|
406
|
-
y.current = { x:
|
|
407
|
-
A.current = null, y.current &&
|
|
408
|
-
})) :
|
|
404
|
+
const I = W(
|
|
405
|
+
(a) => {
|
|
406
|
+
y.current = { x: a.clientX, y: a.clientY }, k ? A.current === null && (A.current = requestAnimationFrame(() => {
|
|
407
|
+
A.current = null, y.current && C(y.current.x, y.current.y);
|
|
408
|
+
})) : C(a.clientX, a.clientY);
|
|
409
409
|
},
|
|
410
410
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
411
|
-
[
|
|
412
|
-
),
|
|
411
|
+
[f, T, F, d, L, k, N, JSON.stringify(S)]
|
|
412
|
+
), R = W(
|
|
413
413
|
() => {
|
|
414
|
-
y.current &&
|
|
414
|
+
y.current && C(y.current.x, y.current.y);
|
|
415
415
|
},
|
|
416
416
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
417
|
-
[
|
|
418
|
-
),
|
|
417
|
+
[f, T, F, d, L, N, JSON.stringify(S)]
|
|
418
|
+
), P = W(
|
|
419
419
|
() => {
|
|
420
420
|
y.current = null, A.current !== null && (cancelAnimationFrame(A.current), A.current = null);
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
for (const
|
|
424
|
-
|
|
421
|
+
const a = E.current;
|
|
422
|
+
a && (a.style.fontVariationSettings = v(f));
|
|
423
|
+
for (const c of O.current)
|
|
424
|
+
c && (c.style.fontVariationSettings = v(f), N && (c.style.letterSpacing = ""));
|
|
425
425
|
},
|
|
426
426
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
427
|
-
[
|
|
427
|
+
[f, N, JSON.stringify(S)]
|
|
428
428
|
);
|
|
429
|
-
|
|
430
|
-
window.removeEventListener("mousemove",
|
|
431
|
-
}), [
|
|
432
|
-
var
|
|
433
|
-
if (!L || !
|
|
429
|
+
tt(() => (window.addEventListener("mousemove", I, { passive: !0 }), window.addEventListener("scroll", R, { passive: !0, capture: !0 }), document.documentElement.addEventListener("mouseleave", P), () => {
|
|
430
|
+
window.removeEventListener("mousemove", I), window.removeEventListener("scroll", R, { capture: !0 }), document.documentElement.removeEventListener("mouseleave", P), A.current !== null && (cancelAnimationFrame(A.current), A.current = null);
|
|
431
|
+
}), [I, R, P]), tt(() => {
|
|
432
|
+
var m, r;
|
|
433
|
+
if (!L || !d) return;
|
|
434
434
|
Y.current = !1;
|
|
435
|
-
const
|
|
436
|
-
if (!
|
|
437
|
-
const
|
|
435
|
+
const a = E.current;
|
|
436
|
+
if (!a) return;
|
|
437
|
+
const c = new ResizeObserver(() => {
|
|
438
438
|
Y.current = !1;
|
|
439
439
|
});
|
|
440
|
-
return
|
|
440
|
+
return c.observe(a), (r = (m = document.fonts) == null ? void 0 : m.ready) == null || r.then(() => {
|
|
441
441
|
Y.current = !1;
|
|
442
|
-
}), () =>
|
|
443
|
-
}, [L,
|
|
442
|
+
}), () => c.disconnect();
|
|
443
|
+
}, [L, d]), tt(() => {
|
|
444
444
|
Y.current = !1;
|
|
445
|
-
}, [
|
|
446
|
-
var
|
|
447
|
-
if (!
|
|
445
|
+
}, [e, d]), tt(() => {
|
|
446
|
+
var c, m;
|
|
447
|
+
if (!N || !d) {
|
|
448
448
|
$.current = 0;
|
|
449
449
|
return;
|
|
450
450
|
}
|
|
451
|
-
function
|
|
452
|
-
const r =
|
|
451
|
+
function a() {
|
|
452
|
+
const r = E.current;
|
|
453
453
|
if (!r) return;
|
|
454
|
-
const
|
|
455
|
-
if (
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
const
|
|
459
|
-
const
|
|
460
|
-
for (const [
|
|
461
|
-
return
|
|
454
|
+
const b = r.textContent ?? "", V = b.replace(/\s/g, "").length;
|
|
455
|
+
if (V === 0) return;
|
|
456
|
+
const g = getComputedStyle(r), p = document.createElement("span");
|
|
457
|
+
p.style.cssText = "position:fixed;top:-9999px;left:-9999px;visibility:hidden;white-space:nowrap;pointer-events:none;", p.style.fontFamily = g.fontFamily, p.style.fontSize = g.fontSize, p.style.fontWeight = g.fontWeight, p.style.lineHeight = g.lineHeight, p.style.letterSpacing = g.letterSpacing, p.textContent = b, document.body.appendChild(p);
|
|
458
|
+
const i = (l) => {
|
|
459
|
+
const o = [`'wght' ${l.toFixed(0)}`];
|
|
460
|
+
for (const [u, x] of Object.entries(S)) o.push(`'${u}' ${x}`);
|
|
461
|
+
return o.join(", ");
|
|
462
462
|
};
|
|
463
|
-
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
const
|
|
467
|
-
document.body.removeChild(
|
|
463
|
+
p.style.fontVariationSettings = i(T);
|
|
464
|
+
const s = p.scrollWidth;
|
|
465
|
+
p.style.fontVariationSettings = i(f);
|
|
466
|
+
const w = p.scrollWidth;
|
|
467
|
+
document.body.removeChild(p), $.current = s > w ? (s - w) / V : 0;
|
|
468
468
|
}
|
|
469
|
-
|
|
470
|
-
}, [
|
|
471
|
-
const
|
|
472
|
-
if (!
|
|
473
|
-
|
|
474
|
-
let
|
|
475
|
-
function
|
|
476
|
-
if (typeof
|
|
477
|
-
return [...
|
|
469
|
+
a(), (m = (c = document.fonts) == null ? void 0 : c.ready) == null || m.then(a);
|
|
470
|
+
}, [N, d, f, T, e, JSON.stringify(S)]);
|
|
471
|
+
const Z = ht(() => {
|
|
472
|
+
if (!d) return e;
|
|
473
|
+
O.current = [];
|
|
474
|
+
let a = 0;
|
|
475
|
+
function c(m) {
|
|
476
|
+
if (typeof m == "string")
|
|
477
|
+
return [...m].map((r) => {
|
|
478
478
|
if (/\s/.test(r)) return r;
|
|
479
|
-
const
|
|
480
|
-
return /* @__PURE__ */
|
|
479
|
+
const b = a++;
|
|
480
|
+
return /* @__PURE__ */ et(
|
|
481
481
|
"span",
|
|
482
482
|
{
|
|
483
|
-
ref: (
|
|
484
|
-
|
|
483
|
+
ref: (V) => {
|
|
484
|
+
O.current[b] = V;
|
|
485
485
|
},
|
|
486
|
-
style: { fontVariationSettings: v(
|
|
486
|
+
style: { fontVariationSettings: v(f) },
|
|
487
487
|
children: r
|
|
488
488
|
},
|
|
489
|
-
|
|
489
|
+
b
|
|
490
490
|
);
|
|
491
491
|
});
|
|
492
|
-
if (Array.isArray(
|
|
493
|
-
if (
|
|
494
|
-
const r =
|
|
492
|
+
if (Array.isArray(m)) return m.map((r, b) => /* @__PURE__ */ et(st.Fragment, { children: c(r) }, b));
|
|
493
|
+
if (st.isValidElement(m)) {
|
|
494
|
+
const r = m;
|
|
495
495
|
if (r.props.children !== void 0)
|
|
496
|
-
return
|
|
496
|
+
return st.cloneElement(r, {}, c(r.props.children));
|
|
497
497
|
}
|
|
498
|
-
return
|
|
498
|
+
return m;
|
|
499
499
|
}
|
|
500
|
-
return
|
|
501
|
-
}, [
|
|
502
|
-
return /* @__PURE__ */
|
|
503
|
-
|
|
500
|
+
return c(e);
|
|
501
|
+
}, [e, d, f, JSON.stringify(S)]);
|
|
502
|
+
return /* @__PURE__ */ et(
|
|
503
|
+
n,
|
|
504
504
|
{
|
|
505
|
-
ref:
|
|
505
|
+
ref: X,
|
|
506
506
|
className: M,
|
|
507
|
-
style: { fontVariationSettings: v(
|
|
508
|
-
children:
|
|
507
|
+
style: { fontVariationSettings: v(f), ...h },
|
|
508
|
+
children: Z
|
|
509
509
|
}
|
|
510
510
|
);
|
|
511
511
|
}
|
|
512
512
|
);
|
|
513
|
-
|
|
513
|
+
dt.displayName = "MagnetChar";
|
|
514
|
+
const xt = dt;
|
|
514
515
|
export {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
516
|
+
ot as MAGNET_TYPE_CLASSES,
|
|
517
|
+
xt as MagnetBlock,
|
|
518
|
+
dt as MagnetChar,
|
|
519
|
+
St as MagnetTypeText,
|
|
520
|
+
gt as applyMagnetType,
|
|
521
|
+
yt as getCleanHTML,
|
|
522
|
+
Ct as removeMagnetType,
|
|
523
|
+
vt as startMagnetType,
|
|
524
|
+
wt as useMagnetType
|
|
523
525
|
};
|