typingfx
Version:
Customizable, smooth, and snappy typing animations for React — built for natural, human-like effects with minimal config.
2 lines (1 loc) • 1.84 kB
JavaScript
import{a as t,b as E,c as g,f as M}from"./chunk-2GRJXXLQ.mjs";import{useEffect as y,useMemo as S,useRef as C,useState as b}from"react";import{jsx as f}from"react/jsx-runtime";var w={children:"",speed:20,delSpeed:40,noCursor:!1,noCursorAfterAnimEnd:!1,steps:[""],repeat:1/0,force:!1,paused:!1},D=({children:i,className:l,componentAnimation:u,delSpeed:r,noCursor:d,noCursorAfterAnimEnd:c,repeat:m,speed:a,steps:o,style:P,paused:v,...A})=>{let[H,L]=b(!0),T=S(()=>{let e=i?[...o,i]:o;return e.length<2&&e.unshift("",""),E(e,u)},[i,o,u]),p=C(null);return y(()=>{L(!0);let e;return requestAnimationFrame(()=>{if(p.current){e=g(p.current);for(let n=0;n<e[0].length;n++){let s=e[0][n],h=e[0][n+1];s.onanimationend=O=>{O.stopPropagation(),s.style.width=s.style.getPropertyValue("--w"),s.classList.remove(t.type,t.hk),h?h.classList.add(t.type):(M(e,m,c),s.classList.add(t.del))}}requestAnimationFrame(()=>e[0][0].classList.add(t.type)),L(!1)}}),()=>e==null?void 0:e.flat().forEach(n=>n.onanimationend=null)},[T,m,c]),y(()=>{var n;if(v)return(n=p.current)==null||n.classList.add(t.paused),()=>null;let e=()=>{var s;(s=p.current)==null||s.classList[document.visibilityState==="visible"?"remove":"add"](t.paused)};return e(),addEventListener("visibilitychange",e),()=>removeEventListener("visibilitychange",e)},[v]),f("div",{...A,className:[l,t.typeout,H?t.processing:"",d?"":t.cursor].join(" "),ref:p,style:{"--speed":a,"--delSpeed":r,...P},children:T.map((e,n)=>f("div",{className:t.hk,children:e},n))})},q=i=>{let{children:l,force:u,steps:r,...d}={...w,...i},[c,m]=b(!1);return y(()=>{let a=window.matchMedia("(prefers-reduced-motion: reduce)"),o=()=>m(a.matches);return o(),a.addEventListener("change",o),()=>a.removeEventListener("change",o)},[]),!u&&c?f("div",{...d,children:r[r.length-1]||l||r[0]}):f(D,{...d,children:l,steps:r})};export{q as a};