char-flow 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CharFlow contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # CharFlow
2
+
3
+ Lightweight animated alphanumeric text for license plates, codes, and flowing paragraphs.
4
+
5
+ Digits and letters roll through their alphabet on change; inserts and deletes slide in and out. Built as a web component with an optional React wrapper.
6
+
7
+ <p align="center">
8
+ <img src="./assets/demo.gif" alt="CharFlow demo: animated text and license plate" width="720" />
9
+ </p>
10
+
11
+ ## Install
12
+
13
+ ```sh
14
+ npm install char-flow
15
+ ```
16
+
17
+ ## Web component
18
+
19
+ Import the element entry to register `<char-flow>`:
20
+
21
+ ```html
22
+ <script type="module">
23
+ import 'char-flow/element'
24
+ </script>
25
+
26
+ <char-flow value="G-123-BB" preset="plate"></char-flow>
27
+ ```
28
+
29
+ Or use the main entry (registers the element and re-exports helpers):
30
+
31
+ ```ts
32
+ import 'char-flow'
33
+ ```
34
+
35
+ ### Attributes
36
+
37
+ | Attribute | Default | Description |
38
+ |---|---|---|
39
+ | `value` | `""` | Text to display |
40
+ | `preset` | `alnum` | `plate` (uppercase, tabular) or `alnum` |
41
+ | `animated` | `true` | Set to `false` to disable motion |
42
+
43
+ Animations respect `prefers-reduced-motion`.
44
+
45
+ ### Styling
46
+
47
+ The component uses shadow DOM. Target the host or the exposed `part`:
48
+
49
+ ```css
50
+ char-flow.plate {
51
+ font-size: 2.5rem;
52
+ font-weight: 700;
53
+ letter-spacing: 0.06em;
54
+ }
55
+
56
+ char-flow::part(root) {
57
+ /* inner shell */
58
+ }
59
+ ```
60
+
61
+ Timing can be adjusted from JavaScript:
62
+
63
+ ```ts
64
+ const el = document.querySelector('char-flow')
65
+ el.spinTiming = { duration: 520, easing: 'cubic-bezier(0.32, 0.72, 0, 1)' }
66
+ el.slideTiming = { duration: 340 }
67
+ ```
68
+
69
+ ## React
70
+
71
+ Register the element first, then use the wrapper:
72
+
73
+ ```tsx
74
+ import 'char-flow/element'
75
+ import { CharFlow } from 'char-flow/react'
76
+
77
+ export function Plate({ value }: { value: string }) {
78
+ return <CharFlow value={value} preset="plate" className="plate" />
79
+ }
80
+ ```
81
+
82
+ React is an optional peer dependency (`>=18`).
83
+
84
+ ## Low-level API
85
+
86
+ The main entry also exports diffing and classification utilities:
87
+
88
+ ```ts
89
+ import { diff, classify } from 'char-flow'
90
+
91
+ diff('ABC-100', 'ABC-9')
92
+ classify('G')
93
+ ```
94
+
95
+ ## Demo
96
+
97
+ ```sh
98
+ npm run demo
99
+ ```
100
+
101
+ Opens a local demo at `http://localhost:3000/demo/`.
102
+
103
+ ## Development
104
+
105
+ ```sh
106
+ npm install
107
+ npm run build
108
+ npm run typecheck
109
+ ```
110
+
111
+ ## License
112
+
113
+ MIT
@@ -0,0 +1,51 @@
1
+ type CharKind = 'digit' | 'letter' | 'other';
2
+ type Preset = 'plate' | 'alnum';
3
+ /** How a changed character moves: roll through an alphabet, or a direct swap. */
4
+ type AnimKind = 'wheel-digit' | 'wheel-letter' | 'slide' | 'static';
5
+ interface EffectTiming {
6
+ duration?: number;
7
+ easing?: string;
8
+ delay?: number;
9
+ }
10
+ type DiffOp = {
11
+ type: 'keep';
12
+ index: number;
13
+ char: string;
14
+ prevKey: number;
15
+ region?: 'suffix';
16
+ } | {
17
+ type: 'replace';
18
+ index: number;
19
+ from: string;
20
+ to: string;
21
+ prevKey: number;
22
+ } | {
23
+ type: 'insert';
24
+ index: number;
25
+ char: string;
26
+ };
27
+
28
+ declare const TAG = "char-flow";
29
+ declare class CharFlowElement extends HTMLElement {
30
+ #private;
31
+ static observedAttributes: readonly ["value", "preset", "animated"];
32
+ connectedCallback(): void;
33
+ disconnectedCallback(): void;
34
+ attributeChangedCallback(name: string): void;
35
+ get value(): string;
36
+ set value(v: string);
37
+ get preset(): Preset;
38
+ set preset(v: Preset);
39
+ get animated(): boolean;
40
+ set animated(v: boolean);
41
+ set spinTiming(t: EffectTiming | undefined);
42
+ set slideTiming(t: EffectTiming | undefined);
43
+ }
44
+ declare function defineCharFlow(tag?: string): void;
45
+ declare global {
46
+ interface HTMLElementTagNameMap {
47
+ 'char-flow': CharFlowElement;
48
+ }
49
+ }
50
+
51
+ export { type AnimKind as A, type CharKind as C, type DiffOp as D, type EffectTiming as E, type Preset as P, TAG as T, CharFlowElement as a, defineCharFlow as d };
@@ -0,0 +1 @@
1
+ export { a as CharFlowElement, T as TAG, d as defineCharFlow } from './element-ohGNSSoB.js';
@@ -0,0 +1,84 @@
1
+ function T(e){let{letterSpacing:t}=getComputedStyle(e);e.style.setProperty("--cf-letter-gap",t==="normal"?"0px":t);}function A(e){let t=()=>T(e);t();let n=new ResizeObserver(t);return n.observe(e),document.fonts?.ready.then(t).catch(()=>{}),()=>n.disconnect()}var S="0123456789",v="ABCDEFGHIJKLMNOPQRSTUVWXYZ",x={duration:520,easing:"cubic-bezier(0.32, 0.72, 0, 1)",delay:0},b={duration:340,easing:"cubic-bezier(0.32, 0.72, 0, 1)",delay:0},R=16;function u(e){return e===" "?"\xA0":e}function H(e,t){return t>="a"&&t<="z"?e.toLowerCase():e}function d(e){if(!e)return "other";let t=e.charCodeAt(0);return t>=48&&t<=57?"digit":t>=65&&t<=90||t>=97&&t<=122?"letter":"other"}function g(e,t){return t==="digit"?e.charCodeAt(0)-48:e.toUpperCase().charCodeAt(0)-65}function I(e){let t=d(e);return t==="digit"?"wheel-digit":t==="letter"?"wheel-letter":"static"}function D(e,t){let n=d(e),i=d(t);return n==="digit"&&i==="digit"?"wheel-digit":n==="letter"&&i==="letter"?"wheel-letter":"slide"}function K(e,t,n){let i=g(e,n),r=g(t,n);if(i===r)return 1;let s=n==="letter"?26:10,o=(r-i+s)%s,a=(i-r+s)%s;return o<=a?1:-1}function Z(e,t,n){return t==="digit"?S[e]:H(v[e],n)}function O(e,t,n){let i=n==="letter"?v.length:S.length,r=g(e,n),s=g(t,n),o=K(e,t,n),a=[];for(let f=r;a.push(Z(f,n,t)),f!==s;f=(f+o+i)%i);return o===1?{chars:a,startIdx:0,endIdx:a.length-1}:{chars:[...a].reverse(),startIdx:a.length-1,endIdx:0}}function ee(e,t){return {chars:[u(e),u(t)],startIdx:0,endIdx:1}}function k(e){return e.fromChar==null||e.fromChar===e.char?null:e.anim==="wheel-digit"?O(e.fromChar,e.char,"digit"):e.anim==="wheel-letter"?O(e.fromChar,e.char,"letter"):ee(e.fromChar,e.char)}function F(e){return e.anim==="wheel-digit"||e.anim==="wheel-letter"}function C(e){let t=document.createElement("span");return t.className="cf-glyph",t.setAttribute("part","glyph"),t.textContent=u(e),t}function $(e,t=""){let n=document.createElement("span");return n.className=t?`cf-cell ${t}`:"cf-cell",n.dataset.key=e.key,n.dataset.char=e.char,n.setAttribute("part","segment"),n}function M(e){let t=$(e);return t.appendChild(C(e.char)),t}function te(e,t){let n=M(e),i=e.runLength&&e.runLength>1?(e.runIndex??0)*R:0;return t.push(r=>{n.animate([{opacity:0,transform:"translateY(0.25em)"},{opacity:1,transform:"translateY(0)"}],{duration:r.slide.duration,easing:r.slide.easing,delay:i,fill:"backwards"});}),n}function ne(e,t){let n=k(e),i=F(e),r=$(e,i?"cf-cell--rolling":""),s=C(e.char);s.style.visibility="hidden";let o=document.createElement("span");o.className="cf-stack";for(let a of n.chars)o.appendChild(C(a));return r.append(s,o),t.push(a=>{let f=-n.startIdx*a.cellHeight,p=-n.endIdx*a.cellHeight,l=i?a.spin:a.slide;o.style.transform=`translateY(${f}px)`;let c=o.animate([{transform:`translateY(${f}px)`},{transform:`translateY(${p}px)`}],{duration:l.duration,easing:l.easing,fill:"forwards"});c.onfinish=()=>{c.cancel(),o.remove(),s.style.visibility="",r.classList.remove("cf-cell--rolling");};}),r}function ie(e,t,n){return e.entering?t?te(e,n):M(e):t&&k(e)?ne(e,n):M(e)}function N(e,t,n,i){let r=n.get(e.key);return r&&!e.entering&&e.fromChar==null&&r.dataset.char===e.char?r:ie(e,t,i)}function Y(e){let t=new Map;for(let n of e.querySelectorAll(".cf-cell[data-key]"))n instanceof HTMLElement&&n.dataset.key&&t.set(n.dataset.key,n);return t}function G(e){let t=parseFloat(e);return Number.isFinite(t)?e.trim().endsWith("ms")?t:t*1e3:0}function re(e){let t=getComputedStyle(e),n=e.querySelector(".cf-glyph");return {cellHeight:n instanceof HTMLElement?n.offsetHeight:0,spin:{duration:G(t.getPropertyValue("--cf-spin-duration")),easing:t.getPropertyValue("--cf-spin-easing").trim()},slide:{duration:G(t.getPropertyValue("--cf-slide-duration")),easing:t.getPropertyValue("--cf-slide-easing").trim()}}}function U(e,t){let n=e.getBoundingClientRect().left,i=new Map;for(let r of t)r.dataset.key&&i.set(r.dataset.key,r.getBoundingClientRect().left-n);return i}function V(e,t,n){let i=Y(e),r=n?U(e,i.values()):new Map,s=[],o=[],a=new Set;for(let l of t){let c=N(l,n,i,s);a.add(l.key),o.push(c);}let f=[];if(n)for(let[l,c]of i)a.has(l)||f.push(c);if(e.replaceChildren(...o,...f),!s.length&&!f.length)return;let p=re(e);if(n){let l=U(e,o);for(let c of o){let m=c.dataset.key;if(!m)continue;let h=r.get(m),y=l.get(m);if(h===void 0||y===void 0)continue;let P=h-y;Math.abs(P)<.5||c.animate([{transform:`translateX(${P}px)`},{transform:"translateX(0)"}],{duration:p.slide.duration,easing:p.slide.easing});}for(let c of f){let m=r.get(c.dataset.key),h=c.offsetWidth;c.style.position="absolute",c.style.top="0",c.style.left=`${m??0}px`,c.style.width=`${h}px`,c.style.pointerEvents="none";let y=c.animate([{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(-0.25em)"}],{duration:p.slide.duration,easing:p.slide.easing,fill:"forwards"});y.onfinish=()=>c.remove();}}for(let l of s)l(p);}function _(e,t){let n=e.length,i=t.length,r=Array.from({length:n+1},()=>Array.from({length:i+1},()=>0));for(let s=0;s<=n;s++)r[s][0]=s;for(let s=0;s<=i;s++)r[0][s]=s;for(let s=1;s<=n;s++)for(let o=1;o<=i;o++)e[s-1]===t[o-1]?r[s][o]=r[s-1][o-1]:r[s][o]=1+Math.min(r[s-1][o],r[s][o-1],r[s-1][o-1]);return r}function se(e,t,n,i){let r=[],s=t.length,o=n.length;for(;s>0||o>0;)s>0&&o>0&&t[s-1]===n[o-1]?(r.push("M"),s--,o--):s>0&&o>0&&e[s][o]===e[s-1][o-1]+1?(r.push("R"),s--,o--):o>0&&e[s][o]===e[s][o-1]+1?(r.push("I"),o--):(r.push("D"),s--);r.reverse();let a=[],f=0,p=0;for(let l of r)l==="M"?(a.push({type:"keep",index:p,char:n[p],prevKey:i+f}),f++,p++):l==="R"?(a.push({type:"replace",index:p,from:t[f],to:n[p],prevKey:i+f}),f++,p++):l==="I"?(a.push({type:"insert",index:p,char:n[p]}),p++):f++;return a}function oe(e,t,n=0){let i=[...e],r=[...t],s=_(i,r);return se(s,i,r,n)}function ae(e,t){let n=t,i=[];for(let r of e)if(r.type==="insert")i.push({type:"insert",index:n++,char:r.char});else if(r.type==="keep"){let s={type:"keep",index:n++,char:r.char,prevKey:r.prevKey};r.region&&(s.region=r.region),i.push(s);}else r.type==="replace"&&i.push({type:"replace",index:n++,from:r.from,to:r.to,prevKey:r.prevKey});return i}function le(e,t){let n=[];for(let i=0;i<t.length;i++){let r=e[i],s=t[i];r===s?n.push({type:"keep",index:i,char:s,prevKey:i}):n.push({type:"replace",index:i,from:r,to:s,prevKey:i});}return n}function X(e,t){if(e.length===t.length)return le(e,t);let n=0;for(;n<e.length&&n<t.length&&e[n]===t[n];)n++;let i=0;for(;i<e.length-n&&i<t.length-n&&e[e.length-1-i]===t[t.length-1-i];)i++;let r=[],s=0;for(let l=0;l<n;l++)r.push({type:"keep",index:s++,char:t[l],prevKey:l});let o=e.slice(n,e.length-i),a=t.slice(n,t.length-i),f=Math.max(o.length,a.length);if(f>0)if(_([...o],[...a])[o.length][a.length]/f>.4)for(let m=0;m<a.length;m++)r.push({type:"insert",index:s++,char:a[m]});else r.push(...ae(oe(o,a,n),s)),s+=a.length;let p=Math.max(n,t.length-i);for(let l=p;l<t.length;l++){let c=e.length-i+(l-(t.length-i));c<n||r.push({type:"keep",index:s++,char:t[l],prevKey:c,region:"suffix"});}return r}var ce=0;function w(e){return `${e}-${++ce}`}function q(e,t,n){return e[t]??w(n)}function fe(e){let t=e.map(i=>({...i})),n=0;for(;n<t.length;){if(!t[n].entering){n++;continue}let r=n+1;for(;r<t.length&&t[r].entering;)r++;let s=r-n;for(let o=n;o<r;o++)t[o]={...t[o],runIndex:o-n,runLength:s};n=r;}return t}function E(e,t,n={}){return {key:t,char:e,kind:d(e),anim:n.anim??I(e),...n}}function pe(e,t){let n=[];for(let i of e){if(i.type==="keep"){n.push(E(i.char,q(t,i.prevKey,"k")));continue}if(i.type==="replace"){n.push(E(i.to,q(t,i.prevKey,"r"),{anim:D(i.from,i.to),fromChar:i.from,fromKind:d(i.from)}));continue}i.type==="insert"&&n.push(E(i.char,w("i"),{entering:true}));}return fe(n)}function z(e,t,n){let i=pe(X(e,t),n);return {segments:i,keys:i.map(r=>r.key)}}function W(e){let t=[...e].map((n,i)=>E(n,w(`s${i}`)));return {segments:t,keys:t.map(n=>n.key)}}var j=`
2
+ :host {
3
+ display: inline-block;
4
+ line-height: inherit;
5
+ font-variant-numeric: tabular-nums;
6
+ --cf-cell-height: 1lh;
7
+ --cf-letter-gap: 0px;
8
+ --cf-spin-duration: ${x.duration}ms;
9
+ --cf-spin-easing: ${x.easing};
10
+ --cf-slide-duration: ${b.duration}ms;
11
+ --cf-slide-easing: ${b.easing};
12
+ }
13
+
14
+ .root {
15
+ display: inline;
16
+ position: relative;
17
+ }
18
+
19
+ .sr {
20
+ position: absolute;
21
+ width: 1px;
22
+ height: 1px;
23
+ padding: 0;
24
+ margin: -1px;
25
+ overflow: hidden;
26
+ clip: rect(0, 0, 0, 0);
27
+ white-space: nowrap;
28
+ border: 0;
29
+ }
30
+
31
+ .visual {
32
+ display: inline-block;
33
+ position: relative;
34
+ white-space: nowrap;
35
+ }
36
+
37
+ .cf-cell {
38
+ display: inline-block;
39
+ height: var(--cf-cell-height);
40
+ line-height: var(--cf-cell-height);
41
+ vertical-align: baseline;
42
+ overflow: hidden;
43
+ position: relative;
44
+ text-align: center;
45
+ }
46
+
47
+ .cf-cell + .cf-cell {
48
+ margin-left: var(--cf-letter-gap);
49
+ }
50
+
51
+ /* Soft top/bottom fade only while a wheel is mid-roll. */
52
+ .cf-cell--rolling {
53
+ -webkit-mask-image: linear-gradient(
54
+ to bottom,
55
+ transparent 0%,
56
+ #000 18%,
57
+ #000 82%,
58
+ transparent 100%
59
+ );
60
+ mask-image: linear-gradient(
61
+ to bottom,
62
+ transparent 0%,
63
+ #000 18%,
64
+ #000 82%,
65
+ transparent 100%
66
+ );
67
+ }
68
+
69
+ .cf-stack {
70
+ position: absolute;
71
+ top: 0;
72
+ left: 0;
73
+ width: 100%;
74
+ will-change: transform;
75
+ }
76
+
77
+ .cf-glyph {
78
+ display: block;
79
+ height: var(--cf-cell-height);
80
+ line-height: var(--cf-cell-height);
81
+ text-align: center;
82
+ }
83
+ `.trim();function B(e,t){t==="plate"?(e.style.textTransform="uppercase",e.style.letterSpacing="0.04em"):(e.style.textTransform="",e.style.letterSpacing="");}function Q(e,t,n){let i={...x,...t},r={...b,...n};e.style.setProperty("--cf-spin-duration",`${i.duration}ms`),e.style.setProperty("--cf-spin-easing",i.easing),e.style.setProperty("--cf-slide-duration",`${r.duration}ms`),e.style.setProperty("--cf-slide-easing",r.easing);}function J(e){return e==="plate"?"plate":"alnum"}var me="char-flow",L=class extends HTMLElement{static observedAttributes=["value","preset","animated"];#e;#t;#n="";#s=[];#i=window.matchMedia("(prefers-reduced-motion: reduce)");#l=()=>this.#p();#o;#c;#f;connectedCallback(){if(!this.shadowRoot){let t=this.attachShadow({mode:"open"}),n=document.createElement("style");n.textContent=j;let i=document.createElement("div");i.className="root",i.setAttribute("part","root"),this.#e=document.createElement("span"),this.#e.className="sr",this.#e.setAttribute("aria-live","polite"),this.#e.setAttribute("aria-atomic","true"),this.#t=document.createElement("span"),this.#t.className="visual",this.#t.setAttribute("aria-hidden","true"),i.append(this.#e,this.#t),t.append(n,i);}this.#i.addEventListener("change",this.#l),this.#p(),this.#r(),this.#o=A(this),this.#a(true);}disconnectedCallback(){this.#i.removeEventListener("change",this.#l),this.#o?.(),this.#o=void 0;}attributeChangedCallback(t){if(this.isConnected){if(t==="value"){this.#a(false);return}this.#r(),t==="animated"&&this.#a(false);}}get value(){return this.getAttribute("value")??""}set value(t){this.setAttribute("value",t);}get preset(){return J(this.getAttribute("preset"))}set preset(t){this.setAttribute("preset",t);}get animated(){return this.getAttribute("animated")!=="false"}set animated(t){t?this.removeAttribute("animated"):this.setAttribute("animated","false");}set spinTiming(t){this.#c=t,this.#r();}set slideTiming(t){this.#f=t,this.#r();}#m(){return !(!this.animated||this.#i.matches)}#p(){this.#i.matches?this.dataset.reduced="":delete this.dataset.reduced;}#r(){B(this,this.preset),Q(this,this.#c,this.#f),T(this);}#a(t){let n=this.value;this.#e.textContent=n;let i=this.#m()&&!t,r;if(t||!this.#n){let s=W(n);r=s.segments,this.#s=s.keys;}else {if(this.#n===n)return;{let s=z(this.#n,n,this.#s);r=s.segments,this.#s=s.keys;}}V(this.#t,r,i),this.#n=n;}};function de(e=me){customElements.get(e)||customElements.define(e,L);}de();export{L as CharFlowElement,me as TAG,de as defineCharFlow};//# sourceMappingURL=element.js.map
84
+ //# sourceMappingURL=element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/layout/metrics.ts","../src/types.ts","../src/render/format.ts","../src/classify.ts","../src/render/stack.ts","../src/render/cell.ts","../src/render/mount.ts","../src/diff.ts","../src/segments.ts","../src/styles.ts","../src/element.ts"],"names":["syncMetrics","host","letterSpacing","observeMetrics","run","ro","DIGITS","LETTERS","DEFAULT_SPIN","DEFAULT_SLIDE","STAGGER_STEP_MS","formatChar","char","displayLetter","stripChar","target","classify","code","wheelIndex","kind","animForChar","k","animForReplace","from","to","fk","tk","spinDirection","a","b","n","up","down","charForIndex","i","wheelPlan","dir","path","slidePlan","planFor","seg","isWheel","glyph","g","makeCell","extraClass","cell","staticCell","enteringCell","pending","delay","ctx","rollingCell","plan","wheel","sizer","stack","c","startY","endY","timing","anim","buildCell","animated","reuseCell","existing","existingCellMap","root","map","el","ms","value","readContext","visual","cs","sample","measureX","cells","base","out","mountVisual","segments","firstX","nodes","survivors","node","exiting","key","lastX","before","after","dx","x","width","levenshteinMatrix","m","dp","j","backtrackOps","keyOffset","raw","ops","ai","bi","step","diffChars","prev","next","reindexOps","startIdx","outIdx","result","op","keep","diffAligned","diff","pre","suf","midPrev","midNext","midMax","suffixStart","prevIdx","keySeq","nextKey","prefix","keyForPrev","prevKeys","prevKey","fallback","assignEnteringRuns","s","len","makeSegment","extra","opsToSegments","buildSegments","prevSegmentKeys","initialSegments","STYLES","applyPresetStyle","preset","applyTimings","spin","slide","l","parsePreset","v","TAG","CharFlowElement","#sr","#visual","#prevValue","#keys","#motionQuery","#onMotionChange","#syncReduced","#stopMetrics","#spinTiming","#slideTiming","style","shell","#applyOptions","#render","name","#canAnimate","initial","init","built","defineCharFlow","tag"],"mappings":"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","file":"element.js","sourcesContent":["/** Sync layout CSS variables from computed host styles. */\nexport function syncMetrics(host: HTMLElement): void {\n const { letterSpacing } = getComputedStyle(host)\n host.style.setProperty('--cf-letter-gap', letterSpacing === 'normal' ? '0px' : letterSpacing)\n}\n\nexport function observeMetrics(host: HTMLElement): () => void {\n const run = (): void => syncMetrics(host)\n\n run()\n\n const ro = new ResizeObserver(run)\n ro.observe(host)\n\n document.fonts?.ready.then(run).catch(() => undefined)\n\n return () => ro.disconnect()\n}\n","export type CharKind = 'digit' | 'letter' | 'other'\n\nexport type Preset = 'plate' | 'alnum'\n\n/** How a changed character moves: roll through an alphabet, or a direct swap. */\nexport type AnimKind = 'wheel-digit' | 'wheel-letter' | 'slide' | 'static'\n\nexport interface EffectTiming {\n duration?: number\n easing?: string\n delay?: number\n}\n\nexport interface CharFlowOptions {\n preset?: Preset\n animated?: boolean\n spinTiming?: EffectTiming\n slideTiming?: EffectTiming\n}\n\nexport type DiffOp =\n | { type: 'keep'; index: number; char: string; prevKey: number; region?: 'suffix' }\n | { type: 'replace'; index: number; from: string; to: string; prevKey: number }\n | { type: 'insert'; index: number; char: string }\n\nexport interface RenderSegment {\n key: string\n char: string\n kind: CharKind\n anim: AnimKind\n fromChar?: string\n fromKind?: CharKind\n entering?: boolean\n /** Index inside a consecutive insert run (for stagger). */\n runIndex?: number\n /** Length of the current insert run. */\n runLength?: number\n}\n\nexport const DIGITS = '0123456789' as const\nexport const LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' as const\n\nexport const DEFAULT_SPIN: Required<EffectTiming> = {\n duration: 520,\n easing: 'cubic-bezier(0.32, 0.72, 0, 1)',\n delay: 0,\n}\n\n/** Used for direct swaps (non-roll) and for entering/exiting/shifting cells. */\nexport const DEFAULT_SLIDE: Required<EffectTiming> = {\n duration: 340,\n easing: 'cubic-bezier(0.32, 0.72, 0, 1)',\n delay: 0,\n}\n\n/** Delay between cells in an insert run. */\nexport const STAGGER_STEP_MS = 16\n","export function formatChar(char: string): string {\n return char === ' ' ? '\\u00a0' : char\n}\n\nexport function displayLetter(stripChar: string, target: string): string {\n if (target >= 'a' && target <= 'z') return stripChar.toLowerCase()\n return stripChar\n}\n","import type { AnimKind, CharKind } from './types'\n\nexport function classify(char: string): CharKind {\n if (!char) return 'other'\n const code = char.charCodeAt(0)\n if (code >= 48 && code <= 57) return 'digit'\n if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) return 'letter'\n return 'other'\n}\n\nexport function wheelIndex(char: string, kind: CharKind): number {\n if (kind === 'digit') return char.charCodeAt(0) - 48\n const upper = char.toUpperCase()\n return upper.charCodeAt(0) - 65\n}\n\n/** Resting animation tag for an unchanged character. */\nexport function animForChar(char: string): AnimKind {\n const k = classify(char)\n if (k === 'digit') return 'wheel-digit'\n if (k === 'letter') return 'wheel-letter'\n return 'static'\n}\n\n/**\n * Same alphabet (digit→digit, letter→letter) rolls through that alphabet.\n * Everything else (cross-kind, or any change involving punctuation) is a\n * direct two-glyph roll: old slides out, new slides in, no in-betweens.\n */\nexport function animForReplace(from: string, to: string): AnimKind {\n const fk = classify(from)\n const tk = classify(to)\n if (fk === 'digit' && tk === 'digit') return 'wheel-digit'\n if (fk === 'letter' && tk === 'letter') return 'wheel-letter'\n return 'slide'\n}\n\nexport function spinDirection(from: string, to: string, kind: CharKind): 1 | -1 {\n const a = wheelIndex(from, kind)\n const b = wheelIndex(to, kind)\n if (a === b) return 1\n const n = kind === 'letter' ? 26 : 10\n const up = (b - a + n) % n\n const down = (a - b + n) % n\n return up <= down ? 1 : -1\n}\n","import { spinDirection, wheelIndex } from '../classify'\nimport { DIGITS, LETTERS } from '../types'\nimport type { RenderSegment } from '../types'\nimport { displayLetter, formatChar } from './format'\n\n/**\n * A vertical column of glyphs plus the start/end positions to slide between.\n * Every animated transition — digit roll, letter roll, or text replacement —\n * is expressed as this one primitive: a stack translated along Y.\n */\nexport interface StackPlan {\n /** Glyphs in visual order, top to bottom. */\n chars: string[]\n /** Index showing at the start of the animation. */\n startIdx: number\n /** Index showing at the end of the animation. */\n endIdx: number\n}\n\nfunction charForIndex(i: number, kind: 'digit' | 'letter', target: string): string {\n if (kind === 'digit') return DIGITS[i]!\n return displayLetter(LETTERS[i]!, target)\n}\n\n/** Glyphs along the shortest path from `from` to `to` around the alphabet. */\nfunction wheelPlan(from: string, to: string, kind: 'digit' | 'letter'): StackPlan {\n const n = kind === 'letter' ? LETTERS.length : DIGITS.length\n const a = wheelIndex(from, kind)\n const b = wheelIndex(to, kind)\n const dir = spinDirection(from, to, kind)\n\n const path: string[] = []\n for (let i = a; ; i = (i + dir + n) % n) {\n path.push(charForIndex(i, kind, to))\n if (i === b) break\n }\n\n // dir +1 rolls up (content moves up, next glyph enters from below).\n // dir -1 rolls down, so reverse the column and start from the bottom.\n if (dir === 1) return { chars: path, startIdx: 0, endIdx: path.length - 1 }\n return { chars: [...path].reverse(), startIdx: path.length - 1, endIdx: 0 }\n}\n\n/** A single-step slide between two arbitrary glyphs (text replacement / morph). */\nfunction slidePlan(from: string, to: string): StackPlan {\n return { chars: [formatChar(from), formatChar(to)], startIdx: 0, endIdx: 1 }\n}\n\n/** Build the plan for a segment, or null if there is nothing to animate. */\nexport function planFor(seg: RenderSegment): StackPlan | null {\n if (seg.fromChar == null || seg.fromChar === seg.char) return null\n if (seg.anim === 'wheel-digit') return wheelPlan(seg.fromChar, seg.char, 'digit')\n if (seg.anim === 'wheel-letter') return wheelPlan(seg.fromChar, seg.char, 'letter')\n return slidePlan(seg.fromChar, seg.char)\n}\n\nexport function isWheel(seg: RenderSegment): boolean {\n return seg.anim === 'wheel-digit' || seg.anim === 'wheel-letter'\n}\n","import type { RenderSegment } from '../types'\nimport { STAGGER_STEP_MS } from '../types'\nimport { formatChar } from './format'\nimport { isWheel, planFor } from './stack'\n\nexport interface AnimContext {\n /** Measured cell height in px (one line of text). */\n cellHeight: number\n spin: { duration: number; easing: string }\n slide: { duration: number; easing: string }\n}\n\n/** Deferred animation: queued during build, launched once after layout. */\nexport type Pending = (ctx: AnimContext) => void\n\nfunction glyph(char: string): HTMLElement {\n const g = document.createElement('span')\n g.className = 'cf-glyph'\n g.setAttribute('part', 'glyph')\n g.textContent = formatChar(char)\n return g\n}\n\nfunction makeCell(seg: RenderSegment, extraClass = ''): HTMLElement {\n const cell = document.createElement('span')\n cell.className = extraClass ? `cf-cell ${extraClass}` : 'cf-cell'\n cell.dataset.key = seg.key\n cell.dataset.char = seg.char\n cell.setAttribute('part', 'segment')\n return cell\n}\n\nfunction staticCell(seg: RenderSegment): HTMLElement {\n const cell = makeCell(seg)\n cell.appendChild(glyph(seg.char))\n return cell\n}\n\nfunction enteringCell(seg: RenderSegment, pending: Pending[]): HTMLElement {\n const cell = staticCell(seg)\n const delay =\n seg.runLength && seg.runLength > 1 ? (seg.runIndex ?? 0) * STAGGER_STEP_MS : 0\n\n pending.push((ctx) => {\n cell.animate(\n [\n { opacity: 0, transform: 'translateY(0.25em)' },\n { opacity: 1, transform: 'translateY(0)' },\n ],\n { duration: ctx.slide.duration, easing: ctx.slide.easing, delay, fill: 'backwards' },\n )\n })\n return cell\n}\n\nfunction rollingCell(seg: RenderSegment, pending: Pending[]): HTMLElement {\n const plan = planFor(seg)!\n const wheel = isWheel(seg)\n const cell = makeCell(seg, wheel ? 'cf-cell--rolling' : '')\n\n // A normal-flow sizer (the resting glyph) owns the cell's width so it stays\n // constant; the multi-glyph stack floats above it and never affects layout.\n const sizer = glyph(seg.char)\n sizer.style.visibility = 'hidden'\n const stack = document.createElement('span')\n stack.className = 'cf-stack'\n for (const c of plan.chars) stack.appendChild(glyph(c))\n cell.append(sizer, stack)\n\n pending.push((ctx) => {\n const startY = -plan.startIdx * ctx.cellHeight\n const endY = -plan.endIdx * ctx.cellHeight\n const timing = wheel ? ctx.spin : ctx.slide\n\n stack.style.transform = `translateY(${startY}px)`\n const anim = stack.animate(\n [{ transform: `translateY(${startY}px)` }, { transform: `translateY(${endY}px)` }],\n { duration: timing.duration, easing: timing.easing, fill: 'forwards' },\n )\n // Drop the stack and reveal the resting sizer once the roll lands.\n anim.onfinish = () => {\n anim.cancel()\n stack.remove()\n sizer.style.visibility = ''\n cell.classList.remove('cf-cell--rolling')\n }\n })\n\n return cell\n}\n\nexport function buildCell(\n seg: RenderSegment,\n animated: boolean,\n pending: Pending[],\n): HTMLElement {\n if (seg.entering) {\n return animated ? enteringCell(seg, pending) : staticCell(seg)\n }\n if (animated && planFor(seg)) {\n return rollingCell(seg, pending)\n }\n return staticCell(seg)\n}\n\nexport function reuseCell(\n seg: RenderSegment,\n animated: boolean,\n existing: Map<string, HTMLElement>,\n pending: Pending[],\n): HTMLElement {\n const cell = existing.get(seg.key)\n // Unchanged, resting cells are reused untouched; anything that moves is rebuilt.\n if (cell && !seg.entering && seg.fromChar == null && cell.dataset.char === seg.char) {\n return cell\n }\n return buildCell(seg, animated, pending)\n}\n\nexport function existingCellMap(root: HTMLElement): Map<string, HTMLElement> {\n const map = new Map<string, HTMLElement>()\n for (const el of root.querySelectorAll('.cf-cell[data-key]')) {\n if (el instanceof HTMLElement && el.dataset.key) map.set(el.dataset.key, el)\n }\n return map\n}\n","import type { RenderSegment } from '../types'\nimport { existingCellMap, reuseCell, type AnimContext, type Pending } from './cell'\n\nfunction ms(value: string): number {\n const n = parseFloat(value)\n if (!Number.isFinite(n)) return 0\n return value.trim().endsWith('ms') ? n : n * 1000\n}\n\nfunction readContext(visual: HTMLElement): AnimContext {\n const cs = getComputedStyle(visual)\n const sample = visual.querySelector('.cf-glyph')\n return {\n cellHeight: sample instanceof HTMLElement ? sample.offsetHeight : 0,\n spin: {\n duration: ms(cs.getPropertyValue('--cf-spin-duration')),\n easing: cs.getPropertyValue('--cf-spin-easing').trim(),\n },\n slide: {\n duration: ms(cs.getPropertyValue('--cf-slide-duration')),\n easing: cs.getPropertyValue('--cf-slide-easing').trim(),\n },\n }\n}\n\n/** x offset (relative to the visual box) of each existing cell, keyed by data-key. */\nfunction measureX(visual: HTMLElement, cells: Iterable<HTMLElement>): Map<string, number> {\n const base = visual.getBoundingClientRect().left\n const out = new Map<string, number>()\n for (const el of cells) {\n if (el.dataset.key) out.set(el.dataset.key, el.getBoundingClientRect().left - base)\n }\n return out\n}\n\nexport function mountVisual(\n visual: HTMLElement,\n segments: RenderSegment[],\n animated: boolean,\n): void {\n const existing = existingCellMap(visual)\n\n // FLIP \"First\": record where every current cell sits before we touch the DOM.\n const firstX = animated ? measureX(visual, existing.values()) : new Map<string, number>()\n\n const pending: Pending[] = []\n const nodes: HTMLElement[] = []\n const survivors = new Set<string>()\n\n for (const seg of segments) {\n const node = reuseCell(seg, animated, existing, pending)\n survivors.add(seg.key)\n nodes.push(node)\n }\n\n // Cells present before but gone now: animate them out instead of popping.\n const exiting: HTMLElement[] = []\n if (animated) {\n for (const [key, el] of existing) {\n if (!survivors.has(key)) exiting.push(el)\n }\n }\n\n // Exiting cells stay in the DOM (absolutely positioned) so they don't affect width.\n visual.replaceChildren(...nodes, ...exiting)\n\n if (!pending.length && !exiting.length) return\n\n const ctx = readContext(visual)\n\n if (animated) {\n // FLIP \"Last/Invert/Play\": slide survivors from their old x back to the new one.\n const lastX = measureX(visual, nodes)\n for (const node of nodes) {\n const key = node.dataset.key\n if (!key) continue\n const before = firstX.get(key)\n const after = lastX.get(key)\n if (before === undefined || after === undefined) continue\n const dx = before - after\n if (Math.abs(dx) < 0.5) continue\n node.animate(\n [{ transform: `translateX(${dx}px)` }, { transform: 'translateX(0)' }],\n { duration: ctx.slide.duration, easing: ctx.slide.easing },\n )\n }\n\n for (const el of exiting) {\n const x = firstX.get(el.dataset.key!)\n const width = el.offsetWidth\n el.style.position = 'absolute'\n el.style.top = '0'\n el.style.left = `${x ?? 0}px`\n el.style.width = `${width}px`\n el.style.pointerEvents = 'none'\n const out = el.animate(\n [\n { opacity: 1, transform: 'translateY(0)' },\n { opacity: 0, transform: 'translateY(-0.25em)' },\n ],\n { duration: ctx.slide.duration, easing: ctx.slide.easing, fill: 'forwards' },\n )\n out.onfinish = () => el.remove()\n }\n }\n\n for (const run of pending) run(ctx)\n}\n","import type { DiffOp } from './types'\n\nfunction levenshteinMatrix(a: string[], b: string[]): number[][] {\n const m = a.length\n const n = b.length\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array.from({ length: n + 1 }, () => 0),\n )\n for (let i = 0; i <= m; i++) dp[i]![0] = i\n for (let j = 0; j <= n; j++) dp[0]![j] = j\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (a[i - 1] === b[j - 1]) {\n dp[i]![j] = dp[i - 1]![j - 1]!\n } else {\n dp[i]![j] = 1 + Math.min(dp[i - 1]![j]!, dp[i]![j - 1]!, dp[i - 1]![j - 1]!)\n }\n }\n }\n\n return dp\n}\n\nfunction backtrackOps(dp: number[][], a: string[], b: string[], keyOffset: number): DiffOp[] {\n const raw: Array<'M' | 'I' | 'D' | 'R'> = []\n let i = a.length\n let j = b.length\n\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && a[i - 1] === b[j - 1]) {\n raw.push('M')\n i--\n j--\n } else if (i > 0 && j > 0 && dp[i]![j] === dp[i - 1]![j - 1]! + 1) {\n raw.push('R')\n i--\n j--\n } else if (j > 0 && dp[i]![j] === dp[i]![j - 1]! + 1) {\n raw.push('I')\n j--\n } else {\n raw.push('D')\n i--\n }\n }\n raw.reverse()\n\n const ops: DiffOp[] = []\n let ai = 0\n let bi = 0\n for (const step of raw) {\n if (step === 'M') {\n ops.push({ type: 'keep', index: bi, char: b[bi]!, prevKey: keyOffset + ai })\n ai++\n bi++\n } else if (step === 'R') {\n ops.push({\n type: 'replace',\n index: bi,\n from: a[ai]!,\n to: b[bi]!,\n prevKey: keyOffset + ai,\n })\n ai++\n bi++\n } else if (step === 'I') {\n ops.push({ type: 'insert', index: bi, char: b[bi]! })\n bi++\n } else {\n ai++\n }\n }\n return ops\n}\n\n/** Shortest edit script via Wagner-Fischer. Deletes are omitted (cells simply disappear). */\nexport function diffChars(prev: string, next: string, keyOffset = 0): DiffOp[] {\n const a = [...prev]\n const b = [...next]\n const dp = levenshteinMatrix(a, b)\n return backtrackOps(dp, a, b, keyOffset)\n}\n\nfunction reindexOps(ops: DiffOp[], startIdx: number): DiffOp[] {\n let outIdx = startIdx\n const result: DiffOp[] = []\n for (const op of ops) {\n if (op.type === 'insert') {\n result.push({ type: 'insert', index: outIdx++, char: op.char })\n } else if (op.type === 'keep') {\n const keep: DiffOp = {\n type: 'keep',\n index: outIdx++,\n char: op.char,\n prevKey: op.prevKey,\n }\n if (op.region) keep.region = op.region\n result.push(keep)\n } else if (op.type === 'replace') {\n result.push({\n type: 'replace',\n index: outIdx++,\n from: op.from,\n to: op.to,\n prevKey: op.prevKey,\n })\n }\n }\n return result\n}\n\n/**\n * Slot-by-slot alignment for same-length values (e.g. license plates). Every\n * position rolls from its old char to its new one, so a dash moving from one\n * group to another rolls in place instead of being deleted and re-inserted.\n */\nfunction diffAligned(prev: string, next: string): DiffOp[] {\n const ops: DiffOp[] = []\n for (let i = 0; i < next.length; i++) {\n const from = prev[i]!\n const to = next[i]!\n if (from === to) {\n ops.push({ type: 'keep', index: i, char: to, prevKey: i })\n } else {\n ops.push({ type: 'replace', index: i, from, to, prevKey: i })\n }\n }\n return ops\n}\n\nexport function diff(prev: string, next: string): DiffOp[] {\n if (prev.length === next.length) return diffAligned(prev, next)\n\n let pre = 0\n while (pre < prev.length && pre < next.length && prev[pre] === next[pre]) pre++\n\n let suf = 0\n while (\n suf < prev.length - pre &&\n suf < next.length - pre &&\n prev[prev.length - 1 - suf] === next[next.length - 1 - suf]\n ) {\n suf++\n }\n\n const ops: DiffOp[] = []\n let outIdx = 0\n\n for (let i = 0; i < pre; i++) {\n ops.push({ type: 'keep', index: outIdx++, char: next[i]!, prevKey: i })\n }\n\n const midPrev = prev.slice(pre, prev.length - suf)\n const midNext = next.slice(pre, next.length - suf)\n const midMax = Math.max(midPrev.length, midNext.length)\n\n if (midMax > 0) {\n const midDist = levenshteinMatrix([...midPrev], [...midNext])[midPrev.length]![midNext.length]!\n const middleUnrelated = midDist / midMax > 0.4\n\n if (middleUnrelated) {\n for (let i = 0; i < midNext.length; i++) {\n ops.push({ type: 'insert', index: outIdx++, char: midNext[i]! })\n }\n } else {\n ops.push(...reindexOps(diffChars(midPrev, midNext, pre), outIdx))\n outIdx += midNext.length\n }\n }\n\n const suffixStart = Math.max(pre, next.length - suf)\n for (let i = suffixStart; i < next.length; i++) {\n const prevIdx = prev.length - suf + (i - (next.length - suf))\n if (prevIdx < pre) continue\n ops.push({\n type: 'keep',\n index: outIdx++,\n char: next[i]!,\n prevKey: prevIdx,\n region: 'suffix',\n })\n }\n\n return ops\n}\n","import { animForChar, animForReplace, classify } from './classify'\nimport { diff } from './diff'\nimport type { DiffOp, RenderSegment } from './types'\n\nlet keySeq = 0\nfunction nextKey(prefix: string): string {\n return `${prefix}-${++keySeq}`\n}\n\nfunction keyForPrev(prevKeys: string[], prevKey: number, fallback: string): string {\n return prevKeys[prevKey] ?? nextKey(fallback)\n}\n\nfunction assignEnteringRuns(segments: RenderSegment[]): RenderSegment[] {\n const out = segments.map((s) => ({ ...s }))\n let i = 0\n\n while (i < out.length) {\n const seg = out[i]!\n if (!seg.entering) {\n i++\n continue\n }\n let j = i + 1\n while (j < out.length && out[j]!.entering) j++\n const len = j - i\n for (let k = i; k < j; k++) {\n out[k] = { ...out[k]!, runIndex: k - i, runLength: len }\n }\n i = j\n }\n\n return out\n}\n\nfunction makeSegment(\n char: string,\n key: string,\n extra: Partial<RenderSegment> = {},\n): RenderSegment {\n return {\n key,\n char,\n kind: classify(char),\n anim: extra.anim ?? animForChar(char),\n ...extra,\n }\n}\n\nfunction opsToSegments(ops: DiffOp[], prevKeys: string[]): RenderSegment[] {\n const segments: RenderSegment[] = []\n\n for (const op of ops) {\n if (op.type === 'keep') {\n segments.push(makeSegment(op.char, keyForPrev(prevKeys, op.prevKey, 'k')))\n continue\n }\n\n if (op.type === 'replace') {\n segments.push(\n makeSegment(op.to, keyForPrev(prevKeys, op.prevKey, 'r'), {\n anim: animForReplace(op.from, op.to),\n fromChar: op.from,\n fromKind: classify(op.from),\n }),\n )\n continue\n }\n\n if (op.type === 'insert') {\n segments.push(makeSegment(op.char, nextKey('i'), { entering: true }))\n }\n }\n\n return assignEnteringRuns(segments)\n}\n\nexport function buildSegments(\n prev: string,\n next: string,\n prevSegmentKeys: string[],\n): { segments: RenderSegment[]; keys: string[] } {\n const segments = opsToSegments(diff(prev, next), prevSegmentKeys)\n return { segments, keys: segments.map((s) => s.key) }\n}\n\nexport function initialSegments(value: string): {\n segments: RenderSegment[]\n keys: string[]\n} {\n const segments = [...value].map((char, i) => makeSegment(char, nextKey(`s${i}`)))\n return { segments, keys: segments.map((s) => s.key) }\n}\n","import type { EffectTiming, Preset } from './types'\nimport { DEFAULT_SLIDE, DEFAULT_SPIN } from './types'\n\nexport const STYLES = `\n:host {\n display: inline-block;\n line-height: inherit;\n font-variant-numeric: tabular-nums;\n --cf-cell-height: 1lh;\n --cf-letter-gap: 0px;\n --cf-spin-duration: ${DEFAULT_SPIN.duration}ms;\n --cf-spin-easing: ${DEFAULT_SPIN.easing};\n --cf-slide-duration: ${DEFAULT_SLIDE.duration}ms;\n --cf-slide-easing: ${DEFAULT_SLIDE.easing};\n}\n\n.root {\n display: inline;\n position: relative;\n}\n\n.sr {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.visual {\n display: inline-block;\n position: relative;\n white-space: nowrap;\n}\n\n.cf-cell {\n display: inline-block;\n height: var(--cf-cell-height);\n line-height: var(--cf-cell-height);\n vertical-align: baseline;\n overflow: hidden;\n position: relative;\n text-align: center;\n}\n\n.cf-cell + .cf-cell {\n margin-left: var(--cf-letter-gap);\n}\n\n/* Soft top/bottom fade only while a wheel is mid-roll. */\n.cf-cell--rolling {\n -webkit-mask-image: linear-gradient(\n to bottom,\n transparent 0%,\n #000 18%,\n #000 82%,\n transparent 100%\n );\n mask-image: linear-gradient(\n to bottom,\n transparent 0%,\n #000 18%,\n #000 82%,\n transparent 100%\n );\n}\n\n.cf-stack {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n will-change: transform;\n}\n\n.cf-glyph {\n display: block;\n height: var(--cf-cell-height);\n line-height: var(--cf-cell-height);\n text-align: center;\n}\n`.trim()\n\nexport function applyPresetStyle(host: HTMLElement, preset: Preset): void {\n if (preset === 'plate') {\n host.style.textTransform = 'uppercase'\n host.style.letterSpacing = '0.04em'\n } else {\n host.style.textTransform = ''\n host.style.letterSpacing = ''\n }\n}\n\nexport function applyTimings(\n host: HTMLElement,\n spin?: EffectTiming,\n slide?: EffectTiming,\n): void {\n const s = { ...DEFAULT_SPIN, ...spin }\n const l = { ...DEFAULT_SLIDE, ...slide }\n host.style.setProperty('--cf-spin-duration', `${s.duration}ms`)\n host.style.setProperty('--cf-spin-easing', s.easing)\n host.style.setProperty('--cf-slide-duration', `${l.duration}ms`)\n host.style.setProperty('--cf-slide-easing', l.easing)\n}\n\nexport function parsePreset(v: string | null): Preset {\n return v === 'plate' ? 'plate' : 'alnum'\n}\n","import { observeMetrics, syncMetrics } from './layout/metrics'\nimport { mountVisual } from './render/mount'\nimport { buildSegments, initialSegments } from './segments'\nimport { applyPresetStyle, applyTimings, parsePreset, STYLES } from './styles'\nimport type { EffectTiming, Preset } from './types'\n\nconst TAG = 'char-flow'\n\nexport class CharFlowElement extends HTMLElement {\n static observedAttributes = ['value', 'preset', 'animated'] as const\n\n #sr!: HTMLElement\n #visual!: HTMLElement\n #prevValue = ''\n #keys: string[] = []\n #motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)')\n #onMotionChange = (): void => this.#syncReduced()\n #stopMetrics: (() => void) | undefined\n\n #spinTiming: EffectTiming | undefined\n #slideTiming: EffectTiming | undefined\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const root = this.attachShadow({ mode: 'open' })\n const style = document.createElement('style')\n style.textContent = STYLES\n const shell = document.createElement('div')\n shell.className = 'root'\n shell.setAttribute('part', 'root')\n\n this.#sr = document.createElement('span')\n this.#sr.className = 'sr'\n this.#sr.setAttribute('aria-live', 'polite')\n this.#sr.setAttribute('aria-atomic', 'true')\n\n this.#visual = document.createElement('span')\n this.#visual.className = 'visual'\n this.#visual.setAttribute('aria-hidden', 'true')\n\n shell.append(this.#sr, this.#visual)\n root.append(style, shell)\n }\n\n this.#motionQuery.addEventListener('change', this.#onMotionChange)\n this.#syncReduced()\n this.#applyOptions()\n this.#stopMetrics = observeMetrics(this)\n this.#render(true)\n }\n\n disconnectedCallback(): void {\n this.#motionQuery.removeEventListener('change', this.#onMotionChange)\n this.#stopMetrics?.()\n this.#stopMetrics = undefined\n }\n\n attributeChangedCallback(name: string): void {\n if (!this.isConnected) return\n if (name === 'value') {\n this.#render(false)\n return\n }\n this.#applyOptions()\n if (name === 'animated') this.#render(false)\n }\n\n get value(): string {\n return this.getAttribute('value') ?? ''\n }\n\n set value(v: string) {\n this.setAttribute('value', v)\n }\n\n get preset(): Preset {\n return parsePreset(this.getAttribute('preset'))\n }\n\n set preset(v: Preset) {\n this.setAttribute('preset', v)\n }\n\n get animated(): boolean {\n return this.getAttribute('animated') !== 'false'\n }\n\n set animated(v: boolean) {\n if (v) this.removeAttribute('animated')\n else this.setAttribute('animated', 'false')\n }\n\n set spinTiming(t: EffectTiming | undefined) {\n this.#spinTiming = t\n this.#applyOptions()\n }\n\n set slideTiming(t: EffectTiming | undefined) {\n this.#slideTiming = t\n this.#applyOptions()\n }\n\n #canAnimate(): boolean {\n if (!this.animated) return false\n if (this.#motionQuery.matches) return false\n return true\n }\n\n #syncReduced(): void {\n if (this.#motionQuery.matches) this.dataset.reduced = ''\n else delete this.dataset.reduced\n }\n\n #applyOptions(): void {\n applyPresetStyle(this, this.preset)\n applyTimings(this, this.#spinTiming, this.#slideTiming)\n syncMetrics(this)\n }\n\n #render(initial: boolean): void {\n const next = this.value\n this.#sr.textContent = next\n\n const animated = this.#canAnimate() && !initial\n\n let segments\n if (initial || !this.#prevValue) {\n const init = initialSegments(next)\n segments = init.segments\n this.#keys = init.keys\n } else if (this.#prevValue === next) {\n return\n } else {\n const built = buildSegments(this.#prevValue, next, this.#keys)\n segments = built.segments\n this.#keys = built.keys\n }\n\n mountVisual(this.#visual, segments, animated)\n this.#prevValue = next\n }\n}\n\nexport function defineCharFlow(tag = TAG): void {\n if (!customElements.get(tag)) {\n customElements.define(tag, CharFlowElement)\n }\n}\n\ndefineCharFlow()\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'char-flow': CharFlowElement\n }\n}\n\nexport { TAG }\n"]}
@@ -0,0 +1,12 @@
1
+ import { D as DiffOp, C as CharKind } from './element-ohGNSSoB.js';
2
+ export { A as AnimKind, a as CharFlowElement, E as EffectTiming, P as Preset, T as TAG, d as defineCharFlow } from './element-ohGNSSoB.js';
3
+ export { CharFlow } from './react.js';
4
+ import 'react';
5
+
6
+ /** Shortest edit script via Wagner-Fischer. Deletes are omitted (cells simply disappear). */
7
+ declare function diffChars(prev: string, next: string, keyOffset?: number): DiffOp[];
8
+ declare function diff(prev: string, next: string): DiffOp[];
9
+
10
+ declare function classify(char: string): CharKind;
11
+
12
+ export { CharKind, classify, diff, diffChars };
package/dist/index.js ADDED
@@ -0,0 +1,84 @@
1
+ import {useRef,useEffect,createElement}from'react';function C(e){let{letterSpacing:t}=getComputedStyle(e);e.style.setProperty("--cf-letter-gap",t==="normal"?"0px":t);}function H(e){let t=()=>C(e);t();let n=new ResizeObserver(t);return n.observe(e),document.fonts?.ready.then(t).catch(()=>{}),()=>n.disconnect()}var w="0123456789",v="ABCDEFGHIJKLMNOPQRSTUVWXYZ",x={duration:520,easing:"cubic-bezier(0.32, 0.72, 0, 1)",delay:0},b={duration:340,easing:"cubic-bezier(0.32, 0.72, 0, 1)",delay:0},I=16;function d(e){return e===" "?"\xA0":e}function K(e,t){return t>="a"&&t<="z"?e.toLowerCase():e}function u(e){if(!e)return "other";let t=e.charCodeAt(0);return t>=48&&t<=57?"digit":t>=65&&t<=90||t>=97&&t<=122?"letter":"other"}function h(e,t){return t==="digit"?e.charCodeAt(0)-48:e.toUpperCase().charCodeAt(0)-65}function D(e){let t=u(e);return t==="digit"?"wheel-digit":t==="letter"?"wheel-letter":"static"}function F(e,t){let n=u(e),r=u(t);return n==="digit"&&r==="digit"?"wheel-digit":n==="letter"&&r==="letter"?"wheel-letter":"slide"}function O(e,t,n){let r=h(e,n),i=h(t,n);if(r===i)return 1;let s=n==="letter"?26:10,o=(i-r+s)%s,l=(r-i+s)%s;return o<=l?1:-1}function re(e,t,n){return t==="digit"?w[e]:K(v[e],n)}function $(e,t,n){let r=n==="letter"?v.length:w.length,i=h(e,n),s=h(t,n),o=O(e,t,n),l=[];for(let c=i;l.push(re(c,n,t)),c!==s;c=(c+o+r)%r);return o===1?{chars:l,startIdx:0,endIdx:l.length-1}:{chars:[...l].reverse(),startIdx:l.length-1,endIdx:0}}function ie(e,t){return {chars:[d(e),d(t)],startIdx:0,endIdx:1}}function S(e){return e.fromChar==null||e.fromChar===e.char?null:e.anim==="wheel-digit"?$(e.fromChar,e.char,"digit"):e.anim==="wheel-letter"?$(e.fromChar,e.char,"letter"):ie(e.fromChar,e.char)}function N(e){return e.anim==="wheel-digit"||e.anim==="wheel-letter"}function k(e){let t=document.createElement("span");return t.className="cf-glyph",t.setAttribute("part","glyph"),t.textContent=d(e),t}function Y(e,t=""){let n=document.createElement("span");return n.className=t?`cf-cell ${t}`:"cf-cell",n.dataset.key=e.key,n.dataset.char=e.char,n.setAttribute("part","segment"),n}function M(e){let t=Y(e);return t.appendChild(k(e.char)),t}function se(e,t){let n=M(e),r=e.runLength&&e.runLength>1?(e.runIndex??0)*I:0;return t.push(i=>{n.animate([{opacity:0,transform:"translateY(0.25em)"},{opacity:1,transform:"translateY(0)"}],{duration:i.slide.duration,easing:i.slide.easing,delay:r,fill:"backwards"});}),n}function oe(e,t){let n=S(e),r=N(e),i=Y(e,r?"cf-cell--rolling":""),s=k(e.char);s.style.visibility="hidden";let o=document.createElement("span");o.className="cf-stack";for(let l of n.chars)o.appendChild(k(l));return i.append(s,o),t.push(l=>{let c=-n.startIdx*l.cellHeight,a=-n.endIdx*l.cellHeight,f=r?l.spin:l.slide;o.style.transform=`translateY(${c}px)`;let p=o.animate([{transform:`translateY(${c}px)`},{transform:`translateY(${a}px)`}],{duration:f.duration,easing:f.easing,fill:"forwards"});p.onfinish=()=>{p.cancel(),o.remove(),s.style.visibility="",i.classList.remove("cf-cell--rolling");};}),i}function le(e,t,n){return e.entering?t?se(e,n):M(e):t&&S(e)?oe(e,n):M(e)}function G(e,t,n,r){let i=n.get(e.key);return i&&!e.entering&&e.fromChar==null&&i.dataset.char===e.char?i:le(e,t,r)}function U(e){let t=new Map;for(let n of e.querySelectorAll(".cf-cell[data-key]"))n instanceof HTMLElement&&n.dataset.key&&t.set(n.dataset.key,n);return t}function V(e){let t=parseFloat(e);return Number.isFinite(t)?e.trim().endsWith("ms")?t:t*1e3:0}function ae(e){let t=getComputedStyle(e),n=e.querySelector(".cf-glyph");return {cellHeight:n instanceof HTMLElement?n.offsetHeight:0,spin:{duration:V(t.getPropertyValue("--cf-spin-duration")),easing:t.getPropertyValue("--cf-spin-easing").trim()},slide:{duration:V(t.getPropertyValue("--cf-slide-duration")),easing:t.getPropertyValue("--cf-slide-easing").trim()}}}function _(e,t){let n=e.getBoundingClientRect().left,r=new Map;for(let i of t)i.dataset.key&&r.set(i.dataset.key,i.getBoundingClientRect().left-n);return r}function X(e,t,n){let r=U(e),i=n?_(e,r.values()):new Map,s=[],o=[],l=new Set;for(let f of t){let p=G(f,n,r,s);l.add(f.key),o.push(p);}let c=[];if(n)for(let[f,p]of r)l.has(f)||c.push(p);if(e.replaceChildren(...o,...c),!s.length&&!c.length)return;let a=ae(e);if(n){let f=_(e,o);for(let p of o){let m=p.dataset.key;if(!m)continue;let g=i.get(m),y=f.get(m);if(g===void 0||y===void 0)continue;let R=g-y;Math.abs(R)<.5||p.animate([{transform:`translateX(${R}px)`},{transform:"translateX(0)"}],{duration:a.slide.duration,easing:a.slide.easing});}for(let p of c){let m=i.get(p.dataset.key),g=p.offsetWidth;p.style.position="absolute",p.style.top="0",p.style.left=`${m??0}px`,p.style.width=`${g}px`,p.style.pointerEvents="none";let y=p.animate([{opacity:1,transform:"translateY(0)"},{opacity:0,transform:"translateY(-0.25em)"}],{duration:a.slide.duration,easing:a.slide.easing,fill:"forwards"});y.onfinish=()=>p.remove();}}for(let f of s)f(a);}function q(e,t){let n=e.length,r=t.length,i=Array.from({length:n+1},()=>Array.from({length:r+1},()=>0));for(let s=0;s<=n;s++)i[s][0]=s;for(let s=0;s<=r;s++)i[0][s]=s;for(let s=1;s<=n;s++)for(let o=1;o<=r;o++)e[s-1]===t[o-1]?i[s][o]=i[s-1][o-1]:i[s][o]=1+Math.min(i[s-1][o],i[s][o-1],i[s-1][o-1]);return i}function ce(e,t,n,r){let i=[],s=t.length,o=n.length;for(;s>0||o>0;)s>0&&o>0&&t[s-1]===n[o-1]?(i.push("M"),s--,o--):s>0&&o>0&&e[s][o]===e[s-1][o-1]+1?(i.push("R"),s--,o--):o>0&&e[s][o]===e[s][o-1]+1?(i.push("I"),o--):(i.push("D"),s--);i.reverse();let l=[],c=0,a=0;for(let f of i)f==="M"?(l.push({type:"keep",index:a,char:n[a],prevKey:r+c}),c++,a++):f==="R"?(l.push({type:"replace",index:a,from:t[c],to:n[a],prevKey:r+c}),c++,a++):f==="I"?(l.push({type:"insert",index:a,char:n[a]}),a++):c++;return l}function z(e,t,n=0){let r=[...e],i=[...t],s=q(r,i);return ce(s,r,i,n)}function fe(e,t){let n=t,r=[];for(let i of e)if(i.type==="insert")r.push({type:"insert",index:n++,char:i.char});else if(i.type==="keep"){let s={type:"keep",index:n++,char:i.char,prevKey:i.prevKey};i.region&&(s.region=i.region),r.push(s);}else i.type==="replace"&&r.push({type:"replace",index:n++,from:i.from,to:i.to,prevKey:i.prevKey});return r}function pe(e,t){let n=[];for(let r=0;r<t.length;r++){let i=e[r],s=t[r];i===s?n.push({type:"keep",index:r,char:s,prevKey:r}):n.push({type:"replace",index:r,from:i,to:s,prevKey:r});}return n}function L(e,t){if(e.length===t.length)return pe(e,t);let n=0;for(;n<e.length&&n<t.length&&e[n]===t[n];)n++;let r=0;for(;r<e.length-n&&r<t.length-n&&e[e.length-1-r]===t[t.length-1-r];)r++;let i=[],s=0;for(let f=0;f<n;f++)i.push({type:"keep",index:s++,char:t[f],prevKey:f});let o=e.slice(n,e.length-r),l=t.slice(n,t.length-r),c=Math.max(o.length,l.length);if(c>0)if(q([...o],[...l])[o.length][l.length]/c>.4)for(let m=0;m<l.length;m++)i.push({type:"insert",index:s++,char:l[m]});else i.push(...fe(z(o,l,n),s)),s+=l.length;let a=Math.max(n,t.length-r);for(let f=a;f<t.length;f++){let p=e.length-r+(f-(t.length-r));p<n||i.push({type:"keep",index:s++,char:t[f],prevKey:p,region:"suffix"});}return i}var me=0;function P(e){return `${e}-${++me}`}function W(e,t,n){return e[t]??P(n)}function ue(e){let t=e.map(r=>({...r})),n=0;for(;n<t.length;){if(!t[n].entering){n++;continue}let i=n+1;for(;i<t.length&&t[i].entering;)i++;let s=i-n;for(let o=n;o<i;o++)t[o]={...t[o],runIndex:o-n,runLength:s};n=i;}return t}function E(e,t,n={}){return {key:t,char:e,kind:u(e),anim:n.anim??D(e),...n}}function de(e,t){let n=[];for(let r of e){if(r.type==="keep"){n.push(E(r.char,W(t,r.prevKey,"k")));continue}if(r.type==="replace"){n.push(E(r.to,W(t,r.prevKey,"r"),{anim:F(r.from,r.to),fromChar:r.from,fromKind:u(r.from)}));continue}r.type==="insert"&&n.push(E(r.char,P("i"),{entering:true}));}return ue(n)}function j(e,t,n){let r=de(L(e,t),n);return {segments:r,keys:r.map(i=>i.key)}}function B(e){let t=[...e].map((n,r)=>E(n,P(`s${r}`)));return {segments:t,keys:t.map(n=>n.key)}}var Q=`
2
+ :host {
3
+ display: inline-block;
4
+ line-height: inherit;
5
+ font-variant-numeric: tabular-nums;
6
+ --cf-cell-height: 1lh;
7
+ --cf-letter-gap: 0px;
8
+ --cf-spin-duration: ${x.duration}ms;
9
+ --cf-spin-easing: ${x.easing};
10
+ --cf-slide-duration: ${b.duration}ms;
11
+ --cf-slide-easing: ${b.easing};
12
+ }
13
+
14
+ .root {
15
+ display: inline;
16
+ position: relative;
17
+ }
18
+
19
+ .sr {
20
+ position: absolute;
21
+ width: 1px;
22
+ height: 1px;
23
+ padding: 0;
24
+ margin: -1px;
25
+ overflow: hidden;
26
+ clip: rect(0, 0, 0, 0);
27
+ white-space: nowrap;
28
+ border: 0;
29
+ }
30
+
31
+ .visual {
32
+ display: inline-block;
33
+ position: relative;
34
+ white-space: nowrap;
35
+ }
36
+
37
+ .cf-cell {
38
+ display: inline-block;
39
+ height: var(--cf-cell-height);
40
+ line-height: var(--cf-cell-height);
41
+ vertical-align: baseline;
42
+ overflow: hidden;
43
+ position: relative;
44
+ text-align: center;
45
+ }
46
+
47
+ .cf-cell + .cf-cell {
48
+ margin-left: var(--cf-letter-gap);
49
+ }
50
+
51
+ /* Soft top/bottom fade only while a wheel is mid-roll. */
52
+ .cf-cell--rolling {
53
+ -webkit-mask-image: linear-gradient(
54
+ to bottom,
55
+ transparent 0%,
56
+ #000 18%,
57
+ #000 82%,
58
+ transparent 100%
59
+ );
60
+ mask-image: linear-gradient(
61
+ to bottom,
62
+ transparent 0%,
63
+ #000 18%,
64
+ #000 82%,
65
+ transparent 100%
66
+ );
67
+ }
68
+
69
+ .cf-stack {
70
+ position: absolute;
71
+ top: 0;
72
+ left: 0;
73
+ width: 100%;
74
+ will-change: transform;
75
+ }
76
+
77
+ .cf-glyph {
78
+ display: block;
79
+ height: var(--cf-cell-height);
80
+ line-height: var(--cf-cell-height);
81
+ text-align: center;
82
+ }
83
+ `.trim();function J(e,t){t==="plate"?(e.style.textTransform="uppercase",e.style.letterSpacing="0.04em"):(e.style.textTransform="",e.style.letterSpacing="");}function Z(e,t,n){let r={...x,...t},i={...b,...n};e.style.setProperty("--cf-spin-duration",`${r.duration}ms`),e.style.setProperty("--cf-spin-easing",r.easing),e.style.setProperty("--cf-slide-duration",`${i.duration}ms`),e.style.setProperty("--cf-slide-easing",i.easing);}function ee(e){return e==="plate"?"plate":"alnum"}var te="char-flow",T=class extends HTMLElement{static observedAttributes=["value","preset","animated"];#e;#t;#n="";#s=[];#r=window.matchMedia("(prefers-reduced-motion: reduce)");#a=()=>this.#p();#o;#c;#f;connectedCallback(){if(!this.shadowRoot){let t=this.attachShadow({mode:"open"}),n=document.createElement("style");n.textContent=Q;let r=document.createElement("div");r.className="root",r.setAttribute("part","root"),this.#e=document.createElement("span"),this.#e.className="sr",this.#e.setAttribute("aria-live","polite"),this.#e.setAttribute("aria-atomic","true"),this.#t=document.createElement("span"),this.#t.className="visual",this.#t.setAttribute("aria-hidden","true"),r.append(this.#e,this.#t),t.append(n,r);}this.#r.addEventListener("change",this.#a),this.#p(),this.#i(),this.#o=H(this),this.#l(true);}disconnectedCallback(){this.#r.removeEventListener("change",this.#a),this.#o?.(),this.#o=void 0;}attributeChangedCallback(t){if(this.isConnected){if(t==="value"){this.#l(false);return}this.#i(),t==="animated"&&this.#l(false);}}get value(){return this.getAttribute("value")??""}set value(t){this.setAttribute("value",t);}get preset(){return ee(this.getAttribute("preset"))}set preset(t){this.setAttribute("preset",t);}get animated(){return this.getAttribute("animated")!=="false"}set animated(t){t?this.removeAttribute("animated"):this.setAttribute("animated","false");}set spinTiming(t){this.#c=t,this.#i();}set slideTiming(t){this.#f=t,this.#i();}#m(){return !(!this.animated||this.#r.matches)}#p(){this.#r.matches?this.dataset.reduced="":delete this.dataset.reduced;}#i(){J(this,this.preset),Z(this,this.#c,this.#f),C(this);}#l(t){let n=this.value;this.#e.textContent=n;let r=this.#m()&&!t,i;if(t||!this.#n){let s=B(n);i=s.segments,this.#s=s.keys;}else {if(this.#n===n)return;{let s=j(this.#n,n,this.#s);i=s.segments,this.#s=s.keys;}}X(this.#t,i,r),this.#n=n;}};function ne(e=te){customElements.get(e)||customElements.define(e,T);}ne();function ye(){if(typeof customElements<"u"&&!customElements.get("char-flow"))throw new Error('CharFlow: import "char-flow/element" before using the React wrapper.')}function xe({value:e,preset:t="alnum",animated:n=true,spinTiming:r,slideTiming:i,className:s,style:o,...l}){let c=useRef(null);return useEffect(()=>{ye();},[]),useEffect(()=>{let a=c.current;a&&a.value!==e&&(a.value=e);},[e]),useEffect(()=>{let a=c.current;a&&(a.preset=t,a.animated=n,r!==void 0&&(a.spinTiming=r),i!==void 0&&(a.slideTiming=i));},[t,n,r,i]),createElement("char-flow",{ref:c,value:e,preset:t,...n?{}:{animated:"false"},class:s,style:o,...l})}export{xe as CharFlow,T as CharFlowElement,te as TAG,u as classify,ne as defineCharFlow,L as diff,z as diffChars};//# sourceMappingURL=index.js.map
84
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/layout/metrics.ts","../src/types.ts","../src/render/format.ts","../src/classify.ts","../src/render/stack.ts","../src/render/cell.ts","../src/render/mount.ts","../src/diff.ts","../src/segments.ts","../src/styles.ts","../src/element.ts","../src/react.tsx"],"names":["syncMetrics","host","letterSpacing","observeMetrics","run","ro","DIGITS","LETTERS","DEFAULT_SPIN","DEFAULT_SLIDE","STAGGER_STEP_MS","formatChar","char","displayLetter","stripChar","target","classify","code","wheelIndex","kind","animForChar","k","animForReplace","from","to","fk","tk","spinDirection","a","b","n","up","down","charForIndex","i","wheelPlan","dir","path","slidePlan","planFor","seg","isWheel","glyph","g","makeCell","extraClass","cell","staticCell","enteringCell","pending","delay","ctx","rollingCell","plan","wheel","sizer","stack","c","startY","endY","timing","anim","buildCell","animated","reuseCell","existing","existingCellMap","root","map","el","ms","value","readContext","visual","cs","sample","measureX","cells","base","out","mountVisual","segments","firstX","nodes","survivors","node","exiting","key","lastX","before","after","dx","x","width","levenshteinMatrix","m","dp","j","backtrackOps","keyOffset","raw","ops","ai","bi","step","diffChars","prev","next","reindexOps","startIdx","outIdx","result","op","keep","diffAligned","diff","pre","suf","midPrev","midNext","midMax","suffixStart","prevIdx","keySeq","nextKey","prefix","keyForPrev","prevKeys","prevKey","fallback","assignEnteringRuns","s","len","makeSegment","extra","opsToSegments","buildSegments","prevSegmentKeys","initialSegments","STYLES","applyPresetStyle","preset","applyTimings","spin","slide","l","parsePreset","v","TAG","CharFlowElement","#sr","#visual","#prevValue","#keys","#motionQuery","#onMotionChange","#syncReduced","#stopMetrics","#spinTiming","#slideTiming","style","shell","#applyOptions","#render","name","#canAnimate","initial","init","built","defineCharFlow","tag","assertRegistered","CharFlow","spinTiming","slideTiming","className","rest","ref","useRef","useEffect","createElement"],"mappings":"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","file":"index.js","sourcesContent":["/** Sync layout CSS variables from computed host styles. */\nexport function syncMetrics(host: HTMLElement): void {\n const { letterSpacing } = getComputedStyle(host)\n host.style.setProperty('--cf-letter-gap', letterSpacing === 'normal' ? '0px' : letterSpacing)\n}\n\nexport function observeMetrics(host: HTMLElement): () => void {\n const run = (): void => syncMetrics(host)\n\n run()\n\n const ro = new ResizeObserver(run)\n ro.observe(host)\n\n document.fonts?.ready.then(run).catch(() => undefined)\n\n return () => ro.disconnect()\n}\n","export type CharKind = 'digit' | 'letter' | 'other'\n\nexport type Preset = 'plate' | 'alnum'\n\n/** How a changed character moves: roll through an alphabet, or a direct swap. */\nexport type AnimKind = 'wheel-digit' | 'wheel-letter' | 'slide' | 'static'\n\nexport interface EffectTiming {\n duration?: number\n easing?: string\n delay?: number\n}\n\nexport interface CharFlowOptions {\n preset?: Preset\n animated?: boolean\n spinTiming?: EffectTiming\n slideTiming?: EffectTiming\n}\n\nexport type DiffOp =\n | { type: 'keep'; index: number; char: string; prevKey: number; region?: 'suffix' }\n | { type: 'replace'; index: number; from: string; to: string; prevKey: number }\n | { type: 'insert'; index: number; char: string }\n\nexport interface RenderSegment {\n key: string\n char: string\n kind: CharKind\n anim: AnimKind\n fromChar?: string\n fromKind?: CharKind\n entering?: boolean\n /** Index inside a consecutive insert run (for stagger). */\n runIndex?: number\n /** Length of the current insert run. */\n runLength?: number\n}\n\nexport const DIGITS = '0123456789' as const\nexport const LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' as const\n\nexport const DEFAULT_SPIN: Required<EffectTiming> = {\n duration: 520,\n easing: 'cubic-bezier(0.32, 0.72, 0, 1)',\n delay: 0,\n}\n\n/** Used for direct swaps (non-roll) and for entering/exiting/shifting cells. */\nexport const DEFAULT_SLIDE: Required<EffectTiming> = {\n duration: 340,\n easing: 'cubic-bezier(0.32, 0.72, 0, 1)',\n delay: 0,\n}\n\n/** Delay between cells in an insert run. */\nexport const STAGGER_STEP_MS = 16\n","export function formatChar(char: string): string {\n return char === ' ' ? '\\u00a0' : char\n}\n\nexport function displayLetter(stripChar: string, target: string): string {\n if (target >= 'a' && target <= 'z') return stripChar.toLowerCase()\n return stripChar\n}\n","import type { AnimKind, CharKind } from './types'\n\nexport function classify(char: string): CharKind {\n if (!char) return 'other'\n const code = char.charCodeAt(0)\n if (code >= 48 && code <= 57) return 'digit'\n if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) return 'letter'\n return 'other'\n}\n\nexport function wheelIndex(char: string, kind: CharKind): number {\n if (kind === 'digit') return char.charCodeAt(0) - 48\n const upper = char.toUpperCase()\n return upper.charCodeAt(0) - 65\n}\n\n/** Resting animation tag for an unchanged character. */\nexport function animForChar(char: string): AnimKind {\n const k = classify(char)\n if (k === 'digit') return 'wheel-digit'\n if (k === 'letter') return 'wheel-letter'\n return 'static'\n}\n\n/**\n * Same alphabet (digit→digit, letter→letter) rolls through that alphabet.\n * Everything else (cross-kind, or any change involving punctuation) is a\n * direct two-glyph roll: old slides out, new slides in, no in-betweens.\n */\nexport function animForReplace(from: string, to: string): AnimKind {\n const fk = classify(from)\n const tk = classify(to)\n if (fk === 'digit' && tk === 'digit') return 'wheel-digit'\n if (fk === 'letter' && tk === 'letter') return 'wheel-letter'\n return 'slide'\n}\n\nexport function spinDirection(from: string, to: string, kind: CharKind): 1 | -1 {\n const a = wheelIndex(from, kind)\n const b = wheelIndex(to, kind)\n if (a === b) return 1\n const n = kind === 'letter' ? 26 : 10\n const up = (b - a + n) % n\n const down = (a - b + n) % n\n return up <= down ? 1 : -1\n}\n","import { spinDirection, wheelIndex } from '../classify'\nimport { DIGITS, LETTERS } from '../types'\nimport type { RenderSegment } from '../types'\nimport { displayLetter, formatChar } from './format'\n\n/**\n * A vertical column of glyphs plus the start/end positions to slide between.\n * Every animated transition — digit roll, letter roll, or text replacement —\n * is expressed as this one primitive: a stack translated along Y.\n */\nexport interface StackPlan {\n /** Glyphs in visual order, top to bottom. */\n chars: string[]\n /** Index showing at the start of the animation. */\n startIdx: number\n /** Index showing at the end of the animation. */\n endIdx: number\n}\n\nfunction charForIndex(i: number, kind: 'digit' | 'letter', target: string): string {\n if (kind === 'digit') return DIGITS[i]!\n return displayLetter(LETTERS[i]!, target)\n}\n\n/** Glyphs along the shortest path from `from` to `to` around the alphabet. */\nfunction wheelPlan(from: string, to: string, kind: 'digit' | 'letter'): StackPlan {\n const n = kind === 'letter' ? LETTERS.length : DIGITS.length\n const a = wheelIndex(from, kind)\n const b = wheelIndex(to, kind)\n const dir = spinDirection(from, to, kind)\n\n const path: string[] = []\n for (let i = a; ; i = (i + dir + n) % n) {\n path.push(charForIndex(i, kind, to))\n if (i === b) break\n }\n\n // dir +1 rolls up (content moves up, next glyph enters from below).\n // dir -1 rolls down, so reverse the column and start from the bottom.\n if (dir === 1) return { chars: path, startIdx: 0, endIdx: path.length - 1 }\n return { chars: [...path].reverse(), startIdx: path.length - 1, endIdx: 0 }\n}\n\n/** A single-step slide between two arbitrary glyphs (text replacement / morph). */\nfunction slidePlan(from: string, to: string): StackPlan {\n return { chars: [formatChar(from), formatChar(to)], startIdx: 0, endIdx: 1 }\n}\n\n/** Build the plan for a segment, or null if there is nothing to animate. */\nexport function planFor(seg: RenderSegment): StackPlan | null {\n if (seg.fromChar == null || seg.fromChar === seg.char) return null\n if (seg.anim === 'wheel-digit') return wheelPlan(seg.fromChar, seg.char, 'digit')\n if (seg.anim === 'wheel-letter') return wheelPlan(seg.fromChar, seg.char, 'letter')\n return slidePlan(seg.fromChar, seg.char)\n}\n\nexport function isWheel(seg: RenderSegment): boolean {\n return seg.anim === 'wheel-digit' || seg.anim === 'wheel-letter'\n}\n","import type { RenderSegment } from '../types'\nimport { STAGGER_STEP_MS } from '../types'\nimport { formatChar } from './format'\nimport { isWheel, planFor } from './stack'\n\nexport interface AnimContext {\n /** Measured cell height in px (one line of text). */\n cellHeight: number\n spin: { duration: number; easing: string }\n slide: { duration: number; easing: string }\n}\n\n/** Deferred animation: queued during build, launched once after layout. */\nexport type Pending = (ctx: AnimContext) => void\n\nfunction glyph(char: string): HTMLElement {\n const g = document.createElement('span')\n g.className = 'cf-glyph'\n g.setAttribute('part', 'glyph')\n g.textContent = formatChar(char)\n return g\n}\n\nfunction makeCell(seg: RenderSegment, extraClass = ''): HTMLElement {\n const cell = document.createElement('span')\n cell.className = extraClass ? `cf-cell ${extraClass}` : 'cf-cell'\n cell.dataset.key = seg.key\n cell.dataset.char = seg.char\n cell.setAttribute('part', 'segment')\n return cell\n}\n\nfunction staticCell(seg: RenderSegment): HTMLElement {\n const cell = makeCell(seg)\n cell.appendChild(glyph(seg.char))\n return cell\n}\n\nfunction enteringCell(seg: RenderSegment, pending: Pending[]): HTMLElement {\n const cell = staticCell(seg)\n const delay =\n seg.runLength && seg.runLength > 1 ? (seg.runIndex ?? 0) * STAGGER_STEP_MS : 0\n\n pending.push((ctx) => {\n cell.animate(\n [\n { opacity: 0, transform: 'translateY(0.25em)' },\n { opacity: 1, transform: 'translateY(0)' },\n ],\n { duration: ctx.slide.duration, easing: ctx.slide.easing, delay, fill: 'backwards' },\n )\n })\n return cell\n}\n\nfunction rollingCell(seg: RenderSegment, pending: Pending[]): HTMLElement {\n const plan = planFor(seg)!\n const wheel = isWheel(seg)\n const cell = makeCell(seg, wheel ? 'cf-cell--rolling' : '')\n\n // A normal-flow sizer (the resting glyph) owns the cell's width so it stays\n // constant; the multi-glyph stack floats above it and never affects layout.\n const sizer = glyph(seg.char)\n sizer.style.visibility = 'hidden'\n const stack = document.createElement('span')\n stack.className = 'cf-stack'\n for (const c of plan.chars) stack.appendChild(glyph(c))\n cell.append(sizer, stack)\n\n pending.push((ctx) => {\n const startY = -plan.startIdx * ctx.cellHeight\n const endY = -plan.endIdx * ctx.cellHeight\n const timing = wheel ? ctx.spin : ctx.slide\n\n stack.style.transform = `translateY(${startY}px)`\n const anim = stack.animate(\n [{ transform: `translateY(${startY}px)` }, { transform: `translateY(${endY}px)` }],\n { duration: timing.duration, easing: timing.easing, fill: 'forwards' },\n )\n // Drop the stack and reveal the resting sizer once the roll lands.\n anim.onfinish = () => {\n anim.cancel()\n stack.remove()\n sizer.style.visibility = ''\n cell.classList.remove('cf-cell--rolling')\n }\n })\n\n return cell\n}\n\nexport function buildCell(\n seg: RenderSegment,\n animated: boolean,\n pending: Pending[],\n): HTMLElement {\n if (seg.entering) {\n return animated ? enteringCell(seg, pending) : staticCell(seg)\n }\n if (animated && planFor(seg)) {\n return rollingCell(seg, pending)\n }\n return staticCell(seg)\n}\n\nexport function reuseCell(\n seg: RenderSegment,\n animated: boolean,\n existing: Map<string, HTMLElement>,\n pending: Pending[],\n): HTMLElement {\n const cell = existing.get(seg.key)\n // Unchanged, resting cells are reused untouched; anything that moves is rebuilt.\n if (cell && !seg.entering && seg.fromChar == null && cell.dataset.char === seg.char) {\n return cell\n }\n return buildCell(seg, animated, pending)\n}\n\nexport function existingCellMap(root: HTMLElement): Map<string, HTMLElement> {\n const map = new Map<string, HTMLElement>()\n for (const el of root.querySelectorAll('.cf-cell[data-key]')) {\n if (el instanceof HTMLElement && el.dataset.key) map.set(el.dataset.key, el)\n }\n return map\n}\n","import type { RenderSegment } from '../types'\nimport { existingCellMap, reuseCell, type AnimContext, type Pending } from './cell'\n\nfunction ms(value: string): number {\n const n = parseFloat(value)\n if (!Number.isFinite(n)) return 0\n return value.trim().endsWith('ms') ? n : n * 1000\n}\n\nfunction readContext(visual: HTMLElement): AnimContext {\n const cs = getComputedStyle(visual)\n const sample = visual.querySelector('.cf-glyph')\n return {\n cellHeight: sample instanceof HTMLElement ? sample.offsetHeight : 0,\n spin: {\n duration: ms(cs.getPropertyValue('--cf-spin-duration')),\n easing: cs.getPropertyValue('--cf-spin-easing').trim(),\n },\n slide: {\n duration: ms(cs.getPropertyValue('--cf-slide-duration')),\n easing: cs.getPropertyValue('--cf-slide-easing').trim(),\n },\n }\n}\n\n/** x offset (relative to the visual box) of each existing cell, keyed by data-key. */\nfunction measureX(visual: HTMLElement, cells: Iterable<HTMLElement>): Map<string, number> {\n const base = visual.getBoundingClientRect().left\n const out = new Map<string, number>()\n for (const el of cells) {\n if (el.dataset.key) out.set(el.dataset.key, el.getBoundingClientRect().left - base)\n }\n return out\n}\n\nexport function mountVisual(\n visual: HTMLElement,\n segments: RenderSegment[],\n animated: boolean,\n): void {\n const existing = existingCellMap(visual)\n\n // FLIP \"First\": record where every current cell sits before we touch the DOM.\n const firstX = animated ? measureX(visual, existing.values()) : new Map<string, number>()\n\n const pending: Pending[] = []\n const nodes: HTMLElement[] = []\n const survivors = new Set<string>()\n\n for (const seg of segments) {\n const node = reuseCell(seg, animated, existing, pending)\n survivors.add(seg.key)\n nodes.push(node)\n }\n\n // Cells present before but gone now: animate them out instead of popping.\n const exiting: HTMLElement[] = []\n if (animated) {\n for (const [key, el] of existing) {\n if (!survivors.has(key)) exiting.push(el)\n }\n }\n\n // Exiting cells stay in the DOM (absolutely positioned) so they don't affect width.\n visual.replaceChildren(...nodes, ...exiting)\n\n if (!pending.length && !exiting.length) return\n\n const ctx = readContext(visual)\n\n if (animated) {\n // FLIP \"Last/Invert/Play\": slide survivors from their old x back to the new one.\n const lastX = measureX(visual, nodes)\n for (const node of nodes) {\n const key = node.dataset.key\n if (!key) continue\n const before = firstX.get(key)\n const after = lastX.get(key)\n if (before === undefined || after === undefined) continue\n const dx = before - after\n if (Math.abs(dx) < 0.5) continue\n node.animate(\n [{ transform: `translateX(${dx}px)` }, { transform: 'translateX(0)' }],\n { duration: ctx.slide.duration, easing: ctx.slide.easing },\n )\n }\n\n for (const el of exiting) {\n const x = firstX.get(el.dataset.key!)\n const width = el.offsetWidth\n el.style.position = 'absolute'\n el.style.top = '0'\n el.style.left = `${x ?? 0}px`\n el.style.width = `${width}px`\n el.style.pointerEvents = 'none'\n const out = el.animate(\n [\n { opacity: 1, transform: 'translateY(0)' },\n { opacity: 0, transform: 'translateY(-0.25em)' },\n ],\n { duration: ctx.slide.duration, easing: ctx.slide.easing, fill: 'forwards' },\n )\n out.onfinish = () => el.remove()\n }\n }\n\n for (const run of pending) run(ctx)\n}\n","import type { DiffOp } from './types'\n\nfunction levenshteinMatrix(a: string[], b: string[]): number[][] {\n const m = a.length\n const n = b.length\n const dp: number[][] = Array.from({ length: m + 1 }, () =>\n Array.from({ length: n + 1 }, () => 0),\n )\n for (let i = 0; i <= m; i++) dp[i]![0] = i\n for (let j = 0; j <= n; j++) dp[0]![j] = j\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n if (a[i - 1] === b[j - 1]) {\n dp[i]![j] = dp[i - 1]![j - 1]!\n } else {\n dp[i]![j] = 1 + Math.min(dp[i - 1]![j]!, dp[i]![j - 1]!, dp[i - 1]![j - 1]!)\n }\n }\n }\n\n return dp\n}\n\nfunction backtrackOps(dp: number[][], a: string[], b: string[], keyOffset: number): DiffOp[] {\n const raw: Array<'M' | 'I' | 'D' | 'R'> = []\n let i = a.length\n let j = b.length\n\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && a[i - 1] === b[j - 1]) {\n raw.push('M')\n i--\n j--\n } else if (i > 0 && j > 0 && dp[i]![j] === dp[i - 1]![j - 1]! + 1) {\n raw.push('R')\n i--\n j--\n } else if (j > 0 && dp[i]![j] === dp[i]![j - 1]! + 1) {\n raw.push('I')\n j--\n } else {\n raw.push('D')\n i--\n }\n }\n raw.reverse()\n\n const ops: DiffOp[] = []\n let ai = 0\n let bi = 0\n for (const step of raw) {\n if (step === 'M') {\n ops.push({ type: 'keep', index: bi, char: b[bi]!, prevKey: keyOffset + ai })\n ai++\n bi++\n } else if (step === 'R') {\n ops.push({\n type: 'replace',\n index: bi,\n from: a[ai]!,\n to: b[bi]!,\n prevKey: keyOffset + ai,\n })\n ai++\n bi++\n } else if (step === 'I') {\n ops.push({ type: 'insert', index: bi, char: b[bi]! })\n bi++\n } else {\n ai++\n }\n }\n return ops\n}\n\n/** Shortest edit script via Wagner-Fischer. Deletes are omitted (cells simply disappear). */\nexport function diffChars(prev: string, next: string, keyOffset = 0): DiffOp[] {\n const a = [...prev]\n const b = [...next]\n const dp = levenshteinMatrix(a, b)\n return backtrackOps(dp, a, b, keyOffset)\n}\n\nfunction reindexOps(ops: DiffOp[], startIdx: number): DiffOp[] {\n let outIdx = startIdx\n const result: DiffOp[] = []\n for (const op of ops) {\n if (op.type === 'insert') {\n result.push({ type: 'insert', index: outIdx++, char: op.char })\n } else if (op.type === 'keep') {\n const keep: DiffOp = {\n type: 'keep',\n index: outIdx++,\n char: op.char,\n prevKey: op.prevKey,\n }\n if (op.region) keep.region = op.region\n result.push(keep)\n } else if (op.type === 'replace') {\n result.push({\n type: 'replace',\n index: outIdx++,\n from: op.from,\n to: op.to,\n prevKey: op.prevKey,\n })\n }\n }\n return result\n}\n\n/**\n * Slot-by-slot alignment for same-length values (e.g. license plates). Every\n * position rolls from its old char to its new one, so a dash moving from one\n * group to another rolls in place instead of being deleted and re-inserted.\n */\nfunction diffAligned(prev: string, next: string): DiffOp[] {\n const ops: DiffOp[] = []\n for (let i = 0; i < next.length; i++) {\n const from = prev[i]!\n const to = next[i]!\n if (from === to) {\n ops.push({ type: 'keep', index: i, char: to, prevKey: i })\n } else {\n ops.push({ type: 'replace', index: i, from, to, prevKey: i })\n }\n }\n return ops\n}\n\nexport function diff(prev: string, next: string): DiffOp[] {\n if (prev.length === next.length) return diffAligned(prev, next)\n\n let pre = 0\n while (pre < prev.length && pre < next.length && prev[pre] === next[pre]) pre++\n\n let suf = 0\n while (\n suf < prev.length - pre &&\n suf < next.length - pre &&\n prev[prev.length - 1 - suf] === next[next.length - 1 - suf]\n ) {\n suf++\n }\n\n const ops: DiffOp[] = []\n let outIdx = 0\n\n for (let i = 0; i < pre; i++) {\n ops.push({ type: 'keep', index: outIdx++, char: next[i]!, prevKey: i })\n }\n\n const midPrev = prev.slice(pre, prev.length - suf)\n const midNext = next.slice(pre, next.length - suf)\n const midMax = Math.max(midPrev.length, midNext.length)\n\n if (midMax > 0) {\n const midDist = levenshteinMatrix([...midPrev], [...midNext])[midPrev.length]![midNext.length]!\n const middleUnrelated = midDist / midMax > 0.4\n\n if (middleUnrelated) {\n for (let i = 0; i < midNext.length; i++) {\n ops.push({ type: 'insert', index: outIdx++, char: midNext[i]! })\n }\n } else {\n ops.push(...reindexOps(diffChars(midPrev, midNext, pre), outIdx))\n outIdx += midNext.length\n }\n }\n\n const suffixStart = Math.max(pre, next.length - suf)\n for (let i = suffixStart; i < next.length; i++) {\n const prevIdx = prev.length - suf + (i - (next.length - suf))\n if (prevIdx < pre) continue\n ops.push({\n type: 'keep',\n index: outIdx++,\n char: next[i]!,\n prevKey: prevIdx,\n region: 'suffix',\n })\n }\n\n return ops\n}\n","import { animForChar, animForReplace, classify } from './classify'\nimport { diff } from './diff'\nimport type { DiffOp, RenderSegment } from './types'\n\nlet keySeq = 0\nfunction nextKey(prefix: string): string {\n return `${prefix}-${++keySeq}`\n}\n\nfunction keyForPrev(prevKeys: string[], prevKey: number, fallback: string): string {\n return prevKeys[prevKey] ?? nextKey(fallback)\n}\n\nfunction assignEnteringRuns(segments: RenderSegment[]): RenderSegment[] {\n const out = segments.map((s) => ({ ...s }))\n let i = 0\n\n while (i < out.length) {\n const seg = out[i]!\n if (!seg.entering) {\n i++\n continue\n }\n let j = i + 1\n while (j < out.length && out[j]!.entering) j++\n const len = j - i\n for (let k = i; k < j; k++) {\n out[k] = { ...out[k]!, runIndex: k - i, runLength: len }\n }\n i = j\n }\n\n return out\n}\n\nfunction makeSegment(\n char: string,\n key: string,\n extra: Partial<RenderSegment> = {},\n): RenderSegment {\n return {\n key,\n char,\n kind: classify(char),\n anim: extra.anim ?? animForChar(char),\n ...extra,\n }\n}\n\nfunction opsToSegments(ops: DiffOp[], prevKeys: string[]): RenderSegment[] {\n const segments: RenderSegment[] = []\n\n for (const op of ops) {\n if (op.type === 'keep') {\n segments.push(makeSegment(op.char, keyForPrev(prevKeys, op.prevKey, 'k')))\n continue\n }\n\n if (op.type === 'replace') {\n segments.push(\n makeSegment(op.to, keyForPrev(prevKeys, op.prevKey, 'r'), {\n anim: animForReplace(op.from, op.to),\n fromChar: op.from,\n fromKind: classify(op.from),\n }),\n )\n continue\n }\n\n if (op.type === 'insert') {\n segments.push(makeSegment(op.char, nextKey('i'), { entering: true }))\n }\n }\n\n return assignEnteringRuns(segments)\n}\n\nexport function buildSegments(\n prev: string,\n next: string,\n prevSegmentKeys: string[],\n): { segments: RenderSegment[]; keys: string[] } {\n const segments = opsToSegments(diff(prev, next), prevSegmentKeys)\n return { segments, keys: segments.map((s) => s.key) }\n}\n\nexport function initialSegments(value: string): {\n segments: RenderSegment[]\n keys: string[]\n} {\n const segments = [...value].map((char, i) => makeSegment(char, nextKey(`s${i}`)))\n return { segments, keys: segments.map((s) => s.key) }\n}\n","import type { EffectTiming, Preset } from './types'\nimport { DEFAULT_SLIDE, DEFAULT_SPIN } from './types'\n\nexport const STYLES = `\n:host {\n display: inline-block;\n line-height: inherit;\n font-variant-numeric: tabular-nums;\n --cf-cell-height: 1lh;\n --cf-letter-gap: 0px;\n --cf-spin-duration: ${DEFAULT_SPIN.duration}ms;\n --cf-spin-easing: ${DEFAULT_SPIN.easing};\n --cf-slide-duration: ${DEFAULT_SLIDE.duration}ms;\n --cf-slide-easing: ${DEFAULT_SLIDE.easing};\n}\n\n.root {\n display: inline;\n position: relative;\n}\n\n.sr {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.visual {\n display: inline-block;\n position: relative;\n white-space: nowrap;\n}\n\n.cf-cell {\n display: inline-block;\n height: var(--cf-cell-height);\n line-height: var(--cf-cell-height);\n vertical-align: baseline;\n overflow: hidden;\n position: relative;\n text-align: center;\n}\n\n.cf-cell + .cf-cell {\n margin-left: var(--cf-letter-gap);\n}\n\n/* Soft top/bottom fade only while a wheel is mid-roll. */\n.cf-cell--rolling {\n -webkit-mask-image: linear-gradient(\n to bottom,\n transparent 0%,\n #000 18%,\n #000 82%,\n transparent 100%\n );\n mask-image: linear-gradient(\n to bottom,\n transparent 0%,\n #000 18%,\n #000 82%,\n transparent 100%\n );\n}\n\n.cf-stack {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n will-change: transform;\n}\n\n.cf-glyph {\n display: block;\n height: var(--cf-cell-height);\n line-height: var(--cf-cell-height);\n text-align: center;\n}\n`.trim()\n\nexport function applyPresetStyle(host: HTMLElement, preset: Preset): void {\n if (preset === 'plate') {\n host.style.textTransform = 'uppercase'\n host.style.letterSpacing = '0.04em'\n } else {\n host.style.textTransform = ''\n host.style.letterSpacing = ''\n }\n}\n\nexport function applyTimings(\n host: HTMLElement,\n spin?: EffectTiming,\n slide?: EffectTiming,\n): void {\n const s = { ...DEFAULT_SPIN, ...spin }\n const l = { ...DEFAULT_SLIDE, ...slide }\n host.style.setProperty('--cf-spin-duration', `${s.duration}ms`)\n host.style.setProperty('--cf-spin-easing', s.easing)\n host.style.setProperty('--cf-slide-duration', `${l.duration}ms`)\n host.style.setProperty('--cf-slide-easing', l.easing)\n}\n\nexport function parsePreset(v: string | null): Preset {\n return v === 'plate' ? 'plate' : 'alnum'\n}\n","import { observeMetrics, syncMetrics } from './layout/metrics'\nimport { mountVisual } from './render/mount'\nimport { buildSegments, initialSegments } from './segments'\nimport { applyPresetStyle, applyTimings, parsePreset, STYLES } from './styles'\nimport type { EffectTiming, Preset } from './types'\n\nconst TAG = 'char-flow'\n\nexport class CharFlowElement extends HTMLElement {\n static observedAttributes = ['value', 'preset', 'animated'] as const\n\n #sr!: HTMLElement\n #visual!: HTMLElement\n #prevValue = ''\n #keys: string[] = []\n #motionQuery = window.matchMedia('(prefers-reduced-motion: reduce)')\n #onMotionChange = (): void => this.#syncReduced()\n #stopMetrics: (() => void) | undefined\n\n #spinTiming: EffectTiming | undefined\n #slideTiming: EffectTiming | undefined\n\n connectedCallback(): void {\n if (!this.shadowRoot) {\n const root = this.attachShadow({ mode: 'open' })\n const style = document.createElement('style')\n style.textContent = STYLES\n const shell = document.createElement('div')\n shell.className = 'root'\n shell.setAttribute('part', 'root')\n\n this.#sr = document.createElement('span')\n this.#sr.className = 'sr'\n this.#sr.setAttribute('aria-live', 'polite')\n this.#sr.setAttribute('aria-atomic', 'true')\n\n this.#visual = document.createElement('span')\n this.#visual.className = 'visual'\n this.#visual.setAttribute('aria-hidden', 'true')\n\n shell.append(this.#sr, this.#visual)\n root.append(style, shell)\n }\n\n this.#motionQuery.addEventListener('change', this.#onMotionChange)\n this.#syncReduced()\n this.#applyOptions()\n this.#stopMetrics = observeMetrics(this)\n this.#render(true)\n }\n\n disconnectedCallback(): void {\n this.#motionQuery.removeEventListener('change', this.#onMotionChange)\n this.#stopMetrics?.()\n this.#stopMetrics = undefined\n }\n\n attributeChangedCallback(name: string): void {\n if (!this.isConnected) return\n if (name === 'value') {\n this.#render(false)\n return\n }\n this.#applyOptions()\n if (name === 'animated') this.#render(false)\n }\n\n get value(): string {\n return this.getAttribute('value') ?? ''\n }\n\n set value(v: string) {\n this.setAttribute('value', v)\n }\n\n get preset(): Preset {\n return parsePreset(this.getAttribute('preset'))\n }\n\n set preset(v: Preset) {\n this.setAttribute('preset', v)\n }\n\n get animated(): boolean {\n return this.getAttribute('animated') !== 'false'\n }\n\n set animated(v: boolean) {\n if (v) this.removeAttribute('animated')\n else this.setAttribute('animated', 'false')\n }\n\n set spinTiming(t: EffectTiming | undefined) {\n this.#spinTiming = t\n this.#applyOptions()\n }\n\n set slideTiming(t: EffectTiming | undefined) {\n this.#slideTiming = t\n this.#applyOptions()\n }\n\n #canAnimate(): boolean {\n if (!this.animated) return false\n if (this.#motionQuery.matches) return false\n return true\n }\n\n #syncReduced(): void {\n if (this.#motionQuery.matches) this.dataset.reduced = ''\n else delete this.dataset.reduced\n }\n\n #applyOptions(): void {\n applyPresetStyle(this, this.preset)\n applyTimings(this, this.#spinTiming, this.#slideTiming)\n syncMetrics(this)\n }\n\n #render(initial: boolean): void {\n const next = this.value\n this.#sr.textContent = next\n\n const animated = this.#canAnimate() && !initial\n\n let segments\n if (initial || !this.#prevValue) {\n const init = initialSegments(next)\n segments = init.segments\n this.#keys = init.keys\n } else if (this.#prevValue === next) {\n return\n } else {\n const built = buildSegments(this.#prevValue, next, this.#keys)\n segments = built.segments\n this.#keys = built.keys\n }\n\n mountVisual(this.#visual, segments, animated)\n this.#prevValue = next\n }\n}\n\nexport function defineCharFlow(tag = TAG): void {\n if (!customElements.get(tag)) {\n customElements.define(tag, CharFlowElement)\n }\n}\n\ndefineCharFlow()\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'char-flow': CharFlowElement\n }\n}\n\nexport { TAG }\n","import { createElement, useEffect, useRef, type HTMLAttributes } from 'react'\nimport type { CharFlowElement } from './element'\nimport type { EffectTiming, Preset } from './types'\n\nexport type { CharFlowElement }\nexport type { Preset, EffectTiming } from './types'\n\nfunction assertRegistered(): void {\n if (typeof customElements !== 'undefined' && !customElements.get('char-flow')) {\n throw new Error(\n 'CharFlow: import \"char-flow/element\" before using the React wrapper.',\n )\n }\n}\n\nexport interface CharFlowProps extends Omit<HTMLAttributes<CharFlowElement>, 'value'> {\n value: string\n preset?: Preset\n animated?: boolean\n spinTiming?: EffectTiming\n slideTiming?: EffectTiming\n}\n\nexport function CharFlow({\n value,\n preset = 'alnum',\n animated = true,\n spinTiming,\n slideTiming,\n className,\n style,\n ...rest\n}: CharFlowProps) {\n const ref = useRef<CharFlowElement>(null)\n\n useEffect(() => {\n assertRegistered()\n }, [])\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n if (el.value !== value) el.value = value\n }, [value])\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n el.preset = preset\n el.animated = animated\n if (spinTiming !== undefined) el.spinTiming = spinTiming\n if (slideTiming !== undefined) el.slideTiming = slideTiming\n }, [preset, animated, spinTiming, slideTiming])\n\n return createElement('char-flow', {\n ref,\n value,\n preset,\n ...(animated ? {} : { animated: 'false' }),\n class: className,\n style,\n ...rest,\n })\n}\n"]}
@@ -0,0 +1,299 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes } from 'react';
3
+ import { a as CharFlowElement, P as Preset, E as EffectTiming } from './element-ohGNSSoB.js';
4
+
5
+ interface CharFlowProps extends Omit<HTMLAttributes<CharFlowElement>, 'value'> {
6
+ value: string;
7
+ preset?: Preset;
8
+ animated?: boolean;
9
+ spinTiming?: EffectTiming;
10
+ slideTiming?: EffectTiming;
11
+ }
12
+ declare function CharFlow({ value, preset, animated, spinTiming, slideTiming, className, style, ...rest }: CharFlowProps): react.DOMElement<{
13
+ slot?: string | undefined | undefined;
14
+ title?: string | undefined | undefined;
15
+ part?: string | undefined | undefined;
16
+ hidden?: boolean | undefined | undefined;
17
+ dir?: string | undefined | undefined;
18
+ "aria-live"?: "off" | "assertive" | "polite" | undefined | undefined;
19
+ "aria-atomic"?: (boolean | "true" | "false") | undefined;
20
+ "aria-hidden"?: (boolean | "true" | "false") | undefined;
21
+ defaultChecked?: boolean | undefined | undefined;
22
+ defaultValue?: string | number | readonly string[] | undefined;
23
+ suppressContentEditableWarning?: boolean | undefined | undefined;
24
+ suppressHydrationWarning?: boolean | undefined | undefined;
25
+ accessKey?: string | undefined | undefined;
26
+ autoCapitalize?: "off" | "none" | "on" | "sentences" | "words" | "characters" | undefined | (string & {}) | undefined;
27
+ autoFocus?: boolean | undefined | undefined;
28
+ contentEditable?: (boolean | "true" | "false") | "inherit" | "plaintext-only" | undefined;
29
+ contextMenu?: string | undefined | undefined;
30
+ draggable?: (boolean | "true" | "false") | undefined;
31
+ enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
32
+ id?: string | undefined | undefined;
33
+ lang?: string | undefined | undefined;
34
+ nonce?: string | undefined | undefined;
35
+ spellCheck?: (boolean | "true" | "false") | undefined;
36
+ tabIndex?: number | undefined | undefined;
37
+ translate?: "yes" | "no" | undefined | undefined;
38
+ radioGroup?: string | undefined | undefined;
39
+ role?: react.AriaRole | undefined;
40
+ about?: string | undefined | undefined;
41
+ content?: string | undefined | undefined;
42
+ datatype?: string | undefined | undefined;
43
+ inlist?: any;
44
+ prefix?: string | undefined | undefined;
45
+ property?: string | undefined | undefined;
46
+ rel?: string | undefined | undefined;
47
+ resource?: string | undefined | undefined;
48
+ rev?: string | undefined | undefined;
49
+ typeof?: string | undefined | undefined;
50
+ vocab?: string | undefined | undefined;
51
+ autoCorrect?: string | undefined | undefined;
52
+ autoSave?: string | undefined | undefined;
53
+ color?: string | undefined | undefined;
54
+ itemProp?: string | undefined | undefined;
55
+ itemScope?: boolean | undefined | undefined;
56
+ itemType?: string | undefined | undefined;
57
+ itemID?: string | undefined | undefined;
58
+ itemRef?: string | undefined | undefined;
59
+ results?: number | undefined | undefined;
60
+ security?: string | undefined | undefined;
61
+ unselectable?: "on" | "off" | undefined | undefined;
62
+ popover?: "" | "auto" | "manual" | "hint" | undefined | undefined;
63
+ popoverTargetAction?: "toggle" | "show" | "hide" | undefined | undefined;
64
+ popoverTarget?: string | undefined | undefined;
65
+ inert?: boolean | undefined | undefined;
66
+ inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined | undefined;
67
+ is?: string | undefined | undefined;
68
+ exportparts?: string | undefined | undefined;
69
+ "aria-activedescendant"?: string | undefined | undefined;
70
+ "aria-autocomplete"?: "none" | "inline" | "list" | "both" | undefined | undefined;
71
+ "aria-braillelabel"?: string | undefined | undefined;
72
+ "aria-brailleroledescription"?: string | undefined | undefined;
73
+ "aria-busy"?: (boolean | "true" | "false") | undefined;
74
+ "aria-checked"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
75
+ "aria-colcount"?: number | undefined | undefined;
76
+ "aria-colindex"?: number | undefined | undefined;
77
+ "aria-colindextext"?: string | undefined | undefined;
78
+ "aria-colspan"?: number | undefined | undefined;
79
+ "aria-controls"?: string | undefined | undefined;
80
+ "aria-current"?: boolean | "false" | "true" | "page" | "step" | "location" | "date" | "time" | undefined | undefined;
81
+ "aria-describedby"?: string | undefined | undefined;
82
+ "aria-description"?: string | undefined | undefined;
83
+ "aria-details"?: string | undefined | undefined;
84
+ "aria-disabled"?: (boolean | "true" | "false") | undefined;
85
+ "aria-dropeffect"?: "none" | "copy" | "execute" | "link" | "move" | "popup" | undefined | undefined;
86
+ "aria-errormessage"?: string | undefined | undefined;
87
+ "aria-expanded"?: (boolean | "true" | "false") | undefined;
88
+ "aria-flowto"?: string | undefined | undefined;
89
+ "aria-grabbed"?: (boolean | "true" | "false") | undefined;
90
+ "aria-haspopup"?: boolean | "false" | "true" | "menu" | "listbox" | "tree" | "grid" | "dialog" | undefined | undefined;
91
+ "aria-invalid"?: boolean | "false" | "true" | "grammar" | "spelling" | undefined | undefined;
92
+ "aria-keyshortcuts"?: string | undefined | undefined;
93
+ "aria-label"?: string | undefined | undefined;
94
+ "aria-labelledby"?: string | undefined | undefined;
95
+ "aria-level"?: number | undefined | undefined;
96
+ "aria-modal"?: (boolean | "true" | "false") | undefined;
97
+ "aria-multiline"?: (boolean | "true" | "false") | undefined;
98
+ "aria-multiselectable"?: (boolean | "true" | "false") | undefined;
99
+ "aria-orientation"?: "horizontal" | "vertical" | undefined | undefined;
100
+ "aria-owns"?: string | undefined | undefined;
101
+ "aria-placeholder"?: string | undefined | undefined;
102
+ "aria-posinset"?: number | undefined | undefined;
103
+ "aria-pressed"?: boolean | "false" | "mixed" | "true" | undefined | undefined;
104
+ "aria-readonly"?: (boolean | "true" | "false") | undefined;
105
+ "aria-relevant"?: "additions" | "additions removals" | "additions text" | "all" | "removals" | "removals additions" | "removals text" | "text" | "text additions" | "text removals" | undefined | undefined;
106
+ "aria-required"?: (boolean | "true" | "false") | undefined;
107
+ "aria-roledescription"?: string | undefined | undefined;
108
+ "aria-rowcount"?: number | undefined | undefined;
109
+ "aria-rowindex"?: number | undefined | undefined;
110
+ "aria-rowindextext"?: string | undefined | undefined;
111
+ "aria-rowspan"?: number | undefined | undefined;
112
+ "aria-selected"?: (boolean | "true" | "false") | undefined;
113
+ "aria-setsize"?: number | undefined | undefined;
114
+ "aria-sort"?: "none" | "ascending" | "descending" | "other" | undefined | undefined;
115
+ "aria-valuemax"?: number | undefined | undefined;
116
+ "aria-valuemin"?: number | undefined | undefined;
117
+ "aria-valuenow"?: number | undefined | undefined;
118
+ "aria-valuetext"?: string | undefined | undefined;
119
+ children?: react.ReactNode;
120
+ dangerouslySetInnerHTML?: {
121
+ __html: string | TrustedHTML;
122
+ } | undefined | undefined;
123
+ onCopy?: react.ClipboardEventHandler<CharFlowElement> | undefined;
124
+ onCopyCapture?: react.ClipboardEventHandler<CharFlowElement> | undefined;
125
+ onCut?: react.ClipboardEventHandler<CharFlowElement> | undefined;
126
+ onCutCapture?: react.ClipboardEventHandler<CharFlowElement> | undefined;
127
+ onPaste?: react.ClipboardEventHandler<CharFlowElement> | undefined;
128
+ onPasteCapture?: react.ClipboardEventHandler<CharFlowElement> | undefined;
129
+ onCompositionEnd?: react.CompositionEventHandler<CharFlowElement> | undefined;
130
+ onCompositionEndCapture?: react.CompositionEventHandler<CharFlowElement> | undefined;
131
+ onCompositionStart?: react.CompositionEventHandler<CharFlowElement> | undefined;
132
+ onCompositionStartCapture?: react.CompositionEventHandler<CharFlowElement> | undefined;
133
+ onCompositionUpdate?: react.CompositionEventHandler<CharFlowElement> | undefined;
134
+ onCompositionUpdateCapture?: react.CompositionEventHandler<CharFlowElement> | undefined;
135
+ onFocus?: react.FocusEventHandler<CharFlowElement> | undefined;
136
+ onFocusCapture?: react.FocusEventHandler<CharFlowElement> | undefined;
137
+ onBlur?: react.FocusEventHandler<CharFlowElement> | undefined;
138
+ onBlurCapture?: react.FocusEventHandler<CharFlowElement> | undefined;
139
+ onChange?: react.ChangeEventHandler<CharFlowElement, Element> | undefined;
140
+ onChangeCapture?: react.ChangeEventHandler<CharFlowElement, Element> | undefined;
141
+ onBeforeInput?: react.InputEventHandler<CharFlowElement> | undefined;
142
+ onBeforeInputCapture?: react.InputEventHandler<CharFlowElement> | undefined;
143
+ onInput?: react.InputEventHandler<CharFlowElement> | undefined;
144
+ onInputCapture?: react.InputEventHandler<CharFlowElement> | undefined;
145
+ onReset?: react.ReactEventHandler<CharFlowElement> | undefined;
146
+ onResetCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
147
+ onSubmit?: react.SubmitEventHandler<CharFlowElement> | undefined;
148
+ onSubmitCapture?: react.SubmitEventHandler<CharFlowElement> | undefined;
149
+ onInvalid?: react.ReactEventHandler<CharFlowElement> | undefined;
150
+ onInvalidCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
151
+ onLoad?: react.ReactEventHandler<CharFlowElement> | undefined;
152
+ onLoadCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
153
+ onError?: react.ReactEventHandler<CharFlowElement> | undefined;
154
+ onErrorCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
155
+ onKeyDown?: react.KeyboardEventHandler<CharFlowElement> | undefined;
156
+ onKeyDownCapture?: react.KeyboardEventHandler<CharFlowElement> | undefined;
157
+ onKeyPress?: react.KeyboardEventHandler<CharFlowElement> | undefined;
158
+ onKeyPressCapture?: react.KeyboardEventHandler<CharFlowElement> | undefined;
159
+ onKeyUp?: react.KeyboardEventHandler<CharFlowElement> | undefined;
160
+ onKeyUpCapture?: react.KeyboardEventHandler<CharFlowElement> | undefined;
161
+ onAbort?: react.ReactEventHandler<CharFlowElement> | undefined;
162
+ onAbortCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
163
+ onCanPlay?: react.ReactEventHandler<CharFlowElement> | undefined;
164
+ onCanPlayCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
165
+ onCanPlayThrough?: react.ReactEventHandler<CharFlowElement> | undefined;
166
+ onCanPlayThroughCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
167
+ onDurationChange?: react.ReactEventHandler<CharFlowElement> | undefined;
168
+ onDurationChangeCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
169
+ onEmptied?: react.ReactEventHandler<CharFlowElement> | undefined;
170
+ onEmptiedCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
171
+ onEncrypted?: react.ReactEventHandler<CharFlowElement> | undefined;
172
+ onEncryptedCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
173
+ onEnded?: react.ReactEventHandler<CharFlowElement> | undefined;
174
+ onEndedCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
175
+ onLoadedData?: react.ReactEventHandler<CharFlowElement> | undefined;
176
+ onLoadedDataCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
177
+ onLoadedMetadata?: react.ReactEventHandler<CharFlowElement> | undefined;
178
+ onLoadedMetadataCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
179
+ onLoadStart?: react.ReactEventHandler<CharFlowElement> | undefined;
180
+ onLoadStartCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
181
+ onPause?: react.ReactEventHandler<CharFlowElement> | undefined;
182
+ onPauseCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
183
+ onPlay?: react.ReactEventHandler<CharFlowElement> | undefined;
184
+ onPlayCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
185
+ onPlaying?: react.ReactEventHandler<CharFlowElement> | undefined;
186
+ onPlayingCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
187
+ onProgress?: react.ReactEventHandler<CharFlowElement> | undefined;
188
+ onProgressCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
189
+ onRateChange?: react.ReactEventHandler<CharFlowElement> | undefined;
190
+ onRateChangeCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
191
+ onSeeked?: react.ReactEventHandler<CharFlowElement> | undefined;
192
+ onSeekedCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
193
+ onSeeking?: react.ReactEventHandler<CharFlowElement> | undefined;
194
+ onSeekingCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
195
+ onStalled?: react.ReactEventHandler<CharFlowElement> | undefined;
196
+ onStalledCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
197
+ onSuspend?: react.ReactEventHandler<CharFlowElement> | undefined;
198
+ onSuspendCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
199
+ onTimeUpdate?: react.ReactEventHandler<CharFlowElement> | undefined;
200
+ onTimeUpdateCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
201
+ onVolumeChange?: react.ReactEventHandler<CharFlowElement> | undefined;
202
+ onVolumeChangeCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
203
+ onWaiting?: react.ReactEventHandler<CharFlowElement> | undefined;
204
+ onWaitingCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
205
+ onAuxClick?: react.MouseEventHandler<CharFlowElement> | undefined;
206
+ onAuxClickCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
207
+ onClick?: react.MouseEventHandler<CharFlowElement> | undefined;
208
+ onClickCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
209
+ onContextMenu?: react.MouseEventHandler<CharFlowElement> | undefined;
210
+ onContextMenuCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
211
+ onDoubleClick?: react.MouseEventHandler<CharFlowElement> | undefined;
212
+ onDoubleClickCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
213
+ onDrag?: react.DragEventHandler<CharFlowElement> | undefined;
214
+ onDragCapture?: react.DragEventHandler<CharFlowElement> | undefined;
215
+ onDragEnd?: react.DragEventHandler<CharFlowElement> | undefined;
216
+ onDragEndCapture?: react.DragEventHandler<CharFlowElement> | undefined;
217
+ onDragEnter?: react.DragEventHandler<CharFlowElement> | undefined;
218
+ onDragEnterCapture?: react.DragEventHandler<CharFlowElement> | undefined;
219
+ onDragExit?: react.DragEventHandler<CharFlowElement> | undefined;
220
+ onDragExitCapture?: react.DragEventHandler<CharFlowElement> | undefined;
221
+ onDragLeave?: react.DragEventHandler<CharFlowElement> | undefined;
222
+ onDragLeaveCapture?: react.DragEventHandler<CharFlowElement> | undefined;
223
+ onDragOver?: react.DragEventHandler<CharFlowElement> | undefined;
224
+ onDragOverCapture?: react.DragEventHandler<CharFlowElement> | undefined;
225
+ onDragStart?: react.DragEventHandler<CharFlowElement> | undefined;
226
+ onDragStartCapture?: react.DragEventHandler<CharFlowElement> | undefined;
227
+ onDrop?: react.DragEventHandler<CharFlowElement> | undefined;
228
+ onDropCapture?: react.DragEventHandler<CharFlowElement> | undefined;
229
+ onMouseDown?: react.MouseEventHandler<CharFlowElement> | undefined;
230
+ onMouseDownCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
231
+ onMouseEnter?: react.MouseEventHandler<CharFlowElement> | undefined;
232
+ onMouseLeave?: react.MouseEventHandler<CharFlowElement> | undefined;
233
+ onMouseMove?: react.MouseEventHandler<CharFlowElement> | undefined;
234
+ onMouseMoveCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
235
+ onMouseOut?: react.MouseEventHandler<CharFlowElement> | undefined;
236
+ onMouseOutCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
237
+ onMouseOver?: react.MouseEventHandler<CharFlowElement> | undefined;
238
+ onMouseOverCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
239
+ onMouseUp?: react.MouseEventHandler<CharFlowElement> | undefined;
240
+ onMouseUpCapture?: react.MouseEventHandler<CharFlowElement> | undefined;
241
+ onSelect?: react.ReactEventHandler<CharFlowElement> | undefined;
242
+ onSelectCapture?: react.ReactEventHandler<CharFlowElement> | undefined;
243
+ onTouchCancel?: react.TouchEventHandler<CharFlowElement> | undefined;
244
+ onTouchCancelCapture?: react.TouchEventHandler<CharFlowElement> | undefined;
245
+ onTouchEnd?: react.TouchEventHandler<CharFlowElement> | undefined;
246
+ onTouchEndCapture?: react.TouchEventHandler<CharFlowElement> | undefined;
247
+ onTouchMove?: react.TouchEventHandler<CharFlowElement> | undefined;
248
+ onTouchMoveCapture?: react.TouchEventHandler<CharFlowElement> | undefined;
249
+ onTouchStart?: react.TouchEventHandler<CharFlowElement> | undefined;
250
+ onTouchStartCapture?: react.TouchEventHandler<CharFlowElement> | undefined;
251
+ onPointerDown?: react.PointerEventHandler<CharFlowElement> | undefined;
252
+ onPointerDownCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
253
+ onPointerMove?: react.PointerEventHandler<CharFlowElement> | undefined;
254
+ onPointerMoveCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
255
+ onPointerUp?: react.PointerEventHandler<CharFlowElement> | undefined;
256
+ onPointerUpCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
257
+ onPointerCancel?: react.PointerEventHandler<CharFlowElement> | undefined;
258
+ onPointerCancelCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
259
+ onPointerEnter?: react.PointerEventHandler<CharFlowElement> | undefined;
260
+ onPointerLeave?: react.PointerEventHandler<CharFlowElement> | undefined;
261
+ onPointerOver?: react.PointerEventHandler<CharFlowElement> | undefined;
262
+ onPointerOverCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
263
+ onPointerOut?: react.PointerEventHandler<CharFlowElement> | undefined;
264
+ onPointerOutCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
265
+ onGotPointerCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
266
+ onGotPointerCaptureCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
267
+ onLostPointerCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
268
+ onLostPointerCaptureCapture?: react.PointerEventHandler<CharFlowElement> | undefined;
269
+ onScroll?: react.UIEventHandler<CharFlowElement> | undefined;
270
+ onScrollCapture?: react.UIEventHandler<CharFlowElement> | undefined;
271
+ onScrollEnd?: react.UIEventHandler<CharFlowElement> | undefined;
272
+ onScrollEndCapture?: react.UIEventHandler<CharFlowElement> | undefined;
273
+ onWheel?: react.WheelEventHandler<CharFlowElement> | undefined;
274
+ onWheelCapture?: react.WheelEventHandler<CharFlowElement> | undefined;
275
+ onAnimationStart?: react.AnimationEventHandler<CharFlowElement> | undefined;
276
+ onAnimationStartCapture?: react.AnimationEventHandler<CharFlowElement> | undefined;
277
+ onAnimationEnd?: react.AnimationEventHandler<CharFlowElement> | undefined;
278
+ onAnimationEndCapture?: react.AnimationEventHandler<CharFlowElement> | undefined;
279
+ onAnimationIteration?: react.AnimationEventHandler<CharFlowElement> | undefined;
280
+ onAnimationIterationCapture?: react.AnimationEventHandler<CharFlowElement> | undefined;
281
+ onToggle?: react.ToggleEventHandler<CharFlowElement> | undefined;
282
+ onBeforeToggle?: react.ToggleEventHandler<CharFlowElement> | undefined;
283
+ onTransitionCancel?: react.TransitionEventHandler<CharFlowElement> | undefined;
284
+ onTransitionCancelCapture?: react.TransitionEventHandler<CharFlowElement> | undefined;
285
+ onTransitionEnd?: react.TransitionEventHandler<CharFlowElement> | undefined;
286
+ onTransitionEndCapture?: react.TransitionEventHandler<CharFlowElement> | undefined;
287
+ onTransitionRun?: react.TransitionEventHandler<CharFlowElement> | undefined;
288
+ onTransitionRunCapture?: react.TransitionEventHandler<CharFlowElement> | undefined;
289
+ onTransitionStart?: react.TransitionEventHandler<CharFlowElement> | undefined;
290
+ onTransitionStartCapture?: react.TransitionEventHandler<CharFlowElement> | undefined;
291
+ class: string | undefined;
292
+ style: react.CSSProperties | undefined;
293
+ animated?: string;
294
+ ref: react.RefObject<CharFlowElement | null>;
295
+ value: string;
296
+ preset: Preset;
297
+ }, CharFlowElement>;
298
+
299
+ export { CharFlow, CharFlowElement, type CharFlowProps, EffectTiming, Preset };
package/dist/react.js ADDED
@@ -0,0 +1,2 @@
1
+ import {useRef,useEffect,createElement}from'react';function p(){if(typeof customElements<"u"&&!customElements.get("char-flow"))throw new Error('CharFlow: import "char-flow/element" before using the React wrapper.')}function h({value:t,preset:r="alnum",animated:n=true,spinTiming:o,slideTiming:f,className:s,style:m,...a}){let i=useRef(null);return useEffect(()=>{p();},[]),useEffect(()=>{let e=i.current;e&&e.value!==t&&(e.value=t);},[t]),useEffect(()=>{let e=i.current;e&&(e.preset=r,e.animated=n,o!==void 0&&(e.spinTiming=o),f!==void 0&&(e.slideTiming=f));},[r,n,o,f]),createElement("char-flow",{ref:i,value:t,preset:r,...n?{}:{animated:"false"},class:s,style:m,...a})}export{h as CharFlow};//# sourceMappingURL=react.js.map
2
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react.tsx"],"names":["assertRegistered","CharFlow","value","preset","animated","spinTiming","slideTiming","className","style","rest","ref","useRef","useEffect","el","createElement"],"mappings":"mDAOA,SAASA,CAAAA,EAAyB,CAChC,GAAI,OAAO,eAAmB,GAAA,EAAe,CAAC,cAAA,CAAe,GAAA,CAAI,WAAW,CAAA,CAC1E,MAAM,IAAI,MACR,sEACF,CAEJ,CAUO,SAASC,CAAAA,CAAS,CACvB,KAAA,CAAAC,CAAAA,CACA,OAAAC,CAAAA,CAAS,OAAA,CACT,QAAA,CAAAC,CAAAA,CAAW,IAAA,CACX,UAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,EACA,SAAA,CAAAC,CAAAA,CACA,KAAA,CAAAC,CAAAA,CACA,GAAGC,CACL,CAAA,CAAkB,CAChB,IAAMC,CAAAA,CAAMC,MAAAA,CAAwB,IAAI,CAAA,CAExC,OAAAC,SAAAA,CAAU,IAAM,CACdZ,IACF,CAAA,CAAG,EAAE,CAAA,CAELY,SAAAA,CAAU,IAAM,CACd,IAAMC,CAAAA,CAAKH,CAAAA,CAAI,OAAA,CACVG,CAAAA,EACDA,CAAAA,CAAG,KAAA,GAAUX,CAAAA,GAAOW,CAAAA,CAAG,KAAA,CAAQX,CAAAA,EACrC,CAAA,CAAG,CAACA,CAAK,CAAC,CAAA,CAEVU,SAAAA,CAAU,IAAM,CACd,IAAMC,CAAAA,CAAKH,CAAAA,CAAI,OAAA,CACVG,CAAAA,GACLA,CAAAA,CAAG,MAAA,CAASV,EACZU,CAAAA,CAAG,QAAA,CAAWT,CAAAA,CACVC,CAAAA,GAAe,MAAA,GAAWQ,CAAAA,CAAG,UAAA,CAAaR,CAAAA,CAAAA,CAC1CC,IAAgB,MAAA,GAAWO,CAAAA,CAAG,WAAA,CAAcP,CAAAA,CAAAA,EAClD,CAAA,CAAG,CAACH,CAAAA,CAAQC,CAAAA,CAAUC,EAAYC,CAAW,CAAC,CAAA,CAEvCQ,aAAAA,CAAc,WAAA,CAAa,CAChC,GAAA,CAAAJ,CAAAA,CACA,MAAAR,CAAAA,CACA,MAAA,CAAAC,CAAAA,CACA,GAAIC,CAAAA,CAAW,EAAC,CAAI,CAAE,SAAU,OAAQ,CAAA,CACxC,KAAA,CAAOG,CAAAA,CACP,KAAA,CAAAC,CAAAA,CACA,GAAGC,CACL,CAAC,CACH","file":"react.js","sourcesContent":["import { createElement, useEffect, useRef, type HTMLAttributes } from 'react'\nimport type { CharFlowElement } from './element'\nimport type { EffectTiming, Preset } from './types'\n\nexport type { CharFlowElement }\nexport type { Preset, EffectTiming } from './types'\n\nfunction assertRegistered(): void {\n if (typeof customElements !== 'undefined' && !customElements.get('char-flow')) {\n throw new Error(\n 'CharFlow: import \"char-flow/element\" before using the React wrapper.',\n )\n }\n}\n\nexport interface CharFlowProps extends Omit<HTMLAttributes<CharFlowElement>, 'value'> {\n value: string\n preset?: Preset\n animated?: boolean\n spinTiming?: EffectTiming\n slideTiming?: EffectTiming\n}\n\nexport function CharFlow({\n value,\n preset = 'alnum',\n animated = true,\n spinTiming,\n slideTiming,\n className,\n style,\n ...rest\n}: CharFlowProps) {\n const ref = useRef<CharFlowElement>(null)\n\n useEffect(() => {\n assertRegistered()\n }, [])\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n if (el.value !== value) el.value = value\n }, [value])\n\n useEffect(() => {\n const el = ref.current\n if (!el) return\n el.preset = preset\n el.animated = animated\n if (spinTiming !== undefined) el.spinTiming = spinTiming\n if (slideTiming !== undefined) el.slideTiming = slideTiming\n }, [preset, animated, spinTiming, slideTiming])\n\n return createElement('char-flow', {\n ref,\n value,\n preset,\n ...(animated ? {} : { animated: 'false' }),\n class: className,\n style,\n ...rest,\n })\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "char-flow",
3
+ "version": "0.1.2",
4
+ "description": "CharFlow — lightweight animated alphanumeric text for license plates, codes, and flowing paragraphs",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "scankenteken",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/scan-kenteken/char-flow.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/scan-kenteken/char-flow/issues"
14
+ },
15
+ "homepage": "https://github.com/scan-kenteken/char-flow#readme",
16
+ "keywords": [
17
+ "animation",
18
+ "text",
19
+ "license-plate",
20
+ "kenteken",
21
+ "web-component",
22
+ "custom-element",
23
+ "react",
24
+ "alphanumeric",
25
+ "diff"
26
+ ],
27
+ "engines": {
28
+ "node": ">=18"
29
+ },
30
+ "main": "./dist/index.js",
31
+ "module": "./dist/index.js",
32
+ "types": "./dist/index.d.ts",
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/index.js"
37
+ },
38
+ "./element": {
39
+ "types": "./dist/element.d.ts",
40
+ "import": "./dist/element.js"
41
+ },
42
+ "./react": {
43
+ "types": "./dist/react.d.ts",
44
+ "import": "./dist/react.js"
45
+ }
46
+ },
47
+ "files": [
48
+ "dist",
49
+ "README.md",
50
+ "LICENSE"
51
+ ],
52
+ "sideEffects": true,
53
+ "scripts": {
54
+ "clean": "node -e \"import('node:fs').then(fs => fs.rmSync('dist', { recursive: true, force: true }))\"",
55
+ "build": "tsup",
56
+ "demo": "npm run build && cp dist/element.js demo/element.js && npx --yes serve . -p 3000",
57
+ "dev": "tsup --watch",
58
+ "typecheck": "tsc --noEmit",
59
+ "prepack": "npm run typecheck && npm run build",
60
+ "capture-demo": "node scripts/capture-demo.mjs"
61
+ },
62
+ "peerDependencies": {
63
+ "react": ">=18"
64
+ },
65
+ "peerDependenciesMeta": {
66
+ "react": {
67
+ "optional": true
68
+ }
69
+ },
70
+ "devDependencies": {
71
+ "@types/react": "^19.1.8",
72
+ "puppeteer-core": "^25.1.0",
73
+ "react": "^19.1.0",
74
+ "tsup": "^8.5.0",
75
+ "typescript": "^5.8.3"
76
+ }
77
+ }