torph 0.0.5 → 0.0.7
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 +34 -8
- package/dist/.DS_Store +0 -0
- package/dist/TextMorph-LC6RO5C5.vue +65 -0
- package/dist/index.d.mts +30 -13
- package/dist/index.d.ts +30 -13
- package/dist/index.js +8 -11
- package/dist/index.mjs +23 -3
- package/dist/react/index.d.mts +22 -3
- package/dist/react/index.d.ts +22 -3
- package/dist/react/index.js +8 -11
- package/dist/react/index.mjs +23 -3
- package/dist/svelte/index.d.mts +19 -1
- package/dist/svelte/index.d.ts +28 -0
- package/dist/svelte/index.js +1 -2
- package/dist/svelte/index.mjs +1 -2
- package/dist/vue/index.d.mts +28 -0
- package/dist/vue/index.d.ts +28 -0
- package/dist/vue/index.js +1 -2
- package/dist/vue/index.mjs +1 -2
- package/package.json +15 -5
- package/dist/TextMorph-N26F7N56.vue +0 -54
- package/dist/chunk-5MHVW5FX.mjs +0 -26
- package/dist/chunk-5MHVW5FX.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/react/index.js.map +0 -1
- package/dist/react/index.mjs.map +0 -1
- package/dist/svelte/index.js.map +0 -1
- package/dist/svelte/index.mjs.map +0 -1
- package/dist/types-CnPojgn6.d.mts +0 -14
- package/dist/types-CnPojgn6.d.ts +0 -14
- package/dist/vue/index.js.map +0 -1
- package/dist/vue/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Torph
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Dependency-free animated text morphing component for React, Vue, Svelte, and vanilla JavaScript.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -89,7 +89,7 @@ const handleComplete = () => {
|
|
|
89
89
|
<script>
|
|
90
90
|
import { TextMorph } from 'torph/svelte';
|
|
91
91
|
|
|
92
|
-
let text = 'Hello World';
|
|
92
|
+
let text = $state('Hello World');
|
|
93
93
|
|
|
94
94
|
const handleComplete = () => {
|
|
95
95
|
console.log('Animation done!');
|
|
@@ -124,6 +124,31 @@ const morph = new TextMorph({
|
|
|
124
124
|
morph.update("Hello World");
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
+
## Spring Animations
|
|
128
|
+
|
|
129
|
+
Pass spring parameters to `ease` for physics-based easing. The duration is computed automatically from the spring physics.
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
import { TextMorph } from "torph/react";
|
|
133
|
+
|
|
134
|
+
function App() {
|
|
135
|
+
const [text, setText] = useState("Hello World");
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<TextMorph ease={{ stiffness: 200, damping: 20 }}>{text}</TextMorph>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Spring Parameters
|
|
144
|
+
|
|
145
|
+
| Parameter | Type | Default | Description |
|
|
146
|
+
| ----------- | -------- | ------- | ----------------------------------------- |
|
|
147
|
+
| `stiffness` | `number` | `100` | Spring stiffness coefficient |
|
|
148
|
+
| `damping` | `number` | `10` | Damping coefficient |
|
|
149
|
+
| `mass` | `number` | `1` | Mass of the spring |
|
|
150
|
+
| `precision` | `number` | `0.001` | Threshold for determining settled position |
|
|
151
|
+
|
|
127
152
|
## API
|
|
128
153
|
|
|
129
154
|
### Options
|
|
@@ -131,17 +156,18 @@ morph.update("Hello World");
|
|
|
131
156
|
All components accept the following props/options:
|
|
132
157
|
|
|
133
158
|
- `text` / `children: string` - The text to display (required)
|
|
134
|
-
- `duration?: number` - Animation duration in milliseconds (default: 400)
|
|
135
|
-
- `ease?: string` - CSS easing function (default: "cubic-bezier(0.19, 1, 0.22, 1)")
|
|
136
|
-
- `
|
|
159
|
+
- `duration?: number` - Animation duration in milliseconds (default: `400`)
|
|
160
|
+
- `ease?: string | SpringParams` - CSS easing function or spring parameters (default: `"cubic-bezier(0.19, 1, 0.22, 1)"`)
|
|
161
|
+
- `scale?: boolean` - Enable scale animation on exiting segments (default: `true`)
|
|
162
|
+
- `locale?: Intl.LocalesArgument` - Locale for text segmentation (default: `"en"`)
|
|
137
163
|
- `debug?: boolean` - Enable debug mode with visual indicators
|
|
138
|
-
- `disabled?: boolean` - Disable all morphing animations (default: false)
|
|
139
|
-
- `respectReducedMotion?: boolean` - Respect user's prefers-reduced-motion setting (default: true)
|
|
164
|
+
- `disabled?: boolean` - Disable all morphing animations (default: `false`)
|
|
165
|
+
- `respectReducedMotion?: boolean` - Respect user's prefers-reduced-motion setting (default: `true`)
|
|
140
166
|
- `onAnimationStart?: () => void` - Callback fired when animation begins
|
|
141
167
|
- `onAnimationComplete?: () => void` - Callback fired when animation completes
|
|
142
168
|
- `className?: string` - CSS class name (React/Vue: `class`)
|
|
143
169
|
- `style?: object | string` - Inline styles
|
|
144
|
-
- `as?: string` - HTML element type (default: "
|
|
170
|
+
- `as?: string` - HTML element type (default: `"span"`)
|
|
145
171
|
|
|
146
172
|
## Found this useful?
|
|
147
173
|
|
package/dist/.DS_Store
CHANGED
|
Binary file
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<component
|
|
3
|
+
:is="as"
|
|
4
|
+
ref="containerRef"
|
|
5
|
+
:class="props.class"
|
|
6
|
+
:style="props.style"
|
|
7
|
+
></component>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup lang="ts">
|
|
11
|
+
import { ref, computed, onUnmounted, watch } from "vue";
|
|
12
|
+
import {
|
|
13
|
+
DEFAULT_AS,
|
|
14
|
+
DEFAULT_TEXT_MORPH_OPTIONS,
|
|
15
|
+
} from "../lib/text-morph";
|
|
16
|
+
import { MorphController } from "../lib/text-morph/controller";
|
|
17
|
+
import type { TextMorphProps } from "./types";
|
|
18
|
+
|
|
19
|
+
const props = withDefaults(defineProps<TextMorphProps>(), {
|
|
20
|
+
locale: DEFAULT_TEXT_MORPH_OPTIONS.locale,
|
|
21
|
+
duration: DEFAULT_TEXT_MORPH_OPTIONS.duration,
|
|
22
|
+
ease: DEFAULT_TEXT_MORPH_OPTIONS.ease,
|
|
23
|
+
scale: DEFAULT_TEXT_MORPH_OPTIONS.scale,
|
|
24
|
+
disabled: DEFAULT_TEXT_MORPH_OPTIONS.disabled,
|
|
25
|
+
respectReducedMotion: DEFAULT_TEXT_MORPH_OPTIONS.respectReducedMotion,
|
|
26
|
+
as: DEFAULT_AS,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const containerRef = ref<HTMLElement | null>(null);
|
|
30
|
+
const controller = new MorphController();
|
|
31
|
+
|
|
32
|
+
const configKey = computed(() =>
|
|
33
|
+
MorphController.serializeConfig(props),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
function createInstance() {
|
|
37
|
+
if (containerRef.value) {
|
|
38
|
+
controller.attach(containerRef.value, {
|
|
39
|
+
locale: props.locale,
|
|
40
|
+
duration: props.duration,
|
|
41
|
+
ease: props.ease,
|
|
42
|
+
debug: props.debug,
|
|
43
|
+
scale: props.scale,
|
|
44
|
+
disabled: props.disabled,
|
|
45
|
+
respectReducedMotion: props.respectReducedMotion,
|
|
46
|
+
onAnimationStart: props.onAnimationStart,
|
|
47
|
+
onAnimationComplete: props.onAnimationComplete,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
watch(containerRef, () => createInstance(), { flush: "post" });
|
|
53
|
+
watch(configKey, () => createInstance());
|
|
54
|
+
|
|
55
|
+
onUnmounted(() => {
|
|
56
|
+
controller.destroy();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
watch(
|
|
60
|
+
() => props.text,
|
|
61
|
+
(newText) => {
|
|
62
|
+
controller.update(newText);
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
</script>
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
interface SpringParams {
|
|
2
|
+
stiffness?: number;
|
|
3
|
+
damping?: number;
|
|
4
|
+
mass?: number;
|
|
5
|
+
precision?: number;
|
|
6
|
+
}
|
|
2
7
|
|
|
3
|
-
|
|
8
|
+
interface TextMorphOptions {
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
element: HTMLElement;
|
|
11
|
+
locale?: Intl.LocalesArgument;
|
|
12
|
+
scale?: boolean;
|
|
13
|
+
duration?: number;
|
|
14
|
+
ease?: string | SpringParams;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
respectReducedMotion?: boolean;
|
|
17
|
+
onAnimationStart?: () => void;
|
|
18
|
+
onAnimationComplete?: () => void;
|
|
19
|
+
}
|
|
4
20
|
|
|
21
|
+
declare const DEFAULT_AS = "span";
|
|
22
|
+
declare const DEFAULT_TEXT_MORPH_OPTIONS: {
|
|
23
|
+
readonly debug: false;
|
|
24
|
+
readonly locale: "en";
|
|
25
|
+
readonly duration: 400;
|
|
26
|
+
readonly scale: true;
|
|
27
|
+
readonly ease: "cubic-bezier(0.19, 1, 0.22, 1)";
|
|
28
|
+
readonly disabled: false;
|
|
29
|
+
readonly respectReducedMotion: true;
|
|
30
|
+
};
|
|
5
31
|
declare class TextMorph {
|
|
6
32
|
private element;
|
|
7
33
|
private options;
|
|
@@ -9,22 +35,13 @@ declare class TextMorph {
|
|
|
9
35
|
private currentMeasures;
|
|
10
36
|
private prevMeasures;
|
|
11
37
|
private isInitialRender;
|
|
12
|
-
private
|
|
13
|
-
private mediaQuery?;
|
|
14
|
-
static styleEl: HTMLStyleElement;
|
|
38
|
+
private reducedMotion;
|
|
15
39
|
constructor(options: TextMorphOptions);
|
|
16
40
|
destroy(): void;
|
|
17
|
-
private handleMediaQueryChange;
|
|
18
41
|
private isDisabled;
|
|
19
42
|
update(value: HTMLElement | string): void;
|
|
20
43
|
private createTextGroup;
|
|
21
|
-
private measure;
|
|
22
44
|
private updateStyles;
|
|
23
|
-
private addStyles;
|
|
24
|
-
private removeStyles;
|
|
25
|
-
private blocks;
|
|
26
|
-
private blocksFallback;
|
|
27
|
-
private log;
|
|
28
45
|
}
|
|
29
46
|
|
|
30
|
-
export { TextMorph, TextMorphOptions
|
|
47
|
+
export { DEFAULT_AS, DEFAULT_TEXT_MORPH_OPTIONS, type SpringParams, TextMorph, type TextMorphOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
interface SpringParams {
|
|
2
|
+
stiffness?: number;
|
|
3
|
+
damping?: number;
|
|
4
|
+
mass?: number;
|
|
5
|
+
precision?: number;
|
|
6
|
+
}
|
|
2
7
|
|
|
3
|
-
|
|
8
|
+
interface TextMorphOptions {
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
element: HTMLElement;
|
|
11
|
+
locale?: Intl.LocalesArgument;
|
|
12
|
+
scale?: boolean;
|
|
13
|
+
duration?: number;
|
|
14
|
+
ease?: string | SpringParams;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
respectReducedMotion?: boolean;
|
|
17
|
+
onAnimationStart?: () => void;
|
|
18
|
+
onAnimationComplete?: () => void;
|
|
19
|
+
}
|
|
4
20
|
|
|
21
|
+
declare const DEFAULT_AS = "span";
|
|
22
|
+
declare const DEFAULT_TEXT_MORPH_OPTIONS: {
|
|
23
|
+
readonly debug: false;
|
|
24
|
+
readonly locale: "en";
|
|
25
|
+
readonly duration: 400;
|
|
26
|
+
readonly scale: true;
|
|
27
|
+
readonly ease: "cubic-bezier(0.19, 1, 0.22, 1)";
|
|
28
|
+
readonly disabled: false;
|
|
29
|
+
readonly respectReducedMotion: true;
|
|
30
|
+
};
|
|
5
31
|
declare class TextMorph {
|
|
6
32
|
private element;
|
|
7
33
|
private options;
|
|
@@ -9,22 +35,13 @@ declare class TextMorph {
|
|
|
9
35
|
private currentMeasures;
|
|
10
36
|
private prevMeasures;
|
|
11
37
|
private isInitialRender;
|
|
12
|
-
private
|
|
13
|
-
private mediaQuery?;
|
|
14
|
-
static styleEl: HTMLStyleElement;
|
|
38
|
+
private reducedMotion;
|
|
15
39
|
constructor(options: TextMorphOptions);
|
|
16
40
|
destroy(): void;
|
|
17
|
-
private handleMediaQueryChange;
|
|
18
41
|
private isDisabled;
|
|
19
42
|
update(value: HTMLElement | string): void;
|
|
20
43
|
private createTextGroup;
|
|
21
|
-
private measure;
|
|
22
44
|
private updateStyles;
|
|
23
|
-
private addStyles;
|
|
24
|
-
private removeStyles;
|
|
25
|
-
private blocks;
|
|
26
|
-
private blocksFallback;
|
|
27
|
-
private log;
|
|
28
45
|
}
|
|
29
46
|
|
|
30
|
-
export { TextMorph, TextMorphOptions
|
|
47
|
+
export { DEFAULT_AS, DEFAULT_TEXT_MORPH_OPTIONS, type SpringParams, TextMorph, type TextMorphOptions };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
[torph-root] {
|
|
1
|
+
'use strict';function $(n,e,t){if(t<1){let u=e*Math.sqrt(1-t*t);return 1-Math.exp(-t*e*n)*(Math.cos(u*n)+t*e/u*Math.sin(u*n))}let i=Math.sqrt(t*t-1),s=-e*(t+i),r=-e*(t-i),o=-s/(r-s);return 1-(1-o)*Math.exp(s*n)-o*Math.exp(r*n)}function B(n,e,t){let r=0;for(let o=0;o<10;o+=.001)if(Math.abs($(o,n,e)-1)>t)r=0;else if(r+=.001,r>.1)return Math.ceil((o-r+.001)*1e3);return Math.ceil(10*1e3)}var I=new Map;function D(n){let{stiffness:e=100,damping:t=10,mass:i=1,precision:s=.001}=n??{},r=`${e}:${t}:${i}:${s}`,o=I.get(r);if(o)return o;let a=Math.sqrt(e/i),u=t/(2*Math.sqrt(e*i)),m=B(a,u,s),c=Math.min(100,Math.max(32,Math.round(m/15))),l=[];for(let g=0;g<c;g++){let b=g/(c-1)*(m/1e3),E=g===c-1?1:$(b,a,u);l.push(Math.round(E*1e4)/1e4+"");}for(;l.length>2&&l[l.length-2]==="1";)l.splice(l.length-2,1);let p={easing:`linear(${l.join(", ")})`,duration:m};return I.set(r,p),p}function H(n,e){let t=n.includes(" ");if(typeof Intl.Segmenter<"u"){let s=new Intl.Segmenter(e,{granularity:t?"word":"grapheme"}).segment(n)[Symbol.iterator]();return j(s)}return Y(n,t)}function j(n){return Array.from(n).reduce((e,t)=>t.segment===" "?[...e,{id:`space-${t.index}`,string:"\xA0"}]:e.find(s=>s.string===t.segment)?[...e,{id:`${t.segment}-${t.index}`,string:t.segment}]:[...e,{id:t.segment,string:t.segment}],[])}function q(n,e,t){let i=n.find(s=>s.string===e);n.push(i?{id:`${e}-${t}`,string:e}:{id:e,string:e});}function Y(n,e){let t=e?n.split(" "):n.split(""),i=[];return t.forEach((s,r)=>{e&&r>0&&i.push({id:`space-${r}`,string:"\xA0"}),q(i,s,r);}),i}var y="torph-root",T="torph-item",f="torph-id",d="torph-exiting",M="torph-debug";function A(n){let e=Array.from(n.children),t={};return e.forEach((i,s)=>{if(i.hasAttribute(d))return;let r=i.getAttribute(f)||`child-${s}`;t[r]={x:i.offsetLeft,y:i.offsetTop};}),t}function S(n,e,t){let i=n[t],s=e[t];return !i||!s?{dx:0,dy:0}:{dx:i.x-s.x,dy:i.y-s.y}}function w(n,e,t,i="backward-first"){let[s,r]=i==="backward-first"?["backward","forward"]:["forward","backward"],o=a=>{if(a==="backward"){for(let u=n-1;u>=0;u--)if(t.has(e[u]))return e[u]}else for(let u=n+1;u<e.length;u++)if(t.has(e[u]))return e[u];return null};return o(s)??o(r)}function _(n,e,t,i){let s=new Set(t.filter((o,a)=>i.has(o)&&!e.has(n[a]))),r=new Map;for(let o=0;o<n.length;o++){let a=n[o];e.has(a)&&r.set(a,w(o,t,s,"forward-first"));}return r}function O(n,e){return Math.min(n*e,150)}function R(n){let e=getComputedStyle(n).transform;if(!e||e==="none")return {tx:0,ty:0};let t=e.match(/matrix\(([^)]+)\)/);if(!t)return {tx:0,ty:0};let i=t[1].split(",").map(Number);return {tx:i[4]||0,ty:i[5]||0}}function Q(n){let{tx:e,ty:t}=R(n),i=Number(getComputedStyle(n).opacity)||1;return n.getAnimations().forEach(s=>s.cancel()),{tx:e,ty:t,opacity:i}}function N(n,e){let{dx:t,dy:i,duration:s,ease:r,scale:o}=e;n.animate({transform:o?`translate(${t}px, ${i}px) scale(0.95)`:`translate(${t}px, ${i}px)`,offset:1},{duration:s,easing:r,fill:"both"});let a=n.animate({opacity:0,offset:1},{duration:O(s,.25),easing:"linear",fill:"both"});a.onfinish=()=>n.remove();}function C(n,e){let{deltaX:t,deltaY:i,isNew:s,duration:r,ease:o}=e,a=Q(n),u=t+a.tx,m=i+a.ty;n.animate({transform:`translate(${u}px, ${m}px) scale(${s?.95:1})`,offset:0},{duration:r,easing:o,fill:"both"});let c=s&&a.opacity>=1?0:a.opacity;c<1&&n.animate([{opacity:c},{opacity:1}],{duration:O(r,s?.5:.25),easing:"linear",fill:"both"});}var x=null;function k(n,e,t,i,s){if(x&&(x(),x=null),e===0||t===0)return;n.style.width="auto",n.style.height="auto",n.offsetWidth;let r=n.offsetWidth,o=n.offsetHeight;n.style.width=`${e}px`,n.style.height=`${t}px`,n.offsetWidth,n.style.width=`${r}px`,n.style.height=`${o}px`;function a(){n.removeEventListener("transitionend",u),clearTimeout(m),x=null,n.style.width="auto",n.style.height="auto",s?.();}function u(c){c.target===n&&(c.propertyName!=="width"&&c.propertyName!=="height"||a());}n.addEventListener("transitionend",u);let m=setTimeout(a,i+50);x=()=>{n.removeEventListener("transitionend",u),clearTimeout(m),x=null;};}function F(n){let e=n.map(t=>{let{tx:i,ty:s}=R(t),r=Number(getComputedStyle(t).opacity)||1;return t.getAnimations().forEach(o=>o.cancel()),{left:t.offsetLeft+i,top:t.offsetTop+s,width:t.offsetWidth,height:t.offsetHeight,opacity:r}});n.forEach((t,i)=>{let s=e[i];t.setAttribute(d,""),t.style.position="absolute",t.style.pointerEvents="none",t.style.left=`${s.left}px`,t.style.top=`${s.top}px`,t.style.width=`${s.width}px`,t.style.height=`${s.height}px`,t.style.opacity=String(s.opacity);});}function P(n,e,t,i){let s=new Map;e.forEach(r=>{let o=r.getAttribute(f);t.has(o)&&!r.hasAttribute(d)&&(s.set(o,r),r.remove());}),Array.from(n.childNodes).forEach(r=>{r.nodeType===Node.TEXT_NODE&&r.remove();}),i.forEach(r=>{let o=s.get(r.id);if(o)o.textContent=r.string,n.appendChild(o);else {let a=document.createElement("span");a.setAttribute(T,""),a.setAttribute(f,r.id),a.textContent=r.string,n.appendChild(a);}});}var K=`
|
|
2
|
+
[${y}] {
|
|
4
3
|
display: inline-flex;
|
|
5
4
|
position: relative;
|
|
6
5
|
will-change: width, height;
|
|
@@ -8,19 +7,17 @@
|
|
|
8
7
|
white-space: nowrap;
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
[
|
|
10
|
+
[${T}] {
|
|
12
11
|
display: inline-block;
|
|
13
12
|
will-change: opacity, transform;
|
|
14
13
|
transform: none;
|
|
15
14
|
opacity: 1;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
[
|
|
19
|
-
outline:2px solid magenta;
|
|
20
|
-
[
|
|
21
|
-
outline:2px solid cyan;
|
|
17
|
+
[${y}][${M}] {
|
|
18
|
+
outline: 2px solid magenta;
|
|
19
|
+
[${T}] {
|
|
20
|
+
outline: 2px solid cyan;
|
|
22
21
|
outline-offset: -4px;
|
|
23
22
|
}
|
|
24
|
-
}
|
|
25
|
-
`,document.head.appendChild(t),d.styleEl=t}removeStyles(){d.styleEl&&(d.styleEl.remove(),d.styleEl=void 0)}blocks(t){return Array.from(t).reduce((o,e)=>e.segment===" "?[...o,{id:`space-${e.index}`,string:"\xA0"}]:o.find(p=>p.string===e.segment)?[...o,{id:`${e.segment}-${e.index}`,string:e.segment}]:[...o,{id:e.segment,string:e.segment}],[])}blocksFallback(t,i){let o=i?t.split(" "):t.split(""),e=[];return i?o.forEach((a,p)=>{p>0&&e.push({id:`space-${p}`,string:"\xA0"}),e.find(u=>u.string===a)?e.push({id:`${a}-${p}`,string:a}):e.push({id:a,string:a})}):o.forEach((a,p)=>{e.find(u=>u.string===a)?e.push({id:`${a}-${p}`,string:a}):e.push({id:a,string:a})}),e}log(...t){this.options.debug&&console.log("[TextMorph]",...t)}};0&&(module.exports={TextMorph,version});
|
|
26
|
-
//# sourceMappingURL=index.js.map
|
|
23
|
+
}`,h=null,v=0;function X(){v++,!h&&(h=document.createElement("style"),h.dataset.torph="true",h.textContent=K,document.head.appendChild(h));}function G(){v--,!(v>0||!h)&&(h.remove(),h=null);}function U(){if(typeof window>"u")return {prefersReducedMotion:false,destroy:()=>{}};let n=window.matchMedia("(prefers-reduced-motion: reduce)"),e={prefersReducedMotion:n.matches,destroy:i};function t(s){e.prefersReducedMotion=s.matches;}function i(){n.removeEventListener("change",t);}return n.addEventListener("change",t),e}var J="span",W={debug:false,locale:"en",duration:400,scale:true,ease:"cubic-bezier(0.19, 1, 0.22, 1)",disabled:false,respectReducedMotion:true},L=class{element;options={};data;currentMeasures={};prevMeasures={};isInitialRender=true;reducedMotion=null;constructor(e){let{ease:t,...i}={...W,...e},s,r;if(typeof t=="object"){let o=D(t);s=o.easing,r=o.duration;}else s=t,r=i.duration;this.options={...i,ease:s,duration:r},this.element=e.element,this.options.respectReducedMotion&&(this.reducedMotion=U()),this.isDisabled()||(this.element.setAttribute(y,""),this.element.style.transitionDuration=`${this.options.duration}ms`,this.element.style.transitionTimingFunction=this.options.ease,e.debug&&this.element.setAttribute(M,"")),this.data="",this.isDisabled()||X();}destroy(){this.reducedMotion?.destroy(),this.element.getAnimations().forEach(e=>e.cancel()),this.element.removeAttribute(y),this.element.removeAttribute(M),G();}isDisabled(){return !!(this.options.disabled||this.reducedMotion?.prefersReducedMotion)}update(e){if(e!==this.data){if(this.data=e,this.isDisabled()){typeof e=="string"&&(this.element.textContent=e);return}if(this.data instanceof HTMLElement)throw new Error("HTMLElement not yet supported");this.options.onAnimationStart&&!this.isInitialRender&&this.options.onAnimationStart(),this.createTextGroup(this.data,this.element);}}createTextGroup(e,t){let i=t.offsetWidth,s=t.offsetHeight,r=H(e,this.options.locale);this.prevMeasures=A(this.element);let o=Array.from(t.children),a=new Set(r.map(p=>p.id)),u=o.filter(p=>!a.has(p.getAttribute(f))&&!p.hasAttribute(d)),m=new Set(u),c=o.map(p=>p.getAttribute(f)),l=_(o,m,c,a);if(F(u),P(t,o,a,r),this.currentMeasures=A(this.element),this.updateStyles(r),u.forEach(p=>{if(this.isInitialRender){p.remove();return}let g=l.get(p),{dx:b,dy:E}=g?S(this.currentMeasures,this.prevMeasures,g):{dx:0,dy:0};N(p,{dx:b,dy:E,duration:this.options.duration,ease:this.options.ease,scale:this.options.scale});}),this.isInitialRender){this.isInitialRender=false,t.style.width="auto",t.style.height="auto";return}k(t,i,s,this.options.duration,this.options.onAnimationComplete);}updateStyles(e){if(this.isInitialRender)return;let t=Array.from(this.element.children),i=e.map(r=>r.id),s=new Set(i.filter(r=>this.prevMeasures[r]));t.forEach((r,o)=>{if(r.hasAttribute(d))return;let a=r.getAttribute(f)||`child-${o}`,u=!this.prevMeasures[a],m=u?w(e.findIndex(p=>p.id===a),i,s):a,{dx:c,dy:l}=m?S(this.prevMeasures,this.currentMeasures,m):{dx:0,dy:0};C(r,{deltaX:c,deltaY:l,isNew:u,duration:this.options.duration,ease:this.options.ease});});}};exports.DEFAULT_AS=J;exports.DEFAULT_TEXT_MORPH_OPTIONS=W;exports.TextMorph=L;
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
-
"
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
function $(n,e,t){if(t<1){let u=e*Math.sqrt(1-t*t);return 1-Math.exp(-t*e*n)*(Math.cos(u*n)+t*e/u*Math.sin(u*n))}let i=Math.sqrt(t*t-1),s=-e*(t+i),r=-e*(t-i),o=-s/(r-s);return 1-(1-o)*Math.exp(s*n)-o*Math.exp(r*n)}function B(n,e,t){let r=0;for(let o=0;o<10;o+=.001)if(Math.abs($(o,n,e)-1)>t)r=0;else if(r+=.001,r>.1)return Math.ceil((o-r+.001)*1e3);return Math.ceil(10*1e3)}var I=new Map;function D(n){let{stiffness:e=100,damping:t=10,mass:i=1,precision:s=.001}=n??{},r=`${e}:${t}:${i}:${s}`,o=I.get(r);if(o)return o;let a=Math.sqrt(e/i),u=t/(2*Math.sqrt(e*i)),m=B(a,u,s),c=Math.min(100,Math.max(32,Math.round(m/15))),l=[];for(let g=0;g<c;g++){let b=g/(c-1)*(m/1e3),E=g===c-1?1:$(b,a,u);l.push(Math.round(E*1e4)/1e4+"");}for(;l.length>2&&l[l.length-2]==="1";)l.splice(l.length-2,1);let p={easing:`linear(${l.join(", ")})`,duration:m};return I.set(r,p),p}function H(n,e){let t=n.includes(" ");if(typeof Intl.Segmenter<"u"){let s=new Intl.Segmenter(e,{granularity:t?"word":"grapheme"}).segment(n)[Symbol.iterator]();return j(s)}return Y(n,t)}function j(n){return Array.from(n).reduce((e,t)=>t.segment===" "?[...e,{id:`space-${t.index}`,string:"\xA0"}]:e.find(s=>s.string===t.segment)?[...e,{id:`${t.segment}-${t.index}`,string:t.segment}]:[...e,{id:t.segment,string:t.segment}],[])}function q(n,e,t){let i=n.find(s=>s.string===e);n.push(i?{id:`${e}-${t}`,string:e}:{id:e,string:e});}function Y(n,e){let t=e?n.split(" "):n.split(""),i=[];return t.forEach((s,r)=>{e&&r>0&&i.push({id:`space-${r}`,string:"\xA0"}),q(i,s,r);}),i}var y="torph-root",T="torph-item",f="torph-id",d="torph-exiting",M="torph-debug";function A(n){let e=Array.from(n.children),t={};return e.forEach((i,s)=>{if(i.hasAttribute(d))return;let r=i.getAttribute(f)||`child-${s}`;t[r]={x:i.offsetLeft,y:i.offsetTop};}),t}function S(n,e,t){let i=n[t],s=e[t];return !i||!s?{dx:0,dy:0}:{dx:i.x-s.x,dy:i.y-s.y}}function w(n,e,t,i="backward-first"){let[s,r]=i==="backward-first"?["backward","forward"]:["forward","backward"],o=a=>{if(a==="backward"){for(let u=n-1;u>=0;u--)if(t.has(e[u]))return e[u]}else for(let u=n+1;u<e.length;u++)if(t.has(e[u]))return e[u];return null};return o(s)??o(r)}function _(n,e,t,i){let s=new Set(t.filter((o,a)=>i.has(o)&&!e.has(n[a]))),r=new Map;for(let o=0;o<n.length;o++){let a=n[o];e.has(a)&&r.set(a,w(o,t,s,"forward-first"));}return r}function O(n,e){return Math.min(n*e,150)}function R(n){let e=getComputedStyle(n).transform;if(!e||e==="none")return {tx:0,ty:0};let t=e.match(/matrix\(([^)]+)\)/);if(!t)return {tx:0,ty:0};let i=t[1].split(",").map(Number);return {tx:i[4]||0,ty:i[5]||0}}function Q(n){let{tx:e,ty:t}=R(n),i=Number(getComputedStyle(n).opacity)||1;return n.getAnimations().forEach(s=>s.cancel()),{tx:e,ty:t,opacity:i}}function N(n,e){let{dx:t,dy:i,duration:s,ease:r,scale:o}=e;n.animate({transform:o?`translate(${t}px, ${i}px) scale(0.95)`:`translate(${t}px, ${i}px)`,offset:1},{duration:s,easing:r,fill:"both"});let a=n.animate({opacity:0,offset:1},{duration:O(s,.25),easing:"linear",fill:"both"});a.onfinish=()=>n.remove();}function C(n,e){let{deltaX:t,deltaY:i,isNew:s,duration:r,ease:o}=e,a=Q(n),u=t+a.tx,m=i+a.ty;n.animate({transform:`translate(${u}px, ${m}px) scale(${s?.95:1})`,offset:0},{duration:r,easing:o,fill:"both"});let c=s&&a.opacity>=1?0:a.opacity;c<1&&n.animate([{opacity:c},{opacity:1}],{duration:O(r,s?.5:.25),easing:"linear",fill:"both"});}var x=null;function k(n,e,t,i,s){if(x&&(x(),x=null),e===0||t===0)return;n.style.width="auto",n.style.height="auto",n.offsetWidth;let r=n.offsetWidth,o=n.offsetHeight;n.style.width=`${e}px`,n.style.height=`${t}px`,n.offsetWidth,n.style.width=`${r}px`,n.style.height=`${o}px`;function a(){n.removeEventListener("transitionend",u),clearTimeout(m),x=null,n.style.width="auto",n.style.height="auto",s?.();}function u(c){c.target===n&&(c.propertyName!=="width"&&c.propertyName!=="height"||a());}n.addEventListener("transitionend",u);let m=setTimeout(a,i+50);x=()=>{n.removeEventListener("transitionend",u),clearTimeout(m),x=null;};}function F(n){let e=n.map(t=>{let{tx:i,ty:s}=R(t),r=Number(getComputedStyle(t).opacity)||1;return t.getAnimations().forEach(o=>o.cancel()),{left:t.offsetLeft+i,top:t.offsetTop+s,width:t.offsetWidth,height:t.offsetHeight,opacity:r}});n.forEach((t,i)=>{let s=e[i];t.setAttribute(d,""),t.style.position="absolute",t.style.pointerEvents="none",t.style.left=`${s.left}px`,t.style.top=`${s.top}px`,t.style.width=`${s.width}px`,t.style.height=`${s.height}px`,t.style.opacity=String(s.opacity);});}function P(n,e,t,i){let s=new Map;e.forEach(r=>{let o=r.getAttribute(f);t.has(o)&&!r.hasAttribute(d)&&(s.set(o,r),r.remove());}),Array.from(n.childNodes).forEach(r=>{r.nodeType===Node.TEXT_NODE&&r.remove();}),i.forEach(r=>{let o=s.get(r.id);if(o)o.textContent=r.string,n.appendChild(o);else {let a=document.createElement("span");a.setAttribute(T,""),a.setAttribute(f,r.id),a.textContent=r.string,n.appendChild(a);}});}var K=`
|
|
2
|
+
[${y}] {
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
position: relative;
|
|
5
|
+
will-change: width, height;
|
|
6
|
+
transition-property: width, height;
|
|
7
|
+
white-space: nowrap;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
[${T}] {
|
|
11
|
+
display: inline-block;
|
|
12
|
+
will-change: opacity, transform;
|
|
13
|
+
transform: none;
|
|
14
|
+
opacity: 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
[${y}][${M}] {
|
|
18
|
+
outline: 2px solid magenta;
|
|
19
|
+
[${T}] {
|
|
20
|
+
outline: 2px solid cyan;
|
|
21
|
+
outline-offset: -4px;
|
|
22
|
+
}
|
|
23
|
+
}`,h=null,v=0;function X(){v++,!h&&(h=document.createElement("style"),h.dataset.torph="true",h.textContent=K,document.head.appendChild(h));}function G(){v--,!(v>0||!h)&&(h.remove(),h=null);}function U(){if(typeof window>"u")return {prefersReducedMotion:false,destroy:()=>{}};let n=window.matchMedia("(prefers-reduced-motion: reduce)"),e={prefersReducedMotion:n.matches,destroy:i};function t(s){e.prefersReducedMotion=s.matches;}function i(){n.removeEventListener("change",t);}return n.addEventListener("change",t),e}var J="span",W={debug:false,locale:"en",duration:400,scale:true,ease:"cubic-bezier(0.19, 1, 0.22, 1)",disabled:false,respectReducedMotion:true},L=class{element;options={};data;currentMeasures={};prevMeasures={};isInitialRender=true;reducedMotion=null;constructor(e){let{ease:t,...i}={...W,...e},s,r;if(typeof t=="object"){let o=D(t);s=o.easing,r=o.duration;}else s=t,r=i.duration;this.options={...i,ease:s,duration:r},this.element=e.element,this.options.respectReducedMotion&&(this.reducedMotion=U()),this.isDisabled()||(this.element.setAttribute(y,""),this.element.style.transitionDuration=`${this.options.duration}ms`,this.element.style.transitionTimingFunction=this.options.ease,e.debug&&this.element.setAttribute(M,"")),this.data="",this.isDisabled()||X();}destroy(){this.reducedMotion?.destroy(),this.element.getAnimations().forEach(e=>e.cancel()),this.element.removeAttribute(y),this.element.removeAttribute(M),G();}isDisabled(){return !!(this.options.disabled||this.reducedMotion?.prefersReducedMotion)}update(e){if(e!==this.data){if(this.data=e,this.isDisabled()){typeof e=="string"&&(this.element.textContent=e);return}if(this.data instanceof HTMLElement)throw new Error("HTMLElement not yet supported");this.options.onAnimationStart&&!this.isInitialRender&&this.options.onAnimationStart(),this.createTextGroup(this.data,this.element);}}createTextGroup(e,t){let i=t.offsetWidth,s=t.offsetHeight,r=H(e,this.options.locale);this.prevMeasures=A(this.element);let o=Array.from(t.children),a=new Set(r.map(p=>p.id)),u=o.filter(p=>!a.has(p.getAttribute(f))&&!p.hasAttribute(d)),m=new Set(u),c=o.map(p=>p.getAttribute(f)),l=_(o,m,c,a);if(F(u),P(t,o,a,r),this.currentMeasures=A(this.element),this.updateStyles(r),u.forEach(p=>{if(this.isInitialRender){p.remove();return}let g=l.get(p),{dx:b,dy:E}=g?S(this.currentMeasures,this.prevMeasures,g):{dx:0,dy:0};N(p,{dx:b,dy:E,duration:this.options.duration,ease:this.options.ease,scale:this.options.scale});}),this.isInitialRender){this.isInitialRender=false,t.style.width="auto",t.style.height="auto";return}k(t,i,s,this.options.duration,this.options.onAnimationComplete);}updateStyles(e){if(this.isInitialRender)return;let t=Array.from(this.element.children),i=e.map(r=>r.id),s=new Set(i.filter(r=>this.prevMeasures[r]));t.forEach((r,o)=>{if(r.hasAttribute(d))return;let a=r.getAttribute(f)||`child-${o}`,u=!this.prevMeasures[a],m=u?w(e.findIndex(p=>p.id===a),i,s):a,{dx:c,dy:l}=m?S(this.prevMeasures,this.currentMeasures,m):{dx:0,dy:0};C(r,{deltaX:c,deltaY:l,isNew:u,duration:this.options.duration,ease:this.options.ease});});}};export{J as DEFAULT_AS,W as DEFAULT_TEXT_MORPH_OPTIONS,L as TextMorph};
|
package/dist/react/index.d.mts
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
interface SpringParams {
|
|
4
|
+
stiffness?: number;
|
|
5
|
+
damping?: number;
|
|
6
|
+
mass?: number;
|
|
7
|
+
precision?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface TextMorphOptions {
|
|
11
|
+
debug?: boolean;
|
|
12
|
+
element: HTMLElement;
|
|
13
|
+
locale?: Intl.LocalesArgument;
|
|
14
|
+
scale?: boolean;
|
|
15
|
+
duration?: number;
|
|
16
|
+
ease?: string | SpringParams;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
respectReducedMotion?: boolean;
|
|
19
|
+
onAnimationStart?: () => void;
|
|
20
|
+
onAnimationComplete?: () => void;
|
|
21
|
+
}
|
|
3
22
|
|
|
4
23
|
type TextMorphProps = Omit<TextMorphOptions, "element"> & {
|
|
5
|
-
children:
|
|
24
|
+
children: React.ReactNode;
|
|
6
25
|
className?: string;
|
|
7
26
|
style?: React.CSSProperties;
|
|
8
|
-
as?:
|
|
27
|
+
as?: React.ElementType;
|
|
9
28
|
};
|
|
10
29
|
declare const TextMorph: ({ children, className, style, as, ...props }: TextMorphProps) => React.JSX.Element;
|
|
11
30
|
declare function useTextMorph(props: Omit<TextMorphOptions, "element">): {
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
interface SpringParams {
|
|
4
|
+
stiffness?: number;
|
|
5
|
+
damping?: number;
|
|
6
|
+
mass?: number;
|
|
7
|
+
precision?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface TextMorphOptions {
|
|
11
|
+
debug?: boolean;
|
|
12
|
+
element: HTMLElement;
|
|
13
|
+
locale?: Intl.LocalesArgument;
|
|
14
|
+
scale?: boolean;
|
|
15
|
+
duration?: number;
|
|
16
|
+
ease?: string | SpringParams;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
respectReducedMotion?: boolean;
|
|
19
|
+
onAnimationStart?: () => void;
|
|
20
|
+
onAnimationComplete?: () => void;
|
|
21
|
+
}
|
|
3
22
|
|
|
4
23
|
type TextMorphProps = Omit<TextMorphOptions, "element"> & {
|
|
5
|
-
children:
|
|
24
|
+
children: React.ReactNode;
|
|
6
25
|
className?: string;
|
|
7
26
|
style?: React.CSSProperties;
|
|
8
|
-
as?:
|
|
27
|
+
as?: React.ElementType;
|
|
9
28
|
};
|
|
10
29
|
declare const TextMorph: ({ children, className, style, as, ...props }: TextMorphProps) => React.JSX.Element;
|
|
11
30
|
declare function useTextMorph(props: Omit<TextMorphOptions, "element">): {
|
package/dist/react/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
[torph-root] {
|
|
1
|
+
'use strict';var g=require('react');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var g__default=/*#__PURE__*/_interopDefault(g);function H(n,e,t){if(t<1){let u=e*Math.sqrt(1-t*t);return 1-Math.exp(-t*e*n)*(Math.cos(u*n)+t*e/u*Math.sin(u*n))}let i=Math.sqrt(t*t-1),s=-e*(t+i),r=-e*(t-i),o=-s/(r-s);return 1-(1-o)*Math.exp(s*n)-o*Math.exp(r*n)}function Y(n,e,t){let r=0;for(let o=0;o<10;o+=.001)if(Math.abs(H(o,n,e)-1)>t)r=0;else if(r+=.001,r>.1)return Math.ceil((o-r+.001)*1e3);return Math.ceil(10*1e3)}var $=new Map;function D(n){let{stiffness:e=100,damping:t=10,mass:i=1,precision:s=.001}=n??{},r=`${e}:${t}:${i}:${s}`,o=$.get(r);if(o)return o;let a=Math.sqrt(e/i),u=t/(2*Math.sqrt(e*i)),p=Y(a,u,s),l=Math.min(100,Math.max(32,Math.round(p/15))),m=[];for(let y=0;y<l;y++){let S=y/(l-1)*(p/1e3),R=y===l-1?1:H(S,a,u);m.push(Math.round(R*1e4)/1e4+"");}for(;m.length>2&&m[m.length-2]==="1";)m.splice(m.length-2,1);let c={easing:`linear(${m.join(", ")})`,duration:p};return $.set(r,c),c}function _(n,e){let t=n.includes(" ");if(typeof Intl.Segmenter<"u"){let s=new Intl.Segmenter(e,{granularity:t?"word":"grapheme"}).segment(n)[Symbol.iterator]();return Q(s)}return V(n,t)}function Q(n){return Array.from(n).reduce((e,t)=>t.segment===" "?[...e,{id:`space-${t.index}`,string:"\xA0"}]:e.find(s=>s.string===t.segment)?[...e,{id:`${t.segment}-${t.index}`,string:t.segment}]:[...e,{id:t.segment,string:t.segment}],[])}function J(n,e,t){let i=n.find(s=>s.string===e);n.push(i?{id:`${e}-${t}`,string:e}:{id:e,string:e});}function V(n,e){let t=e?n.split(" "):n.split(""),i=[];return t.forEach((s,r)=>{e&&r>0&&i.push({id:`space-${r}`,string:"\xA0"}),J(i,s,r);}),i}var x="torph-root",M="torph-item",f="torph-id",d="torph-exiting",b="torph-debug";function w(n){let e=Array.from(n.children),t={};return e.forEach((i,s)=>{if(i.hasAttribute(d))return;let r=i.getAttribute(f)||`child-${s}`;t[r]={x:i.offsetLeft,y:i.offsetTop};}),t}function v(n,e,t){let i=n[t],s=e[t];return !i||!s?{dx:0,dy:0}:{dx:i.x-s.x,dy:i.y-s.y}}function L(n,e,t,i="backward-first"){let[s,r]=i==="backward-first"?["backward","forward"]:["forward","backward"],o=a=>{if(a==="backward"){for(let u=n-1;u>=0;u--)if(t.has(e[u]))return e[u]}else for(let u=n+1;u<e.length;u++)if(t.has(e[u]))return e[u];return null};return o(s)??o(r)}function C(n,e,t,i){let s=new Set(t.filter((o,a)=>i.has(o)&&!e.has(n[a]))),r=new Map;for(let o=0;o<n.length;o++){let a=n[o];e.has(a)&&r.set(a,L(o,t,s,"forward-first"));}return r}function N(n,e){return Math.min(n*e,150)}function I(n){let e=getComputedStyle(n).transform;if(!e||e==="none")return {tx:0,ty:0};let t=e.match(/matrix\(([^)]+)\)/);if(!t)return {tx:0,ty:0};let i=t[1].split(",").map(Number);return {tx:i[4]||0,ty:i[5]||0}}function z(n){let{tx:e,ty:t}=I(n),i=Number(getComputedStyle(n).opacity)||1;return n.getAnimations().forEach(s=>s.cancel()),{tx:e,ty:t,opacity:i}}function k(n,e){let{dx:t,dy:i,duration:s,ease:r,scale:o}=e;n.animate({transform:o?`translate(${t}px, ${i}px) scale(0.95)`:`translate(${t}px, ${i}px)`,offset:1},{duration:s,easing:r,fill:"both"});let a=n.animate({opacity:0,offset:1},{duration:N(s,.25),easing:"linear",fill:"both"});a.onfinish=()=>n.remove();}function P(n,e){let{deltaX:t,deltaY:i,isNew:s,duration:r,ease:o}=e,a=z(n),u=t+a.tx,p=i+a.ty;n.animate({transform:`translate(${u}px, ${p}px) scale(${s?.95:1})`,offset:0},{duration:r,easing:o,fill:"both"});let l=s&&a.opacity>=1?0:a.opacity;l<1&&n.animate([{opacity:l},{opacity:1}],{duration:N(r,s?.5:.25),easing:"linear",fill:"both"});}var T=null;function F(n,e,t,i,s){if(T&&(T(),T=null),e===0||t===0)return;n.style.width="auto",n.style.height="auto",n.offsetWidth;let r=n.offsetWidth,o=n.offsetHeight;n.style.width=`${e}px`,n.style.height=`${t}px`,n.offsetWidth,n.style.width=`${r}px`,n.style.height=`${o}px`;function a(){n.removeEventListener("transitionend",u),clearTimeout(p),T=null,n.style.width="auto",n.style.height="auto",s?.();}function u(l){l.target===n&&(l.propertyName!=="width"&&l.propertyName!=="height"||a());}n.addEventListener("transitionend",u);let p=setTimeout(a,i+50);T=()=>{n.removeEventListener("transitionend",u),clearTimeout(p),T=null;};}function X(n){let e=n.map(t=>{let{tx:i,ty:s}=I(t),r=Number(getComputedStyle(t).opacity)||1;return t.getAnimations().forEach(o=>o.cancel()),{left:t.offsetLeft+i,top:t.offsetTop+s,width:t.offsetWidth,height:t.offsetHeight,opacity:r}});n.forEach((t,i)=>{let s=e[i];t.setAttribute(d,""),t.style.position="absolute",t.style.pointerEvents="none",t.style.left=`${s.left}px`,t.style.top=`${s.top}px`,t.style.width=`${s.width}px`,t.style.height=`${s.height}px`,t.style.opacity=String(s.opacity);});}function G(n,e,t,i){let s=new Map;e.forEach(r=>{let o=r.getAttribute(f);t.has(o)&&!r.hasAttribute(d)&&(s.set(o,r),r.remove());}),Array.from(n.childNodes).forEach(r=>{r.nodeType===Node.TEXT_NODE&&r.remove();}),i.forEach(r=>{let o=s.get(r.id);if(o)o.textContent=r.string,n.appendChild(o);else {let a=document.createElement("span");a.setAttribute(M,""),a.setAttribute(f,r.id),a.textContent=r.string,n.appendChild(a);}});}var Z=`
|
|
2
|
+
[${x}] {
|
|
4
3
|
display: inline-flex;
|
|
5
4
|
position: relative;
|
|
6
5
|
will-change: width, height;
|
|
@@ -8,19 +7,17 @@
|
|
|
8
7
|
white-space: nowrap;
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
[
|
|
10
|
+
[${M}] {
|
|
12
11
|
display: inline-block;
|
|
13
12
|
will-change: opacity, transform;
|
|
14
13
|
transform: none;
|
|
15
14
|
opacity: 1;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
[
|
|
19
|
-
outline:2px solid magenta;
|
|
20
|
-
[
|
|
21
|
-
outline:2px solid cyan;
|
|
17
|
+
[${x}][${b}] {
|
|
18
|
+
outline: 2px solid magenta;
|
|
19
|
+
[${M}] {
|
|
20
|
+
outline: 2px solid cyan;
|
|
22
21
|
outline-offset: -4px;
|
|
23
22
|
}
|
|
24
|
-
}
|
|
25
|
-
`,document.head.appendChild(t),a.styleEl=t}removeStyles(){a.styleEl&&(a.styleEl.remove(),a.styleEl=void 0)}blocks(t){return Array.from(t).reduce((o,i)=>i.segment===" "?[...o,{id:`space-${i.index}`,string:"\xA0"}]:o.find(p=>p.string===i.segment)?[...o,{id:`${i.segment}-${i.index}`,string:i.segment}]:[...o,{id:i.segment,string:i.segment}],[])}blocksFallback(t,e){let o=e?t.split(" "):t.split(""),i=[];return e?o.forEach((h,p)=>{p>0&&i.push({id:`space-${p}`,string:"\xA0"}),i.find(d=>d.string===h)?i.push({id:`${h}-${p}`,string:h}):i.push({id:h,string:h})}):o.forEach((h,p)=>{i.find(d=>d.string===h)?i.push({id:`${h}-${p}`,string:h}):i.push({id:h,string:h})}),i}log(...t){this.options.debug&&console.log("[TextMorph]",...t)}};var S=({children:a,className:t,style:e,as:o="div",...i})=>{let{ref:h,update:p}=A(i);return m.default.useEffect(()=>{p(a)},[a,p]),m.default.createElement(o,{ref:h,className:t,style:e})};function A(a){let t=m.default.useRef(null),e=m.default.useRef(null);return m.default.useEffect(()=>(t.current&&(e.current=new E({element:t.current,...a})),()=>{e.current?.destroy()}),[]),{ref:t,update:i=>{e.current?.update(i)}}}0&&(module.exports={TextMorph,useTextMorph});
|
|
26
|
-
//# sourceMappingURL=index.js.map
|
|
23
|
+
}`,h=null,O=0;function U(){O++,!h&&(h=document.createElement("style"),h.dataset.torph="true",h.textContent=Z,document.head.appendChild(h));}function W(){O--,!(O>0||!h)&&(h.remove(),h=null);}function j(){if(typeof window>"u")return {prefersReducedMotion:false,destroy:()=>{}};let n=window.matchMedia("(prefers-reduced-motion: reduce)"),e={prefersReducedMotion:n.matches,destroy:i};function t(s){e.prefersReducedMotion=s.matches;}function i(){n.removeEventListener("change",t);}return n.addEventListener("change",t),e}var E=class n{instance=null;lastText="";configKey="";attach(e,t){this.instance?.destroy(),this.instance=new A({element:e,...t}),this.configKey=n.serializeConfig(t),this.lastText&&this.instance.update(this.lastText);}update(e){this.lastText=e,this.instance?.update(e);}needsRecreate(e){return n.serializeConfig(e)!==this.configKey}destroy(){this.instance?.destroy(),this.instance=null;}static serializeConfig(e){return JSON.stringify({ease:e.ease,duration:e.duration,locale:e.locale,scale:e.scale,debug:e.debug,disabled:e.disabled,respectReducedMotion:e.respectReducedMotion})}};var B="span",tt={debug:false,locale:"en",duration:400,scale:true,ease:"cubic-bezier(0.19, 1, 0.22, 1)",disabled:false,respectReducedMotion:true},A=class{element;options={};data;currentMeasures={};prevMeasures={};isInitialRender=true;reducedMotion=null;constructor(e){let{ease:t,...i}={...tt,...e},s,r;if(typeof t=="object"){let o=D(t);s=o.easing,r=o.duration;}else s=t,r=i.duration;this.options={...i,ease:s,duration:r},this.element=e.element,this.options.respectReducedMotion&&(this.reducedMotion=j()),this.isDisabled()||(this.element.setAttribute(x,""),this.element.style.transitionDuration=`${this.options.duration}ms`,this.element.style.transitionTimingFunction=this.options.ease,e.debug&&this.element.setAttribute(b,"")),this.data="",this.isDisabled()||U();}destroy(){this.reducedMotion?.destroy(),this.element.getAnimations().forEach(e=>e.cancel()),this.element.removeAttribute(x),this.element.removeAttribute(b),W();}isDisabled(){return !!(this.options.disabled||this.reducedMotion?.prefersReducedMotion)}update(e){if(e!==this.data){if(this.data=e,this.isDisabled()){typeof e=="string"&&(this.element.textContent=e);return}if(this.data instanceof HTMLElement)throw new Error("HTMLElement not yet supported");this.options.onAnimationStart&&!this.isInitialRender&&this.options.onAnimationStart(),this.createTextGroup(this.data,this.element);}}createTextGroup(e,t){let i=t.offsetWidth,s=t.offsetHeight,r=_(e,this.options.locale);this.prevMeasures=w(this.element);let o=Array.from(t.children),a=new Set(r.map(c=>c.id)),u=o.filter(c=>!a.has(c.getAttribute(f))&&!c.hasAttribute(d)),p=new Set(u),l=o.map(c=>c.getAttribute(f)),m=C(o,p,l,a);if(X(u),G(t,o,a,r),this.currentMeasures=w(this.element),this.updateStyles(r),u.forEach(c=>{if(this.isInitialRender){c.remove();return}let y=m.get(c),{dx:S,dy:R}=y?v(this.currentMeasures,this.prevMeasures,y):{dx:0,dy:0};k(c,{dx:S,dy:R,duration:this.options.duration,ease:this.options.ease,scale:this.options.scale});}),this.isInitialRender){this.isInitialRender=false,t.style.width="auto",t.style.height="auto";return}F(t,i,s,this.options.duration,this.options.onAnimationComplete);}updateStyles(e){if(this.isInitialRender)return;let t=Array.from(this.element.children),i=e.map(r=>r.id),s=new Set(i.filter(r=>this.prevMeasures[r]));t.forEach((r,o)=>{if(r.hasAttribute(d))return;let a=r.getAttribute(f)||`child-${o}`,u=!this.prevMeasures[a],p=u?L(e.findIndex(c=>c.id===a),i,s):a,{dx:l,dy:m}=p?v(this.prevMeasures,this.currentMeasures,p):{dx:0,dy:0};P(r,{deltaX:l,deltaY:m,isNew:u,duration:this.options.duration,ease:this.options.ease});});}};function K(n){if(typeof n=="string")return n;if(typeof n=="number")return String(n);if(!n||typeof n=="boolean")return "";if(Array.isArray(n))return n.map(K).join("");throw g__default.default.isValidElement(n)?new Error("TextMorph only accepts text content. Found a React element \u2014 use strings, numbers, or expressions instead."):new Error(`TextMorph received an unsupported child of type "${typeof n}".`)}var et=({children:n,className:e,style:t,as:i=B,...s})=>{let{ref:r,update:o}=q(s),a=K(n),u=g__default.default.useRef({__html:a});return g__default.default.useEffect(()=>{o(a);},[a,o]),g__default.default.createElement(i,{ref:r,className:e,style:t,dangerouslySetInnerHTML:u.current})};function q(n){let e=g__default.default.useRef(null),t=g__default.default.useRef(new E),i=E.serializeConfig(n);g__default.default.useEffect(()=>(e.current&&t.current.attach(e.current,n),()=>{t.current.destroy();}),[i]);let s=g__default.default.useCallback(r=>{t.current.update(r);},[]);return {ref:e,update:s}}exports.TextMorph=et;exports.useTextMorph=q;
|
package/dist/react/index.mjs
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
-
"
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import g from'react';function H(n,e,t){if(t<1){let u=e*Math.sqrt(1-t*t);return 1-Math.exp(-t*e*n)*(Math.cos(u*n)+t*e/u*Math.sin(u*n))}let i=Math.sqrt(t*t-1),s=-e*(t+i),r=-e*(t-i),o=-s/(r-s);return 1-(1-o)*Math.exp(s*n)-o*Math.exp(r*n)}function Y(n,e,t){let r=0;for(let o=0;o<10;o+=.001)if(Math.abs(H(o,n,e)-1)>t)r=0;else if(r+=.001,r>.1)return Math.ceil((o-r+.001)*1e3);return Math.ceil(10*1e3)}var $=new Map;function D(n){let{stiffness:e=100,damping:t=10,mass:i=1,precision:s=.001}=n??{},r=`${e}:${t}:${i}:${s}`,o=$.get(r);if(o)return o;let a=Math.sqrt(e/i),u=t/(2*Math.sqrt(e*i)),p=Y(a,u,s),l=Math.min(100,Math.max(32,Math.round(p/15))),m=[];for(let y=0;y<l;y++){let S=y/(l-1)*(p/1e3),R=y===l-1?1:H(S,a,u);m.push(Math.round(R*1e4)/1e4+"");}for(;m.length>2&&m[m.length-2]==="1";)m.splice(m.length-2,1);let c={easing:`linear(${m.join(", ")})`,duration:p};return $.set(r,c),c}function _(n,e){let t=n.includes(" ");if(typeof Intl.Segmenter<"u"){let s=new Intl.Segmenter(e,{granularity:t?"word":"grapheme"}).segment(n)[Symbol.iterator]();return Q(s)}return V(n,t)}function Q(n){return Array.from(n).reduce((e,t)=>t.segment===" "?[...e,{id:`space-${t.index}`,string:"\xA0"}]:e.find(s=>s.string===t.segment)?[...e,{id:`${t.segment}-${t.index}`,string:t.segment}]:[...e,{id:t.segment,string:t.segment}],[])}function J(n,e,t){let i=n.find(s=>s.string===e);n.push(i?{id:`${e}-${t}`,string:e}:{id:e,string:e});}function V(n,e){let t=e?n.split(" "):n.split(""),i=[];return t.forEach((s,r)=>{e&&r>0&&i.push({id:`space-${r}`,string:"\xA0"}),J(i,s,r);}),i}var x="torph-root",M="torph-item",f="torph-id",d="torph-exiting",b="torph-debug";function w(n){let e=Array.from(n.children),t={};return e.forEach((i,s)=>{if(i.hasAttribute(d))return;let r=i.getAttribute(f)||`child-${s}`;t[r]={x:i.offsetLeft,y:i.offsetTop};}),t}function v(n,e,t){let i=n[t],s=e[t];return !i||!s?{dx:0,dy:0}:{dx:i.x-s.x,dy:i.y-s.y}}function L(n,e,t,i="backward-first"){let[s,r]=i==="backward-first"?["backward","forward"]:["forward","backward"],o=a=>{if(a==="backward"){for(let u=n-1;u>=0;u--)if(t.has(e[u]))return e[u]}else for(let u=n+1;u<e.length;u++)if(t.has(e[u]))return e[u];return null};return o(s)??o(r)}function C(n,e,t,i){let s=new Set(t.filter((o,a)=>i.has(o)&&!e.has(n[a]))),r=new Map;for(let o=0;o<n.length;o++){let a=n[o];e.has(a)&&r.set(a,L(o,t,s,"forward-first"));}return r}function N(n,e){return Math.min(n*e,150)}function I(n){let e=getComputedStyle(n).transform;if(!e||e==="none")return {tx:0,ty:0};let t=e.match(/matrix\(([^)]+)\)/);if(!t)return {tx:0,ty:0};let i=t[1].split(",").map(Number);return {tx:i[4]||0,ty:i[5]||0}}function z(n){let{tx:e,ty:t}=I(n),i=Number(getComputedStyle(n).opacity)||1;return n.getAnimations().forEach(s=>s.cancel()),{tx:e,ty:t,opacity:i}}function k(n,e){let{dx:t,dy:i,duration:s,ease:r,scale:o}=e;n.animate({transform:o?`translate(${t}px, ${i}px) scale(0.95)`:`translate(${t}px, ${i}px)`,offset:1},{duration:s,easing:r,fill:"both"});let a=n.animate({opacity:0,offset:1},{duration:N(s,.25),easing:"linear",fill:"both"});a.onfinish=()=>n.remove();}function P(n,e){let{deltaX:t,deltaY:i,isNew:s,duration:r,ease:o}=e,a=z(n),u=t+a.tx,p=i+a.ty;n.animate({transform:`translate(${u}px, ${p}px) scale(${s?.95:1})`,offset:0},{duration:r,easing:o,fill:"both"});let l=s&&a.opacity>=1?0:a.opacity;l<1&&n.animate([{opacity:l},{opacity:1}],{duration:N(r,s?.5:.25),easing:"linear",fill:"both"});}var T=null;function F(n,e,t,i,s){if(T&&(T(),T=null),e===0||t===0)return;n.style.width="auto",n.style.height="auto",n.offsetWidth;let r=n.offsetWidth,o=n.offsetHeight;n.style.width=`${e}px`,n.style.height=`${t}px`,n.offsetWidth,n.style.width=`${r}px`,n.style.height=`${o}px`;function a(){n.removeEventListener("transitionend",u),clearTimeout(p),T=null,n.style.width="auto",n.style.height="auto",s?.();}function u(l){l.target===n&&(l.propertyName!=="width"&&l.propertyName!=="height"||a());}n.addEventListener("transitionend",u);let p=setTimeout(a,i+50);T=()=>{n.removeEventListener("transitionend",u),clearTimeout(p),T=null;};}function X(n){let e=n.map(t=>{let{tx:i,ty:s}=I(t),r=Number(getComputedStyle(t).opacity)||1;return t.getAnimations().forEach(o=>o.cancel()),{left:t.offsetLeft+i,top:t.offsetTop+s,width:t.offsetWidth,height:t.offsetHeight,opacity:r}});n.forEach((t,i)=>{let s=e[i];t.setAttribute(d,""),t.style.position="absolute",t.style.pointerEvents="none",t.style.left=`${s.left}px`,t.style.top=`${s.top}px`,t.style.width=`${s.width}px`,t.style.height=`${s.height}px`,t.style.opacity=String(s.opacity);});}function G(n,e,t,i){let s=new Map;e.forEach(r=>{let o=r.getAttribute(f);t.has(o)&&!r.hasAttribute(d)&&(s.set(o,r),r.remove());}),Array.from(n.childNodes).forEach(r=>{r.nodeType===Node.TEXT_NODE&&r.remove();}),i.forEach(r=>{let o=s.get(r.id);if(o)o.textContent=r.string,n.appendChild(o);else {let a=document.createElement("span");a.setAttribute(M,""),a.setAttribute(f,r.id),a.textContent=r.string,n.appendChild(a);}});}var Z=`
|
|
2
|
+
[${x}] {
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
position: relative;
|
|
5
|
+
will-change: width, height;
|
|
6
|
+
transition-property: width, height;
|
|
7
|
+
white-space: nowrap;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
[${M}] {
|
|
11
|
+
display: inline-block;
|
|
12
|
+
will-change: opacity, transform;
|
|
13
|
+
transform: none;
|
|
14
|
+
opacity: 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
[${x}][${b}] {
|
|
18
|
+
outline: 2px solid magenta;
|
|
19
|
+
[${M}] {
|
|
20
|
+
outline: 2px solid cyan;
|
|
21
|
+
outline-offset: -4px;
|
|
22
|
+
}
|
|
23
|
+
}`,h=null,O=0;function U(){O++,!h&&(h=document.createElement("style"),h.dataset.torph="true",h.textContent=Z,document.head.appendChild(h));}function W(){O--,!(O>0||!h)&&(h.remove(),h=null);}function j(){if(typeof window>"u")return {prefersReducedMotion:false,destroy:()=>{}};let n=window.matchMedia("(prefers-reduced-motion: reduce)"),e={prefersReducedMotion:n.matches,destroy:i};function t(s){e.prefersReducedMotion=s.matches;}function i(){n.removeEventListener("change",t);}return n.addEventListener("change",t),e}var E=class n{instance=null;lastText="";configKey="";attach(e,t){this.instance?.destroy(),this.instance=new A({element:e,...t}),this.configKey=n.serializeConfig(t),this.lastText&&this.instance.update(this.lastText);}update(e){this.lastText=e,this.instance?.update(e);}needsRecreate(e){return n.serializeConfig(e)!==this.configKey}destroy(){this.instance?.destroy(),this.instance=null;}static serializeConfig(e){return JSON.stringify({ease:e.ease,duration:e.duration,locale:e.locale,scale:e.scale,debug:e.debug,disabled:e.disabled,respectReducedMotion:e.respectReducedMotion})}};var B="span",tt={debug:false,locale:"en",duration:400,scale:true,ease:"cubic-bezier(0.19, 1, 0.22, 1)",disabled:false,respectReducedMotion:true},A=class{element;options={};data;currentMeasures={};prevMeasures={};isInitialRender=true;reducedMotion=null;constructor(e){let{ease:t,...i}={...tt,...e},s,r;if(typeof t=="object"){let o=D(t);s=o.easing,r=o.duration;}else s=t,r=i.duration;this.options={...i,ease:s,duration:r},this.element=e.element,this.options.respectReducedMotion&&(this.reducedMotion=j()),this.isDisabled()||(this.element.setAttribute(x,""),this.element.style.transitionDuration=`${this.options.duration}ms`,this.element.style.transitionTimingFunction=this.options.ease,e.debug&&this.element.setAttribute(b,"")),this.data="",this.isDisabled()||U();}destroy(){this.reducedMotion?.destroy(),this.element.getAnimations().forEach(e=>e.cancel()),this.element.removeAttribute(x),this.element.removeAttribute(b),W();}isDisabled(){return !!(this.options.disabled||this.reducedMotion?.prefersReducedMotion)}update(e){if(e!==this.data){if(this.data=e,this.isDisabled()){typeof e=="string"&&(this.element.textContent=e);return}if(this.data instanceof HTMLElement)throw new Error("HTMLElement not yet supported");this.options.onAnimationStart&&!this.isInitialRender&&this.options.onAnimationStart(),this.createTextGroup(this.data,this.element);}}createTextGroup(e,t){let i=t.offsetWidth,s=t.offsetHeight,r=_(e,this.options.locale);this.prevMeasures=w(this.element);let o=Array.from(t.children),a=new Set(r.map(c=>c.id)),u=o.filter(c=>!a.has(c.getAttribute(f))&&!c.hasAttribute(d)),p=new Set(u),l=o.map(c=>c.getAttribute(f)),m=C(o,p,l,a);if(X(u),G(t,o,a,r),this.currentMeasures=w(this.element),this.updateStyles(r),u.forEach(c=>{if(this.isInitialRender){c.remove();return}let y=m.get(c),{dx:S,dy:R}=y?v(this.currentMeasures,this.prevMeasures,y):{dx:0,dy:0};k(c,{dx:S,dy:R,duration:this.options.duration,ease:this.options.ease,scale:this.options.scale});}),this.isInitialRender){this.isInitialRender=false,t.style.width="auto",t.style.height="auto";return}F(t,i,s,this.options.duration,this.options.onAnimationComplete);}updateStyles(e){if(this.isInitialRender)return;let t=Array.from(this.element.children),i=e.map(r=>r.id),s=new Set(i.filter(r=>this.prevMeasures[r]));t.forEach((r,o)=>{if(r.hasAttribute(d))return;let a=r.getAttribute(f)||`child-${o}`,u=!this.prevMeasures[a],p=u?L(e.findIndex(c=>c.id===a),i,s):a,{dx:l,dy:m}=p?v(this.prevMeasures,this.currentMeasures,p):{dx:0,dy:0};P(r,{deltaX:l,deltaY:m,isNew:u,duration:this.options.duration,ease:this.options.ease});});}};function K(n){if(typeof n=="string")return n;if(typeof n=="number")return String(n);if(!n||typeof n=="boolean")return "";if(Array.isArray(n))return n.map(K).join("");throw g.isValidElement(n)?new Error("TextMorph only accepts text content. Found a React element \u2014 use strings, numbers, or expressions instead."):new Error(`TextMorph received an unsupported child of type "${typeof n}".`)}var et=({children:n,className:e,style:t,as:i=B,...s})=>{let{ref:r,update:o}=q(s),a=K(n),u=g.useRef({__html:a});return g.useEffect(()=>{o(a);},[a,o]),g.createElement(i,{ref:r,className:e,style:t,dangerouslySetInnerHTML:u.current})};function q(n){let e=g.useRef(null),t=g.useRef(new E),i=E.serializeConfig(n);g.useEffect(()=>(e.current&&t.current.attach(e.current,n),()=>{t.current.destroy();}),[i]);let s=g.useCallback(r=>{t.current.update(r);},[]);return {ref:e,update:s}}export{et as TextMorph,q as useTextMorph};
|
package/dist/svelte/index.d.mts
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
interface SpringParams {
|
|
2
|
+
stiffness?: number;
|
|
3
|
+
damping?: number;
|
|
4
|
+
mass?: number;
|
|
5
|
+
precision?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface TextMorphOptions {
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
element: HTMLElement;
|
|
11
|
+
locale?: Intl.LocalesArgument;
|
|
12
|
+
scale?: boolean;
|
|
13
|
+
duration?: number;
|
|
14
|
+
ease?: string | SpringParams;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
respectReducedMotion?: boolean;
|
|
17
|
+
onAnimationStart?: () => void;
|
|
18
|
+
onAnimationComplete?: () => void;
|
|
19
|
+
}
|
|
2
20
|
|
|
3
21
|
interface TextMorphProps extends Omit<TextMorphOptions, "element"> {
|
|
4
22
|
text: string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
interface SpringParams {
|
|
2
|
+
stiffness?: number;
|
|
3
|
+
damping?: number;
|
|
4
|
+
mass?: number;
|
|
5
|
+
precision?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface TextMorphOptions {
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
element: HTMLElement;
|
|
11
|
+
locale?: Intl.LocalesArgument;
|
|
12
|
+
scale?: boolean;
|
|
13
|
+
duration?: number;
|
|
14
|
+
ease?: string | SpringParams;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
respectReducedMotion?: boolean;
|
|
17
|
+
onAnimationStart?: () => void;
|
|
18
|
+
onAnimationComplete?: () => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface TextMorphProps extends Omit<TextMorphOptions, "element"> {
|
|
22
|
+
text: string;
|
|
23
|
+
class?: string;
|
|
24
|
+
style?: string;
|
|
25
|
+
as?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type { TextMorphProps };
|
package/dist/svelte/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
'use strict';require('svelte/internal/disclose-version');var e=require('svelte/internal/client'),textMorph=require('../lib/text-morph'),controller=require('../lib/text-morph/controller');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var e__namespace=/*#__PURE__*/_interopNamespace(e);function c(s,t){e__namespace.push(t,true);let p=e__namespace.prop(t,"locale",19,()=>textMorph.DEFAULT_TEXT_MORPH_OPTIONS.locale),u=e__namespace.prop(t,"duration",19,()=>textMorph.DEFAULT_TEXT_MORPH_OPTIONS.duration),m=e__namespace.prop(t,"ease",19,()=>textMorph.DEFAULT_TEXT_MORPH_OPTIONS.ease),f=e__namespace.prop(t,"scale",19,()=>textMorph.DEFAULT_TEXT_MORPH_OPTIONS.scale),g=e__namespace.prop(t,"debug",19,()=>textMorph.DEFAULT_TEXT_MORPH_OPTIONS.debug),$=e__namespace.prop(t,"disabled",19,()=>textMorph.DEFAULT_TEXT_MORPH_OPTIONS.disabled),b=e__namespace.prop(t,"respectReducedMotion",19,()=>textMorph.DEFAULT_TEXT_MORPH_OPTIONS.respectReducedMotion),A=e__namespace.prop(t,"onAnimationStart",19,()=>{}),M=e__namespace.prop(t,"onAnimationComplete",19,()=>{}),_=e__namespace.prop(t,"as",3,textMorph.DEFAULT_AS),h=e__namespace.rest_props(t,["$$slots","$$events","$$legacy","text","locale","duration","ease","scale","debug","disabled","respectReducedMotion","onAnimationStart","onAnimationComplete","as"]),a=e__namespace.state(void 0),n=new controller.MorphController,i=e__namespace.derived(()=>({locale:p(),duration:u(),ease:m(),debug:g(),scale:f(),disabled:$(),respectReducedMotion:b(),onAnimationStart:A(),onAnimationComplete:M()})),v=e__namespace.derived(()=>controller.MorphController.serializeConfig(e__namespace.get(i)));e__namespace.user_effect(()=>{if(e__namespace.get(v),e__namespace.get(a))return n.attach(e__namespace.get(a),e__namespace.get(i)),()=>{n.destroy();}}),e__namespace.user_effect(()=>{n.update(t.text);});var r=e__namespace.comment(),x=e__namespace.first_child(r);e__namespace.element(x,_,false,(d,C)=>{e__namespace.bind_this(d,T=>e__namespace.set(a,T,true),()=>e__namespace.get(a)),e__namespace.attribute_effect(d,()=>({...h}));}),e__namespace.append(s,r),e__namespace.pop();}exports.TextMorph=c;
|
package/dist/svelte/index.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
import'svelte/internal/disclose-version';import*as e from'svelte/internal/client';import {DEFAULT_TEXT_MORPH_OPTIONS,DEFAULT_AS}from'../lib/text-morph';import {MorphController}from'../lib/text-morph/controller';function c(s,t){e.push(t,true);let p=e.prop(t,"locale",19,()=>DEFAULT_TEXT_MORPH_OPTIONS.locale),u=e.prop(t,"duration",19,()=>DEFAULT_TEXT_MORPH_OPTIONS.duration),m=e.prop(t,"ease",19,()=>DEFAULT_TEXT_MORPH_OPTIONS.ease),f=e.prop(t,"scale",19,()=>DEFAULT_TEXT_MORPH_OPTIONS.scale),g=e.prop(t,"debug",19,()=>DEFAULT_TEXT_MORPH_OPTIONS.debug),$=e.prop(t,"disabled",19,()=>DEFAULT_TEXT_MORPH_OPTIONS.disabled),b=e.prop(t,"respectReducedMotion",19,()=>DEFAULT_TEXT_MORPH_OPTIONS.respectReducedMotion),A=e.prop(t,"onAnimationStart",19,()=>{}),M=e.prop(t,"onAnimationComplete",19,()=>{}),_=e.prop(t,"as",3,DEFAULT_AS),h=e.rest_props(t,["$$slots","$$events","$$legacy","text","locale","duration","ease","scale","debug","disabled","respectReducedMotion","onAnimationStart","onAnimationComplete","as"]),a=e.state(void 0),n=new MorphController,i=e.derived(()=>({locale:p(),duration:u(),ease:m(),debug:g(),scale:f(),disabled:$(),respectReducedMotion:b(),onAnimationStart:A(),onAnimationComplete:M()})),v=e.derived(()=>MorphController.serializeConfig(e.get(i)));e.user_effect(()=>{if(e.get(v),e.get(a))return n.attach(e.get(a),e.get(i)),()=>{n.destroy();}}),e.user_effect(()=>{n.update(t.text);});var r=e.comment(),x=e.first_child(r);e.element(x,_,false,(d,C)=>{e.bind_this(d,T=>e.set(a,T,true),()=>e.get(a)),e.attribute_effect(d,()=>({...h}));}),e.append(s,r),e.pop();}export{c as TextMorph};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
interface SpringParams {
|
|
2
|
+
stiffness?: number;
|
|
3
|
+
damping?: number;
|
|
4
|
+
mass?: number;
|
|
5
|
+
precision?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface TextMorphOptions {
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
element: HTMLElement;
|
|
11
|
+
locale?: Intl.LocalesArgument;
|
|
12
|
+
scale?: boolean;
|
|
13
|
+
duration?: number;
|
|
14
|
+
ease?: string | SpringParams;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
respectReducedMotion?: boolean;
|
|
17
|
+
onAnimationStart?: () => void;
|
|
18
|
+
onAnimationComplete?: () => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface TextMorphProps extends Omit<TextMorphOptions, "element"> {
|
|
22
|
+
text: string;
|
|
23
|
+
class?: string;
|
|
24
|
+
style?: Record<string, string | number>;
|
|
25
|
+
as?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type { TextMorphProps };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
interface SpringParams {
|
|
2
|
+
stiffness?: number;
|
|
3
|
+
damping?: number;
|
|
4
|
+
mass?: number;
|
|
5
|
+
precision?: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface TextMorphOptions {
|
|
9
|
+
debug?: boolean;
|
|
10
|
+
element: HTMLElement;
|
|
11
|
+
locale?: Intl.LocalesArgument;
|
|
12
|
+
scale?: boolean;
|
|
13
|
+
duration?: number;
|
|
14
|
+
ease?: string | SpringParams;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
respectReducedMotion?: boolean;
|
|
17
|
+
onAnimationStart?: () => void;
|
|
18
|
+
onAnimationComplete?: () => void;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface TextMorphProps extends Omit<TextMorphOptions, "element"> {
|
|
22
|
+
text: string;
|
|
23
|
+
class?: string;
|
|
24
|
+
style?: Record<string, string | number>;
|
|
25
|
+
as?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type { TextMorphProps };
|
package/dist/vue/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
'use strict';var TextMorphLC6RO5C5_vue=require('../TextMorph-LC6RO5C5.vue');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var TextMorphLC6RO5C5_vue__default=/*#__PURE__*/_interopDefault(TextMorphLC6RO5C5_vue);Object.defineProperty(exports,"TextMorph",{enumerable:true,get:function(){return TextMorphLC6RO5C5_vue__default.default}});
|
package/dist/vue/index.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
export{default as TextMorph}from'../TextMorph-LC6RO5C5.vue';
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "torph",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Dependency-free animated text component.",
|
|
5
|
+
"homepage": "https://torph.lochie.me",
|
|
5
6
|
"author": "Lochie Axon",
|
|
6
7
|
"license": "MIT",
|
|
7
8
|
"repository": {
|
|
@@ -9,6 +10,8 @@
|
|
|
9
10
|
"url": "git+https://github.com/lochie/torph.git",
|
|
10
11
|
"directory": "packages/torph"
|
|
11
12
|
},
|
|
13
|
+
"main": "dist/index.js",
|
|
14
|
+
"module": "dist/index.mjs",
|
|
12
15
|
"types": "dist/index.d.ts",
|
|
13
16
|
"exports": {
|
|
14
17
|
".": {
|
|
@@ -22,12 +25,18 @@
|
|
|
22
25
|
"require": "./dist/react/index.js"
|
|
23
26
|
},
|
|
24
27
|
"./vue": {
|
|
25
|
-
"types":
|
|
28
|
+
"types": {
|
|
29
|
+
"import": "./dist/vue/index.d.mts",
|
|
30
|
+
"require": "./dist/vue/index.d.ts"
|
|
31
|
+
},
|
|
26
32
|
"import": "./dist/vue/index.mjs",
|
|
27
33
|
"require": "./dist/vue/index.js"
|
|
28
34
|
},
|
|
29
35
|
"./svelte": {
|
|
30
|
-
"types":
|
|
36
|
+
"types": {
|
|
37
|
+
"import": "./dist/svelte/index.d.mts",
|
|
38
|
+
"require": "./dist/svelte/index.d.ts"
|
|
39
|
+
},
|
|
31
40
|
"import": "./dist/svelte/index.mjs",
|
|
32
41
|
"require": "./dist/svelte/index.js"
|
|
33
42
|
}
|
|
@@ -46,6 +55,7 @@
|
|
|
46
55
|
"bugs": {
|
|
47
56
|
"url": "https://github.com/lochie/torph/issues"
|
|
48
57
|
},
|
|
58
|
+
"sideEffects": false,
|
|
49
59
|
"files": [
|
|
50
60
|
"dist/*"
|
|
51
61
|
],
|
|
@@ -53,7 +63,7 @@
|
|
|
53
63
|
"react": ">=18",
|
|
54
64
|
"react-dom": ">=18",
|
|
55
65
|
"vue": ">=3",
|
|
56
|
-
"svelte": ">=
|
|
66
|
+
"svelte": ">=5"
|
|
57
67
|
},
|
|
58
68
|
"peerDependenciesMeta": {
|
|
59
69
|
"react": {
|
|
@@ -85,7 +95,7 @@
|
|
|
85
95
|
"prettier": "^3.0.3",
|
|
86
96
|
"react": "^18.2.0",
|
|
87
97
|
"react-dom": "^18.2.0",
|
|
88
|
-
"svelte": "^
|
|
98
|
+
"svelte": "^5.0.0",
|
|
89
99
|
"tsup": "^8.5.0",
|
|
90
100
|
"typescript": "^5.9.3",
|
|
91
101
|
"vue": "^3.3.0"
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<component
|
|
3
|
-
:is="as"
|
|
4
|
-
ref="containerRef"
|
|
5
|
-
:class="props.class"
|
|
6
|
-
:style="props.style"
|
|
7
|
-
></component>
|
|
8
|
-
</template>
|
|
9
|
-
|
|
10
|
-
<script setup lang="ts">
|
|
11
|
-
import { ref, onMounted, onUnmounted, watch } from "vue";
|
|
12
|
-
import { TextMorph as Morph } from "../lib/text-morph";
|
|
13
|
-
import type { TextMorphProps } from "./types";
|
|
14
|
-
|
|
15
|
-
const props = withDefaults(defineProps<TextMorphProps>(), {
|
|
16
|
-
locale: "en",
|
|
17
|
-
duration: 400,
|
|
18
|
-
ease: "cubic-bezier(0.19, 1, 0.22, 1)",
|
|
19
|
-
disabled: false,
|
|
20
|
-
respectReducedMotion: true,
|
|
21
|
-
as: "div",
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const containerRef = ref<HTMLElement | null>(null);
|
|
25
|
-
let morphInstance: Morph | null = null;
|
|
26
|
-
|
|
27
|
-
onMounted(() => {
|
|
28
|
-
if (containerRef.value) {
|
|
29
|
-
morphInstance = new Morph({
|
|
30
|
-
element: containerRef.value,
|
|
31
|
-
locale: props.locale,
|
|
32
|
-
duration: props.duration,
|
|
33
|
-
ease: props.ease,
|
|
34
|
-
debug: props.debug,
|
|
35
|
-
disabled: props.disabled,
|
|
36
|
-
respectReducedMotion: props.respectReducedMotion,
|
|
37
|
-
onAnimationStart: props.onAnimationStart,
|
|
38
|
-
onAnimationComplete: props.onAnimationComplete,
|
|
39
|
-
});
|
|
40
|
-
morphInstance.update(props.text);
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
onUnmounted(() => {
|
|
45
|
-
morphInstance?.destroy();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
watch(
|
|
49
|
-
() => props.text,
|
|
50
|
-
(newText) => {
|
|
51
|
-
morphInstance?.update(newText);
|
|
52
|
-
},
|
|
53
|
-
);
|
|
54
|
-
</script>
|
package/dist/chunk-5MHVW5FX.mjs
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
var E=class f{element;options={};data;currentMeasures={};prevMeasures={};isInitialRender=!0;prefersReducedMotion=!1;mediaQuery;static styleEl;constructor(t){if(this.options={locale:"en",duration:400,scale:!0,ease:"cubic-bezier(0.19, 1, 0.22, 1)",respectReducedMotion:!0,...t},this.element=t.element,typeof window<"u"&&this.options.respectReducedMotion){this.mediaQuery=window.matchMedia("(prefers-reduced-motion: reduce)"),this.prefersReducedMotion=this.mediaQuery.matches;let s=o=>{this.prefersReducedMotion=o.matches};this.mediaQuery.addEventListener("change",s)}this.isDisabled()||(this.element.setAttribute("torph-root",""),this.element.style.transitionDuration=`${this.options.duration}ms`,this.element.style.transitionTimingFunction=this.options.ease,t.debug&&this.element.setAttribute("torph-debug","")),this.data=this.element.innerHTML,this.isDisabled()||this.addStyles()}destroy(){this.mediaQuery&&this.mediaQuery.removeEventListener("change",this.handleMediaQueryChange),this.element.getAnimations().forEach(t=>t.cancel()),this.element.removeAttribute("torph-root"),this.element.removeAttribute("torph-debug"),this.removeStyles()}handleMediaQueryChange=t=>{this.prefersReducedMotion=t.matches};isDisabled(){return!!(this.options.disabled||this.options.respectReducedMotion&&this.prefersReducedMotion)}update(t){if(t!==this.data){if(this.data=t,this.isDisabled()){typeof t=="string"&&(this.element.textContent=t);return}if(this.data instanceof HTMLElement)throw new Error("HTMLElement not yet supported");this.options.onAnimationStart&&!this.isInitialRender&&this.options.onAnimationStart(),this.createTextGroup(this.data,this.element)}}createTextGroup(t,s){let o=s.offsetWidth,i=s.offsetHeight,a=t.includes(" "),h;if(typeof Intl.Segmenter<"u"){let r=new Intl.Segmenter(this.options.locale,{granularity:a?"word":"grapheme"}).segment(t)[Symbol.iterator]();h=this.blocks(r)}else h=this.blocksFallback(t,a);this.prevMeasures=this.measure();let l=Array.from(s.children),d=new Set(h.map(e=>e.id)),g=l.filter(e=>!d.has(e.getAttribute("torph-id"))&&!e.hasAttribute("torph-exiting")),y=new Set(g),m=new Map;for(let e=0;e<l.length;e++){let r=l[e];if(!y.has(r))continue;let p=null;for(let n=e+1;n<l.length;n++){let u=l[n].getAttribute("torph-id");if(d.has(u)&&!y.has(l[n])){p=u;break}}if(!p)for(let n=e-1;n>=0;n--){let u=l[n].getAttribute("torph-id");if(d.has(u)&&!y.has(l[n])){p=u;break}}m.set(r,p)}let x=s.getBoundingClientRect();if(g.forEach(e=>{let r=e.getBoundingClientRect();e.setAttribute("torph-exiting",""),e.style.position="absolute",e.style.pointerEvents="none",e.style.left=`${r.left-x.left}px`,e.style.top=`${r.top-x.top}px`,e.style.width=`${r.width}px`,e.style.height=`${r.height}px`}),l.forEach(e=>{let r=e.getAttribute("torph-id");d.has(r)&&e.remove()}),h.forEach(e=>{let r=document.createElement("span");r.setAttribute("torph-item",""),r.setAttribute("torph-id",e.id),r.textContent=e.string,s.appendChild(r)}),this.currentMeasures=this.measure(),this.updateStyles(h),g.forEach(e=>{if(this.isInitialRender){e.remove();return}let r=m.get(e),p=0,n=0;if(r&&this.prevMeasures[r]&&this.currentMeasures[r]){let M=this.prevMeasures[r],v=this.currentMeasures[r];p=v.x-M.x,n=v.y-M.y}e.getAnimations().forEach(M=>M.cancel()),e.animate({transform:this.options.scale?`translate(${p}px, ${n}px) scale(0.95)`:`translate(${p}px, ${n}px)`,offset:1},{duration:this.options.duration,easing:this.options.ease,fill:"both"});let u=e.animate({opacity:0,offset:1},{duration:this.options.duration*.25,easing:"linear",fill:"both"});u.onfinish=()=>e.remove()}),this.isInitialRender){this.isInitialRender=!1,s.style.width="auto",s.style.height="auto";return}if(o===0||i===0)return;s.style.width="auto",s.style.height="auto",s.offsetWidth;let c=s.offsetWidth,b=s.offsetHeight;s.style.width=`${o}px`,s.style.height=`${i}px`,s.offsetWidth,s.style.width=`${c}px`,s.style.height=`${b}px`,setTimeout(()=>{s.style.width="auto",s.style.height="auto",this.options.onAnimationComplete&&this.options.onAnimationComplete()},this.options.duration)}measure(){let t=Array.from(this.element.children),s={};return t.forEach((o,i)=>{if(o.hasAttribute("torph-exiting"))return;let a=o.getAttribute("torph-id")||`child-${i}`;s[a]={x:o.offsetLeft,y:o.offsetTop}}),s}updateStyles(t){if(this.isInitialRender)return;let s=Array.from(this.element.children),o=new Set(t.map(i=>i.id).filter(i=>this.prevMeasures[i]));s.forEach((i,a)=>{if(i.hasAttribute("torph-exiting"))return;let h=i.getAttribute("torph-id")||`child-${a}`,l=this.prevMeasures[h],d=this.currentMeasures[h],g=d?.x||0,y=d?.y||0,m=l?l.x-g:0,x=l?l.y-y:0,c=!l;if(c){let r=t.findIndex(n=>n.id===h),p=null;for(let n=r-1;n>=0;n--)if(o.has(t[n].id)){p=t[n].id;break}if(!p){for(let n=r+1;n<t.length;n++)if(o.has(t[n].id)){p=t[n].id;break}}if(p){let n=this.prevMeasures[p],u=this.currentMeasures[p];m=n.x-u.x,x=n.y-u.y}}i.getAnimations().forEach(r=>r.cancel()),i.animate({transform:`translate(${m}px, ${x}px) scale(${c?.95:1})`,offset:0},{duration:this.options.duration,easing:this.options.ease,fill:"both"});let b=c?this.options.duration*.25:0,e=c?this.options.duration*.25:0;i.animate({opacity:c?0:1,offset:0},{duration:b,delay:e,easing:"linear",fill:"both"})})}addStyles(){if(f.styleEl)return;let t=document.createElement("style");t.dataset.torph="true",t.innerHTML=`
|
|
3
|
-
[torph-root] {
|
|
4
|
-
display: inline-flex;
|
|
5
|
-
position: relative;
|
|
6
|
-
will-change: width, height;
|
|
7
|
-
transition-property: width, height;
|
|
8
|
-
white-space: nowrap;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
[torph-item] {
|
|
12
|
-
display: inline-block;
|
|
13
|
-
will-change: opacity, transform;
|
|
14
|
-
transform: none;
|
|
15
|
-
opacity: 1;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
[torph-root][torph-debug] {
|
|
19
|
-
outline:2px solid magenta;
|
|
20
|
-
[torph-item] {
|
|
21
|
-
outline:2px solid cyan;
|
|
22
|
-
outline-offset: -4px;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
`,document.head.appendChild(t),f.styleEl=t}removeStyles(){f.styleEl&&(f.styleEl.remove(),f.styleEl=void 0)}blocks(t){return Array.from(t).reduce((o,i)=>i.segment===" "?[...o,{id:`space-${i.index}`,string:"\xA0"}]:o.find(h=>h.string===i.segment)?[...o,{id:`${i.segment}-${i.index}`,string:i.segment}]:[...o,{id:i.segment,string:i.segment}],[])}blocksFallback(t,s){let o=s?t.split(" "):t.split(""),i=[];return s?o.forEach((a,h)=>{h>0&&i.push({id:`space-${h}`,string:"\xA0"}),i.find(d=>d.string===a)?i.push({id:`${a}-${h}`,string:a}):i.push({id:a,string:a})}):o.forEach((a,h)=>{i.find(d=>d.string===a)?i.push({id:`${a}-${h}`,string:a}):i.push({id:a,string:a})}),i}log(...t){this.options.debug&&console.log("[TextMorph]",...t)}};export{E as a};
|
|
26
|
-
//# sourceMappingURL=chunk-5MHVW5FX.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/text-morph/index.ts"],"sourcesContent":["import type { TextMorphOptions } from \"./types\";\n\nexport type { TextMorphOptions } from \"./types\";\n\ntype Block = {\n id: string;\n string: string;\n};\ntype Measures = {\n [key: string]: { x: number; y: number };\n};\n\nexport class TextMorph {\n private element: HTMLElement;\n private options: Omit<TextMorphOptions, \"element\"> = {};\n\n private data: HTMLElement | string;\n\n private currentMeasures: Measures = {};\n private prevMeasures: Measures = {};\n private isInitialRender = true;\n private prefersReducedMotion = false;\n private mediaQuery?: MediaQueryList;\n\n static styleEl: HTMLStyleElement;\n\n constructor(options: TextMorphOptions) {\n this.options = {\n locale: \"en\",\n duration: 400,\n scale: true,\n ease: \"cubic-bezier(0.19, 1, 0.22, 1)\",\n respectReducedMotion: true,\n ...options,\n };\n\n this.element = options.element;\n\n // reduced motion detection\n if (typeof window !== \"undefined\" && this.options.respectReducedMotion) {\n this.mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n this.prefersReducedMotion = this.mediaQuery.matches;\n\n const listener = (event: MediaQueryListEvent) => {\n this.prefersReducedMotion = event.matches;\n };\n\n this.mediaQuery.addEventListener(\"change\", listener);\n }\n\n if (!this.isDisabled()) {\n this.element.setAttribute(\"torph-root\", \"\");\n this.element.style.transitionDuration = `${this.options.duration}ms`;\n this.element.style.transitionTimingFunction = this.options.ease!;\n\n if (options.debug) this.element.setAttribute(\"torph-debug\", \"\");\n }\n\n this.data = this.element.innerHTML;\n\n if (!this.isDisabled()) {\n this.addStyles();\n }\n }\n\n destroy() {\n if (this.mediaQuery) {\n this.mediaQuery.removeEventListener(\n \"change\",\n this.handleMediaQueryChange,\n );\n }\n this.element.getAnimations().forEach((anim) => anim.cancel());\n this.element.removeAttribute(\"torph-root\");\n this.element.removeAttribute(\"torph-debug\");\n this.removeStyles();\n }\n\n private handleMediaQueryChange = (event: MediaQueryListEvent) => {\n this.prefersReducedMotion = event.matches;\n };\n\n private isDisabled(): boolean {\n return Boolean(\n this.options.disabled ||\n (this.options.respectReducedMotion && this.prefersReducedMotion),\n );\n }\n\n update(value: HTMLElement | string) {\n if (value === this.data) return;\n this.data = value;\n\n if (this.isDisabled()) {\n if (typeof value === \"string\") {\n this.element.textContent = value;\n }\n return;\n }\n\n if (this.data instanceof HTMLElement) {\n // TODO: handle HTMLElement case\n throw new Error(\"HTMLElement not yet supported\");\n } else {\n if (this.options.onAnimationStart && !this.isInitialRender) {\n this.options.onAnimationStart();\n }\n this.createTextGroup(this.data, this.element);\n }\n }\n\n private createTextGroup(value: string, element: HTMLElement) {\n const oldWidth = element.offsetWidth;\n const oldHeight = element.offsetHeight;\n\n const byWord = value.includes(\" \");\n let blocks: Block[];\n\n if (typeof Intl.Segmenter !== \"undefined\") {\n const segmenter = new Intl.Segmenter(this.options.locale, {\n granularity: byWord ? \"word\" : \"grapheme\",\n });\n const iterator = segmenter.segment(value)[Symbol.iterator]();\n blocks = this.blocks(iterator);\n } else {\n // Fallback for browsers without Intl.Segmenter\n blocks = this.blocksFallback(value, byWord);\n }\n\n this.prevMeasures = this.measure();\n const oldChildren = Array.from(element.children) as HTMLElement[];\n const newIds = new Set(blocks.map((b) => b.id));\n\n const exiting = oldChildren.filter(\n (child) =>\n !newIds.has(child.getAttribute(\"torph-id\") as string) &&\n !child.hasAttribute(\"torph-exiting\"),\n );\n\n // For each exiting char, find the nearest persistent neighbor in old order\n // so we can make it follow that neighbor's FLIP movement\n const exitingSet = new Set(exiting);\n const exitingAnchorId = new Map<HTMLElement, string | null>();\n for (let i = 0; i < oldChildren.length; i++) {\n const child = oldChildren[i]!;\n if (!exitingSet.has(child)) continue;\n\n // Look forward for nearest persistent char\n let anchor: string | null = null;\n for (let j = i + 1; j < oldChildren.length; j++) {\n const siblingId = oldChildren[j]!.getAttribute(\"torph-id\") as string;\n if (newIds.has(siblingId) && !exitingSet.has(oldChildren[j]!)) {\n anchor = siblingId;\n break;\n }\n }\n // If none forward, look backward\n if (!anchor) {\n for (let j = i - 1; j >= 0; j--) {\n const siblingId = oldChildren[j]!.getAttribute(\"torph-id\") as string;\n if (newIds.has(siblingId) && !exitingSet.has(oldChildren[j]!)) {\n anchor = siblingId;\n break;\n }\n }\n }\n exitingAnchorId.set(child, anchor);\n }\n\n const parentRect = element.getBoundingClientRect();\n exiting.forEach((child) => {\n const rect = child.getBoundingClientRect();\n child.setAttribute(\"torph-exiting\", \"\");\n child.style.position = \"absolute\";\n child.style.pointerEvents = \"none\";\n child.style.left = `${rect.left - parentRect.left}px`;\n child.style.top = `${rect.top - parentRect.top}px`;\n child.style.width = `${rect.width}px`;\n child.style.height = `${rect.height}px`;\n });\n\n oldChildren.forEach((child) => {\n const id = child.getAttribute(\"torph-id\") as string;\n if (newIds.has(id)) child.remove();\n });\n\n blocks.forEach((block) => {\n const span = document.createElement(\"span\");\n span.setAttribute(\"torph-item\", \"\");\n span.setAttribute(\"torph-id\", block.id);\n span.textContent = block.string;\n element.appendChild(span);\n });\n\n this.currentMeasures = this.measure();\n this.updateStyles(blocks);\n\n exiting.forEach((child) => {\n if (this.isInitialRender) {\n child.remove();\n return;\n }\n\n // Find the anchor neighbor's FLIP delta so we move in sync with it\n const anchorId = exitingAnchorId.get(child);\n let dx = 0;\n let dy = 0;\n\n if (\n anchorId &&\n this.prevMeasures[anchorId] &&\n this.currentMeasures[anchorId]\n ) {\n const anchorPrev = this.prevMeasures[anchorId]!;\n const anchorCurr = this.currentMeasures[anchorId]!;\n dx = anchorCurr.x - anchorPrev.x;\n dy = anchorCurr.y - anchorPrev.y;\n }\n\n child.getAnimations().forEach((a) => a.cancel());\n child.animate(\n {\n transform: this.options.scale\n ? `translate(${dx}px, ${dy}px) scale(0.95)`\n : `translate(${dx}px, ${dy}px)`,\n offset: 1,\n },\n {\n duration: this.options.duration,\n easing: this.options.ease,\n fill: \"both\",\n },\n );\n const animation: Animation = child.animate(\n {\n opacity: 0,\n offset: 1,\n },\n {\n duration: this.options.duration! * 0.25,\n easing: \"linear\",\n fill: \"both\",\n },\n );\n animation.onfinish = () => child.remove();\n });\n\n if (this.isInitialRender) {\n this.isInitialRender = false;\n element.style.width = \"auto\";\n element.style.height = \"auto\";\n return;\n }\n\n if (oldWidth === 0 || oldHeight === 0) return;\n\n element.style.width = \"auto\";\n element.style.height = \"auto\";\n void element.offsetWidth; // force reflow\n\n const newWidth = element.offsetWidth;\n const newHeight = element.offsetHeight;\n\n element.style.width = `${oldWidth}px`;\n element.style.height = `${oldHeight}px`;\n void element.offsetWidth; // force reflow\n\n element.style.width = `${newWidth}px`;\n element.style.height = `${newHeight}px`;\n\n // TODO: move to `transitionend` event listener\n setTimeout(() => {\n element.style.width = \"auto\";\n element.style.height = \"auto\";\n if (this.options.onAnimationComplete) {\n this.options.onAnimationComplete();\n }\n }, this.options.duration);\n }\n\n private measure() {\n const children = Array.from(this.element.children) as HTMLElement[];\n const measures: Measures = {};\n\n children.forEach((child, index) => {\n if (child.hasAttribute(\"torph-exiting\")) return;\n const key = child.getAttribute(\"torph-id\") || `child-${index}`;\n measures[key] = {\n x: child.offsetLeft,\n y: child.offsetTop,\n };\n });\n\n return measures;\n }\n\n private updateStyles(blocks: Block[]) {\n if (this.isInitialRender) return;\n\n const children = Array.from(this.element.children) as HTMLElement[];\n\n const persistentIds = new Set(\n blocks.map((b) => b.id).filter((id) => this.prevMeasures[id]),\n );\n\n children.forEach((child, index) => {\n if (child.hasAttribute(\"torph-exiting\")) return;\n const key = child.getAttribute(\"torph-id\") || `child-${index}`;\n const prev = this.prevMeasures[key];\n const current = this.currentMeasures[key];\n\n const cx = current?.x || 0;\n const cy = current?.y || 0;\n\n let deltaX = prev ? prev.x - cx : 0;\n let deltaY = prev ? prev.y - cy : 0;\n const isNew = !prev;\n\n // For new chars, use the nearest persistent neighbor's FLIP delta\n // so all new chars get the same consistent offset\n if (isNew) {\n const blockIndex = blocks.findIndex((b) => b.id === key);\n let anchorId: string | null = null;\n\n for (let j = blockIndex - 1; j >= 0; j--) {\n if (persistentIds.has(blocks[j]!.id)) {\n anchorId = blocks[j]!.id;\n break;\n }\n }\n if (!anchorId) {\n for (let j = blockIndex + 1; j < blocks.length; j++) {\n if (persistentIds.has(blocks[j]!.id)) {\n anchorId = blocks[j]!.id;\n break;\n }\n }\n }\n\n if (anchorId) {\n const anchorPrev = this.prevMeasures[anchorId]!;\n const anchorCurr = this.currentMeasures[anchorId]!;\n deltaX = anchorPrev.x - anchorCurr.x;\n deltaY = anchorPrev.y - anchorCurr.y;\n }\n }\n\n child.getAnimations().forEach((a) => a.cancel());\n child.animate(\n {\n transform: `translate(${deltaX}px, ${deltaY}px) scale(${isNew ? 0.95 : 1})`,\n offset: 0,\n },\n {\n duration: this.options.duration,\n easing: this.options.ease,\n fill: \"both\",\n },\n );\n const duration = isNew ? this.options.duration! * 0.25 : 0;\n const delay = isNew ? this.options.duration! * 0.25 : 0;\n child.animate(\n {\n opacity: isNew ? 0 : 1,\n offset: 0,\n },\n {\n duration: duration,\n delay: delay,\n easing: \"linear\",\n fill: \"both\",\n },\n );\n });\n }\n\n private addStyles() {\n if (TextMorph.styleEl) return;\n\n const style = document.createElement(\"style\");\n style.dataset.torph = \"true\";\n style.innerHTML = `\n[torph-root] {\n display: inline-flex;\n position: relative;\n will-change: width, height;\n transition-property: width, height;\n white-space: nowrap;\n}\n\n[torph-item] {\n display: inline-block;\n will-change: opacity, transform;\n transform: none;\n opacity: 1;\n}\n\n[torph-root][torph-debug] {\n outline:2px solid magenta;\n [torph-item] {\n outline:2px solid cyan;\n outline-offset: -4px;\n }\n}\n `;\n document.head.appendChild(style);\n TextMorph.styleEl = style;\n }\n\n private removeStyles() {\n if (TextMorph.styleEl) {\n TextMorph.styleEl.remove();\n TextMorph.styleEl = undefined!;\n }\n }\n\n // utils\n\n private blocks(iterator: Intl.SegmentIterator<Intl.SegmentData>) {\n const uniqueStrings: Block[] = Array.from(iterator).reduce(\n (acc, string) => {\n if (string.segment === \" \") {\n return [...acc, { id: `space-${string.index}`, string: \"\\u00A0\" }];\n }\n\n const existingString = acc.find((x) => x.string === string.segment);\n if (existingString) {\n return [\n ...acc,\n { id: `${string.segment}-${string.index}`, string: string.segment },\n ];\n }\n\n return [\n ...acc,\n {\n id: string.segment,\n string: string.segment,\n },\n ];\n },\n [] as Block[],\n );\n\n return uniqueStrings;\n }\n\n private blocksFallback(value: string, byWord: boolean): Block[] {\n const segments = byWord ? value.split(\" \") : value.split(\"\");\n const blocks: Block[] = [];\n\n if (byWord) {\n segments.forEach((segment, index) => {\n if (index > 0) {\n blocks.push({ id: `space-${index}`, string: \"\\u00A0\" });\n }\n const existing = blocks.find((x) => x.string === segment);\n if (existing) {\n blocks.push({ id: `${segment}-${index}`, string: segment });\n } else {\n blocks.push({ id: segment, string: segment });\n }\n });\n } else {\n segments.forEach((segment, index) => {\n const existing = blocks.find((x) => x.string === segment);\n if (existing) {\n blocks.push({ id: `${segment}-${index}`, string: segment });\n } else {\n blocks.push({ id: segment, string: segment });\n }\n });\n }\n\n return blocks;\n }\n\n private log(...args: any[]) {\n if (this.options.debug) console.log(\"[TextMorph]\", ...args);\n }\n}\n"],"mappings":";AAYO,IAAMA,EAAN,MAAMC,CAAU,CACb,QACA,QAA6C,CAAC,EAE9C,KAEA,gBAA4B,CAAC,EAC7B,aAAyB,CAAC,EAC1B,gBAAkB,GAClB,qBAAuB,GACvB,WAER,OAAO,QAEP,YAAYC,EAA2B,CAarC,GAZA,KAAK,QAAU,CACb,OAAQ,KACR,SAAU,IACV,MAAO,GACP,KAAM,iCACN,qBAAsB,GACtB,GAAGA,CACL,EAEA,KAAK,QAAUA,EAAQ,QAGnB,OAAO,OAAW,KAAe,KAAK,QAAQ,qBAAsB,CACtE,KAAK,WAAa,OAAO,WAAW,kCAAkC,EACtE,KAAK,qBAAuB,KAAK,WAAW,QAE5C,IAAMC,EAAYC,GAA+B,CAC/C,KAAK,qBAAuBA,EAAM,OACpC,EAEA,KAAK,WAAW,iBAAiB,SAAUD,CAAQ,CACrD,CAEK,KAAK,WAAW,IACnB,KAAK,QAAQ,aAAa,aAAc,EAAE,EAC1C,KAAK,QAAQ,MAAM,mBAAqB,GAAG,KAAK,QAAQ,QAAQ,KAChE,KAAK,QAAQ,MAAM,yBAA2B,KAAK,QAAQ,KAEvDD,EAAQ,OAAO,KAAK,QAAQ,aAAa,cAAe,EAAE,GAGhE,KAAK,KAAO,KAAK,QAAQ,UAEpB,KAAK,WAAW,GACnB,KAAK,UAAU,CAEnB,CAEA,SAAU,CACJ,KAAK,YACP,KAAK,WAAW,oBACd,SACA,KAAK,sBACP,EAEF,KAAK,QAAQ,cAAc,EAAE,QAASG,GAASA,EAAK,OAAO,CAAC,EAC5D,KAAK,QAAQ,gBAAgB,YAAY,EACzC,KAAK,QAAQ,gBAAgB,aAAa,EAC1C,KAAK,aAAa,CACpB,CAEQ,uBAA0BD,GAA+B,CAC/D,KAAK,qBAAuBA,EAAM,OACpC,EAEQ,YAAsB,CAC5B,MAAO,GACL,KAAK,QAAQ,UACV,KAAK,QAAQ,sBAAwB,KAAK,qBAEjD,CAEA,OAAOE,EAA6B,CAClC,GAAIA,IAAU,KAAK,KAGnB,IAFA,KAAK,KAAOA,EAER,KAAK,WAAW,EAAG,CACjB,OAAOA,GAAU,WACnB,KAAK,QAAQ,YAAcA,GAE7B,MACF,CAEA,GAAI,KAAK,gBAAgB,YAEvB,MAAM,IAAI,MAAM,+BAA+B,EAE3C,KAAK,QAAQ,kBAAoB,CAAC,KAAK,iBACzC,KAAK,QAAQ,iBAAiB,EAEhC,KAAK,gBAAgB,KAAK,KAAM,KAAK,OAAO,EAEhD,CAEQ,gBAAgBA,EAAeC,EAAsB,CAC3D,IAAMC,EAAWD,EAAQ,YACnBE,EAAYF,EAAQ,aAEpBG,EAASJ,EAAM,SAAS,GAAG,EAC7BK,EAEJ,GAAI,OAAO,KAAK,UAAc,IAAa,CAIzC,IAAMC,EAHY,IAAI,KAAK,UAAU,KAAK,QAAQ,OAAQ,CACxD,YAAaF,EAAS,OAAS,UACjC,CAAC,EAC0B,QAAQJ,CAAK,EAAE,OAAO,QAAQ,EAAE,EAC3DK,EAAS,KAAK,OAAOC,CAAQ,CAC/B,MAEED,EAAS,KAAK,eAAeL,EAAOI,CAAM,EAG5C,KAAK,aAAe,KAAK,QAAQ,EACjC,IAAMG,EAAc,MAAM,KAAKN,EAAQ,QAAQ,EACzCO,EAAS,IAAI,IAAIH,EAAO,IAAKI,GAAMA,EAAE,EAAE,CAAC,EAExCC,EAAUH,EAAY,OACzBI,GACC,CAACH,EAAO,IAAIG,EAAM,aAAa,UAAU,CAAW,GACpD,CAACA,EAAM,aAAa,eAAe,CACvC,EAIMC,EAAa,IAAI,IAAIF,CAAO,EAC5BG,EAAkB,IAAI,IAC5B,QAASC,EAAI,EAAGA,EAAIP,EAAY,OAAQO,IAAK,CAC3C,IAAMH,EAAQJ,EAAYO,CAAC,EAC3B,GAAI,CAACF,EAAW,IAAID,CAAK,EAAG,SAG5B,IAAII,EAAwB,KAC5B,QAASC,EAAIF,EAAI,EAAGE,EAAIT,EAAY,OAAQS,IAAK,CAC/C,IAAMC,EAAYV,EAAYS,CAAC,EAAG,aAAa,UAAU,EACzD,GAAIR,EAAO,IAAIS,CAAS,GAAK,CAACL,EAAW,IAAIL,EAAYS,CAAC,CAAE,EAAG,CAC7DD,EAASE,EACT,KACF,CACF,CAEA,GAAI,CAACF,EACH,QAASC,EAAIF,EAAI,EAAGE,GAAK,EAAGA,IAAK,CAC/B,IAAMC,EAAYV,EAAYS,CAAC,EAAG,aAAa,UAAU,EACzD,GAAIR,EAAO,IAAIS,CAAS,GAAK,CAACL,EAAW,IAAIL,EAAYS,CAAC,CAAE,EAAG,CAC7DD,EAASE,EACT,KACF,CACF,CAEFJ,EAAgB,IAAIF,EAAOI,CAAM,CACnC,CAEA,IAAMG,EAAajB,EAAQ,sBAAsB,EA8EjD,GA7EAS,EAAQ,QAASC,GAAU,CACzB,IAAMQ,EAAOR,EAAM,sBAAsB,EACzCA,EAAM,aAAa,gBAAiB,EAAE,EACtCA,EAAM,MAAM,SAAW,WACvBA,EAAM,MAAM,cAAgB,OAC5BA,EAAM,MAAM,KAAO,GAAGQ,EAAK,KAAOD,EAAW,IAAI,KACjDP,EAAM,MAAM,IAAM,GAAGQ,EAAK,IAAMD,EAAW,GAAG,KAC9CP,EAAM,MAAM,MAAQ,GAAGQ,EAAK,KAAK,KACjCR,EAAM,MAAM,OAAS,GAAGQ,EAAK,MAAM,IACrC,CAAC,EAEDZ,EAAY,QAASI,GAAU,CAC7B,IAAMS,EAAKT,EAAM,aAAa,UAAU,EACpCH,EAAO,IAAIY,CAAE,GAAGT,EAAM,OAAO,CACnC,CAAC,EAEDN,EAAO,QAASgB,GAAU,CACxB,IAAMC,EAAO,SAAS,cAAc,MAAM,EAC1CA,EAAK,aAAa,aAAc,EAAE,EAClCA,EAAK,aAAa,WAAYD,EAAM,EAAE,EACtCC,EAAK,YAAcD,EAAM,OACzBpB,EAAQ,YAAYqB,CAAI,CAC1B,CAAC,EAED,KAAK,gBAAkB,KAAK,QAAQ,EACpC,KAAK,aAAajB,CAAM,EAExBK,EAAQ,QAASC,GAAU,CACzB,GAAI,KAAK,gBAAiB,CACxBA,EAAM,OAAO,EACb,MACF,CAGA,IAAMY,EAAWV,EAAgB,IAAIF,CAAK,EACtCa,EAAK,EACLC,EAAK,EAET,GACEF,GACA,KAAK,aAAaA,CAAQ,GAC1B,KAAK,gBAAgBA,CAAQ,EAC7B,CACA,IAAMG,EAAa,KAAK,aAAaH,CAAQ,EACvCI,EAAa,KAAK,gBAAgBJ,CAAQ,EAChDC,EAAKG,EAAW,EAAID,EAAW,EAC/BD,EAAKE,EAAW,EAAID,EAAW,CACjC,CAEAf,EAAM,cAAc,EAAE,QAASiB,GAAMA,EAAE,OAAO,CAAC,EAC/CjB,EAAM,QACJ,CACE,UAAW,KAAK,QAAQ,MACpB,aAAaa,CAAE,OAAOC,CAAE,kBACxB,aAAaD,CAAE,OAAOC,CAAE,MAC5B,OAAQ,CACV,EACA,CACE,SAAU,KAAK,QAAQ,SACvB,OAAQ,KAAK,QAAQ,KACrB,KAAM,MACR,CACF,EACA,IAAMI,EAAuBlB,EAAM,QACjC,CACE,QAAS,EACT,OAAQ,CACV,EACA,CACE,SAAU,KAAK,QAAQ,SAAY,IACnC,OAAQ,SACR,KAAM,MACR,CACF,EACAkB,EAAU,SAAW,IAAMlB,EAAM,OAAO,CAC1C,CAAC,EAEG,KAAK,gBAAiB,CACxB,KAAK,gBAAkB,GACvBV,EAAQ,MAAM,MAAQ,OACtBA,EAAQ,MAAM,OAAS,OACvB,MACF,CAEA,GAAIC,IAAa,GAAKC,IAAc,EAAG,OAEvCF,EAAQ,MAAM,MAAQ,OACtBA,EAAQ,MAAM,OAAS,OAClBA,EAAQ,YAEb,IAAM6B,EAAW7B,EAAQ,YACnB8B,EAAY9B,EAAQ,aAE1BA,EAAQ,MAAM,MAAQ,GAAGC,CAAQ,KACjCD,EAAQ,MAAM,OAAS,GAAGE,CAAS,KAC9BF,EAAQ,YAEbA,EAAQ,MAAM,MAAQ,GAAG6B,CAAQ,KACjC7B,EAAQ,MAAM,OAAS,GAAG8B,CAAS,KAGnC,WAAW,IAAM,CACf9B,EAAQ,MAAM,MAAQ,OACtBA,EAAQ,MAAM,OAAS,OACnB,KAAK,QAAQ,qBACf,KAAK,QAAQ,oBAAoB,CAErC,EAAG,KAAK,QAAQ,QAAQ,CAC1B,CAEQ,SAAU,CAChB,IAAM+B,EAAW,MAAM,KAAK,KAAK,QAAQ,QAAQ,EAC3CC,EAAqB,CAAC,EAE5B,OAAAD,EAAS,QAAQ,CAACrB,EAAOuB,IAAU,CACjC,GAAIvB,EAAM,aAAa,eAAe,EAAG,OACzC,IAAMwB,EAAMxB,EAAM,aAAa,UAAU,GAAK,SAASuB,CAAK,GAC5DD,EAASE,CAAG,EAAI,CACd,EAAGxB,EAAM,WACT,EAAGA,EAAM,SACX,CACF,CAAC,EAEMsB,CACT,CAEQ,aAAa5B,EAAiB,CACpC,GAAI,KAAK,gBAAiB,OAE1B,IAAM2B,EAAW,MAAM,KAAK,KAAK,QAAQ,QAAQ,EAE3CI,EAAgB,IAAI,IACxB/B,EAAO,IAAKI,GAAMA,EAAE,EAAE,EAAE,OAAQW,GAAO,KAAK,aAAaA,CAAE,CAAC,CAC9D,EAEAY,EAAS,QAAQ,CAACrB,EAAOuB,IAAU,CACjC,GAAIvB,EAAM,aAAa,eAAe,EAAG,OACzC,IAAMwB,EAAMxB,EAAM,aAAa,UAAU,GAAK,SAASuB,CAAK,GACtDG,EAAO,KAAK,aAAaF,CAAG,EAC5BG,EAAU,KAAK,gBAAgBH,CAAG,EAElCI,EAAKD,GAAS,GAAK,EACnBE,EAAKF,GAAS,GAAK,EAErBG,EAASJ,EAAOA,EAAK,EAAIE,EAAK,EAC9BG,EAASL,EAAOA,EAAK,EAAIG,EAAK,EAC5BG,EAAQ,CAACN,EAIf,GAAIM,EAAO,CACT,IAAMC,EAAavC,EAAO,UAAWI,GAAMA,EAAE,KAAO0B,CAAG,EACnDZ,EAA0B,KAE9B,QAASP,EAAI4B,EAAa,EAAG5B,GAAK,EAAGA,IACnC,GAAIoB,EAAc,IAAI/B,EAAOW,CAAC,EAAG,EAAE,EAAG,CACpCO,EAAWlB,EAAOW,CAAC,EAAG,GACtB,KACF,CAEF,GAAI,CAACO,GACH,QAASP,EAAI4B,EAAa,EAAG5B,EAAIX,EAAO,OAAQW,IAC9C,GAAIoB,EAAc,IAAI/B,EAAOW,CAAC,EAAG,EAAE,EAAG,CACpCO,EAAWlB,EAAOW,CAAC,EAAG,GACtB,KACF,EAIJ,GAAIO,EAAU,CACZ,IAAMG,EAAa,KAAK,aAAaH,CAAQ,EACvCI,EAAa,KAAK,gBAAgBJ,CAAQ,EAChDkB,EAASf,EAAW,EAAIC,EAAW,EACnCe,EAAShB,EAAW,EAAIC,EAAW,CACrC,CACF,CAEAhB,EAAM,cAAc,EAAE,QAASiB,GAAMA,EAAE,OAAO,CAAC,EAC/CjB,EAAM,QACJ,CACE,UAAW,aAAa8B,CAAM,OAAOC,CAAM,aAAaC,EAAQ,IAAO,CAAC,IACxE,OAAQ,CACV,EACA,CACE,SAAU,KAAK,QAAQ,SACvB,OAAQ,KAAK,QAAQ,KACrB,KAAM,MACR,CACF,EACA,IAAME,EAAWF,EAAQ,KAAK,QAAQ,SAAY,IAAO,EACnDG,EAAQH,EAAQ,KAAK,QAAQ,SAAY,IAAO,EACtDhC,EAAM,QACJ,CACE,QAASgC,EAAQ,EAAI,EACrB,OAAQ,CACV,EACA,CACE,SAAUE,EACV,MAAOC,EACP,OAAQ,SACR,KAAM,MACR,CACF,CACF,CAAC,CACH,CAEQ,WAAY,CAClB,GAAInD,EAAU,QAAS,OAEvB,IAAMoD,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,QAAQ,MAAQ,OACtBA,EAAM,UAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAwBlB,SAAS,KAAK,YAAYA,CAAK,EAC/BpD,EAAU,QAAUoD,CACtB,CAEQ,cAAe,CACjBpD,EAAU,UACZA,EAAU,QAAQ,OAAO,EACzBA,EAAU,QAAU,OAExB,CAIQ,OAAOW,EAAkD,CA0B/D,OAzB+B,MAAM,KAAKA,CAAQ,EAAE,OAClD,CAAC0C,EAAKC,IACAA,EAAO,UAAY,IACd,CAAC,GAAGD,EAAK,CAAE,GAAI,SAASC,EAAO,KAAK,GAAI,OAAQ,MAAS,CAAC,EAG5CD,EAAI,KAAME,GAAMA,EAAE,SAAWD,EAAO,OAAO,EAEzD,CACL,GAAGD,EACH,CAAE,GAAI,GAAGC,EAAO,OAAO,IAAIA,EAAO,KAAK,GAAI,OAAQA,EAAO,OAAQ,CACpE,EAGK,CACL,GAAGD,EACH,CACE,GAAIC,EAAO,QACX,OAAQA,EAAO,OACjB,CACF,EAEF,CAAC,CACH,CAGF,CAEQ,eAAejD,EAAeI,EAA0B,CAC9D,IAAM+C,EAAW/C,EAASJ,EAAM,MAAM,GAAG,EAAIA,EAAM,MAAM,EAAE,EACrDK,EAAkB,CAAC,EAEzB,OAAID,EACF+C,EAAS,QAAQ,CAACC,EAASlB,IAAU,CAC/BA,EAAQ,GACV7B,EAAO,KAAK,CAAE,GAAI,SAAS6B,CAAK,GAAI,OAAQ,MAAS,CAAC,EAEvC7B,EAAO,KAAM6C,GAAMA,EAAE,SAAWE,CAAO,EAEtD/C,EAAO,KAAK,CAAE,GAAI,GAAG+C,CAAO,IAAIlB,CAAK,GAAI,OAAQkB,CAAQ,CAAC,EAE1D/C,EAAO,KAAK,CAAE,GAAI+C,EAAS,OAAQA,CAAQ,CAAC,CAEhD,CAAC,EAEDD,EAAS,QAAQ,CAACC,EAASlB,IAAU,CAClB7B,EAAO,KAAM6C,GAAMA,EAAE,SAAWE,CAAO,EAEtD/C,EAAO,KAAK,CAAE,GAAI,GAAG+C,CAAO,IAAIlB,CAAK,GAAI,OAAQkB,CAAQ,CAAC,EAE1D/C,EAAO,KAAK,CAAE,GAAI+C,EAAS,OAAQA,CAAQ,CAAC,CAEhD,CAAC,EAGI/C,CACT,CAEQ,OAAOgD,EAAa,CACtB,KAAK,QAAQ,OAAO,QAAQ,IAAI,cAAe,GAAGA,CAAI,CAC5D,CACF","names":["TextMorph","_TextMorph","options","listener","event","anim","value","element","oldWidth","oldHeight","byWord","blocks","iterator","oldChildren","newIds","b","exiting","child","exitingSet","exitingAnchorId","i","anchor","j","siblingId","parentRect","rect","id","block","span","anchorId","dx","dy","anchorPrev","anchorCurr","a","animation","newWidth","newHeight","children","measures","index","key","persistentIds","prev","current","cx","cy","deltaX","deltaY","isNew","blockIndex","duration","delay","style","acc","string","x","segments","segment","args"]}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../package.json","../src/lib/text-morph/index.ts"],"sourcesContent":["export { version } from \"./../package.json\";\n\nexport { TextMorph } from \"./lib/text-morph\";\nexport type { TextMorphOptions } from \"./lib/text-morph/types\";\n","{\n \"name\": \"torph\",\n \"version\": \"0.0.5\",\n \"description\": \"Dependency-free animated text component.\",\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 \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\"\n },\n \"./react\": {\n \"types\": \"./dist/react/index.d.ts\",\n \"import\": \"./dist/react/index.mjs\",\n \"require\": \"./dist/react/index.js\"\n },\n \"./vue\": {\n \"types\": \"./dist/vue/index.d.ts\",\n \"import\": \"./dist/vue/index.mjs\",\n \"require\": \"./dist/vue/index.js\"\n },\n \"./svelte\": {\n \"types\": \"./dist/svelte/index.d.ts\",\n \"import\": \"./dist/svelte/index.mjs\",\n \"require\": \"./dist/svelte/index.js\"\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 \"vue\",\n \"svelte\",\n \"text\",\n \"animation\",\n \"morph\"\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 \"vue\": \">=3\",\n \"svelte\": \">=4\"\n },\n \"peerDependenciesMeta\": {\n \"react\": {\n \"optional\": true\n },\n \"react-dom\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"svelte\": {\n \"optional\": true\n }\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 \"svelte\": \"^4.0.0\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.9.3\",\n \"vue\": \"^3.3.0\"\n }\n}\n","import type { TextMorphOptions } from \"./types\";\n\nexport type { TextMorphOptions } from \"./types\";\n\ntype Block = {\n id: string;\n string: string;\n};\ntype Measures = {\n [key: string]: { x: number; y: number };\n};\n\nexport class TextMorph {\n private element: HTMLElement;\n private options: Omit<TextMorphOptions, \"element\"> = {};\n\n private data: HTMLElement | string;\n\n private currentMeasures: Measures = {};\n private prevMeasures: Measures = {};\n private isInitialRender = true;\n private prefersReducedMotion = false;\n private mediaQuery?: MediaQueryList;\n\n static styleEl: HTMLStyleElement;\n\n constructor(options: TextMorphOptions) {\n this.options = {\n locale: \"en\",\n duration: 400,\n scale: true,\n ease: \"cubic-bezier(0.19, 1, 0.22, 1)\",\n respectReducedMotion: true,\n ...options,\n };\n\n this.element = options.element;\n\n // reduced motion detection\n if (typeof window !== \"undefined\" && this.options.respectReducedMotion) {\n this.mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n this.prefersReducedMotion = this.mediaQuery.matches;\n\n const listener = (event: MediaQueryListEvent) => {\n this.prefersReducedMotion = event.matches;\n };\n\n this.mediaQuery.addEventListener(\"change\", listener);\n }\n\n if (!this.isDisabled()) {\n this.element.setAttribute(\"torph-root\", \"\");\n this.element.style.transitionDuration = `${this.options.duration}ms`;\n this.element.style.transitionTimingFunction = this.options.ease!;\n\n if (options.debug) this.element.setAttribute(\"torph-debug\", \"\");\n }\n\n this.data = this.element.innerHTML;\n\n if (!this.isDisabled()) {\n this.addStyles();\n }\n }\n\n destroy() {\n if (this.mediaQuery) {\n this.mediaQuery.removeEventListener(\n \"change\",\n this.handleMediaQueryChange,\n );\n }\n this.element.getAnimations().forEach((anim) => anim.cancel());\n this.element.removeAttribute(\"torph-root\");\n this.element.removeAttribute(\"torph-debug\");\n this.removeStyles();\n }\n\n private handleMediaQueryChange = (event: MediaQueryListEvent) => {\n this.prefersReducedMotion = event.matches;\n };\n\n private isDisabled(): boolean {\n return Boolean(\n this.options.disabled ||\n (this.options.respectReducedMotion && this.prefersReducedMotion),\n );\n }\n\n update(value: HTMLElement | string) {\n if (value === this.data) return;\n this.data = value;\n\n if (this.isDisabled()) {\n if (typeof value === \"string\") {\n this.element.textContent = value;\n }\n return;\n }\n\n if (this.data instanceof HTMLElement) {\n // TODO: handle HTMLElement case\n throw new Error(\"HTMLElement not yet supported\");\n } else {\n if (this.options.onAnimationStart && !this.isInitialRender) {\n this.options.onAnimationStart();\n }\n this.createTextGroup(this.data, this.element);\n }\n }\n\n private createTextGroup(value: string, element: HTMLElement) {\n const oldWidth = element.offsetWidth;\n const oldHeight = element.offsetHeight;\n\n const byWord = value.includes(\" \");\n let blocks: Block[];\n\n if (typeof Intl.Segmenter !== \"undefined\") {\n const segmenter = new Intl.Segmenter(this.options.locale, {\n granularity: byWord ? \"word\" : \"grapheme\",\n });\n const iterator = segmenter.segment(value)[Symbol.iterator]();\n blocks = this.blocks(iterator);\n } else {\n // Fallback for browsers without Intl.Segmenter\n blocks = this.blocksFallback(value, byWord);\n }\n\n this.prevMeasures = this.measure();\n const oldChildren = Array.from(element.children) as HTMLElement[];\n const newIds = new Set(blocks.map((b) => b.id));\n\n const exiting = oldChildren.filter(\n (child) =>\n !newIds.has(child.getAttribute(\"torph-id\") as string) &&\n !child.hasAttribute(\"torph-exiting\"),\n );\n\n // For each exiting char, find the nearest persistent neighbor in old order\n // so we can make it follow that neighbor's FLIP movement\n const exitingSet = new Set(exiting);\n const exitingAnchorId = new Map<HTMLElement, string | null>();\n for (let i = 0; i < oldChildren.length; i++) {\n const child = oldChildren[i]!;\n if (!exitingSet.has(child)) continue;\n\n // Look forward for nearest persistent char\n let anchor: string | null = null;\n for (let j = i + 1; j < oldChildren.length; j++) {\n const siblingId = oldChildren[j]!.getAttribute(\"torph-id\") as string;\n if (newIds.has(siblingId) && !exitingSet.has(oldChildren[j]!)) {\n anchor = siblingId;\n break;\n }\n }\n // If none forward, look backward\n if (!anchor) {\n for (let j = i - 1; j >= 0; j--) {\n const siblingId = oldChildren[j]!.getAttribute(\"torph-id\") as string;\n if (newIds.has(siblingId) && !exitingSet.has(oldChildren[j]!)) {\n anchor = siblingId;\n break;\n }\n }\n }\n exitingAnchorId.set(child, anchor);\n }\n\n const parentRect = element.getBoundingClientRect();\n exiting.forEach((child) => {\n const rect = child.getBoundingClientRect();\n child.setAttribute(\"torph-exiting\", \"\");\n child.style.position = \"absolute\";\n child.style.pointerEvents = \"none\";\n child.style.left = `${rect.left - parentRect.left}px`;\n child.style.top = `${rect.top - parentRect.top}px`;\n child.style.width = `${rect.width}px`;\n child.style.height = `${rect.height}px`;\n });\n\n oldChildren.forEach((child) => {\n const id = child.getAttribute(\"torph-id\") as string;\n if (newIds.has(id)) child.remove();\n });\n\n blocks.forEach((block) => {\n const span = document.createElement(\"span\");\n span.setAttribute(\"torph-item\", \"\");\n span.setAttribute(\"torph-id\", block.id);\n span.textContent = block.string;\n element.appendChild(span);\n });\n\n this.currentMeasures = this.measure();\n this.updateStyles(blocks);\n\n exiting.forEach((child) => {\n if (this.isInitialRender) {\n child.remove();\n return;\n }\n\n // Find the anchor neighbor's FLIP delta so we move in sync with it\n const anchorId = exitingAnchorId.get(child);\n let dx = 0;\n let dy = 0;\n\n if (\n anchorId &&\n this.prevMeasures[anchorId] &&\n this.currentMeasures[anchorId]\n ) {\n const anchorPrev = this.prevMeasures[anchorId]!;\n const anchorCurr = this.currentMeasures[anchorId]!;\n dx = anchorCurr.x - anchorPrev.x;\n dy = anchorCurr.y - anchorPrev.y;\n }\n\n child.getAnimations().forEach((a) => a.cancel());\n child.animate(\n {\n transform: this.options.scale\n ? `translate(${dx}px, ${dy}px) scale(0.95)`\n : `translate(${dx}px, ${dy}px)`,\n offset: 1,\n },\n {\n duration: this.options.duration,\n easing: this.options.ease,\n fill: \"both\",\n },\n );\n const animation: Animation = child.animate(\n {\n opacity: 0,\n offset: 1,\n },\n {\n duration: this.options.duration! * 0.25,\n easing: \"linear\",\n fill: \"both\",\n },\n );\n animation.onfinish = () => child.remove();\n });\n\n if (this.isInitialRender) {\n this.isInitialRender = false;\n element.style.width = \"auto\";\n element.style.height = \"auto\";\n return;\n }\n\n if (oldWidth === 0 || oldHeight === 0) return;\n\n element.style.width = \"auto\";\n element.style.height = \"auto\";\n void element.offsetWidth; // force reflow\n\n const newWidth = element.offsetWidth;\n const newHeight = element.offsetHeight;\n\n element.style.width = `${oldWidth}px`;\n element.style.height = `${oldHeight}px`;\n void element.offsetWidth; // force reflow\n\n element.style.width = `${newWidth}px`;\n element.style.height = `${newHeight}px`;\n\n // TODO: move to `transitionend` event listener\n setTimeout(() => {\n element.style.width = \"auto\";\n element.style.height = \"auto\";\n if (this.options.onAnimationComplete) {\n this.options.onAnimationComplete();\n }\n }, this.options.duration);\n }\n\n private measure() {\n const children = Array.from(this.element.children) as HTMLElement[];\n const measures: Measures = {};\n\n children.forEach((child, index) => {\n if (child.hasAttribute(\"torph-exiting\")) return;\n const key = child.getAttribute(\"torph-id\") || `child-${index}`;\n measures[key] = {\n x: child.offsetLeft,\n y: child.offsetTop,\n };\n });\n\n return measures;\n }\n\n private updateStyles(blocks: Block[]) {\n if (this.isInitialRender) return;\n\n const children = Array.from(this.element.children) as HTMLElement[];\n\n const persistentIds = new Set(\n blocks.map((b) => b.id).filter((id) => this.prevMeasures[id]),\n );\n\n children.forEach((child, index) => {\n if (child.hasAttribute(\"torph-exiting\")) return;\n const key = child.getAttribute(\"torph-id\") || `child-${index}`;\n const prev = this.prevMeasures[key];\n const current = this.currentMeasures[key];\n\n const cx = current?.x || 0;\n const cy = current?.y || 0;\n\n let deltaX = prev ? prev.x - cx : 0;\n let deltaY = prev ? prev.y - cy : 0;\n const isNew = !prev;\n\n // For new chars, use the nearest persistent neighbor's FLIP delta\n // so all new chars get the same consistent offset\n if (isNew) {\n const blockIndex = blocks.findIndex((b) => b.id === key);\n let anchorId: string | null = null;\n\n for (let j = blockIndex - 1; j >= 0; j--) {\n if (persistentIds.has(blocks[j]!.id)) {\n anchorId = blocks[j]!.id;\n break;\n }\n }\n if (!anchorId) {\n for (let j = blockIndex + 1; j < blocks.length; j++) {\n if (persistentIds.has(blocks[j]!.id)) {\n anchorId = blocks[j]!.id;\n break;\n }\n }\n }\n\n if (anchorId) {\n const anchorPrev = this.prevMeasures[anchorId]!;\n const anchorCurr = this.currentMeasures[anchorId]!;\n deltaX = anchorPrev.x - anchorCurr.x;\n deltaY = anchorPrev.y - anchorCurr.y;\n }\n }\n\n child.getAnimations().forEach((a) => a.cancel());\n child.animate(\n {\n transform: `translate(${deltaX}px, ${deltaY}px) scale(${isNew ? 0.95 : 1})`,\n offset: 0,\n },\n {\n duration: this.options.duration,\n easing: this.options.ease,\n fill: \"both\",\n },\n );\n const duration = isNew ? this.options.duration! * 0.25 : 0;\n const delay = isNew ? this.options.duration! * 0.25 : 0;\n child.animate(\n {\n opacity: isNew ? 0 : 1,\n offset: 0,\n },\n {\n duration: duration,\n delay: delay,\n easing: \"linear\",\n fill: \"both\",\n },\n );\n });\n }\n\n private addStyles() {\n if (TextMorph.styleEl) return;\n\n const style = document.createElement(\"style\");\n style.dataset.torph = \"true\";\n style.innerHTML = `\n[torph-root] {\n display: inline-flex;\n position: relative;\n will-change: width, height;\n transition-property: width, height;\n white-space: nowrap;\n}\n\n[torph-item] {\n display: inline-block;\n will-change: opacity, transform;\n transform: none;\n opacity: 1;\n}\n\n[torph-root][torph-debug] {\n outline:2px solid magenta;\n [torph-item] {\n outline:2px solid cyan;\n outline-offset: -4px;\n }\n}\n `;\n document.head.appendChild(style);\n TextMorph.styleEl = style;\n }\n\n private removeStyles() {\n if (TextMorph.styleEl) {\n TextMorph.styleEl.remove();\n TextMorph.styleEl = undefined!;\n }\n }\n\n // utils\n\n private blocks(iterator: Intl.SegmentIterator<Intl.SegmentData>) {\n const uniqueStrings: Block[] = Array.from(iterator).reduce(\n (acc, string) => {\n if (string.segment === \" \") {\n return [...acc, { id: `space-${string.index}`, string: \"\\u00A0\" }];\n }\n\n const existingString = acc.find((x) => x.string === string.segment);\n if (existingString) {\n return [\n ...acc,\n { id: `${string.segment}-${string.index}`, string: string.segment },\n ];\n }\n\n return [\n ...acc,\n {\n id: string.segment,\n string: string.segment,\n },\n ];\n },\n [] as Block[],\n );\n\n return uniqueStrings;\n }\n\n private blocksFallback(value: string, byWord: boolean): Block[] {\n const segments = byWord ? value.split(\" \") : value.split(\"\");\n const blocks: Block[] = [];\n\n if (byWord) {\n segments.forEach((segment, index) => {\n if (index > 0) {\n blocks.push({ id: `space-${index}`, string: \"\\u00A0\" });\n }\n const existing = blocks.find((x) => x.string === segment);\n if (existing) {\n blocks.push({ id: `${segment}-${index}`, string: segment });\n } else {\n blocks.push({ id: segment, string: segment });\n }\n });\n } else {\n segments.forEach((segment, index) => {\n const existing = blocks.find((x) => x.string === segment);\n if (existing) {\n blocks.push({ id: `${segment}-${index}`, string: segment });\n } else {\n blocks.push({ id: segment, string: segment });\n }\n });\n }\n\n return blocks;\n }\n\n private log(...args: any[]) {\n if (this.options.debug) console.log(\"[TextMorph]\", ...args);\n }\n}\n"],"mappings":";yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,eAAAE,EAAA,YAAAC,IAAA,eAAAC,EAAAJ,GCEE,IAAAK,EAAW,QCUN,IAAMC,EAAN,MAAMC,CAAU,CACb,QACA,QAA6C,CAAC,EAE9C,KAEA,gBAA4B,CAAC,EAC7B,aAAyB,CAAC,EAC1B,gBAAkB,GAClB,qBAAuB,GACvB,WAER,OAAO,QAEP,YAAYC,EAA2B,CAarC,GAZA,KAAK,QAAU,CACb,OAAQ,KACR,SAAU,IACV,MAAO,GACP,KAAM,iCACN,qBAAsB,GACtB,GAAGA,CACL,EAEA,KAAK,QAAUA,EAAQ,QAGnB,OAAO,OAAW,KAAe,KAAK,QAAQ,qBAAsB,CACtE,KAAK,WAAa,OAAO,WAAW,kCAAkC,EACtE,KAAK,qBAAuB,KAAK,WAAW,QAE5C,IAAMC,EAAYC,GAA+B,CAC/C,KAAK,qBAAuBA,EAAM,OACpC,EAEA,KAAK,WAAW,iBAAiB,SAAUD,CAAQ,CACrD,CAEK,KAAK,WAAW,IACnB,KAAK,QAAQ,aAAa,aAAc,EAAE,EAC1C,KAAK,QAAQ,MAAM,mBAAqB,GAAG,KAAK,QAAQ,QAAQ,KAChE,KAAK,QAAQ,MAAM,yBAA2B,KAAK,QAAQ,KAEvDD,EAAQ,OAAO,KAAK,QAAQ,aAAa,cAAe,EAAE,GAGhE,KAAK,KAAO,KAAK,QAAQ,UAEpB,KAAK,WAAW,GACnB,KAAK,UAAU,CAEnB,CAEA,SAAU,CACJ,KAAK,YACP,KAAK,WAAW,oBACd,SACA,KAAK,sBACP,EAEF,KAAK,QAAQ,cAAc,EAAE,QAASG,GAASA,EAAK,OAAO,CAAC,EAC5D,KAAK,QAAQ,gBAAgB,YAAY,EACzC,KAAK,QAAQ,gBAAgB,aAAa,EAC1C,KAAK,aAAa,CACpB,CAEQ,uBAA0BD,GAA+B,CAC/D,KAAK,qBAAuBA,EAAM,OACpC,EAEQ,YAAsB,CAC5B,MAAO,GACL,KAAK,QAAQ,UACV,KAAK,QAAQ,sBAAwB,KAAK,qBAEjD,CAEA,OAAOE,EAA6B,CAClC,GAAIA,IAAU,KAAK,KAGnB,IAFA,KAAK,KAAOA,EAER,KAAK,WAAW,EAAG,CACjB,OAAOA,GAAU,WACnB,KAAK,QAAQ,YAAcA,GAE7B,MACF,CAEA,GAAI,KAAK,gBAAgB,YAEvB,MAAM,IAAI,MAAM,+BAA+B,EAE3C,KAAK,QAAQ,kBAAoB,CAAC,KAAK,iBACzC,KAAK,QAAQ,iBAAiB,EAEhC,KAAK,gBAAgB,KAAK,KAAM,KAAK,OAAO,EAEhD,CAEQ,gBAAgBA,EAAeC,EAAsB,CAC3D,IAAMC,EAAWD,EAAQ,YACnBE,EAAYF,EAAQ,aAEpBG,EAASJ,EAAM,SAAS,GAAG,EAC7BK,EAEJ,GAAI,OAAO,KAAK,UAAc,IAAa,CAIzC,IAAMC,EAHY,IAAI,KAAK,UAAU,KAAK,QAAQ,OAAQ,CACxD,YAAaF,EAAS,OAAS,UACjC,CAAC,EAC0B,QAAQJ,CAAK,EAAE,OAAO,QAAQ,EAAE,EAC3DK,EAAS,KAAK,OAAOC,CAAQ,CAC/B,MAEED,EAAS,KAAK,eAAeL,EAAOI,CAAM,EAG5C,KAAK,aAAe,KAAK,QAAQ,EACjC,IAAMG,EAAc,MAAM,KAAKN,EAAQ,QAAQ,EACzCO,EAAS,IAAI,IAAIH,EAAO,IAAKI,GAAMA,EAAE,EAAE,CAAC,EAExCC,EAAUH,EAAY,OACzBI,GACC,CAACH,EAAO,IAAIG,EAAM,aAAa,UAAU,CAAW,GACpD,CAACA,EAAM,aAAa,eAAe,CACvC,EAIMC,EAAa,IAAI,IAAIF,CAAO,EAC5BG,EAAkB,IAAI,IAC5B,QAASC,EAAI,EAAGA,EAAIP,EAAY,OAAQO,IAAK,CAC3C,IAAMH,EAAQJ,EAAYO,CAAC,EAC3B,GAAI,CAACF,EAAW,IAAID,CAAK,EAAG,SAG5B,IAAII,EAAwB,KAC5B,QAASC,EAAIF,EAAI,EAAGE,EAAIT,EAAY,OAAQS,IAAK,CAC/C,IAAMC,EAAYV,EAAYS,CAAC,EAAG,aAAa,UAAU,EACzD,GAAIR,EAAO,IAAIS,CAAS,GAAK,CAACL,EAAW,IAAIL,EAAYS,CAAC,CAAE,EAAG,CAC7DD,EAASE,EACT,KACF,CACF,CAEA,GAAI,CAACF,EACH,QAASC,EAAIF,EAAI,EAAGE,GAAK,EAAGA,IAAK,CAC/B,IAAMC,EAAYV,EAAYS,CAAC,EAAG,aAAa,UAAU,EACzD,GAAIR,EAAO,IAAIS,CAAS,GAAK,CAACL,EAAW,IAAIL,EAAYS,CAAC,CAAE,EAAG,CAC7DD,EAASE,EACT,KACF,CACF,CAEFJ,EAAgB,IAAIF,EAAOI,CAAM,CACnC,CAEA,IAAMG,EAAajB,EAAQ,sBAAsB,EA8EjD,GA7EAS,EAAQ,QAASC,GAAU,CACzB,IAAMQ,EAAOR,EAAM,sBAAsB,EACzCA,EAAM,aAAa,gBAAiB,EAAE,EACtCA,EAAM,MAAM,SAAW,WACvBA,EAAM,MAAM,cAAgB,OAC5BA,EAAM,MAAM,KAAO,GAAGQ,EAAK,KAAOD,EAAW,IAAI,KACjDP,EAAM,MAAM,IAAM,GAAGQ,EAAK,IAAMD,EAAW,GAAG,KAC9CP,EAAM,MAAM,MAAQ,GAAGQ,EAAK,KAAK,KACjCR,EAAM,MAAM,OAAS,GAAGQ,EAAK,MAAM,IACrC,CAAC,EAEDZ,EAAY,QAASI,GAAU,CAC7B,IAAMS,EAAKT,EAAM,aAAa,UAAU,EACpCH,EAAO,IAAIY,CAAE,GAAGT,EAAM,OAAO,CACnC,CAAC,EAEDN,EAAO,QAASgB,GAAU,CACxB,IAAMC,EAAO,SAAS,cAAc,MAAM,EAC1CA,EAAK,aAAa,aAAc,EAAE,EAClCA,EAAK,aAAa,WAAYD,EAAM,EAAE,EACtCC,EAAK,YAAcD,EAAM,OACzBpB,EAAQ,YAAYqB,CAAI,CAC1B,CAAC,EAED,KAAK,gBAAkB,KAAK,QAAQ,EACpC,KAAK,aAAajB,CAAM,EAExBK,EAAQ,QAASC,GAAU,CACzB,GAAI,KAAK,gBAAiB,CACxBA,EAAM,OAAO,EACb,MACF,CAGA,IAAMY,EAAWV,EAAgB,IAAIF,CAAK,EACtCa,EAAK,EACLC,EAAK,EAET,GACEF,GACA,KAAK,aAAaA,CAAQ,GAC1B,KAAK,gBAAgBA,CAAQ,EAC7B,CACA,IAAMG,EAAa,KAAK,aAAaH,CAAQ,EACvCI,EAAa,KAAK,gBAAgBJ,CAAQ,EAChDC,EAAKG,EAAW,EAAID,EAAW,EAC/BD,EAAKE,EAAW,EAAID,EAAW,CACjC,CAEAf,EAAM,cAAc,EAAE,QAASiB,GAAMA,EAAE,OAAO,CAAC,EAC/CjB,EAAM,QACJ,CACE,UAAW,KAAK,QAAQ,MACpB,aAAaa,CAAE,OAAOC,CAAE,kBACxB,aAAaD,CAAE,OAAOC,CAAE,MAC5B,OAAQ,CACV,EACA,CACE,SAAU,KAAK,QAAQ,SACvB,OAAQ,KAAK,QAAQ,KACrB,KAAM,MACR,CACF,EACA,IAAMI,EAAuBlB,EAAM,QACjC,CACE,QAAS,EACT,OAAQ,CACV,EACA,CACE,SAAU,KAAK,QAAQ,SAAY,IACnC,OAAQ,SACR,KAAM,MACR,CACF,EACAkB,EAAU,SAAW,IAAMlB,EAAM,OAAO,CAC1C,CAAC,EAEG,KAAK,gBAAiB,CACxB,KAAK,gBAAkB,GACvBV,EAAQ,MAAM,MAAQ,OACtBA,EAAQ,MAAM,OAAS,OACvB,MACF,CAEA,GAAIC,IAAa,GAAKC,IAAc,EAAG,OAEvCF,EAAQ,MAAM,MAAQ,OACtBA,EAAQ,MAAM,OAAS,OAClBA,EAAQ,YAEb,IAAM6B,EAAW7B,EAAQ,YACnB8B,EAAY9B,EAAQ,aAE1BA,EAAQ,MAAM,MAAQ,GAAGC,CAAQ,KACjCD,EAAQ,MAAM,OAAS,GAAGE,CAAS,KAC9BF,EAAQ,YAEbA,EAAQ,MAAM,MAAQ,GAAG6B,CAAQ,KACjC7B,EAAQ,MAAM,OAAS,GAAG8B,CAAS,KAGnC,WAAW,IAAM,CACf9B,EAAQ,MAAM,MAAQ,OACtBA,EAAQ,MAAM,OAAS,OACnB,KAAK,QAAQ,qBACf,KAAK,QAAQ,oBAAoB,CAErC,EAAG,KAAK,QAAQ,QAAQ,CAC1B,CAEQ,SAAU,CAChB,IAAM+B,EAAW,MAAM,KAAK,KAAK,QAAQ,QAAQ,EAC3CC,EAAqB,CAAC,EAE5B,OAAAD,EAAS,QAAQ,CAACrB,EAAOuB,IAAU,CACjC,GAAIvB,EAAM,aAAa,eAAe,EAAG,OACzC,IAAMwB,EAAMxB,EAAM,aAAa,UAAU,GAAK,SAASuB,CAAK,GAC5DD,EAASE,CAAG,EAAI,CACd,EAAGxB,EAAM,WACT,EAAGA,EAAM,SACX,CACF,CAAC,EAEMsB,CACT,CAEQ,aAAa5B,EAAiB,CACpC,GAAI,KAAK,gBAAiB,OAE1B,IAAM2B,EAAW,MAAM,KAAK,KAAK,QAAQ,QAAQ,EAE3CI,EAAgB,IAAI,IACxB/B,EAAO,IAAKI,GAAMA,EAAE,EAAE,EAAE,OAAQW,GAAO,KAAK,aAAaA,CAAE,CAAC,CAC9D,EAEAY,EAAS,QAAQ,CAACrB,EAAOuB,IAAU,CACjC,GAAIvB,EAAM,aAAa,eAAe,EAAG,OACzC,IAAMwB,EAAMxB,EAAM,aAAa,UAAU,GAAK,SAASuB,CAAK,GACtDG,EAAO,KAAK,aAAaF,CAAG,EAC5BG,EAAU,KAAK,gBAAgBH,CAAG,EAElCI,EAAKD,GAAS,GAAK,EACnBE,EAAKF,GAAS,GAAK,EAErBG,EAASJ,EAAOA,EAAK,EAAIE,EAAK,EAC9BG,EAASL,EAAOA,EAAK,EAAIG,EAAK,EAC5BG,EAAQ,CAACN,EAIf,GAAIM,EAAO,CACT,IAAMC,EAAavC,EAAO,UAAWI,GAAMA,EAAE,KAAO0B,CAAG,EACnDZ,EAA0B,KAE9B,QAASP,EAAI4B,EAAa,EAAG5B,GAAK,EAAGA,IACnC,GAAIoB,EAAc,IAAI/B,EAAOW,CAAC,EAAG,EAAE,EAAG,CACpCO,EAAWlB,EAAOW,CAAC,EAAG,GACtB,KACF,CAEF,GAAI,CAACO,GACH,QAASP,EAAI4B,EAAa,EAAG5B,EAAIX,EAAO,OAAQW,IAC9C,GAAIoB,EAAc,IAAI/B,EAAOW,CAAC,EAAG,EAAE,EAAG,CACpCO,EAAWlB,EAAOW,CAAC,EAAG,GACtB,KACF,EAIJ,GAAIO,EAAU,CACZ,IAAMG,EAAa,KAAK,aAAaH,CAAQ,EACvCI,EAAa,KAAK,gBAAgBJ,CAAQ,EAChDkB,EAASf,EAAW,EAAIC,EAAW,EACnCe,EAAShB,EAAW,EAAIC,EAAW,CACrC,CACF,CAEAhB,EAAM,cAAc,EAAE,QAASiB,GAAMA,EAAE,OAAO,CAAC,EAC/CjB,EAAM,QACJ,CACE,UAAW,aAAa8B,CAAM,OAAOC,CAAM,aAAaC,EAAQ,IAAO,CAAC,IACxE,OAAQ,CACV,EACA,CACE,SAAU,KAAK,QAAQ,SACvB,OAAQ,KAAK,QAAQ,KACrB,KAAM,MACR,CACF,EACA,IAAME,EAAWF,EAAQ,KAAK,QAAQ,SAAY,IAAO,EACnDG,EAAQH,EAAQ,KAAK,QAAQ,SAAY,IAAO,EACtDhC,EAAM,QACJ,CACE,QAASgC,EAAQ,EAAI,EACrB,OAAQ,CACV,EACA,CACE,SAAUE,EACV,MAAOC,EACP,OAAQ,SACR,KAAM,MACR,CACF,CACF,CAAC,CACH,CAEQ,WAAY,CAClB,GAAInD,EAAU,QAAS,OAEvB,IAAMoD,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,QAAQ,MAAQ,OACtBA,EAAM,UAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAwBlB,SAAS,KAAK,YAAYA,CAAK,EAC/BpD,EAAU,QAAUoD,CACtB,CAEQ,cAAe,CACjBpD,EAAU,UACZA,EAAU,QAAQ,OAAO,EACzBA,EAAU,QAAU,OAExB,CAIQ,OAAOW,EAAkD,CA0B/D,OAzB+B,MAAM,KAAKA,CAAQ,EAAE,OAClD,CAAC0C,EAAKC,IACAA,EAAO,UAAY,IACd,CAAC,GAAGD,EAAK,CAAE,GAAI,SAASC,EAAO,KAAK,GAAI,OAAQ,MAAS,CAAC,EAG5CD,EAAI,KAAME,GAAMA,EAAE,SAAWD,EAAO,OAAO,EAEzD,CACL,GAAGD,EACH,CAAE,GAAI,GAAGC,EAAO,OAAO,IAAIA,EAAO,KAAK,GAAI,OAAQA,EAAO,OAAQ,CACpE,EAGK,CACL,GAAGD,EACH,CACE,GAAIC,EAAO,QACX,OAAQA,EAAO,OACjB,CACF,EAEF,CAAC,CACH,CAGF,CAEQ,eAAejD,EAAeI,EAA0B,CAC9D,IAAM+C,EAAW/C,EAASJ,EAAM,MAAM,GAAG,EAAIA,EAAM,MAAM,EAAE,EACrDK,EAAkB,CAAC,EAEzB,OAAID,EACF+C,EAAS,QAAQ,CAACC,EAASlB,IAAU,CAC/BA,EAAQ,GACV7B,EAAO,KAAK,CAAE,GAAI,SAAS6B,CAAK,GAAI,OAAQ,MAAS,CAAC,EAEvC7B,EAAO,KAAM6C,GAAMA,EAAE,SAAWE,CAAO,EAEtD/C,EAAO,KAAK,CAAE,GAAI,GAAG+C,CAAO,IAAIlB,CAAK,GAAI,OAAQkB,CAAQ,CAAC,EAE1D/C,EAAO,KAAK,CAAE,GAAI+C,EAAS,OAAQA,CAAQ,CAAC,CAEhD,CAAC,EAEDD,EAAS,QAAQ,CAACC,EAASlB,IAAU,CAClB7B,EAAO,KAAM6C,GAAMA,EAAE,SAAWE,CAAO,EAEtD/C,EAAO,KAAK,CAAE,GAAI,GAAG+C,CAAO,IAAIlB,CAAK,GAAI,OAAQkB,CAAQ,CAAC,EAE1D/C,EAAO,KAAK,CAAE,GAAI+C,EAAS,OAAQA,CAAQ,CAAC,CAEhD,CAAC,EAGI/C,CACT,CAEQ,OAAOgD,EAAa,CACtB,KAAK,QAAQ,OAAO,QAAQ,IAAI,cAAe,GAAGA,CAAI,CAC5D,CACF","names":["src_exports","__export","TextMorph","version","__toCommonJS","version","TextMorph","_TextMorph","options","listener","event","anim","value","element","oldWidth","oldHeight","byWord","blocks","iterator","oldChildren","newIds","b","exiting","child","exitingSet","exitingAnchorId","i","anchor","j","siblingId","parentRect","rect","id","block","span","anchorId","dx","dy","anchorPrev","anchorCurr","a","animation","newWidth","newHeight","children","measures","index","key","persistentIds","prev","current","cx","cy","deltaX","deltaY","isNew","blockIndex","duration","delay","style","acc","string","x","segments","segment","args"]}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"torph\",\n \"version\": \"0.0.5\",\n \"description\": \"Dependency-free animated text component.\",\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 \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.js\"\n },\n \"./react\": {\n \"types\": \"./dist/react/index.d.ts\",\n \"import\": \"./dist/react/index.mjs\",\n \"require\": \"./dist/react/index.js\"\n },\n \"./vue\": {\n \"types\": \"./dist/vue/index.d.ts\",\n \"import\": \"./dist/vue/index.mjs\",\n \"require\": \"./dist/vue/index.js\"\n },\n \"./svelte\": {\n \"types\": \"./dist/svelte/index.d.ts\",\n \"import\": \"./dist/svelte/index.mjs\",\n \"require\": \"./dist/svelte/index.js\"\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 \"vue\",\n \"svelte\",\n \"text\",\n \"animation\",\n \"morph\"\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 \"vue\": \">=3\",\n \"svelte\": \">=4\"\n },\n \"peerDependenciesMeta\": {\n \"react\": {\n \"optional\": true\n },\n \"react-dom\": {\n \"optional\": true\n },\n \"vue\": {\n \"optional\": true\n },\n \"svelte\": {\n \"optional\": true\n }\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 \"svelte\": \"^4.0.0\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.9.3\",\n \"vue\": \"^3.3.0\"\n }\n}\n"],"mappings":";yCAEE,IAAAA,EAAW","names":["version"]}
|
package/dist/react/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/index.ts","../../src/react/TextMorph.tsx","../../src/lib/text-morph/index.ts"],"sourcesContent":["export { TextMorph, useTextMorph } from \"./TextMorph\";\nexport type { TextMorphProps } from \"./TextMorph\";\n\n","\"use client\";\n\nimport React from \"react\";\nimport { TextMorph as Morph } from \"../lib/text-morph\";\nimport type { TextMorphOptions } from \"../lib/text-morph/types\";\n\nexport type TextMorphProps = Omit<TextMorphOptions, \"element\"> & {\n children: string; //React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n as?: keyof JSX.IntrinsicElements;\n};\n\nexport const TextMorph = ({\n children,\n className,\n style,\n as = \"div\",\n ...props\n}: TextMorphProps) => {\n const { ref, update } = useTextMorph(props);\n\n React.useEffect(() => {\n update(children);\n }, [children, update]);\n\n const Component = as as any;\n return <Component ref={ref} className={className} style={style} />;\n};\n\nexport function useTextMorph(props: Omit<TextMorphOptions, \"element\">) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const morphRef = React.useRef<Morph | null>(null);\n\n React.useEffect(() => {\n if (ref.current) {\n morphRef.current = new Morph({ element: ref.current, ...props });\n }\n\n return () => {\n morphRef.current?.destroy();\n };\n }, []);\n\n const update = (text: string) => {\n morphRef.current?.update(text);\n };\n\n return { ref, update };\n}\n","import type { TextMorphOptions } from \"./types\";\n\nexport type { TextMorphOptions } from \"./types\";\n\ntype Block = {\n id: string;\n string: string;\n};\ntype Measures = {\n [key: string]: { x: number; y: number };\n};\n\nexport class TextMorph {\n private element: HTMLElement;\n private options: Omit<TextMorphOptions, \"element\"> = {};\n\n private data: HTMLElement | string;\n\n private currentMeasures: Measures = {};\n private prevMeasures: Measures = {};\n private isInitialRender = true;\n private prefersReducedMotion = false;\n private mediaQuery?: MediaQueryList;\n\n static styleEl: HTMLStyleElement;\n\n constructor(options: TextMorphOptions) {\n this.options = {\n locale: \"en\",\n duration: 400,\n scale: true,\n ease: \"cubic-bezier(0.19, 1, 0.22, 1)\",\n respectReducedMotion: true,\n ...options,\n };\n\n this.element = options.element;\n\n // reduced motion detection\n if (typeof window !== \"undefined\" && this.options.respectReducedMotion) {\n this.mediaQuery = window.matchMedia(\"(prefers-reduced-motion: reduce)\");\n this.prefersReducedMotion = this.mediaQuery.matches;\n\n const listener = (event: MediaQueryListEvent) => {\n this.prefersReducedMotion = event.matches;\n };\n\n this.mediaQuery.addEventListener(\"change\", listener);\n }\n\n if (!this.isDisabled()) {\n this.element.setAttribute(\"torph-root\", \"\");\n this.element.style.transitionDuration = `${this.options.duration}ms`;\n this.element.style.transitionTimingFunction = this.options.ease!;\n\n if (options.debug) this.element.setAttribute(\"torph-debug\", \"\");\n }\n\n this.data = this.element.innerHTML;\n\n if (!this.isDisabled()) {\n this.addStyles();\n }\n }\n\n destroy() {\n if (this.mediaQuery) {\n this.mediaQuery.removeEventListener(\n \"change\",\n this.handleMediaQueryChange,\n );\n }\n this.element.getAnimations().forEach((anim) => anim.cancel());\n this.element.removeAttribute(\"torph-root\");\n this.element.removeAttribute(\"torph-debug\");\n this.removeStyles();\n }\n\n private handleMediaQueryChange = (event: MediaQueryListEvent) => {\n this.prefersReducedMotion = event.matches;\n };\n\n private isDisabled(): boolean {\n return Boolean(\n this.options.disabled ||\n (this.options.respectReducedMotion && this.prefersReducedMotion),\n );\n }\n\n update(value: HTMLElement | string) {\n if (value === this.data) return;\n this.data = value;\n\n if (this.isDisabled()) {\n if (typeof value === \"string\") {\n this.element.textContent = value;\n }\n return;\n }\n\n if (this.data instanceof HTMLElement) {\n // TODO: handle HTMLElement case\n throw new Error(\"HTMLElement not yet supported\");\n } else {\n if (this.options.onAnimationStart && !this.isInitialRender) {\n this.options.onAnimationStart();\n }\n this.createTextGroup(this.data, this.element);\n }\n }\n\n private createTextGroup(value: string, element: HTMLElement) {\n const oldWidth = element.offsetWidth;\n const oldHeight = element.offsetHeight;\n\n const byWord = value.includes(\" \");\n let blocks: Block[];\n\n if (typeof Intl.Segmenter !== \"undefined\") {\n const segmenter = new Intl.Segmenter(this.options.locale, {\n granularity: byWord ? \"word\" : \"grapheme\",\n });\n const iterator = segmenter.segment(value)[Symbol.iterator]();\n blocks = this.blocks(iterator);\n } else {\n // Fallback for browsers without Intl.Segmenter\n blocks = this.blocksFallback(value, byWord);\n }\n\n this.prevMeasures = this.measure();\n const oldChildren = Array.from(element.children) as HTMLElement[];\n const newIds = new Set(blocks.map((b) => b.id));\n\n const exiting = oldChildren.filter(\n (child) =>\n !newIds.has(child.getAttribute(\"torph-id\") as string) &&\n !child.hasAttribute(\"torph-exiting\"),\n );\n\n // For each exiting char, find the nearest persistent neighbor in old order\n // so we can make it follow that neighbor's FLIP movement\n const exitingSet = new Set(exiting);\n const exitingAnchorId = new Map<HTMLElement, string | null>();\n for (let i = 0; i < oldChildren.length; i++) {\n const child = oldChildren[i]!;\n if (!exitingSet.has(child)) continue;\n\n // Look forward for nearest persistent char\n let anchor: string | null = null;\n for (let j = i + 1; j < oldChildren.length; j++) {\n const siblingId = oldChildren[j]!.getAttribute(\"torph-id\") as string;\n if (newIds.has(siblingId) && !exitingSet.has(oldChildren[j]!)) {\n anchor = siblingId;\n break;\n }\n }\n // If none forward, look backward\n if (!anchor) {\n for (let j = i - 1; j >= 0; j--) {\n const siblingId = oldChildren[j]!.getAttribute(\"torph-id\") as string;\n if (newIds.has(siblingId) && !exitingSet.has(oldChildren[j]!)) {\n anchor = siblingId;\n break;\n }\n }\n }\n exitingAnchorId.set(child, anchor);\n }\n\n const parentRect = element.getBoundingClientRect();\n exiting.forEach((child) => {\n const rect = child.getBoundingClientRect();\n child.setAttribute(\"torph-exiting\", \"\");\n child.style.position = \"absolute\";\n child.style.pointerEvents = \"none\";\n child.style.left = `${rect.left - parentRect.left}px`;\n child.style.top = `${rect.top - parentRect.top}px`;\n child.style.width = `${rect.width}px`;\n child.style.height = `${rect.height}px`;\n });\n\n oldChildren.forEach((child) => {\n const id = child.getAttribute(\"torph-id\") as string;\n if (newIds.has(id)) child.remove();\n });\n\n blocks.forEach((block) => {\n const span = document.createElement(\"span\");\n span.setAttribute(\"torph-item\", \"\");\n span.setAttribute(\"torph-id\", block.id);\n span.textContent = block.string;\n element.appendChild(span);\n });\n\n this.currentMeasures = this.measure();\n this.updateStyles(blocks);\n\n exiting.forEach((child) => {\n if (this.isInitialRender) {\n child.remove();\n return;\n }\n\n // Find the anchor neighbor's FLIP delta so we move in sync with it\n const anchorId = exitingAnchorId.get(child);\n let dx = 0;\n let dy = 0;\n\n if (\n anchorId &&\n this.prevMeasures[anchorId] &&\n this.currentMeasures[anchorId]\n ) {\n const anchorPrev = this.prevMeasures[anchorId]!;\n const anchorCurr = this.currentMeasures[anchorId]!;\n dx = anchorCurr.x - anchorPrev.x;\n dy = anchorCurr.y - anchorPrev.y;\n }\n\n child.getAnimations().forEach((a) => a.cancel());\n child.animate(\n {\n transform: this.options.scale\n ? `translate(${dx}px, ${dy}px) scale(0.95)`\n : `translate(${dx}px, ${dy}px)`,\n offset: 1,\n },\n {\n duration: this.options.duration,\n easing: this.options.ease,\n fill: \"both\",\n },\n );\n const animation: Animation = child.animate(\n {\n opacity: 0,\n offset: 1,\n },\n {\n duration: this.options.duration! * 0.25,\n easing: \"linear\",\n fill: \"both\",\n },\n );\n animation.onfinish = () => child.remove();\n });\n\n if (this.isInitialRender) {\n this.isInitialRender = false;\n element.style.width = \"auto\";\n element.style.height = \"auto\";\n return;\n }\n\n if (oldWidth === 0 || oldHeight === 0) return;\n\n element.style.width = \"auto\";\n element.style.height = \"auto\";\n void element.offsetWidth; // force reflow\n\n const newWidth = element.offsetWidth;\n const newHeight = element.offsetHeight;\n\n element.style.width = `${oldWidth}px`;\n element.style.height = `${oldHeight}px`;\n void element.offsetWidth; // force reflow\n\n element.style.width = `${newWidth}px`;\n element.style.height = `${newHeight}px`;\n\n // TODO: move to `transitionend` event listener\n setTimeout(() => {\n element.style.width = \"auto\";\n element.style.height = \"auto\";\n if (this.options.onAnimationComplete) {\n this.options.onAnimationComplete();\n }\n }, this.options.duration);\n }\n\n private measure() {\n const children = Array.from(this.element.children) as HTMLElement[];\n const measures: Measures = {};\n\n children.forEach((child, index) => {\n if (child.hasAttribute(\"torph-exiting\")) return;\n const key = child.getAttribute(\"torph-id\") || `child-${index}`;\n measures[key] = {\n x: child.offsetLeft,\n y: child.offsetTop,\n };\n });\n\n return measures;\n }\n\n private updateStyles(blocks: Block[]) {\n if (this.isInitialRender) return;\n\n const children = Array.from(this.element.children) as HTMLElement[];\n\n const persistentIds = new Set(\n blocks.map((b) => b.id).filter((id) => this.prevMeasures[id]),\n );\n\n children.forEach((child, index) => {\n if (child.hasAttribute(\"torph-exiting\")) return;\n const key = child.getAttribute(\"torph-id\") || `child-${index}`;\n const prev = this.prevMeasures[key];\n const current = this.currentMeasures[key];\n\n const cx = current?.x || 0;\n const cy = current?.y || 0;\n\n let deltaX = prev ? prev.x - cx : 0;\n let deltaY = prev ? prev.y - cy : 0;\n const isNew = !prev;\n\n // For new chars, use the nearest persistent neighbor's FLIP delta\n // so all new chars get the same consistent offset\n if (isNew) {\n const blockIndex = blocks.findIndex((b) => b.id === key);\n let anchorId: string | null = null;\n\n for (let j = blockIndex - 1; j >= 0; j--) {\n if (persistentIds.has(blocks[j]!.id)) {\n anchorId = blocks[j]!.id;\n break;\n }\n }\n if (!anchorId) {\n for (let j = blockIndex + 1; j < blocks.length; j++) {\n if (persistentIds.has(blocks[j]!.id)) {\n anchorId = blocks[j]!.id;\n break;\n }\n }\n }\n\n if (anchorId) {\n const anchorPrev = this.prevMeasures[anchorId]!;\n const anchorCurr = this.currentMeasures[anchorId]!;\n deltaX = anchorPrev.x - anchorCurr.x;\n deltaY = anchorPrev.y - anchorCurr.y;\n }\n }\n\n child.getAnimations().forEach((a) => a.cancel());\n child.animate(\n {\n transform: `translate(${deltaX}px, ${deltaY}px) scale(${isNew ? 0.95 : 1})`,\n offset: 0,\n },\n {\n duration: this.options.duration,\n easing: this.options.ease,\n fill: \"both\",\n },\n );\n const duration = isNew ? this.options.duration! * 0.25 : 0;\n const delay = isNew ? this.options.duration! * 0.25 : 0;\n child.animate(\n {\n opacity: isNew ? 0 : 1,\n offset: 0,\n },\n {\n duration: duration,\n delay: delay,\n easing: \"linear\",\n fill: \"both\",\n },\n );\n });\n }\n\n private addStyles() {\n if (TextMorph.styleEl) return;\n\n const style = document.createElement(\"style\");\n style.dataset.torph = \"true\";\n style.innerHTML = `\n[torph-root] {\n display: inline-flex;\n position: relative;\n will-change: width, height;\n transition-property: width, height;\n white-space: nowrap;\n}\n\n[torph-item] {\n display: inline-block;\n will-change: opacity, transform;\n transform: none;\n opacity: 1;\n}\n\n[torph-root][torph-debug] {\n outline:2px solid magenta;\n [torph-item] {\n outline:2px solid cyan;\n outline-offset: -4px;\n }\n}\n `;\n document.head.appendChild(style);\n TextMorph.styleEl = style;\n }\n\n private removeStyles() {\n if (TextMorph.styleEl) {\n TextMorph.styleEl.remove();\n TextMorph.styleEl = undefined!;\n }\n }\n\n // utils\n\n private blocks(iterator: Intl.SegmentIterator<Intl.SegmentData>) {\n const uniqueStrings: Block[] = Array.from(iterator).reduce(\n (acc, string) => {\n if (string.segment === \" \") {\n return [...acc, { id: `space-${string.index}`, string: \"\\u00A0\" }];\n }\n\n const existingString = acc.find((x) => x.string === string.segment);\n if (existingString) {\n return [\n ...acc,\n { id: `${string.segment}-${string.index}`, string: string.segment },\n ];\n }\n\n return [\n ...acc,\n {\n id: string.segment,\n string: string.segment,\n },\n ];\n },\n [] as Block[],\n );\n\n return uniqueStrings;\n }\n\n private blocksFallback(value: string, byWord: boolean): Block[] {\n const segments = byWord ? value.split(\" \") : value.split(\"\");\n const blocks: Block[] = [];\n\n if (byWord) {\n segments.forEach((segment, index) => {\n if (index > 0) {\n blocks.push({ id: `space-${index}`, string: \"\\u00A0\" });\n }\n const existing = blocks.find((x) => x.string === segment);\n if (existing) {\n blocks.push({ id: `${segment}-${index}`, string: segment });\n } else {\n blocks.push({ id: segment, string: segment });\n }\n });\n } else {\n segments.forEach((segment, index) => {\n const existing = blocks.find((x) => x.string === segment);\n if (existing) {\n blocks.push({ id: `${segment}-${index}`, string: segment });\n } else {\n blocks.push({ id: segment, string: segment });\n }\n });\n }\n\n return blocks;\n }\n\n private log(...args: any[]) {\n if (this.options.debug) console.log(\"[TextMorph]\", ...args);\n }\n}\n"],"mappings":"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","names":["react_exports","__export","TextMorph","useTextMorph","__toCommonJS","import_react","TextMorph","_TextMorph","options","listener","event","anim","value","element","oldWidth","oldHeight","byWord","blocks","iterator","oldChildren","newIds","b","exiting","child","exitingSet","exitingAnchorId","i","anchor","j","siblingId","parentRect","rect","id","block","span","anchorId","dx","dy","anchorPrev","anchorCurr","a","animation","newWidth","newHeight","children","measures","index","key","persistentIds","prev","current","cx","cy","deltaX","deltaY","isNew","blockIndex","duration","delay","style","acc","string","x","segments","segment","args","TextMorph","children","className","style","as","props","ref","update","useTextMorph","React","morphRef","text"]}
|
package/dist/react/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/TextMorph.tsx"],"sourcesContent":["\"use client\";\n\nimport React from \"react\";\nimport { TextMorph as Morph } from \"../lib/text-morph\";\nimport type { TextMorphOptions } from \"../lib/text-morph/types\";\n\nexport type TextMorphProps = Omit<TextMorphOptions, \"element\"> & {\n children: string; //React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n as?: keyof JSX.IntrinsicElements;\n};\n\nexport const TextMorph = ({\n children,\n className,\n style,\n as = \"div\",\n ...props\n}: TextMorphProps) => {\n const { ref, update } = useTextMorph(props);\n\n React.useEffect(() => {\n update(children);\n }, [children, update]);\n\n const Component = as as any;\n return <Component ref={ref} className={className} style={style} />;\n};\n\nexport function useTextMorph(props: Omit<TextMorphOptions, \"element\">) {\n const ref = React.useRef<HTMLDivElement | null>(null);\n const morphRef = React.useRef<Morph | null>(null);\n\n React.useEffect(() => {\n if (ref.current) {\n morphRef.current = new Morph({ element: ref.current, ...props });\n }\n\n return () => {\n morphRef.current?.destroy();\n };\n }, []);\n\n const update = (text: string) => {\n morphRef.current?.update(text);\n };\n\n return { ref, update };\n}\n"],"mappings":";0CAEA,OAAOA,MAAW,QAWX,IAAMC,EAAY,CAAC,CACxB,SAAAC,EACA,UAAAC,EACA,MAAAC,EACA,GAAAC,EAAK,MACL,GAAGC,CACL,IAAsB,CACpB,GAAM,CAAE,IAAAC,EAAK,OAAAC,CAAO,EAAIC,EAAaH,CAAK,EAE1C,OAAAI,EAAM,UAAU,IAAM,CACpBF,EAAON,CAAQ,CACjB,EAAG,CAACA,EAAUM,CAAM,CAAC,EAGdE,EAAA,cADWL,EACV,CAAU,IAAKE,EAAK,UAAWJ,EAAW,MAAOC,EAAO,CAClE,EAEO,SAASK,EAAaH,EAA0C,CACrE,IAAMC,EAAMG,EAAM,OAA8B,IAAI,EAC9CC,EAAWD,EAAM,OAAqB,IAAI,EAEhD,OAAAA,EAAM,UAAU,KACVH,EAAI,UACNI,EAAS,QAAU,IAAIV,EAAM,CAAE,QAASM,EAAI,QAAS,GAAGD,CAAM,CAAC,GAG1D,IAAM,CACXK,EAAS,SAAS,QAAQ,CAC5B,GACC,CAAC,CAAC,EAME,CAAE,IAAAJ,EAAK,OAJEK,GAAiB,CAC/BD,EAAS,SAAS,OAAOC,CAAI,CAC/B,CAEqB,CACvB","names":["React","TextMorph","children","className","style","as","props","ref","update","useTextMorph","React","morphRef","text"]}
|
package/dist/svelte/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/svelte/index.ts","../../src/svelte/TextMorph.svelte"],"sourcesContent":["export { default as TextMorph } from \"./TextMorph.svelte\";\nexport type { TextMorphProps } from \"./types\";\n\n","/* src/svelte/TextMorph.svelte generated by Svelte v4.2.20 */\nimport {\n\tSvelteComponent,\n\tassign,\n\tbinding_callbacks,\n\tdetach,\n\telement,\n\tempty,\n\tget_spread_update,\n\tinit,\n\tinsert,\n\tnoop,\n\tsafe_not_equal,\n\tset_dynamic_element_data\n} from \"svelte/internal\";\n\nimport \"svelte/internal/disclose-version\";\nimport { onMount, onDestroy } from \"svelte\";\nimport { TextMorph as Morph } from \"../lib/text-morph\";\n\nfunction create_dynamic_element(ctx) {\n\tlet svelte_element;\n\tlet svelte_element_levels = [{ class: /*className*/ ctx[0] }, { style: /*style*/ ctx[1] }];\n\tlet svelte_element_data = {};\n\n\tfor (let i = 0; i < svelte_element_levels.length; i += 1) {\n\t\tsvelte_element_data = assign(svelte_element_data, svelte_element_levels[i]);\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tsvelte_element = element(/*as*/ ctx[2]);\n\t\t\tset_dynamic_element_data(/*as*/ ctx[2])(svelte_element, svelte_element_data);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, svelte_element, anchor);\n\t\t\t/*svelte_element_binding*/ ctx[14](svelte_element);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tset_dynamic_element_data(/*as*/ ctx[2])(svelte_element, svelte_element_data = get_spread_update(svelte_element_levels, [\n\t\t\t\tdirty & /*className*/ 1 && { class: /*className*/ ctx[0] },\n\t\t\t\tdirty & /*style*/ 2 && { style: /*style*/ ctx[1] }\n\t\t\t]));\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(svelte_element);\n\t\t\t}\n\n\t\t\t/*svelte_element_binding*/ ctx[14](null);\n\t\t}\n\t};\n}\n\nfunction create_fragment(ctx) {\n\tlet previous_tag = /*as*/ ctx[2];\n\tlet svelte_element_anchor;\n\tlet svelte_element = /*as*/ ctx[2] && create_dynamic_element(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (svelte_element) svelte_element.c();\n\t\t\tsvelte_element_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (svelte_element) svelte_element.m(target, anchor);\n\t\t\tinsert(target, svelte_element_anchor, anchor);\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (/*as*/ ctx[2]) {\n\t\t\t\tif (!previous_tag) {\n\t\t\t\t\tsvelte_element = create_dynamic_element(ctx);\n\t\t\t\t\tprevious_tag = /*as*/ ctx[2];\n\t\t\t\t\tsvelte_element.c();\n\t\t\t\t\tsvelte_element.m(svelte_element_anchor.parentNode, svelte_element_anchor);\n\t\t\t\t} else if (safe_not_equal(previous_tag, /*as*/ ctx[2])) {\n\t\t\t\t\tsvelte_element.d(1);\n\t\t\t\t\tsvelte_element = create_dynamic_element(ctx);\n\t\t\t\t\tprevious_tag = /*as*/ ctx[2];\n\t\t\t\t\tsvelte_element.c();\n\t\t\t\t\tsvelte_element.m(svelte_element_anchor.parentNode, svelte_element_anchor);\n\t\t\t\t} else {\n\t\t\t\t\tsvelte_element.p(ctx, dirty);\n\t\t\t\t}\n\t\t\t} else if (previous_tag) {\n\t\t\t\tsvelte_element.d(1);\n\t\t\t\tsvelte_element = null;\n\t\t\t\tprevious_tag = /*as*/ ctx[2];\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(svelte_element_anchor);\n\t\t\t}\n\n\t\t\tif (svelte_element) svelte_element.d(detaching);\n\t\t}\n\t};\n}\n\nfunction instance($$self, $$props, $$invalidate) {\n\tlet { text } = $$props;\n\tlet { locale = \"en\" } = $$props;\n\tlet { duration = 400 } = $$props;\n\tlet { ease = \"cubic-bezier(0.19, 1, 0.22, 1)\" } = $$props;\n\tlet { debug = false } = $$props;\n\tlet { disabled = false } = $$props;\n\tlet { respectReducedMotion = true } = $$props;\n\tlet { onAnimationStart = void 0 } = $$props;\n\tlet { onAnimationComplete = void 0 } = $$props;\n\tlet { class: className = \"\" } = $$props;\n\tlet { style = \"\" } = $$props;\n\tlet { as = \"div\" } = $$props;\n\tlet containerRef;\n\tlet morphInstance = null;\n\n\tonMount(() => {\n\t\tif (containerRef) {\n\t\t\t$$invalidate(13, morphInstance = new Morph({\n\t\t\t\t\telement: containerRef,\n\t\t\t\t\tlocale,\n\t\t\t\t\tduration,\n\t\t\t\t\tease,\n\t\t\t\t\tdebug,\n\t\t\t\t\tdisabled,\n\t\t\t\t\trespectReducedMotion,\n\t\t\t\t\tonAnimationStart,\n\t\t\t\t\tonAnimationComplete\n\t\t\t\t}));\n\n\t\t\tmorphInstance.update(text);\n\t\t}\n\t});\n\n\tonDestroy(() => {\n\t\tmorphInstance?.destroy();\n\t});\n\n\tfunction svelte_element_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tcontainerRef = $$value;\n\t\t\t$$invalidate(3, containerRef);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('text' in $$props) $$invalidate(4, text = $$props.text);\n\t\tif ('locale' in $$props) $$invalidate(5, locale = $$props.locale);\n\t\tif ('duration' in $$props) $$invalidate(6, duration = $$props.duration);\n\t\tif ('ease' in $$props) $$invalidate(7, ease = $$props.ease);\n\t\tif ('debug' in $$props) $$invalidate(8, debug = $$props.debug);\n\t\tif ('disabled' in $$props) $$invalidate(9, disabled = $$props.disabled);\n\t\tif ('respectReducedMotion' in $$props) $$invalidate(10, respectReducedMotion = $$props.respectReducedMotion);\n\t\tif ('onAnimationStart' in $$props) $$invalidate(11, onAnimationStart = $$props.onAnimationStart);\n\t\tif ('onAnimationComplete' in $$props) $$invalidate(12, onAnimationComplete = $$props.onAnimationComplete);\n\t\tif ('class' in $$props) $$invalidate(0, className = $$props.class);\n\t\tif ('style' in $$props) $$invalidate(1, style = $$props.style);\n\t\tif ('as' in $$props) $$invalidate(2, as = $$props.as);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*morphInstance, text*/ 8208) {\n\t\t\t$: if (morphInstance) {\n\t\t\t\tmorphInstance.update(text);\n\t\t\t}\n\t\t}\n\t};\n\n\treturn [\n\t\tclassName,\n\t\tstyle,\n\t\tas,\n\t\tcontainerRef,\n\t\ttext,\n\t\tlocale,\n\t\tduration,\n\t\tease,\n\t\tdebug,\n\t\tdisabled,\n\t\trespectReducedMotion,\n\t\tonAnimationStart,\n\t\tonAnimationComplete,\n\t\tmorphInstance,\n\t\tsvelte_element_binding\n\t];\n}\n\nclass TextMorph extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance, create_fragment, safe_not_equal, {\n\t\t\ttext: 4,\n\t\t\tlocale: 5,\n\t\t\tduration: 6,\n\t\t\tease: 7,\n\t\t\tdebug: 8,\n\t\t\tdisabled: 9,\n\t\t\trespectReducedMotion: 10,\n\t\t\tonAnimationStart: 11,\n\t\t\tonAnimationComplete: 12,\n\t\t\tclass: 0,\n\t\t\tstyle: 1,\n\t\t\tas: 2\n\t\t});\n\t}\n}\n\nexport default TextMorph;"],"mappings":"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","names":["svelte_exports","__export","TextMorph_default","__toCommonJS","import_internal","import_disclose_version","import_svelte","import_text_morph","create_dynamic_element","ctx","svelte_element","svelte_element_levels","svelte_element_data","i","target","anchor","dirty","detaching","create_fragment","previous_tag","svelte_element_anchor","instance","$$self","$$props","$$invalidate","text","locale","duration","ease","debug","disabled","respectReducedMotion","onAnimationStart","onAnimationComplete","className","style","as","containerRef","morphInstance","Morph","svelte_element_binding","$$value","TextMorph","options","TextMorph_default"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/svelte/TextMorph.svelte"],"sourcesContent":["/* src/svelte/TextMorph.svelte generated by Svelte v4.2.20 */\nimport {\n\tSvelteComponent,\n\tassign,\n\tbinding_callbacks,\n\tdetach,\n\telement,\n\tempty,\n\tget_spread_update,\n\tinit,\n\tinsert,\n\tnoop,\n\tsafe_not_equal,\n\tset_dynamic_element_data\n} from \"svelte/internal\";\n\nimport \"svelte/internal/disclose-version\";\nimport { onMount, onDestroy } from \"svelte\";\nimport { TextMorph as Morph } from \"../lib/text-morph\";\n\nfunction create_dynamic_element(ctx) {\n\tlet svelte_element;\n\tlet svelte_element_levels = [{ class: /*className*/ ctx[0] }, { style: /*style*/ ctx[1] }];\n\tlet svelte_element_data = {};\n\n\tfor (let i = 0; i < svelte_element_levels.length; i += 1) {\n\t\tsvelte_element_data = assign(svelte_element_data, svelte_element_levels[i]);\n\t}\n\n\treturn {\n\t\tc() {\n\t\t\tsvelte_element = element(/*as*/ ctx[2]);\n\t\t\tset_dynamic_element_data(/*as*/ ctx[2])(svelte_element, svelte_element_data);\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tinsert(target, svelte_element, anchor);\n\t\t\t/*svelte_element_binding*/ ctx[14](svelte_element);\n\t\t},\n\t\tp(ctx, dirty) {\n\t\t\tset_dynamic_element_data(/*as*/ ctx[2])(svelte_element, svelte_element_data = get_spread_update(svelte_element_levels, [\n\t\t\t\tdirty & /*className*/ 1 && { class: /*className*/ ctx[0] },\n\t\t\t\tdirty & /*style*/ 2 && { style: /*style*/ ctx[1] }\n\t\t\t]));\n\t\t},\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(svelte_element);\n\t\t\t}\n\n\t\t\t/*svelte_element_binding*/ ctx[14](null);\n\t\t}\n\t};\n}\n\nfunction create_fragment(ctx) {\n\tlet previous_tag = /*as*/ ctx[2];\n\tlet svelte_element_anchor;\n\tlet svelte_element = /*as*/ ctx[2] && create_dynamic_element(ctx);\n\n\treturn {\n\t\tc() {\n\t\t\tif (svelte_element) svelte_element.c();\n\t\t\tsvelte_element_anchor = empty();\n\t\t},\n\t\tm(target, anchor) {\n\t\t\tif (svelte_element) svelte_element.m(target, anchor);\n\t\t\tinsert(target, svelte_element_anchor, anchor);\n\t\t},\n\t\tp(ctx, [dirty]) {\n\t\t\tif (/*as*/ ctx[2]) {\n\t\t\t\tif (!previous_tag) {\n\t\t\t\t\tsvelte_element = create_dynamic_element(ctx);\n\t\t\t\t\tprevious_tag = /*as*/ ctx[2];\n\t\t\t\t\tsvelte_element.c();\n\t\t\t\t\tsvelte_element.m(svelte_element_anchor.parentNode, svelte_element_anchor);\n\t\t\t\t} else if (safe_not_equal(previous_tag, /*as*/ ctx[2])) {\n\t\t\t\t\tsvelte_element.d(1);\n\t\t\t\t\tsvelte_element = create_dynamic_element(ctx);\n\t\t\t\t\tprevious_tag = /*as*/ ctx[2];\n\t\t\t\t\tsvelte_element.c();\n\t\t\t\t\tsvelte_element.m(svelte_element_anchor.parentNode, svelte_element_anchor);\n\t\t\t\t} else {\n\t\t\t\t\tsvelte_element.p(ctx, dirty);\n\t\t\t\t}\n\t\t\t} else if (previous_tag) {\n\t\t\t\tsvelte_element.d(1);\n\t\t\t\tsvelte_element = null;\n\t\t\t\tprevious_tag = /*as*/ ctx[2];\n\t\t\t}\n\t\t},\n\t\ti: noop,\n\t\to: noop,\n\t\td(detaching) {\n\t\t\tif (detaching) {\n\t\t\t\tdetach(svelte_element_anchor);\n\t\t\t}\n\n\t\t\tif (svelte_element) svelte_element.d(detaching);\n\t\t}\n\t};\n}\n\nfunction instance($$self, $$props, $$invalidate) {\n\tlet { text } = $$props;\n\tlet { locale = \"en\" } = $$props;\n\tlet { duration = 400 } = $$props;\n\tlet { ease = \"cubic-bezier(0.19, 1, 0.22, 1)\" } = $$props;\n\tlet { debug = false } = $$props;\n\tlet { disabled = false } = $$props;\n\tlet { respectReducedMotion = true } = $$props;\n\tlet { onAnimationStart = void 0 } = $$props;\n\tlet { onAnimationComplete = void 0 } = $$props;\n\tlet { class: className = \"\" } = $$props;\n\tlet { style = \"\" } = $$props;\n\tlet { as = \"div\" } = $$props;\n\tlet containerRef;\n\tlet morphInstance = null;\n\n\tonMount(() => {\n\t\tif (containerRef) {\n\t\t\t$$invalidate(13, morphInstance = new Morph({\n\t\t\t\t\telement: containerRef,\n\t\t\t\t\tlocale,\n\t\t\t\t\tduration,\n\t\t\t\t\tease,\n\t\t\t\t\tdebug,\n\t\t\t\t\tdisabled,\n\t\t\t\t\trespectReducedMotion,\n\t\t\t\t\tonAnimationStart,\n\t\t\t\t\tonAnimationComplete\n\t\t\t\t}));\n\n\t\t\tmorphInstance.update(text);\n\t\t}\n\t});\n\n\tonDestroy(() => {\n\t\tmorphInstance?.destroy();\n\t});\n\n\tfunction svelte_element_binding($$value) {\n\t\tbinding_callbacks[$$value ? 'unshift' : 'push'](() => {\n\t\t\tcontainerRef = $$value;\n\t\t\t$$invalidate(3, containerRef);\n\t\t});\n\t}\n\n\t$$self.$$set = $$props => {\n\t\tif ('text' in $$props) $$invalidate(4, text = $$props.text);\n\t\tif ('locale' in $$props) $$invalidate(5, locale = $$props.locale);\n\t\tif ('duration' in $$props) $$invalidate(6, duration = $$props.duration);\n\t\tif ('ease' in $$props) $$invalidate(7, ease = $$props.ease);\n\t\tif ('debug' in $$props) $$invalidate(8, debug = $$props.debug);\n\t\tif ('disabled' in $$props) $$invalidate(9, disabled = $$props.disabled);\n\t\tif ('respectReducedMotion' in $$props) $$invalidate(10, respectReducedMotion = $$props.respectReducedMotion);\n\t\tif ('onAnimationStart' in $$props) $$invalidate(11, onAnimationStart = $$props.onAnimationStart);\n\t\tif ('onAnimationComplete' in $$props) $$invalidate(12, onAnimationComplete = $$props.onAnimationComplete);\n\t\tif ('class' in $$props) $$invalidate(0, className = $$props.class);\n\t\tif ('style' in $$props) $$invalidate(1, style = $$props.style);\n\t\tif ('as' in $$props) $$invalidate(2, as = $$props.as);\n\t};\n\n\t$$self.$$.update = () => {\n\t\tif ($$self.$$.dirty & /*morphInstance, text*/ 8208) {\n\t\t\t$: if (morphInstance) {\n\t\t\t\tmorphInstance.update(text);\n\t\t\t}\n\t\t}\n\t};\n\n\treturn [\n\t\tclassName,\n\t\tstyle,\n\t\tas,\n\t\tcontainerRef,\n\t\ttext,\n\t\tlocale,\n\t\tduration,\n\t\tease,\n\t\tdebug,\n\t\tdisabled,\n\t\trespectReducedMotion,\n\t\tonAnimationStart,\n\t\tonAnimationComplete,\n\t\tmorphInstance,\n\t\tsvelte_element_binding\n\t];\n}\n\nclass TextMorph extends SvelteComponent {\n\tconstructor(options) {\n\t\tsuper();\n\n\t\tinit(this, options, instance, create_fragment, safe_not_equal, {\n\t\t\ttext: 4,\n\t\t\tlocale: 5,\n\t\t\tduration: 6,\n\t\t\tease: 7,\n\t\t\tdebug: 8,\n\t\t\tdisabled: 9,\n\t\t\trespectReducedMotion: 10,\n\t\t\tonAnimationStart: 11,\n\t\t\tonAnimationComplete: 12,\n\t\t\tclass: 0,\n\t\t\tstyle: 1,\n\t\t\tas: 2\n\t\t});\n\t}\n}\n\nexport default TextMorph;"],"mappings":"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","names":["SvelteComponent","assign","binding_callbacks","detach","element","empty","get_spread_update","init","insert","noop","safe_not_equal","set_dynamic_element_data","onMount","onDestroy","Morph","create_dynamic_element","ctx","svelte_element","svelte_element_levels","svelte_element_data","i","target","anchor","dirty","detaching","create_fragment","previous_tag","svelte_element_anchor","instance","$$self","$$props","$$invalidate","text","locale","duration","ease","debug","disabled","respectReducedMotion","onAnimationStart","onAnimationComplete","className","style","as","containerRef","morphInstance","svelte_element_binding","$$value","TextMorph","options","TextMorph_default"]}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
interface TextMorphOptions {
|
|
2
|
-
debug?: boolean;
|
|
3
|
-
element: HTMLElement;
|
|
4
|
-
locale?: Intl.LocalesArgument;
|
|
5
|
-
scale?: boolean;
|
|
6
|
-
duration?: number;
|
|
7
|
-
ease?: string;
|
|
8
|
-
disabled?: boolean;
|
|
9
|
-
respectReducedMotion?: boolean;
|
|
10
|
-
onAnimationStart?: () => void;
|
|
11
|
-
onAnimationComplete?: () => void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type { TextMorphOptions as T };
|
package/dist/types-CnPojgn6.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
interface TextMorphOptions {
|
|
2
|
-
debug?: boolean;
|
|
3
|
-
element: HTMLElement;
|
|
4
|
-
locale?: Intl.LocalesArgument;
|
|
5
|
-
scale?: boolean;
|
|
6
|
-
duration?: number;
|
|
7
|
-
ease?: string;
|
|
8
|
-
disabled?: boolean;
|
|
9
|
-
respectReducedMotion?: boolean;
|
|
10
|
-
onAnimationStart?: () => void;
|
|
11
|
-
onAnimationComplete?: () => void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type { TextMorphOptions as T };
|
package/dist/vue/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/vue/index.ts"],"sourcesContent":["export { default as TextMorph } from \"./TextMorph.vue\";\nexport type { TextMorphProps } from \"./types\";\n\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,0CAAAE,EAAAF,GAAA,IAAAG,EAAqC","names":["vue_exports","__export","__toCommonJS","import_TextMorph"]}
|
package/dist/vue/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/vue/index.ts"],"sourcesContent":["export { default as TextMorph } from \"./TextMorph.vue\";\nexport type { TextMorphProps } from \"./types\";\n\n"],"mappings":"AAAA,OAAoB,WAAXA,MAA4B","names":["default"]}
|