text-slicer 1.4.0-dev.8 → 1.4.0-dev.9

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/dist/index.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l={splitMode:"both",cssVariables:!1,dataAttributes:!1,keepWhitespaceNodes:!0},a=Object.freeze({word:"ts-word",char:"ts-char",whitespace:"ts-whitespace"}),i=" ",u=t=>typeof window>"u"||typeof document>"u"?null:t?typeof t=="string"?document.querySelector(t):t:null,c=t=>{const e=Intl.Segmenter;if(typeof e=="function"){const s=new e("en",{granularity:"grapheme"});return Array.from(s.segment(t),n=>n.segment)}return Array.from(t)},h=t=>t.split(i),o=t=>{const e={};return Object.keys(t).forEach(s=>{const n=t[s];n!==void 0&&(e[s]=n)}),e};exports.CLASSNAMES=a,exports.TextSlicer=class{el;original;opts;callbacks;charIndex;mounted;constructor(t={},e){const s=u(t.container);this.el=s,this.original=(n=>!!n&&typeof HTMLElement<"u"&&n instanceof HTMLElement)(s)?s.textContent?.toString()??"":"",this.opts={...l,...o(t)},this.callbacks=e,this.charIndex=0,this.mounted=!1}get metrics(){const t=this.original;return{wordTotal:t.length?h(t).length:0,charTotal:t.length,renderedAt:Date.now()}}init(){this.el&&(this.mounted=!0,this.split())}reinit(t,e){this.el&&(typeof t=="string"&&(this.original=t),e&&(this.opts={...this.opts,...o(e)}),this.split())}clear(){this.el&&this.el.replaceChildren()}split(){if(!this.el)return;this.clear(),this.charIndex=0;const t=this.original,e=document.createDocumentFragment(),s=h(t);this.opts.splitMode==="chars"?this.appendChars(e,t):this.appendWords(e,s),this.el.appendChild(e),this.opts.cssVariables&&(this.el.style.setProperty("--word-total",String(s.length)),this.el.style.setProperty("--char-total",String(t.length))),this.callbacks?.onAfterRender?.(this.metrics)}destroy(){this.el&&(this.clear(),this.mounted=!1)}updateOptions(t){this.opts={...this.opts,...o(t)},this.mounted&&this.split()}appendWords(t,e){e.forEach((s,n)=>{if(this.opts.splitMode==="both"){const r=this.createWordSpan(n,s);for(const p of c(s)){const d=this.createCharSpan(p);r.append(d)}t.append(r)}else{const r=this.createWordSpan(n);r.append(document.createTextNode(s)),t.append(r)}n<e.length-1&&t.append(this.createSpaceSpan())})}appendChars(t,e){for(const s of c(e)){const n=this.createCharSpan(s);t.append(n)}}createWordSpan(t,e=""){const s=document.createElement("span");return s.classList.add(a.word),this.opts.dataAttributes&&e&&s.setAttribute("data-word",e),this.opts.cssVariables&&s.style.setProperty("--word-index",String(t)),s}createCharSpan(t){const e=document.createElement("span");return e.textContent=t,this.opts.dataAttributes&&e.setAttribute("data-char",t),t===i?(e.classList.add(a.whitespace),this.opts.keepWhitespaceNodes||(e.textContent=i)):(e.classList.add(a.char),this.opts.cssVariables&&e.style.setProperty("--char-index",String(this.charIndex)),this.charIndex+=1),e}createSpaceSpan(){const t=document.createElement("span");return t.classList.add(a.whitespace),t.textContent=i,t}};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p={splitMode:"both",cssVariables:!1,dataAttributes:!1,keepWhitespaceNodes:!0,freezeWordWidths:!1},i=Object.freeze({word:"ts-word",char:"ts-char",whitespace:"ts-whitespace"}),o=" ",u=t=>typeof window>"u"||typeof document>"u"?null:t?typeof t=="string"?document.querySelector(t):t:null,a=t=>{const e=Intl.Segmenter;if(typeof e=="function"){const s=new e("en",{granularity:"grapheme"});return Array.from(s.segment(t),r=>r.segment)}return Array.from(t)},d=t=>t.split(o),h=t=>{const e={};return Object.keys(t).forEach(s=>{const r=t[s];r!==void 0&&(e[s]=r)}),e};exports.CLASSNAMES=i,exports.TextSlicer=class{el;original;opts;callbacks;charIndex;mounted;ro=null;frozen=!1;freezeWordWidthsBound=()=>{this.freezeWordWidths()};constructor(t={},e){const s=u(t.container);this.el=s,this.original=(r=>!!r&&typeof HTMLElement<"u"&&r instanceof HTMLElement)(s)?s.textContent?.toString()??"":"",this.opts={...p,...h(t)},this.callbacks=e,this.charIndex=0,this.mounted=!1}get metrics(){const t=this.original;return{wordTotal:t.length?d(t).length:0,charTotal:t.length,renderedAt:Date.now()}}init(){this.el&&(this.mounted=!0,this.split())}reinit(t,e){this.el&&(typeof t=="string"&&(this.original=t),e&&(this.opts={...this.opts,...h(e)}),this.split())}clear(){this.el&&(this.unfreezeWordWidths(),this.el.replaceChildren())}split(){if(!this.el)return;this.clear(),this.charIndex=0;const t=this.original,e=document.createDocumentFragment(),s=d(t);this.opts.splitMode==="chars"?this.appendChars(e,t):this.appendWords(e,s),this.el.appendChild(e),this.opts.cssVariables&&(this.el.style.setProperty("--word-total",String(s.length)),this.el.style.setProperty("--char-total",String(t.length))),this.scheduleFreezeWordWidths().then(()=>{this.callbacks?.onAfterRender?.(this.metrics)}).catch(()=>{})}destroy(){this.el&&(this.detachResizeObserver(),this.clear(),this.mounted=!1)}updateOptions(t){this.opts={...this.opts,...h(t)},this.mounted&&this.split()}appendWords(t,e){e.forEach((s,r)=>{if(this.opts.splitMode==="both"){const n=this.createWordSpan(r,s);for(const c of a(s)){const l=this.createCharSpan(c);n.append(l)}t.append(n)}else{const n=this.createWordSpan(r);n.append(document.createTextNode(s)),t.append(n)}r<e.length-1&&t.append(this.createSpaceSpan())})}appendChars(t,e){for(const s of a(e)){const r=this.createCharSpan(s);t.append(r)}}createWordSpan(t,e=""){const s=document.createElement("span");return s.classList.add(i.word),this.opts.dataAttributes&&e&&s.setAttribute("data-word",e),this.opts.cssVariables&&s.style.setProperty("--word-index",String(t)),s}createCharSpan(t){const e=document.createElement("span");return e.textContent=t,this.opts.dataAttributes&&e.setAttribute("data-char",t),t===o?(e.classList.add(i.whitespace),this.opts.keepWhitespaceNodes||(e.textContent=o)):(e.classList.add(i.char),this.opts.cssVariables&&e.style.setProperty("--char-index",String(this.charIndex)),this.charIndex+=1),e}createSpaceSpan(){const t=document.createElement("span");return t.classList.add(i.whitespace),t.textContent=o,t}async scheduleFreezeWordWidths(){if(this.el&&this.opts.freezeWordWidths){try{await document.fonts?.ready}catch{}await new Promise(t=>requestAnimationFrame(()=>t())),this.freezeWordWidths(),this.attachResizeObserver()}}freezeWordWidths(){this.el&&(this.el.querySelectorAll(`.${i.word}`).forEach(t=>{t.style.width="",t.style.flex="";const{width:e}=t.getBoundingClientRect();t.style.width=`${Math.ceil(e)}px`,t.style.flex="0 0 auto"}),this.frozen=!0)}unfreezeWordWidths(){!this.el||!this.frozen||(this.el.querySelectorAll(`.${i.word}`).forEach(t=>{t.style.width="",t.style.flex=""}),this.frozen=!1)}attachResizeObserver(){this.el&&this.opts.freezeWordWidths&&(this.ro||(this.ro=new ResizeObserver(()=>{this.freezeWordWidths()}),this.ro.observe(this.el)),window.addEventListener("resize",this.freezeWordWidthsBound,{passive:!0}))}detachResizeObserver(){this.ro&&(this.ro.disconnect(),this.ro=null),window.removeEventListener("resize",this.freezeWordWidthsBound)}};
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ export interface TextSlicerOptions {
5
5
  cssVariables?: boolean;
6
6
  dataAttributes?: boolean;
7
7
  keepWhitespaceNodes?: boolean;
8
+ freezeWordWidths?: boolean;
8
9
  }
9
10
  export interface TextSlicerMetrics {
10
11
  wordTotal: number;
@@ -26,6 +27,9 @@ export declare class TextSlicer {
26
27
  private callbacks;
27
28
  private charIndex;
28
29
  private mounted;
30
+ private ro;
31
+ private frozen;
32
+ private freezeWordWidthsBound;
29
33
  constructor(options?: TextSlicerOptions, callbacks?: TextSlicerCallbacks);
30
34
  get metrics(): TextSlicerMetrics;
31
35
  init(): void;
@@ -39,4 +43,9 @@ export declare class TextSlicer {
39
43
  private createWordSpan;
40
44
  private createCharSpan;
41
45
  private createSpaceSpan;
46
+ private scheduleFreezeWordWidths;
47
+ private freezeWordWidths;
48
+ private unfreezeWordWidths;
49
+ private attachResizeObserver;
50
+ private detachResizeObserver;
42
51
  }
package/dist/index.es.js CHANGED
@@ -1,89 +1,126 @@
1
- const u = { splitMode: "both", cssVariables: !1, dataAttributes: !1, keepWhitespaceNodes: !0 }, i = Object.freeze({ word: "ts-word", char: "ts-char", whitespace: "ts-whitespace" }), o = " ", m = (n) => typeof window > "u" || typeof document > "u" ? null : n ? typeof n == "string" ? document.querySelector(n) : n : null, h = (n) => {
1
+ const u = { splitMode: "both", cssVariables: !1, dataAttributes: !1, keepWhitespaceNodes: !0, freezeWordWidths: !1 }, n = Object.freeze({ word: "ts-word", char: "ts-char", whitespace: "ts-whitespace" }), h = " ", f = (r) => typeof window > "u" || typeof document > "u" ? null : r ? typeof r == "string" ? document.querySelector(r) : r : null, d = (r) => {
2
2
  const t = Intl.Segmenter;
3
3
  if (typeof t == "function") {
4
4
  const e = new t("en", { granularity: "grapheme" });
5
- return Array.from(e.segment(n), (s) => s.segment);
5
+ return Array.from(e.segment(r), (s) => s.segment);
6
6
  }
7
- return Array.from(n);
8
- }, p = (n) => n.split(o), c = (n) => {
7
+ return Array.from(r);
8
+ }, c = (r) => r.split(h), a = (r) => {
9
9
  const t = {};
10
- return Object.keys(n).forEach((e) => {
11
- const s = n[e];
10
+ return Object.keys(r).forEach((e) => {
11
+ const s = r[e];
12
12
  s !== void 0 && (t[e] = s);
13
13
  }), t;
14
14
  };
15
- class g {
15
+ class W {
16
16
  el;
17
17
  original;
18
18
  opts;
19
19
  callbacks;
20
20
  charIndex;
21
21
  mounted;
22
+ ro = null;
23
+ frozen = !1;
24
+ freezeWordWidthsBound = () => {
25
+ this.freezeWordWidths();
26
+ };
22
27
  constructor(t = {}, e) {
23
- const s = m(t.container);
24
- this.el = s, this.original = ((r) => !!r && typeof HTMLElement < "u" && r instanceof HTMLElement)(s) ? s.textContent?.toString() ?? "" : "", this.opts = { ...u, ...c(t) }, this.callbacks = e, this.charIndex = 0, this.mounted = !1;
28
+ const s = f(t.container);
29
+ this.el = s, this.original = ((i) => !!i && typeof HTMLElement < "u" && i instanceof HTMLElement)(s) ? s.textContent?.toString() ?? "" : "", this.opts = { ...u, ...a(t) }, this.callbacks = e, this.charIndex = 0, this.mounted = !1;
25
30
  }
26
31
  get metrics() {
27
32
  const t = this.original;
28
- return { wordTotal: t.length ? p(t).length : 0, charTotal: t.length, renderedAt: Date.now() };
33
+ return { wordTotal: t.length ? c(t).length : 0, charTotal: t.length, renderedAt: Date.now() };
29
34
  }
30
35
  init() {
31
36
  this.el && (this.mounted = !0, this.split());
32
37
  }
33
38
  reinit(t, e) {
34
- this.el && (typeof t == "string" && (this.original = t), e && (this.opts = { ...this.opts, ...c(e) }), this.split());
39
+ this.el && (typeof t == "string" && (this.original = t), e && (this.opts = { ...this.opts, ...a(e) }), this.split());
35
40
  }
36
41
  clear() {
37
- this.el && this.el.replaceChildren();
42
+ this.el && (this.unfreezeWordWidths(), this.el.replaceChildren());
38
43
  }
39
44
  split() {
40
45
  if (!this.el) return;
41
46
  this.clear(), this.charIndex = 0;
42
- const t = this.original, e = document.createDocumentFragment(), s = p(t);
43
- this.opts.splitMode === "chars" ? this.appendChars(e, t) : this.appendWords(e, s), this.el.appendChild(e), this.opts.cssVariables && (this.el.style.setProperty("--word-total", String(s.length)), this.el.style.setProperty("--char-total", String(t.length))), this.callbacks?.onAfterRender?.(this.metrics);
47
+ const t = this.original, e = document.createDocumentFragment(), s = c(t);
48
+ this.opts.splitMode === "chars" ? this.appendChars(e, t) : this.appendWords(e, s), this.el.appendChild(e), this.opts.cssVariables && (this.el.style.setProperty("--word-total", String(s.length)), this.el.style.setProperty("--char-total", String(t.length))), this.scheduleFreezeWordWidths().then(() => {
49
+ this.callbacks?.onAfterRender?.(this.metrics);
50
+ }).catch(() => {
51
+ });
44
52
  }
45
53
  destroy() {
46
- this.el && (this.clear(), this.mounted = !1);
54
+ this.el && (this.detachResizeObserver(), this.clear(), this.mounted = !1);
47
55
  }
48
56
  updateOptions(t) {
49
- this.opts = { ...this.opts, ...c(t) }, this.mounted && this.split();
57
+ this.opts = { ...this.opts, ...a(t) }, this.mounted && this.split();
50
58
  }
51
59
  appendWords(t, e) {
52
- e.forEach((s, r) => {
60
+ e.forEach((s, i) => {
53
61
  if (this.opts.splitMode === "both") {
54
- const a = this.createWordSpan(r, s);
55
- for (const d of h(s)) {
56
- const l = this.createCharSpan(d);
57
- a.append(l);
62
+ const o = this.createWordSpan(i, s);
63
+ for (const l of d(s)) {
64
+ const p = this.createCharSpan(l);
65
+ o.append(p);
58
66
  }
59
- t.append(a);
67
+ t.append(o);
60
68
  } else {
61
- const a = this.createWordSpan(r);
62
- a.append(document.createTextNode(s)), t.append(a);
69
+ const o = this.createWordSpan(i);
70
+ o.append(document.createTextNode(s)), t.append(o);
63
71
  }
64
- r < e.length - 1 && t.append(this.createSpaceSpan());
72
+ i < e.length - 1 && t.append(this.createSpaceSpan());
65
73
  });
66
74
  }
67
75
  appendChars(t, e) {
68
- for (const s of h(e)) {
69
- const r = this.createCharSpan(s);
70
- t.append(r);
76
+ for (const s of d(e)) {
77
+ const i = this.createCharSpan(s);
78
+ t.append(i);
71
79
  }
72
80
  }
73
81
  createWordSpan(t, e = "") {
74
82
  const s = document.createElement("span");
75
- return s.classList.add(i.word), this.opts.dataAttributes && e && s.setAttribute("data-word", e), this.opts.cssVariables && s.style.setProperty("--word-index", String(t)), s;
83
+ return s.classList.add(n.word), this.opts.dataAttributes && e && s.setAttribute("data-word", e), this.opts.cssVariables && s.style.setProperty("--word-index", String(t)), s;
76
84
  }
77
85
  createCharSpan(t) {
78
86
  const e = document.createElement("span");
79
- return e.textContent = t, this.opts.dataAttributes && e.setAttribute("data-char", t), t === o ? (e.classList.add(i.whitespace), this.opts.keepWhitespaceNodes || (e.textContent = o)) : (e.classList.add(i.char), this.opts.cssVariables && e.style.setProperty("--char-index", String(this.charIndex)), this.charIndex += 1), e;
87
+ return e.textContent = t, this.opts.dataAttributes && e.setAttribute("data-char", t), t === h ? (e.classList.add(n.whitespace), this.opts.keepWhitespaceNodes || (e.textContent = h)) : (e.classList.add(n.char), this.opts.cssVariables && e.style.setProperty("--char-index", String(this.charIndex)), this.charIndex += 1), e;
80
88
  }
81
89
  createSpaceSpan() {
82
90
  const t = document.createElement("span");
83
- return t.classList.add(i.whitespace), t.textContent = o, t;
91
+ return t.classList.add(n.whitespace), t.textContent = h, t;
92
+ }
93
+ async scheduleFreezeWordWidths() {
94
+ if (this.el && this.opts.freezeWordWidths) {
95
+ try {
96
+ await document.fonts?.ready;
97
+ } catch {
98
+ }
99
+ await new Promise((t) => requestAnimationFrame(() => t())), this.freezeWordWidths(), this.attachResizeObserver();
100
+ }
101
+ }
102
+ freezeWordWidths() {
103
+ this.el && (this.el.querySelectorAll(`.${n.word}`).forEach((t) => {
104
+ t.style.width = "", t.style.flex = "";
105
+ const { width: e } = t.getBoundingClientRect();
106
+ t.style.width = `${Math.ceil(e)}px`, t.style.flex = "0 0 auto";
107
+ }), this.frozen = !0);
108
+ }
109
+ unfreezeWordWidths() {
110
+ !this.el || !this.frozen || (this.el.querySelectorAll(`.${n.word}`).forEach((t) => {
111
+ t.style.width = "", t.style.flex = "";
112
+ }), this.frozen = !1);
113
+ }
114
+ attachResizeObserver() {
115
+ this.el && this.opts.freezeWordWidths && (this.ro || (this.ro = new ResizeObserver(() => {
116
+ this.freezeWordWidths();
117
+ }), this.ro.observe(this.el)), window.addEventListener("resize", this.freezeWordWidthsBound, { passive: !0 }));
118
+ }
119
+ detachResizeObserver() {
120
+ this.ro && (this.ro.disconnect(), this.ro = null), window.removeEventListener("resize", this.freezeWordWidthsBound);
84
121
  }
85
122
  }
86
123
  export {
87
- i as CLASSNAMES,
88
- g as TextSlicer
124
+ n as CLASSNAMES,
125
+ W as TextSlicer
89
126
  };
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- (function(i,r){typeof exports=="object"&&typeof module<"u"?r(exports):typeof define=="function"&&define.amd?define(["exports"],r):r((i=typeof globalThis<"u"?globalThis:i||self).TextSlicer={})})(this,function(i){"use strict";const r={splitMode:"both",cssVariables:!1,dataAttributes:!1,keepWhitespaceNodes:!0},o=Object.freeze({word:"ts-word",char:"ts-char",whitespace:"ts-whitespace"}),c=" ",l=t=>typeof window>"u"||typeof document>"u"?null:t?typeof t=="string"?document.querySelector(t):t:null,d=t=>{const e=Intl.Segmenter;if(typeof e=="function"){const s=new e("en",{granularity:"grapheme"});return Array.from(s.segment(t),n=>n.segment)}return Array.from(t)},p=t=>t.split(c),h=t=>{const e={};return Object.keys(t).forEach(s=>{const n=t[s];n!==void 0&&(e[s]=n)}),e};i.CLASSNAMES=o,i.TextSlicer=class{el;original;opts;callbacks;charIndex;mounted;constructor(t={},e){const s=l(t.container);this.el=s,this.original=(n=>!!n&&typeof HTMLElement<"u"&&n instanceof HTMLElement)(s)?s.textContent?.toString()??"":"",this.opts={...r,...h(t)},this.callbacks=e,this.charIndex=0,this.mounted=!1}get metrics(){const t=this.original;return{wordTotal:t.length?p(t).length:0,charTotal:t.length,renderedAt:Date.now()}}init(){this.el&&(this.mounted=!0,this.split())}reinit(t,e){this.el&&(typeof t=="string"&&(this.original=t),e&&(this.opts={...this.opts,...h(e)}),this.split())}clear(){this.el&&this.el.replaceChildren()}split(){if(!this.el)return;this.clear(),this.charIndex=0;const t=this.original,e=document.createDocumentFragment(),s=p(t);this.opts.splitMode==="chars"?this.appendChars(e,t):this.appendWords(e,s),this.el.appendChild(e),this.opts.cssVariables&&(this.el.style.setProperty("--word-total",String(s.length)),this.el.style.setProperty("--char-total",String(t.length))),this.callbacks?.onAfterRender?.(this.metrics)}destroy(){this.el&&(this.clear(),this.mounted=!1)}updateOptions(t){this.opts={...this.opts,...h(t)},this.mounted&&this.split()}appendWords(t,e){e.forEach((s,n)=>{if(this.opts.splitMode==="both"){const a=this.createWordSpan(n,s);for(const u of d(s)){const f=this.createCharSpan(u);a.append(f)}t.append(a)}else{const a=this.createWordSpan(n);a.append(document.createTextNode(s)),t.append(a)}n<e.length-1&&t.append(this.createSpaceSpan())})}appendChars(t,e){for(const s of d(e)){const n=this.createCharSpan(s);t.append(n)}}createWordSpan(t,e=""){const s=document.createElement("span");return s.classList.add(o.word),this.opts.dataAttributes&&e&&s.setAttribute("data-word",e),this.opts.cssVariables&&s.style.setProperty("--word-index",String(t)),s}createCharSpan(t){const e=document.createElement("span");return e.textContent=t,this.opts.dataAttributes&&e.setAttribute("data-char",t),t===c?(e.classList.add(o.whitespace),this.opts.keepWhitespaceNodes||(e.textContent=c)):(e.classList.add(o.char),this.opts.cssVariables&&e.style.setProperty("--char-index",String(this.charIndex)),this.charIndex+=1),e}createSpaceSpan(){const t=document.createElement("span");return t.classList.add(o.whitespace),t.textContent=c,t}},Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
1
+ (function(n,o){typeof exports=="object"&&typeof module<"u"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):o((n=typeof globalThis<"u"?globalThis:n||self).TextSlicer={})})(this,function(n){"use strict";const o={splitMode:"both",cssVariables:!1,dataAttributes:!1,keepWhitespaceNodes:!0,freezeWordWidths:!1},i=Object.freeze({word:"ts-word",char:"ts-char",whitespace:"ts-whitespace"}),a=" ",p=t=>typeof window>"u"||typeof document>"u"?null:t?typeof t=="string"?document.querySelector(t):t:null,c=t=>{const e=Intl.Segmenter;if(typeof e=="function"){const s=new e("en",{granularity:"grapheme"});return Array.from(s.segment(t),r=>r.segment)}return Array.from(t)},l=t=>t.split(a),d=t=>{const e={};return Object.keys(t).forEach(s=>{const r=t[s];r!==void 0&&(e[s]=r)}),e};n.CLASSNAMES=i,n.TextSlicer=class{el;original;opts;callbacks;charIndex;mounted;ro=null;frozen=!1;freezeWordWidthsBound=()=>{this.freezeWordWidths()};constructor(t={},e){const s=p(t.container);this.el=s,this.original=(r=>!!r&&typeof HTMLElement<"u"&&r instanceof HTMLElement)(s)?s.textContent?.toString()??"":"",this.opts={...o,...d(t)},this.callbacks=e,this.charIndex=0,this.mounted=!1}get metrics(){const t=this.original;return{wordTotal:t.length?l(t).length:0,charTotal:t.length,renderedAt:Date.now()}}init(){this.el&&(this.mounted=!0,this.split())}reinit(t,e){this.el&&(typeof t=="string"&&(this.original=t),e&&(this.opts={...this.opts,...d(e)}),this.split())}clear(){this.el&&(this.unfreezeWordWidths(),this.el.replaceChildren())}split(){if(!this.el)return;this.clear(),this.charIndex=0;const t=this.original,e=document.createDocumentFragment(),s=l(t);this.opts.splitMode==="chars"?this.appendChars(e,t):this.appendWords(e,s),this.el.appendChild(e),this.opts.cssVariables&&(this.el.style.setProperty("--word-total",String(s.length)),this.el.style.setProperty("--char-total",String(t.length))),this.scheduleFreezeWordWidths().then(()=>{this.callbacks?.onAfterRender?.(this.metrics)}).catch(()=>{})}destroy(){this.el&&(this.detachResizeObserver(),this.clear(),this.mounted=!1)}updateOptions(t){this.opts={...this.opts,...d(t)},this.mounted&&this.split()}appendWords(t,e){e.forEach((s,r)=>{if(this.opts.splitMode==="both"){const h=this.createWordSpan(r,s);for(const f of c(s)){const u=this.createCharSpan(f);h.append(u)}t.append(h)}else{const h=this.createWordSpan(r);h.append(document.createTextNode(s)),t.append(h)}r<e.length-1&&t.append(this.createSpaceSpan())})}appendChars(t,e){for(const s of c(e)){const r=this.createCharSpan(s);t.append(r)}}createWordSpan(t,e=""){const s=document.createElement("span");return s.classList.add(i.word),this.opts.dataAttributes&&e&&s.setAttribute("data-word",e),this.opts.cssVariables&&s.style.setProperty("--word-index",String(t)),s}createCharSpan(t){const e=document.createElement("span");return e.textContent=t,this.opts.dataAttributes&&e.setAttribute("data-char",t),t===a?(e.classList.add(i.whitespace),this.opts.keepWhitespaceNodes||(e.textContent=a)):(e.classList.add(i.char),this.opts.cssVariables&&e.style.setProperty("--char-index",String(this.charIndex)),this.charIndex+=1),e}createSpaceSpan(){const t=document.createElement("span");return t.classList.add(i.whitespace),t.textContent=a,t}async scheduleFreezeWordWidths(){if(this.el&&this.opts.freezeWordWidths){try{await document.fonts?.ready}catch{}await new Promise(t=>requestAnimationFrame(()=>t())),this.freezeWordWidths(),this.attachResizeObserver()}}freezeWordWidths(){this.el&&(this.el.querySelectorAll(`.${i.word}`).forEach(t=>{t.style.width="",t.style.flex="";const{width:e}=t.getBoundingClientRect();t.style.width=`${Math.ceil(e)}px`,t.style.flex="0 0 auto"}),this.frozen=!0)}unfreezeWordWidths(){!this.el||!this.frozen||(this.el.querySelectorAll(`.${i.word}`).forEach(t=>{t.style.width="",t.style.flex=""}),this.frozen=!1)}attachResizeObserver(){this.el&&this.opts.freezeWordWidths&&(this.ro||(this.ro=new ResizeObserver(()=>{this.freezeWordWidths()}),this.ro.observe(this.el)),window.addEventListener("resize",this.freezeWordWidthsBound,{passive:!0}))}detachResizeObserver(){this.ro&&(this.ro.disconnect(),this.ro=null),window.removeEventListener("resize",this.freezeWordWidthsBound)}},Object.defineProperty(n,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "text-slicer",
3
- "version": "1.4.0-dev.8",
3
+ "version": "1.4.0-dev.9",
4
4
  "description": "TextSlicer is designed to split text within an HTML element into separate words and/or characters, wrapping each word and/or character in separate span elements.",
5
5
  "author": "ux-ui.pro",
6
6
  "license": "MIT",