torph 0.0.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/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/.DS_Store +0 -0
- package/dist/chunk-2RJBUJEF.mjs +3 -0
- package/dist/chunk-2RJBUJEF.mjs.map +1 -0
- package/dist/chunk-66KQLHAM.mjs +3 -0
- package/dist/chunk-66KQLHAM.mjs.map +1 -0
- package/dist/chunk-I42X5RZV.mjs +3 -0
- package/dist/chunk-I42X5RZV.mjs.map +1 -0
- package/dist/chunk-RM2STLUA.mjs +2 -0
- package/dist/chunk-RM2STLUA.mjs.map +1 -0
- package/dist/chunk-SZ3JXWX5.mjs +3 -0
- package/dist/chunk-SZ3JXWX5.mjs.map +1 -0
- package/dist/chunk-Y6MZSIYO.mjs +3 -0
- package/dist/chunk-Y6MZSIYO.mjs.map +1 -0
- package/dist/components/text-morph/index.d.mts +7 -0
- package/dist/components/text-morph/index.d.ts +7 -0
- package/dist/components/text-morph/index.js +3 -0
- package/dist/components/text-morph/index.js.map +1 -0
- package/dist/components/text-morph/index.mjs +3 -0
- package/dist/components/text-morph/index.mjs.map +1 -0
- package/dist/components/text-morph/styles.d.mts +5 -0
- package/dist/components/text-morph/styles.d.ts +5 -0
- package/dist/components/text-morph/styles.js +3 -0
- package/dist/components/text-morph/styles.js.map +1 -0
- package/dist/components/text-morph/styles.mjs +3 -0
- package/dist/components/text-morph/styles.mjs.map +1 -0
- package/dist/components/text-morph/types.d.mts +12 -0
- package/dist/components/text-morph/types.d.ts +12 -0
- package/dist/components/text-morph/types.js +3 -0
- package/dist/components/text-morph/types.js.map +1 -0
- package/dist/components/text-morph/types.mjs +3 -0
- package/dist/components/text-morph/types.mjs.map +1 -0
- package/dist/config.d.mts +10 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -0
- package/dist/config.mjs +3 -0
- package/dist/config.mjs.map +1 -0
- package/dist/hooks/useDebounce.d.mts +3 -0
- package/dist/hooks/useDebounce.d.ts +3 -0
- package/dist/hooks/useDebounce.js +3 -0
- package/dist/hooks/useDebounce.js.map +1 -0
- package/dist/hooks/useDebounce.mjs +3 -0
- package/dist/hooks/useDebounce.mjs.map +1 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3 -0
- package/dist/index.mjs.map +1 -0
- package/dist/utils.d.mts +4 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +3 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +3 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +71 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Lochie Axon
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# torph
|
|
2
|
+
|
|
3
|
+
An animated text component for React.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```shell
|
|
8
|
+
pnpm i torph
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { TextMorph } from "torph";
|
|
15
|
+
|
|
16
|
+
<TextMorph>Hello world</TextMorph>;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Options
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
<TextMorph
|
|
23
|
+
children="Hello world"
|
|
24
|
+
duration={1} // duration of the transition in seconds
|
|
25
|
+
/>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Found it useful?
|
|
29
|
+
|
|
30
|
+
Follow me on [Twitter](https://twitter.com/lochieaxon).
|
|
31
|
+
|
|
32
|
+
### Other projects
|
|
33
|
+
|
|
34
|
+
You might also like:
|
|
35
|
+
|
|
36
|
+
- [number-flow](https://number-flow.barvian.me/) - Animated number component by [Maxwell Barvian](https://x.com/mbarvian).
|
|
37
|
+
- [easing.dev](https://easing.dev) - Easily create custom easing graphs.
|
package/dist/.DS_Store
ADDED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useDebounce.ts"],"sourcesContent":["import React from \"react\";\n\nconst useDebounce = (value: string, delay: number) => {\n const [debouncedValue, setDebouncedValue] = React.useState(value);\n\n React.useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n};\n\nexport default useDebounce;\n"],"mappings":";AAAA,OAAOA,MAAW,QAElB,IAAMC,EAAc,CAACC,EAAeC,IAAkB,CACpD,GAAM,CAACC,EAAgBC,CAAiB,EAAIL,EAAM,SAASE,CAAK,EAEhE,OAAAF,EAAM,UAAU,IAAM,CACpB,IAAMM,EAAU,WAAW,IAAM,CAC/BD,EAAkBH,CAAK,CACzB,EAAGC,CAAK,EAER,MAAO,IAAM,CACX,aAAaG,CAAO,CACtB,CACF,EAAG,CAACJ,EAAOC,CAAK,CAAC,EAEVC,CACT,EAEOG,EAAQN","names":["React","useDebounce","value","delay","debouncedValue","setDebouncedValue","handler","useDebounce_default"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var f=(r,o)=>{let g=r.length,i=o.length,e=Array.from({length:g+1},()=>Array(i+1).fill(0)),s=0,l=0;for(let t=1;t<=g;t+=1)for(let n=1;n<=i;n+=1)r[t-1]===o[n-1]&&(e[t][n]=e[t-1][n-1]+1,e[t][n]>s&&(s=e[t][n],l=t));return r.substring(l-s,l)},c=!1;export{f as a,c as b};
|
|
3
|
+
//# sourceMappingURL=chunk-66KQLHAM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["export const findLCS = (a: string, b: string): string => {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array(n + 1).fill(0),\n );\n let maxLength = 0;\n let endIndex = 0;\n\n for (let i = 1; i <= m; i += 1) {\n for (let j = 1; j <= n; j += 1) {\n if (a[i - 1] === b[j - 1]) {\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n dp[i][j] = dp[i - 1][j - 1] + 1;\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n if (dp[i][j] > maxLength) {\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n maxLength = dp[i][j];\n endIndex = i;\n }\n }\n }\n }\n return a.substring(endIndex - maxLength, endIndex);\n};\n\nexport const debug = false;\n"],"mappings":";AAAO,IAAMA,EAAU,CAACC,EAAWC,IAAsB,CACvD,IAAMC,EAAIF,EAAE,OACNG,EAAIF,EAAE,OACNG,EAAiB,MAAM,KAAK,CAAE,OAAQF,EAAI,CAAE,EAAG,IACnD,MAAMC,EAAI,CAAC,EAAE,KAAK,CAAC,CACrB,EACIE,EAAY,EACZC,EAAW,EAEf,QAASC,EAAI,EAAGA,GAAKL,EAAGK,GAAK,EAC3B,QAASC,EAAI,EAAGA,GAAKL,EAAGK,GAAK,EACvBR,EAAEO,EAAI,CAAC,IAAMN,EAAEO,EAAI,CAAC,IAEtBJ,EAAGG,CAAC,EAAEC,CAAC,EAAIJ,EAAGG,EAAI,CAAC,EAAEC,EAAI,CAAC,EAAI,EAE1BJ,EAAGG,CAAC,EAAEC,CAAC,EAAIH,IAEbA,EAAYD,EAAGG,CAAC,EAAEC,CAAC,EACnBF,EAAWC,IAKnB,OAAOP,EAAE,UAAUM,EAAWD,EAAWC,CAAQ,CACnD,EAEaG,EAAQ","names":["findLCS","a","b","m","n","dp","maxLength","endIndex","i","j","debug"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["import { TextMorphProps } from \"./components/text-morph/types\";\n\ntype DefaultTextMorphProps = Omit<TextMorphProps, \"duration\" | \"children\"> & {\n duration: NonNullable<TextMorphProps[\"duration\"]>;\n children?: TextMorphProps[\"children\"];\n};\n\nconst defaultConfig: DefaultTextMorphProps = {\n duration: 0.4,\n ease: [0.19, 1, 0.22, 1],\n respectMotionPreference: true,\n};\n\nexport default defaultConfig;\n"],"mappings":";AAOA,IAAMA,EAAuC,CAC3C,SAAU,GACV,KAAM,CAAC,IAAM,EAAG,IAAM,CAAC,EACvB,wBAAyB,EAC3B,EAEOC,EAAQD","names":["defaultConfig","config_default"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import{a as m}from"./chunk-I42X5RZV.mjs";import{a as v}from"./chunk-66KQLHAM.mjs";import{a as T}from"./chunk-2RJBUJEF.mjs";import{a as n}from"./chunk-Y6MZSIYO.mjs";import p from"react";import{motion as c,AnimatePresence as y}from"motion/react";import{jsx as e,jsxs as k}from"react/jsx-runtime";var B=({debug:A,children:o,duration:C=m.duration,ease:L=m.ease,onAnimationComplete:E})=>{let t=p.useId(),d=p.useRef(o),$=T(o,100),f=p.useRef(null),[I,M]=p.useState("auto"),s={duration:C,ease:L},S=d.current;p.useEffect(()=>{d.current=$},[$]),p.useEffect(()=>{if(f.current){let u=new ResizeObserver(a=>{let r=a[0]?.contentRect.width;r&&M(r)});return u.observe(f.current),()=>{u.disconnect()}}return()=>{}},[]);let i=v(S,o),x=i?o.indexOf(i):0,g=i?x+i.length:0,b=o.slice(0,x),h=o.slice(g),P="0.125em",l=(u,a,r)=>e(c.span,{style:n.span,layout:"position",layoutId:`${t}-${a}`,exit:{opacity:0,scale:.95},transition:s,onAnimationComplete:E,children:e(y,{initial:r!==.5,mode:"popLayout",children:e(c.span,{style:n.span,initial:{x:r===0||r===1?P:0,opacity:0,scale:.95},animate:{x:0,opacity:1,scale:1},transition:{...s,delay:(s.duration??m.duration)*.2},children:a},`${t}-${u}-${a}`)})},`${t}-${a}`),R={width:I};return e(c.span,{style:{...n.container,...A?n.debug:{}},initial:R,animate:R,transition:s,children:e("span",{ref:f,style:n.span,children:e(y,{initial:!1,mode:"popLayout",children:e(c.span,{layoutId:`${t}-torph`,layout:"position",transition:s,style:n.span,children:k(y,{initial:!1,mode:"popLayout",children:[b&&l(`${t}-prefix`,b,0),i&&e(c.span,{layout:"position",layoutId:`${t}-lcs`,transition:s,style:{...n.span},children:l(`${t}-lcs-chars`,i,.5)}),h&&l(`${t}-suffix`,h,1)]})},`${t}-torph`)})})})};export{B as a};
|
|
3
|
+
//# sourceMappingURL=chunk-SZ3JXWX5.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/text-morph/index.tsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\n\nimport { motion, AnimatePresence, Transition } from \"motion/react\";\nimport styles from \"./styles\";\n\nimport { TextMorphProps } from \"./types\";\nimport defaultConfig from \"../../config\";\nimport { findLCS } from \"../../utils\";\n\nimport useDebounce from \"../../hooks/useDebounce\";\n\nexport const TextMorph = ({\n debug,\n children,\n //fontSize,\n //fontWeight,\n duration = defaultConfig.duration,\n ease = defaultConfig.ease,\n // respectMotionPreference = defaultConfig.respectMotionPreference,\n onAnimationComplete,\n}: TextMorphProps) => {\n const id = React.useId();\n const previousRef = React.useRef(children);\n const debounceChildren = useDebounce(children, 100);\n const containerRef = React.useRef<HTMLSpanElement>(null);\n const [width, setWidth] = React.useState<number | \"auto\">(\"auto\");\n\n const transition: Transition = {\n duration,\n ease,\n };\n\n const previous = previousRef.current;\n React.useEffect(() => {\n previousRef.current = debounceChildren;\n }, [debounceChildren]);\n\n React.useEffect(() => {\n if (containerRef.current) {\n const resizeObserver = new ResizeObserver((entries) => {\n const observedWidth = entries[0]?.contentRect.width;\n if (observedWidth) setWidth(observedWidth);\n });\n\n resizeObserver.observe(containerRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }\n return () => {};\n }, []);\n\n const lcs = findLCS(previous, children);\n const prefixEnd = lcs ? children.indexOf(lcs) : 0;\n const suffixStart = lcs ? prefixEnd + lcs.length : 0;\n\n const prefix = children.slice(0, prefixEnd);\n const suffix = children.slice(suffixStart);\n\n const shiftDistance = \"0.125em\";\n\n const renderChars = (key: string, text: string, originX: number) => (\n <motion.span\n style={styles.span}\n key={`${id}-${text}`}\n layout=\"position\"\n layoutId={`${id}-${text}`}\n exit={{\n opacity: 0,\n scale: 0.95,\n }}\n transition={transition}\n onAnimationComplete={onAnimationComplete}\n >\n <AnimatePresence initial={originX !== 0.5} mode=\"popLayout\">\n <motion.span\n style={styles.span}\n key={`${id}-${key}-${text}`}\n initial={{\n x:\n originX === 0 ? shiftDistance : originX === 1 ? shiftDistance : 0,\n opacity: 0,\n scale: 0.95,\n }}\n animate={{\n x: 0,\n opacity: 1,\n scale: 1,\n }}\n transition={{\n ...transition,\n delay: (transition.duration ?? defaultConfig.duration) * 0.2,\n }}\n >\n {text}\n </motion.span>\n </AnimatePresence>\n </motion.span>\n );\n\n const animationProps = {\n width,\n //fontSize: fontSize ? `${fontSize}px` : undefined,\n //fontWeight: fontWeight ? fontWeight : undefined,\n //fontVariationSettings: fontWeight ? `\"wght\" ${fontWeight}` : undefined,\n };\n\n return (\n <motion.span\n style={{ ...styles.container, ...(debug ? styles.debug : {}) }}\n initial={animationProps}\n animate={animationProps}\n transition={transition}\n >\n <span ref={containerRef} style={styles.span}>\n <AnimatePresence initial={false} mode=\"popLayout\">\n <motion.span\n key={`${id}-torph`}\n layoutId={`${id}-torph`}\n layout=\"position\"\n transition={transition}\n style={styles.span}\n >\n <AnimatePresence initial={false} mode=\"popLayout\">\n {prefix && renderChars(`${id}-prefix`, prefix, 0)}\n {lcs && (\n <motion.span\n layout=\"position\"\n layoutId={`${id}-lcs`}\n transition={transition}\n style={{ ...styles.span }}\n >\n {renderChars(`${id}-lcs-chars`, lcs, 0.5)}\n </motion.span>\n )}\n {suffix && renderChars(`${id}-suffix`, suffix, 1)}\n </AnimatePresence>\n </motion.span>\n </AnimatePresence>\n </span>\n </motion.span>\n );\n};\n"],"mappings":"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","names":["React","motion","AnimatePresence","jsx","jsxs","TextMorph","debug","children","duration","config_default","ease","onAnimationComplete","id","React","previousRef","debounceChildren","useDebounce_default","containerRef","width","setWidth","transition","previous","resizeObserver","entries","observedWidth","lcs","findLCS","prefixEnd","suffixStart","prefix","suffix","shiftDistance","renderChars","key","text","originX","motion","styles_default","AnimatePresence","animationProps"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/text-morph/styles.ts"],"sourcesContent":["const styles: { [key: string]: React.CSSProperties } = {\n container: {\n position: \"relative\",\n display: \"inline-flex\",\n },\n span: {\n position: \"relative\",\n display: \"inline-flex\",\n whiteSpace: \"pre\",\n },\n debug: {\n outline: \"1px solid red\",\n },\n};\n\nexport default styles;\n"],"mappings":";AAAA,IAAMA,EAAiD,CACrD,UAAW,CACT,SAAU,WACV,QAAS,aACX,EACA,KAAM,CACJ,SAAU,WACV,QAAS,cACT,WAAY,KACd,EACA,MAAO,CACL,QAAS,eACX,CACF,EAEOC,EAAQD","names":["styles","styles_default"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { TextMorphProps } from './types.mjs';
|
|
3
|
+
import 'motion';
|
|
4
|
+
|
|
5
|
+
declare const TextMorph: ({ debug, children, duration, ease, onAnimationComplete, }: TextMorphProps) => react_jsx_runtime.JSX.Element;
|
|
6
|
+
|
|
7
|
+
export { TextMorph };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { TextMorphProps } from './types.js';
|
|
3
|
+
import 'motion';
|
|
4
|
+
|
|
5
|
+
declare const TextMorph: ({ debug, children, duration, ease, onAnimationComplete, }: TextMorphProps) => react_jsx_runtime.JSX.Element;
|
|
6
|
+
|
|
7
|
+
export { TextMorph };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";"use client";var O=Object.create;var b=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,W=Object.prototype.hasOwnProperty;var H=(t,e)=>{for(var n in e)b(t,n,{get:e[n],enumerable:!0})},A=(t,e,n,c)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of N(e))!W.call(t,o)&&o!==n&&b(t,o,{get:()=>e[o],enumerable:!(c=z(e,o))||c.enumerable});return t};var L=(t,e,n)=>(n=t!=null?O(V(t)):{},A(e||!t||!t.__esModule?b(n,"default",{value:t,enumerable:!0}):n,t)),j=t=>A(b({},"__esModule",{value:!0}),t);var J={};H(J,{TextMorph:()=>G});module.exports=j(J);var l=L(require("react")),p=require("motion/react");var q={container:{position:"relative",display:"inline-flex"},span:{position:"relative",display:"inline-flex",whiteSpace:"pre"},debug:{outline:"1px solid red"}},u=q;var B={duration:.4,ease:[.19,1,.22,1],respectMotionPreference:!0},g=B;var v=(t,e)=>{let n=t.length,c=e.length,o=Array.from({length:n+1},()=>Array(c+1).fill(0)),s=0,f=0;for(let i=1;i<=n;i+=1)for(let r=1;r<=c;r+=1)t[i-1]===e[r-1]&&(o[i][r]=o[i-1][r-1]+1,o[i][r]>s&&(s=o[i][r],f=i));return t.substring(f-s,f)};var T=L(require("react")),F=(t,e)=>{let[n,c]=T.default.useState(t);return T.default.useEffect(()=>{let o=setTimeout(()=>{c(t)},e);return()=>{clearTimeout(o)}},[t,e]),n},D=F;var a=require("react/jsx-runtime"),G=({debug:t,children:e,duration:n=g.duration,ease:c=g.ease,onAnimationComplete:o})=>{let s=l.default.useId(),f=l.default.useRef(e),i=D(e,100),r=l.default.useRef(null),[E,I]=l.default.useState("auto"),m={duration:n,ease:c},k=f.current;l.default.useEffect(()=>{f.current=i},[i]),l.default.useEffect(()=>{if(r.current){let h=new ResizeObserver(y=>{let x=y[0]?.contentRect.width;x&&I(x)});return h.observe(r.current),()=>{h.disconnect()}}return()=>{}},[]);let d=v(k,e),$=d?e.indexOf(d):0,w=d?$+d.length:0,M=e.slice(0,$),R=e.slice(w),S="0.125em",P=(h,y,x)=>(0,a.jsx)(p.motion.span,{style:u.span,layout:"position",layoutId:`${s}-${y}`,exit:{opacity:0,scale:.95},transition:m,onAnimationComplete:o,children:(0,a.jsx)(p.AnimatePresence,{initial:x!==.5,mode:"popLayout",children:(0,a.jsx)(p.motion.span,{style:u.span,initial:{x:x===0||x===1?S:0,opacity:0,scale:.95},animate:{x:0,opacity:1,scale:1},transition:{...m,delay:(m.duration??g.duration)*.2},children:y},`${s}-${h}-${y}`)})},`${s}-${y}`),C={width:E};return(0,a.jsx)(p.motion.span,{style:{...u.container,...t?u.debug:{}},initial:C,animate:C,transition:m,children:(0,a.jsx)("span",{ref:r,style:u.span,children:(0,a.jsx)(p.AnimatePresence,{initial:!1,mode:"popLayout",children:(0,a.jsx)(p.motion.span,{layoutId:`${s}-torph`,layout:"position",transition:m,style:u.span,children:(0,a.jsxs)(p.AnimatePresence,{initial:!1,mode:"popLayout",children:[M&&P(`${s}-prefix`,M,0),d&&(0,a.jsx)(p.motion.span,{layout:"position",layoutId:`${s}-lcs`,transition:m,style:{...u.span},children:P(`${s}-lcs-chars`,d,.5)}),R&&P(`${s}-suffix`,R,1)]})},`${s}-torph`)})})})};0&&(module.exports={TextMorph});
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/text-morph/index.tsx","../../../src/components/text-morph/styles.ts","../../../src/config.ts","../../../src/utils.ts","../../../src/hooks/useDebounce.ts"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\n\nimport { motion, AnimatePresence, Transition } from \"motion/react\";\nimport styles from \"./styles\";\n\nimport { TextMorphProps } from \"./types\";\nimport defaultConfig from \"../../config\";\nimport { findLCS } from \"../../utils\";\n\nimport useDebounce from \"../../hooks/useDebounce\";\n\nexport const TextMorph = ({\n debug,\n children,\n //fontSize,\n //fontWeight,\n duration = defaultConfig.duration,\n ease = defaultConfig.ease,\n // respectMotionPreference = defaultConfig.respectMotionPreference,\n onAnimationComplete,\n}: TextMorphProps) => {\n const id = React.useId();\n const previousRef = React.useRef(children);\n const debounceChildren = useDebounce(children, 100);\n const containerRef = React.useRef<HTMLSpanElement>(null);\n const [width, setWidth] = React.useState<number | \"auto\">(\"auto\");\n\n const transition: Transition = {\n duration,\n ease,\n };\n\n const previous = previousRef.current;\n React.useEffect(() => {\n previousRef.current = debounceChildren;\n }, [debounceChildren]);\n\n React.useEffect(() => {\n if (containerRef.current) {\n const resizeObserver = new ResizeObserver((entries) => {\n const observedWidth = entries[0]?.contentRect.width;\n if (observedWidth) setWidth(observedWidth);\n });\n\n resizeObserver.observe(containerRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }\n return () => {};\n }, []);\n\n const lcs = findLCS(previous, children);\n const prefixEnd = lcs ? children.indexOf(lcs) : 0;\n const suffixStart = lcs ? prefixEnd + lcs.length : 0;\n\n const prefix = children.slice(0, prefixEnd);\n const suffix = children.slice(suffixStart);\n\n const shiftDistance = \"0.125em\";\n\n const renderChars = (key: string, text: string, originX: number) => (\n <motion.span\n style={styles.span}\n key={`${id}-${text}`}\n layout=\"position\"\n layoutId={`${id}-${text}`}\n exit={{\n opacity: 0,\n scale: 0.95,\n }}\n transition={transition}\n onAnimationComplete={onAnimationComplete}\n >\n <AnimatePresence initial={originX !== 0.5} mode=\"popLayout\">\n <motion.span\n style={styles.span}\n key={`${id}-${key}-${text}`}\n initial={{\n x:\n originX === 0 ? shiftDistance : originX === 1 ? shiftDistance : 0,\n opacity: 0,\n scale: 0.95,\n }}\n animate={{\n x: 0,\n opacity: 1,\n scale: 1,\n }}\n transition={{\n ...transition,\n delay: (transition.duration ?? defaultConfig.duration) * 0.2,\n }}\n >\n {text}\n </motion.span>\n </AnimatePresence>\n </motion.span>\n );\n\n const animationProps = {\n width,\n //fontSize: fontSize ? `${fontSize}px` : undefined,\n //fontWeight: fontWeight ? fontWeight : undefined,\n //fontVariationSettings: fontWeight ? `\"wght\" ${fontWeight}` : undefined,\n };\n\n return (\n <motion.span\n style={{ ...styles.container, ...(debug ? styles.debug : {}) }}\n initial={animationProps}\n animate={animationProps}\n transition={transition}\n >\n <span ref={containerRef} style={styles.span}>\n <AnimatePresence initial={false} mode=\"popLayout\">\n <motion.span\n key={`${id}-torph`}\n layoutId={`${id}-torph`}\n layout=\"position\"\n transition={transition}\n style={styles.span}\n >\n <AnimatePresence initial={false} mode=\"popLayout\">\n {prefix && renderChars(`${id}-prefix`, prefix, 0)}\n {lcs && (\n <motion.span\n layout=\"position\"\n layoutId={`${id}-lcs`}\n transition={transition}\n style={{ ...styles.span }}\n >\n {renderChars(`${id}-lcs-chars`, lcs, 0.5)}\n </motion.span>\n )}\n {suffix && renderChars(`${id}-suffix`, suffix, 1)}\n </AnimatePresence>\n </motion.span>\n </AnimatePresence>\n </span>\n </motion.span>\n );\n};\n","const styles: { [key: string]: React.CSSProperties } = {\n container: {\n position: \"relative\",\n display: \"inline-flex\",\n },\n span: {\n position: \"relative\",\n display: \"inline-flex\",\n whiteSpace: \"pre\",\n },\n debug: {\n outline: \"1px solid red\",\n },\n};\n\nexport default styles;\n","import { TextMorphProps } from \"./components/text-morph/types\";\n\ntype DefaultTextMorphProps = Omit<TextMorphProps, \"duration\" | \"children\"> & {\n duration: NonNullable<TextMorphProps[\"duration\"]>;\n children?: TextMorphProps[\"children\"];\n};\n\nconst defaultConfig: DefaultTextMorphProps = {\n duration: 0.4,\n ease: [0.19, 1, 0.22, 1],\n respectMotionPreference: true,\n};\n\nexport default defaultConfig;\n","export const findLCS = (a: string, b: string): string => {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array(n + 1).fill(0),\n );\n let maxLength = 0;\n let endIndex = 0;\n\n for (let i = 1; i <= m; i += 1) {\n for (let j = 1; j <= n; j += 1) {\n if (a[i - 1] === b[j - 1]) {\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n dp[i][j] = dp[i - 1][j - 1] + 1;\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n if (dp[i][j] > maxLength) {\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n maxLength = dp[i][j];\n endIndex = i;\n }\n }\n }\n }\n return a.substring(endIndex - maxLength, endIndex);\n};\n\nexport const debug = false;\n","import React from \"react\";\n\nconst useDebounce = (value: string, delay: number) => {\n const [debouncedValue, setDebouncedValue] = React.useState(value);\n\n React.useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n};\n\nexport default useDebounce;\n"],"mappings":"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","names":["text_morph_exports","__export","TextMorph","__toCommonJS","import_react","styles","styles_default","defaultConfig","config_default","findLCS","a","b","m","n","dp","maxLength","endIndex","j","import_react","useDebounce","value","delay","debouncedValue","setDebouncedValue","React","handler","useDebounce_default","import_jsx_runtime","TextMorph","debug","children","duration","config_default","ease","onAnimationComplete","id","React","previousRef","debounceChildren","useDebounce_default","containerRef","width","setWidth","transition","previous","resizeObserver","entries","observedWidth","lcs","findLCS","prefixEnd","suffixStart","prefix","suffix","shiftDistance","renderChars","key","text","originX","styles_default","animationProps"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";var n=Object.defineProperty;var o=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var a=Object.prototype.hasOwnProperty;var r=(i,e)=>{for(var l in e)n(i,l,{get:e[l],enumerable:!0})},d=(i,e,l,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of p(e))!a.call(i,t)&&t!==l&&n(i,t,{get:()=>e[t],enumerable:!(s=o(e,t))||s.enumerable});return i};var c=i=>d(n({},"__esModule",{value:!0}),i);var f={};r(f,{default:()=>y});module.exports=c(f);var x={container:{position:"relative",display:"inline-flex"},span:{position:"relative",display:"inline-flex",whiteSpace:"pre"},debug:{outline:"1px solid red"}},y=x;
|
|
3
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/text-morph/styles.ts"],"sourcesContent":["const styles: { [key: string]: React.CSSProperties } = {\n container: {\n position: \"relative\",\n display: \"inline-flex\",\n },\n span: {\n position: \"relative\",\n display: \"inline-flex\",\n whiteSpace: \"pre\",\n },\n debug: {\n outline: \"1px solid red\",\n },\n};\n\nexport default styles;\n"],"mappings":";yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAMI,EAAiD,CACrD,UAAW,CACT,SAAU,WACV,QAAS,aACX,EACA,KAAM,CACJ,SAAU,WACV,QAAS,cACT,WAAY,KACd,EACA,MAAO,CACL,QAAS,eACX,CACF,EAEOF,EAAQE","names":["styles_exports","__export","styles_default","__toCommonJS","styles"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Transition } from 'motion';
|
|
2
|
+
|
|
3
|
+
interface TextMorphProps {
|
|
4
|
+
debug?: boolean;
|
|
5
|
+
children: string;
|
|
6
|
+
duration?: Transition["duration"];
|
|
7
|
+
ease?: Transition["ease"];
|
|
8
|
+
respectMotionPreference?: boolean;
|
|
9
|
+
onAnimationComplete?: () => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type { TextMorphProps };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Transition } from 'motion';
|
|
2
|
+
|
|
3
|
+
interface TextMorphProps {
|
|
4
|
+
debug?: boolean;
|
|
5
|
+
children: string;
|
|
6
|
+
duration?: Transition["duration"];
|
|
7
|
+
ease?: Transition["ease"];
|
|
8
|
+
respectMotionPreference?: boolean;
|
|
9
|
+
onAnimationComplete?: () => void;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type { TextMorphProps };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";var r=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var d=(o,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of s(e))!p.call(o,n)&&n!==t&&r(o,n,{get:()=>e[n],enumerable:!(i=a(e,n))||i.enumerable});return o};var c=o=>d(r({},"__esModule",{value:!0}),o);var l={};module.exports=c(l);
|
|
3
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/text-morph/types.ts"],"sourcesContent":["import { Transition } from \"motion\";\n\nexport interface TextMorphProps {\n debug?: boolean;\n children: string; // TODO: support ReactNode\n //fontSize?: number; // potentially supported in future\n //fontWeight?: number; // potentially supported in future\n duration?: Transition[\"duration\"];\n ease?: Transition[\"ease\"];\n respectMotionPreference?: boolean;\n onAnimationComplete?: () => void;\n}\n"],"mappings":";+WAAA,IAAAA,EAAA,kBAAAC,EAAAD","names":["types_exports","__toCommonJS"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TextMorphProps } from './components/text-morph/types.mjs';
|
|
2
|
+
import 'motion';
|
|
3
|
+
|
|
4
|
+
type DefaultTextMorphProps = Omit<TextMorphProps, "duration" | "children"> & {
|
|
5
|
+
duration: NonNullable<TextMorphProps["duration"]>;
|
|
6
|
+
children?: TextMorphProps["children"];
|
|
7
|
+
};
|
|
8
|
+
declare const defaultConfig: DefaultTextMorphProps;
|
|
9
|
+
|
|
10
|
+
export { defaultConfig as default };
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TextMorphProps } from './components/text-morph/types.js';
|
|
2
|
+
import 'motion';
|
|
3
|
+
|
|
4
|
+
type DefaultTextMorphProps = Omit<TextMorphProps, "duration" | "children"> & {
|
|
5
|
+
duration: NonNullable<TextMorphProps["duration"]>;
|
|
6
|
+
children?: TextMorphProps["children"];
|
|
7
|
+
};
|
|
8
|
+
declare const defaultConfig: DefaultTextMorphProps;
|
|
9
|
+
|
|
10
|
+
export { defaultConfig as default };
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";var p=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var a=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var u=(e,r)=>{for(var t in r)p(e,t,{get:r[t],enumerable:!0})},d=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of a(r))!l.call(e,o)&&o!==t&&p(e,o,{get:()=>r[o],enumerable:!(n=i(r,o))||n.enumerable});return e};var h=e=>d(p({},"__esModule",{value:!0}),e);var x={};u(x,{default:()=>f});module.exports=h(x);var s={duration:.4,ease:[.19,1,.22,1],respectMotionPreference:!0},f=s;
|
|
3
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts"],"sourcesContent":["import { TextMorphProps } from \"./components/text-morph/types\";\n\ntype DefaultTextMorphProps = Omit<TextMorphProps, \"duration\" | \"children\"> & {\n duration: NonNullable<TextMorphProps[\"duration\"]>;\n children?: TextMorphProps[\"children\"];\n};\n\nconst defaultConfig: DefaultTextMorphProps = {\n duration: 0.4,\n ease: [0.19, 1, 0.22, 1],\n respectMotionPreference: true,\n};\n\nexport default defaultConfig;\n"],"mappings":";yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,IAAA,eAAAC,EAAAH,GAOA,IAAMI,EAAuC,CAC3C,SAAU,GACV,KAAM,CAAC,IAAM,EAAG,IAAM,CAAC,EACvB,wBAAyB,EAC3B,EAEOF,EAAQE","names":["config_exports","__export","config_default","__toCommonJS","defaultConfig"]}
|
package/dist/config.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";var m=Object.create;var r=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,f=Object.prototype.hasOwnProperty;var i=(e,t)=>{for(var u in t)r(e,u,{get:t[u],enumerable:!0})},s=(e,t,u,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of b(t))!f.call(e,n)&&n!==u&&r(e,n,{get:()=>t[n],enumerable:!(o=a(t,n))||o.enumerable});return e};var l=(e,t,u)=>(u=e!=null?m(d(e)):{},s(t||!e||!e.__esModule?r(u,"default",{value:e,enumerable:!0}):u,e)),p=e=>s(r({},"__esModule",{value:!0}),e);var V={};i(V,{default:()=>T});module.exports=p(V);var c=l(require("react")),D=(e,t)=>{let[u,o]=c.default.useState(e);return c.default.useEffect(()=>{let n=setTimeout(()=>{o(e)},t);return()=>{clearTimeout(n)}},[e,t]),u},T=D;
|
|
3
|
+
//# sourceMappingURL=useDebounce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useDebounce.ts"],"sourcesContent":["import React from \"react\";\n\nconst useDebounce = (value: string, delay: number) => {\n const [debouncedValue, setDebouncedValue] = React.useState(value);\n\n React.useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n};\n\nexport default useDebounce;\n"],"mappings":";0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAkB,oBAEZC,EAAc,CAACC,EAAeC,IAAkB,CACpD,GAAM,CAACC,EAAgBC,CAAiB,EAAI,EAAAC,QAAM,SAASJ,CAAK,EAEhE,SAAAI,QAAM,UAAU,IAAM,CACpB,IAAMC,EAAU,WAAW,IAAM,CAC/BF,EAAkBH,CAAK,CACzB,EAAGC,CAAK,EAER,MAAO,IAAM,CACX,aAAaI,CAAO,CACtB,CACF,EAAG,CAACL,EAAOC,CAAK,CAAC,EAEVC,CACT,EAEON,EAAQG","names":["useDebounce_exports","__export","useDebounce_default","__toCommonJS","import_react","useDebounce","value","delay","debouncedValue","setDebouncedValue","React","handler"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.d.mts
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";var q=Object.create;var g=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var V=Object.getPrototypeOf,W=Object.prototype.hasOwnProperty;var H=(t,e)=>{for(var n in e)g(t,n,{get:e[n],enumerable:!0})},C=(t,e,n,c)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of N(e))!W.call(t,i)&&i!==n&&g(t,i,{get:()=>e[i],enumerable:!(c=z(e,i))||c.enumerable});return t};var S=(t,e,n)=>(n=t!=null?q(V(t)):{},C(e||!t||!t.__esModule?g(n,"default",{value:t,enumerable:!0}):n,t)),B=t=>C(g({},"__esModule",{value:!0}),t);var Q={};H(Q,{TextMorph:()=>k,version:()=>D});module.exports=B(Q);var D="0.0.1";var u=S(require("react")),a=require("motion/react");var G={container:{position:"relative",display:"inline-flex"},span:{position:"relative",display:"inline-flex",whiteSpace:"pre"},debug:{outline:"1px solid red"}},l=G;var J={duration:.4,ease:[.19,1,.22,1],respectMotionPreference:!0},b=J;var L=(t,e)=>{let n=t.length,c=e.length,i=Array.from({length:n+1},()=>Array(c+1).fill(0)),s=0,d=0;for(let o=1;o<=n;o+=1)for(let r=1;r<=c;r+=1)t[o-1]===e[r-1]&&(i[o][r]=i[o-1][r-1]+1,i[o][r]>s&&(s=i[o][r],d=o));return t.substring(d-s,d)};var P=S(require("react")),K=(t,e)=>{let[n,c]=P.default.useState(t);return P.default.useEffect(()=>{let i=setTimeout(()=>{c(t)},e);return()=>{clearTimeout(i)}},[t,e]),n},j=K;var p=require("react/jsx-runtime"),k=({debug:t,children:e,duration:n=b.duration,ease:c=b.ease,onAnimationComplete:i})=>{let s=u.default.useId(),d=u.default.useRef(e),o=j(e,100),r=u.default.useRef(null),[w,I]=u.default.useState("auto"),m={duration:n,ease:c},E=d.current;u.default.useEffect(()=>{d.current=o},[o]),u.default.useEffect(()=>{if(r.current){let y=new ResizeObserver(x=>{let h=x[0]?.contentRect.width;h&&I(h)});return y.observe(r.current),()=>{y.disconnect()}}return()=>{}},[]);let f=L(E,e),M=f?e.indexOf(f):0,O=f?M+f.length:0,$=e.slice(0,M),v=e.slice(O),R="0.125em",T=(y,x,h)=>(0,p.jsx)(a.motion.span,{style:l.span,layout:"position",layoutId:`${s}-${x}`,exit:{opacity:0,scale:.95},transition:m,onAnimationComplete:i,children:(0,p.jsx)(a.AnimatePresence,{initial:h!==.5,mode:"popLayout",children:(0,p.jsx)(a.motion.span,{style:l.span,initial:{x:h===0||h===1?R:0,opacity:0,scale:.95},animate:{x:0,opacity:1,scale:1},transition:{...m,delay:(m.duration??b.duration)*.2},children:x},`${s}-${y}-${x}`)})},`${s}-${x}`),A={width:w};return(0,p.jsx)(a.motion.span,{style:{...l.container,...t?l.debug:{}},initial:A,animate:A,transition:m,children:(0,p.jsx)("span",{ref:r,style:l.span,children:(0,p.jsx)(a.AnimatePresence,{initial:!1,mode:"popLayout",children:(0,p.jsx)(a.motion.span,{layoutId:`${s}-torph`,layout:"position",transition:m,style:l.span,children:(0,p.jsxs)(a.AnimatePresence,{initial:!1,mode:"popLayout",children:[$&&T(`${s}-prefix`,$,0),f&&(0,p.jsx)(a.motion.span,{layout:"position",layoutId:`${s}-lcs`,transition:m,style:{...l.span},children:T(`${s}-lcs-chars`,f,.5)}),v&&T(`${s}-suffix`,v,1)]})},`${s}-torph`)})})})};0&&(module.exports={TextMorph,version});
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../package.json","../src/components/text-morph/index.tsx","../src/components/text-morph/styles.ts","../src/config.ts","../src/utils.ts","../src/hooks/useDebounce.ts"],"sourcesContent":["export { version } from \"./../package.json\";\n\nexport { TextMorph } from \"./components/text-morph\";\nexport { TextMorphProps } from \"./components/text-morph/types\";\n","{\n \"name\": \"torph\",\n \"version\": \"0.0.1\",\n \"description\": \"An animated text component for React.\",\n \"author\": \"Lochie Axon\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/lochie/torph.git\",\n \"directory\": \"packages/torph\"\n },\n \"types\": \"dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\"\n },\n \"./*\": {\n \"import\": \"./dist/components/*/index.mjs\",\n \"require\": \"./dist/components/*/index.js\",\n \"types\": \"./dist/components/*/index.d.ts\"\n }\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"eslint -c .eslintrc.cjs ./src/**/*.{ts,tsx}\",\n \"lint:fix\": \"eslint --fix -c .eslintrc.cjs ./src/**/*.{ts,tsx}\",\n \"pre-commit\": \"lint-staged\"\n },\n \"keywords\": [\n \"react\",\n \"text\",\n \"animation\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/lochie/torph/issues\"\n },\n \"files\": [\n \"dist/*\"\n ],\n \"peerDependencies\": {\n \"react\": \">=18\",\n \"react-dom\": \">=18\"\n },\n \"devDependencies\": {\n \"@types/react\": \"^18.2.15\",\n \"@typescript-eslint/eslint-plugin\": \"^6.8.0\",\n \"@typescript-eslint/parser\": \"^6.8.0\",\n \"eslint\": \"^9.36.0\",\n \"eslint-config-airbnb\": \"^19.0.4\",\n \"eslint-config-airbnb-typescript\": \"^17.1.0\",\n \"eslint-config-prettier\": \"^9.0.0\",\n \"eslint-plugin-import\": \"^2.28.1\",\n \"eslint-plugin-jsx-a11y\": \"^6.7.1\",\n \"eslint-plugin-prettier\": \"^5.0.1\",\n \"eslint-plugin-react\": \"^7.33.2\",\n \"eslint-plugin-react-hooks\": \"^4.6.0\",\n \"prettier\": \"^3.0.3\",\n \"react\": \"^18.2.0\",\n \"react-dom\": \"^18.2.0\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.0.2\"\n },\n \"dependencies\": {\n \"motion\": \"^12.23.16\"\n }\n}\n","\"use client\";\n\nimport React from \"react\";\n\nimport { motion, AnimatePresence, Transition } from \"motion/react\";\nimport styles from \"./styles\";\n\nimport { TextMorphProps } from \"./types\";\nimport defaultConfig from \"../../config\";\nimport { findLCS } from \"../../utils\";\n\nimport useDebounce from \"../../hooks/useDebounce\";\n\nexport const TextMorph = ({\n debug,\n children,\n //fontSize,\n //fontWeight,\n duration = defaultConfig.duration,\n ease = defaultConfig.ease,\n // respectMotionPreference = defaultConfig.respectMotionPreference,\n onAnimationComplete,\n}: TextMorphProps) => {\n const id = React.useId();\n const previousRef = React.useRef(children);\n const debounceChildren = useDebounce(children, 100);\n const containerRef = React.useRef<HTMLSpanElement>(null);\n const [width, setWidth] = React.useState<number | \"auto\">(\"auto\");\n\n const transition: Transition = {\n duration,\n ease,\n };\n\n const previous = previousRef.current;\n React.useEffect(() => {\n previousRef.current = debounceChildren;\n }, [debounceChildren]);\n\n React.useEffect(() => {\n if (containerRef.current) {\n const resizeObserver = new ResizeObserver((entries) => {\n const observedWidth = entries[0]?.contentRect.width;\n if (observedWidth) setWidth(observedWidth);\n });\n\n resizeObserver.observe(containerRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }\n return () => {};\n }, []);\n\n const lcs = findLCS(previous, children);\n const prefixEnd = lcs ? children.indexOf(lcs) : 0;\n const suffixStart = lcs ? prefixEnd + lcs.length : 0;\n\n const prefix = children.slice(0, prefixEnd);\n const suffix = children.slice(suffixStart);\n\n const shiftDistance = \"0.125em\";\n\n const renderChars = (key: string, text: string, originX: number) => (\n <motion.span\n style={styles.span}\n key={`${id}-${text}`}\n layout=\"position\"\n layoutId={`${id}-${text}`}\n exit={{\n opacity: 0,\n scale: 0.95,\n }}\n transition={transition}\n onAnimationComplete={onAnimationComplete}\n >\n <AnimatePresence initial={originX !== 0.5} mode=\"popLayout\">\n <motion.span\n style={styles.span}\n key={`${id}-${key}-${text}`}\n initial={{\n x:\n originX === 0 ? shiftDistance : originX === 1 ? shiftDistance : 0,\n opacity: 0,\n scale: 0.95,\n }}\n animate={{\n x: 0,\n opacity: 1,\n scale: 1,\n }}\n transition={{\n ...transition,\n delay: (transition.duration ?? defaultConfig.duration) * 0.2,\n }}\n >\n {text}\n </motion.span>\n </AnimatePresence>\n </motion.span>\n );\n\n const animationProps = {\n width,\n //fontSize: fontSize ? `${fontSize}px` : undefined,\n //fontWeight: fontWeight ? fontWeight : undefined,\n //fontVariationSettings: fontWeight ? `\"wght\" ${fontWeight}` : undefined,\n };\n\n return (\n <motion.span\n style={{ ...styles.container, ...(debug ? styles.debug : {}) }}\n initial={animationProps}\n animate={animationProps}\n transition={transition}\n >\n <span ref={containerRef} style={styles.span}>\n <AnimatePresence initial={false} mode=\"popLayout\">\n <motion.span\n key={`${id}-torph`}\n layoutId={`${id}-torph`}\n layout=\"position\"\n transition={transition}\n style={styles.span}\n >\n <AnimatePresence initial={false} mode=\"popLayout\">\n {prefix && renderChars(`${id}-prefix`, prefix, 0)}\n {lcs && (\n <motion.span\n layout=\"position\"\n layoutId={`${id}-lcs`}\n transition={transition}\n style={{ ...styles.span }}\n >\n {renderChars(`${id}-lcs-chars`, lcs, 0.5)}\n </motion.span>\n )}\n {suffix && renderChars(`${id}-suffix`, suffix, 1)}\n </AnimatePresence>\n </motion.span>\n </AnimatePresence>\n </span>\n </motion.span>\n );\n};\n","const styles: { [key: string]: React.CSSProperties } = {\n container: {\n position: \"relative\",\n display: \"inline-flex\",\n },\n span: {\n position: \"relative\",\n display: \"inline-flex\",\n whiteSpace: \"pre\",\n },\n debug: {\n outline: \"1px solid red\",\n },\n};\n\nexport default styles;\n","import { TextMorphProps } from \"./components/text-morph/types\";\n\ntype DefaultTextMorphProps = Omit<TextMorphProps, \"duration\" | \"children\"> & {\n duration: NonNullable<TextMorphProps[\"duration\"]>;\n children?: TextMorphProps[\"children\"];\n};\n\nconst defaultConfig: DefaultTextMorphProps = {\n duration: 0.4,\n ease: [0.19, 1, 0.22, 1],\n respectMotionPreference: true,\n};\n\nexport default defaultConfig;\n","export const findLCS = (a: string, b: string): string => {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array(n + 1).fill(0),\n );\n let maxLength = 0;\n let endIndex = 0;\n\n for (let i = 1; i <= m; i += 1) {\n for (let j = 1; j <= n; j += 1) {\n if (a[i - 1] === b[j - 1]) {\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n dp[i][j] = dp[i - 1][j - 1] + 1;\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n if (dp[i][j] > maxLength) {\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n maxLength = dp[i][j];\n endIndex = i;\n }\n }\n }\n }\n return a.substring(endIndex - maxLength, endIndex);\n};\n\nexport const debug = false;\n","import React from \"react\";\n\nconst useDebounce = (value: string, delay: number) => {\n const [debouncedValue, setDebouncedValue] = React.useState(value);\n\n React.useEffect(() => {\n const handler = setTimeout(() => {\n setDebouncedValue(value);\n }, delay);\n\n return () => {\n clearTimeout(handler);\n };\n }, [value, delay]);\n\n return debouncedValue;\n};\n\nexport default useDebounce;\n"],"mappings":"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","names":["index_exports","__export","TextMorph","version","__toCommonJS","version","import_react","styles","styles_default","defaultConfig","config_default","findLCS","a","b","m","n","dp","maxLength","endIndex","i","j","import_react","useDebounce","value","delay","debouncedValue","setDebouncedValue","React","handler","useDebounce_default","import_jsx_runtime","TextMorph","debug","children","duration","config_default","ease","onAnimationComplete","id","React","previousRef","debounceChildren","useDebounce_default","containerRef","width","setWidth","transition","previous","resizeObserver","entries","observedWidth","lcs","findLCS","prefixEnd","suffixStart","prefix","suffix","shiftDistance","renderChars","key","text","originX","styles_default","animationProps"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import{a as t}from"./chunk-SZ3JXWX5.mjs";import"./chunk-I42X5RZV.mjs";import"./chunk-66KQLHAM.mjs";import"./chunk-2RJBUJEF.mjs";import"./chunk-Y6MZSIYO.mjs";import"./chunk-RM2STLUA.mjs";var i="0.0.1";export{t as TextMorph,i as version};
|
|
3
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"torph\",\n \"version\": \"0.0.1\",\n \"description\": \"An animated text component for React.\",\n \"author\": \"Lochie Axon\",\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/lochie/torph.git\",\n \"directory\": \"packages/torph\"\n },\n \"types\": \"dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\"\n },\n \"./*\": {\n \"import\": \"./dist/components/*/index.mjs\",\n \"require\": \"./dist/components/*/index.js\",\n \"types\": \"./dist/components/*/index.d.ts\"\n }\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"lint\": \"eslint -c .eslintrc.cjs ./src/**/*.{ts,tsx}\",\n \"lint:fix\": \"eslint --fix -c .eslintrc.cjs ./src/**/*.{ts,tsx}\",\n \"pre-commit\": \"lint-staged\"\n },\n \"keywords\": [\n \"react\",\n \"text\",\n \"animation\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/lochie/torph/issues\"\n },\n \"files\": [\n \"dist/*\"\n ],\n \"peerDependencies\": {\n \"react\": \">=18\",\n \"react-dom\": \">=18\"\n },\n \"devDependencies\": {\n \"@types/react\": \"^18.2.15\",\n \"@typescript-eslint/eslint-plugin\": \"^6.8.0\",\n \"@typescript-eslint/parser\": \"^6.8.0\",\n \"eslint\": \"^9.36.0\",\n \"eslint-config-airbnb\": \"^19.0.4\",\n \"eslint-config-airbnb-typescript\": \"^17.1.0\",\n \"eslint-config-prettier\": \"^9.0.0\",\n \"eslint-plugin-import\": \"^2.28.1\",\n \"eslint-plugin-jsx-a11y\": \"^6.7.1\",\n \"eslint-plugin-prettier\": \"^5.0.1\",\n \"eslint-plugin-react\": \"^7.33.2\",\n \"eslint-plugin-react-hooks\": \"^4.6.0\",\n \"prettier\": \"^3.0.3\",\n \"react\": \"^18.2.0\",\n \"react-dom\": \"^18.2.0\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.0.2\"\n },\n \"dependencies\": {\n \"motion\": \"^12.23.16\"\n }\n}\n"],"mappings":";0LAEE,IAAAA,EAAW","names":["version"]}
|
package/dist/utils.d.mts
ADDED
package/dist/utils.d.ts
ADDED
package/dist/utils.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";var f=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var m=(n,t)=>{for(var s in t)f(n,s,{get:t[s],enumerable:!0})},u=(n,t,s,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of d(t))!h.call(n,e)&&e!==s&&f(n,e,{get:()=>t[e],enumerable:!(o=c(t,e))||o.enumerable});return n};var x=n=>u(f({},"__esModule",{value:!0}),n);var b={};m(b,{debug:()=>a,findLCS:()=>p});module.exports=x(b);var p=(n,t)=>{let s=n.length,o=t.length,e=Array.from({length:s+1},()=>Array(o+1).fill(0)),g=0,i=0;for(let r=1;r<=s;r+=1)for(let l=1;l<=o;l+=1)n[r-1]===t[l-1]&&(e[r][l]=e[r-1][l-1]+1,e[r][l]>g&&(g=e[r][l],i=r));return n.substring(i-g,i)},a=!1;0&&(module.exports={debug,findLCS});
|
|
3
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts"],"sourcesContent":["export const findLCS = (a: string, b: string): string => {\n const m = a.length;\n const n = b.length;\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array(n + 1).fill(0),\n );\n let maxLength = 0;\n let endIndex = 0;\n\n for (let i = 1; i <= m; i += 1) {\n for (let j = 1; j <= n; j += 1) {\n if (a[i - 1] === b[j - 1]) {\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n dp[i][j] = dp[i - 1][j - 1] + 1;\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n if (dp[i][j] > maxLength) {\n // @ts-expect-error Property 'dp' does not exist on type 'number[][]'.\n maxLength = dp[i][j];\n endIndex = i;\n }\n }\n }\n }\n return a.substring(endIndex - maxLength, endIndex);\n};\n\nexport const debug = false;\n"],"mappings":";yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,WAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GAAO,IAAMG,EAAU,CAACE,EAAWC,IAAsB,CACvD,IAAMC,EAAIF,EAAE,OACNG,EAAIF,EAAE,OACNG,EAAiB,MAAM,KAAK,CAAE,OAAQF,EAAI,CAAE,EAAG,IACnD,MAAMC,EAAI,CAAC,EAAE,KAAK,CAAC,CACrB,EACIE,EAAY,EACZC,EAAW,EAEf,QAASC,EAAI,EAAGA,GAAKL,EAAGK,GAAK,EAC3B,QAASC,EAAI,EAAGA,GAAKL,EAAGK,GAAK,EACvBR,EAAEO,EAAI,CAAC,IAAMN,EAAEO,EAAI,CAAC,IAEtBJ,EAAGG,CAAC,EAAEC,CAAC,EAAIJ,EAAGG,EAAI,CAAC,EAAEC,EAAI,CAAC,EAAI,EAE1BJ,EAAGG,CAAC,EAAEC,CAAC,EAAIH,IAEbA,EAAYD,EAAGG,CAAC,EAAEC,CAAC,EACnBF,EAAWC,IAKnB,OAAOP,EAAE,UAAUM,EAAWD,EAAWC,CAAQ,CACnD,EAEaT,EAAQ","names":["utils_exports","__export","debug","findLCS","__toCommonJS","a","b","m","n","dp","maxLength","endIndex","i","j"]}
|
package/dist/utils.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "torph",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "An animated text component for React.",
|
|
5
|
+
"author": "Lochie Axon",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/lochie/torph.git",
|
|
10
|
+
"directory": "packages/torph"
|
|
11
|
+
},
|
|
12
|
+
"types": "dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./dist/index.mjs",
|
|
16
|
+
"require": "./dist/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./*": {
|
|
19
|
+
"import": "./dist/components/*/index.mjs",
|
|
20
|
+
"require": "./dist/components/*/index.js",
|
|
21
|
+
"types": "./dist/components/*/index.d.ts"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"react",
|
|
29
|
+
"text",
|
|
30
|
+
"animation"
|
|
31
|
+
],
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/lochie/torph/issues"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist/*"
|
|
37
|
+
],
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": ">=18",
|
|
40
|
+
"react-dom": ">=18"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/react": "^18.2.15",
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "^6.8.0",
|
|
45
|
+
"@typescript-eslint/parser": "^6.8.0",
|
|
46
|
+
"eslint": "^9.36.0",
|
|
47
|
+
"eslint-config-airbnb": "^19.0.4",
|
|
48
|
+
"eslint-config-airbnb-typescript": "^17.1.0",
|
|
49
|
+
"eslint-config-prettier": "^9.0.0",
|
|
50
|
+
"eslint-plugin-import": "^2.28.1",
|
|
51
|
+
"eslint-plugin-jsx-a11y": "^6.7.1",
|
|
52
|
+
"eslint-plugin-prettier": "^5.0.1",
|
|
53
|
+
"eslint-plugin-react": "^7.33.2",
|
|
54
|
+
"eslint-plugin-react-hooks": "^4.6.0",
|
|
55
|
+
"prettier": "^3.0.3",
|
|
56
|
+
"react": "^18.2.0",
|
|
57
|
+
"react-dom": "^18.2.0",
|
|
58
|
+
"tsup": "^8.5.0",
|
|
59
|
+
"typescript": "^5.0.2"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"motion": "^12.23.16"
|
|
63
|
+
},
|
|
64
|
+
"scripts": {
|
|
65
|
+
"build": "tsup",
|
|
66
|
+
"dev": "tsup --watch",
|
|
67
|
+
"lint": "eslint -c .eslintrc.cjs ./src/**/*.{ts,tsx}",
|
|
68
|
+
"lint:fix": "eslint --fix -c .eslintrc.cjs ./src/**/*.{ts,tsx}",
|
|
69
|
+
"pre-commit": "lint-staged"
|
|
70
|
+
}
|
|
71
|
+
}
|