text-slicer 1.4.0-dev.2 → 1.4.0-dev.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  </div>
11
11
 
12
12
  <p align="center">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.</p>
13
- <p align="center"><sup>1kB gzipped</sup></p>
13
+ <p align="center"><sup>1.5kB gzipped</sup></p>
14
14
  <p align="center"><a href="https://codepen.io/ux-ui/full/vYMoGoG">Demo</a></p>
15
15
  <br>
16
16
 
package/dist/index.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";class a{textElement;originalText;splitMode;cssVariables;dataAttributes;waitForFonts;fontReadyTimeout;stabilizeLayout;nowrapWords;useFlexWords;charIndexCounter=0;destroyed=!1;constructor(t={}){const{container:s=".text-slicer",splitMode:e="both",cssVariables:n=!1,dataAttributes:i=!1,waitForFonts:r=!1,fontReadyTimeout:o=1500,stabilizeLayout:l=!1,nowrapWords:h=!1,useFlexWords:d=!0}=t;if(this.textElement=typeof s=="string"?document.querySelector(s):s??null,!this.textElement)return this.originalText="",this.splitMode="both",this.cssVariables=!1,this.dataAttributes=!1,this.waitForFonts=!1,this.fontReadyTimeout=0,this.stabilizeLayout=!1,this.nowrapWords=!1,void(this.useFlexWords=!0);this.originalText=(this.textElement.textContent??"").trim(),this.splitMode=e,this.cssVariables=n,this.dataAttributes=i,this.waitForFonts=r,this.fontReadyTimeout=o,this.stabilizeLayout=l,this.nowrapWords=h,this.useFlexWords=d,this.originalText.length>0&&this.textElement.setAttribute("aria-label",this.originalText)}async init(){this.textElement&&(this.waitForFonts&&await a.waitFontsReady(this.fontReadyTimeout).catch(()=>{}),await a.nextFrame(),this.split())}destroy(){this.textElement&&!this.destroyed&&(this.textElement.innerHTML="",this.textElement.textContent=this.originalText,this.textElement.removeAttribute("aria-hidden"),this.destroyed=!0)}split(){if(!this.textElement)return;this.clear(),this.charIndexCounter=0;const t=document.createDocumentFragment(),s=this.originalText.split(" "),e=this.originalText.length;this.splitMode==="words"||this.splitMode==="both"?this.splitWords(t,s):this.splitMode==="chars"&&this.splitChars(t),this.textElement.appendChild(t),a.forceReflow(this.textElement),this.cssVariables&&(this.textElement.style.setProperty("--word-total",String(s.length)),this.textElement.style.setProperty("--char-total",String(e))),this.textElement.setAttribute("aria-hidden","false")}splitWords(t,s){s.forEach((e,n)=>{if(this.splitMode==="both"){const i=this.createWordSpan(n,e);for(const r of e)i.append(this.createCharSpan(r,!0));t.append(i)}else{const i=this.createWordSpan(n);i.append(document.createTextNode(e)),t.append(i)}n<s.length-1&&t.append(a.createSpaceSpan())})}splitChars(t){for(const s of this.originalText)t.append(this.createCharSpan(s,!1))}createWordSpan(t,s=""){const e=document.createElement("span");return e.classList.add("word"),this.dataAttributes&&e.setAttribute("data-word",s),this.cssVariables&&e.style.setProperty("--word-index",String(t)),(this.stabilizeLayout||this.useFlexWords)&&(a.applyWordLayout(e,this.useFlexWords),this.nowrapWords&&(e.style.whiteSpace="nowrap")),e}createCharSpan(t,s){const e=document.createElement("span");return e.textContent=t,this.dataAttributes&&e.setAttribute("data-char",t),t===" "?e.classList.add("whitespace"):(e.classList.add("char"),this.cssVariables&&e.style.setProperty("--char-index",String(this.charIndexCounter)),(this.stabilizeLayout||this.useFlexWords)&&a.applyCharLayout(e,s),this.charIndexCounter+=1),e}static createSpaceSpan(){const t=document.createElement("span");return t.classList.add("whitespace"),t.textContent=" ",t}clear(){this.textElement&&(this.textElement.innerHTML="")}static applyWordLayout(t,s){s?(t.style.display="inline-flex",t.style.flexWrap="nowrap",t.style.alignItems="baseline",t.style.verticalAlign="baseline",t.style.lineHeight="1em"):(t.style.display="inline-block",t.style.verticalAlign="baseline",t.style.lineHeight="1em"),t.style.backfaceVisibility="hidden"}static applyCharLayout(t,s){s?t.style.display="block":(t.style.display="inline-block",t.style.verticalAlign="baseline"),t.style.lineHeight="1em",t.style.willChange="transform",t.style.backfaceVisibility="hidden"}static forceReflow(t){t.offsetHeight}static nextFrame(){return new Promise(t=>requestAnimationFrame(()=>t()))}static getFontFaceSet(){const t=document;return typeof t.fonts=="object"&&t.fonts?t.fonts:null}static waitFontsReady(t){const s=a.getFontFaceSet();return s&&s.ready!==void 0?new Promise(e=>{let n=!1;const i=()=>{n||(n=!0,e())};s.ready.then(()=>i()).catch(()=>i()),t>0&&window.setTimeout(()=>i(),t)}):Promise.resolve()}}module.exports=a;
1
+ "use strict";class a{textElement;originalText;splitMode;cssVariables;dataAttributes;waitForFonts;fontReadyTimeout;stabilizeLayout;nowrapWords;innerWrapper;charIndexCounter=0;destroyed=!1;constructor(t={}){const{container:e=".text-slicer",splitMode:s="both",cssVariables:n=!1,dataAttributes:i=!1,waitForFonts:r=!1,fontReadyTimeout:o=1500,stabilizeLayout:l=!1,nowrapWords:h=!1,innerWrapper:c=!0}=t;if(this.textElement=typeof e=="string"?document.querySelector(e):e??null,!this.textElement)return this.originalText="",this.splitMode="both",this.cssVariables=!1,this.dataAttributes=!1,this.waitForFonts=!1,this.fontReadyTimeout=0,this.stabilizeLayout=!1,this.nowrapWords=!1,void(this.innerWrapper=!0);this.originalText=(this.textElement.textContent??"").trim(),this.splitMode=s,this.cssVariables=n,this.dataAttributes=i,this.waitForFonts=r,this.fontReadyTimeout=o,this.stabilizeLayout=l,this.nowrapWords=h,this.innerWrapper=c,this.originalText.length>0&&this.textElement.setAttribute("aria-label",this.originalText)}async init(){this.textElement&&(this.waitForFonts&&await a.waitFontsReady(this.fontReadyTimeout).catch(()=>{}),await a.nextFrame(),this.split())}destroy(){this.textElement&&!this.destroyed&&(this.textElement.innerHTML="",this.textElement.textContent=this.originalText,this.textElement.removeAttribute("aria-hidden"),this.destroyed=!0)}split(){if(!this.textElement)return;this.clear(),this.charIndexCounter=0;const t=document.createDocumentFragment(),e=this.originalText.split(" "),s=this.originalText.length;this.splitMode==="words"||this.splitMode==="both"?this.splitWords(t,e):this.splitMode==="chars"&&this.splitChars(t),this.textElement.appendChild(t),a.forceReflow(this.textElement),this.cssVariables&&(this.textElement.style.setProperty("--word-total",String(e.length)),this.textElement.style.setProperty("--char-total",String(s))),this.textElement.setAttribute("aria-hidden","false")}splitWords(t,e){e.forEach((s,n)=>{if(this.splitMode==="both"){const i=this.createWordSpan(n,s);for(const r of s)i.append(this.createCharSpan(r));t.append(i)}else{const i=this.createWordSpan(n);i.append(document.createTextNode(s)),t.append(i)}n<e.length-1&&t.append(a.createSpaceSpan())})}splitChars(t){for(const e of this.originalText)t.append(this.createCharSpan(e))}createWordSpan(t,e=""){const s=document.createElement("span");return s.classList.add("word"),this.dataAttributes&&s.setAttribute("data-word",e),this.cssVariables&&s.style.setProperty("--word-index",String(t)),this.stabilizeLayout&&(a.applyStableInlineBox(s),this.nowrapWords&&(s.style.whiteSpace="nowrap")),s}createCharSpan(t){const e=document.createElement("span");if(t===" ")return e.classList.add("whitespace"),e.textContent=" ",e;if(e.classList.add("char"),this.cssVariables&&e.style.setProperty("--char-index",String(this.charIndexCounter)),this.dataAttributes&&e.setAttribute("data-char",t),this.stabilizeLayout&&a.applyStableInlineBox(e),this.innerWrapper){const s=document.createElement("span");s.classList.add("char-inner"),s.textContent=t,e.appendChild(s)}else e.textContent=t;return this.charIndexCounter+=1,e}static createSpaceSpan(){const t=document.createElement("span");return t.classList.add("whitespace"),t.textContent=" ",t}clear(){this.textElement&&(this.textElement.innerHTML="")}static applyStableInlineBox(t){t.style.display="inline-block",t.style.verticalAlign="baseline",t.style.lineHeight="1em",t.style.backfaceVisibility="hidden",t.style.willChange="transform"}static forceReflow(t){t.offsetHeight}static nextFrame(){return new Promise(t=>requestAnimationFrame(()=>t()))}static getFontFaceSet(){const t=document;return typeof t.fonts=="object"&&t.fonts?t.fonts:null}static waitFontsReady(t){const e=a.getFontFaceSet();return e&&e.ready!==void 0?new Promise(s=>{let n=!1;const i=()=>{n||(n=!0,s())};e.ready.then(()=>i()).catch(()=>i()),t>0&&window.setTimeout(()=>i(),t)}):Promise.resolve()}}module.exports=a;
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export interface TextSlicerOptions {
8
8
  fontReadyTimeout?: number;
9
9
  stabilizeLayout?: boolean;
10
10
  nowrapWords?: boolean;
11
- useFlexWords?: boolean;
11
+ innerWrapper?: boolean;
12
12
  }
13
13
  declare class TextSlicer {
14
14
  private readonly textElement;
@@ -20,7 +20,7 @@ declare class TextSlicer {
20
20
  private readonly fontReadyTimeout;
21
21
  private readonly stabilizeLayout;
22
22
  private readonly nowrapWords;
23
- private readonly useFlexWords;
23
+ private readonly innerWrapper;
24
24
  private charIndexCounter;
25
25
  private destroyed;
26
26
  constructor(options?: TextSlicerOptions);
@@ -33,8 +33,7 @@ declare class TextSlicer {
33
33
  private createCharSpan;
34
34
  private static createSpaceSpan;
35
35
  private clear;
36
- private static applyWordLayout;
37
- private static applyCharLayout;
36
+ private static applyStableInlineBox;
38
37
  private static forceReflow;
39
38
  private static nextFrame;
40
39
  private static getFontFaceSet;
package/dist/index.es.js CHANGED
@@ -8,13 +8,13 @@ class n {
8
8
  fontReadyTimeout;
9
9
  stabilizeLayout;
10
10
  nowrapWords;
11
- useFlexWords;
11
+ innerWrapper;
12
12
  charIndexCounter = 0;
13
13
  destroyed = !1;
14
14
  constructor(t = {}) {
15
- const { container: s = ".text-slicer", splitMode: e = "both", cssVariables: a = !1, dataAttributes: i = !1, waitForFonts: r = !1, fontReadyTimeout: o = 1500, stabilizeLayout: l = !1, nowrapWords: h = !1, useFlexWords: d = !0 } = t;
16
- if (this.textElement = typeof s == "string" ? document.querySelector(s) : s ?? null, !this.textElement) return this.originalText = "", this.splitMode = "both", this.cssVariables = !1, this.dataAttributes = !1, this.waitForFonts = !1, this.fontReadyTimeout = 0, this.stabilizeLayout = !1, this.nowrapWords = !1, void (this.useFlexWords = !0);
17
- this.originalText = (this.textElement.textContent ?? "").trim(), this.splitMode = e, this.cssVariables = a, this.dataAttributes = i, this.waitForFonts = r, this.fontReadyTimeout = o, this.stabilizeLayout = l, this.nowrapWords = h, this.useFlexWords = d, this.originalText.length > 0 && this.textElement.setAttribute("aria-label", this.originalText);
15
+ const { container: e = ".text-slicer", splitMode: s = "both", cssVariables: a = !1, dataAttributes: i = !1, waitForFonts: r = !1, fontReadyTimeout: o = 1500, stabilizeLayout: l = !1, nowrapWords: h = !1, innerWrapper: d = !0 } = t;
16
+ if (this.textElement = typeof e == "string" ? document.querySelector(e) : e ?? null, !this.textElement) return this.originalText = "", this.splitMode = "both", this.cssVariables = !1, this.dataAttributes = !1, this.waitForFonts = !1, this.fontReadyTimeout = 0, this.stabilizeLayout = !1, this.nowrapWords = !1, void (this.innerWrapper = !0);
17
+ this.originalText = (this.textElement.textContent ?? "").trim(), this.splitMode = s, this.cssVariables = a, this.dataAttributes = i, this.waitForFonts = r, this.fontReadyTimeout = o, this.stabilizeLayout = l, this.nowrapWords = h, this.innerWrapper = d, this.originalText.length > 0 && this.textElement.setAttribute("aria-label", this.originalText);
18
18
  }
19
19
  async init() {
20
20
  this.textElement && (this.waitForFonts && await n.waitFontsReady(this.fontReadyTimeout).catch(() => {
@@ -26,32 +26,37 @@ class n {
26
26
  split() {
27
27
  if (!this.textElement) return;
28
28
  this.clear(), this.charIndexCounter = 0;
29
- const t = document.createDocumentFragment(), s = this.originalText.split(" "), e = this.originalText.length;
30
- this.splitMode === "words" || this.splitMode === "both" ? this.splitWords(t, s) : this.splitMode === "chars" && this.splitChars(t), this.textElement.appendChild(t), n.forceReflow(this.textElement), this.cssVariables && (this.textElement.style.setProperty("--word-total", String(s.length)), this.textElement.style.setProperty("--char-total", String(e))), this.textElement.setAttribute("aria-hidden", "false");
29
+ const t = document.createDocumentFragment(), e = this.originalText.split(" "), s = this.originalText.length;
30
+ this.splitMode === "words" || this.splitMode === "both" ? this.splitWords(t, e) : this.splitMode === "chars" && this.splitChars(t), this.textElement.appendChild(t), n.forceReflow(this.textElement), this.cssVariables && (this.textElement.style.setProperty("--word-total", String(e.length)), this.textElement.style.setProperty("--char-total", String(s))), this.textElement.setAttribute("aria-hidden", "false");
31
31
  }
32
- splitWords(t, s) {
33
- s.forEach((e, a) => {
32
+ splitWords(t, e) {
33
+ e.forEach((s, a) => {
34
34
  if (this.splitMode === "both") {
35
- const i = this.createWordSpan(a, e);
36
- for (const r of e) i.append(this.createCharSpan(r, !0));
35
+ const i = this.createWordSpan(a, s);
36
+ for (const r of s) i.append(this.createCharSpan(r));
37
37
  t.append(i);
38
38
  } else {
39
39
  const i = this.createWordSpan(a);
40
- i.append(document.createTextNode(e)), t.append(i);
40
+ i.append(document.createTextNode(s)), t.append(i);
41
41
  }
42
- a < s.length - 1 && t.append(n.createSpaceSpan());
42
+ a < e.length - 1 && t.append(n.createSpaceSpan());
43
43
  });
44
44
  }
45
45
  splitChars(t) {
46
- for (const s of this.originalText) t.append(this.createCharSpan(s, !1));
46
+ for (const e of this.originalText) t.append(this.createCharSpan(e));
47
47
  }
48
- createWordSpan(t, s = "") {
49
- const e = document.createElement("span");
50
- return e.classList.add("word"), this.dataAttributes && e.setAttribute("data-word", s), this.cssVariables && e.style.setProperty("--word-index", String(t)), (this.stabilizeLayout || this.useFlexWords) && (n.applyWordLayout(e, this.useFlexWords), this.nowrapWords && (e.style.whiteSpace = "nowrap")), e;
48
+ createWordSpan(t, e = "") {
49
+ const s = document.createElement("span");
50
+ return s.classList.add("word"), this.dataAttributes && s.setAttribute("data-word", e), this.cssVariables && s.style.setProperty("--word-index", String(t)), this.stabilizeLayout && (n.applyStableInlineBox(s), this.nowrapWords && (s.style.whiteSpace = "nowrap")), s;
51
51
  }
52
- createCharSpan(t, s) {
52
+ createCharSpan(t) {
53
53
  const e = document.createElement("span");
54
- return e.textContent = t, this.dataAttributes && e.setAttribute("data-char", t), t === " " ? e.classList.add("whitespace") : (e.classList.add("char"), this.cssVariables && e.style.setProperty("--char-index", String(this.charIndexCounter)), (this.stabilizeLayout || this.useFlexWords) && n.applyCharLayout(e, s), this.charIndexCounter += 1), e;
54
+ if (t === " ") return e.classList.add("whitespace"), e.textContent = " ", e;
55
+ if (e.classList.add("char"), this.cssVariables && e.style.setProperty("--char-index", String(this.charIndexCounter)), this.dataAttributes && e.setAttribute("data-char", t), this.stabilizeLayout && n.applyStableInlineBox(e), this.innerWrapper) {
56
+ const s = document.createElement("span");
57
+ s.classList.add("char-inner"), s.textContent = t, e.appendChild(s);
58
+ } else e.textContent = t;
59
+ return this.charIndexCounter += 1, e;
55
60
  }
56
61
  static createSpaceSpan() {
57
62
  const t = document.createElement("span");
@@ -60,11 +65,8 @@ class n {
60
65
  clear() {
61
66
  this.textElement && (this.textElement.innerHTML = "");
62
67
  }
63
- static applyWordLayout(t, s) {
64
- s ? (t.style.display = "inline-flex", t.style.flexWrap = "nowrap", t.style.alignItems = "baseline", t.style.verticalAlign = "baseline", t.style.lineHeight = "1em") : (t.style.display = "inline-block", t.style.verticalAlign = "baseline", t.style.lineHeight = "1em"), t.style.backfaceVisibility = "hidden";
65
- }
66
- static applyCharLayout(t, s) {
67
- s ? t.style.display = "block" : (t.style.display = "inline-block", t.style.verticalAlign = "baseline"), t.style.lineHeight = "1em", t.style.willChange = "transform", t.style.backfaceVisibility = "hidden";
68
+ static applyStableInlineBox(t) {
69
+ t.style.display = "inline-block", t.style.verticalAlign = "baseline", t.style.lineHeight = "1em", t.style.backfaceVisibility = "hidden", t.style.willChange = "transform";
68
70
  }
69
71
  static forceReflow(t) {
70
72
  t.offsetHeight;
@@ -77,13 +79,13 @@ class n {
77
79
  return typeof t.fonts == "object" && t.fonts ? t.fonts : null;
78
80
  }
79
81
  static waitFontsReady(t) {
80
- const s = n.getFontFaceSet();
81
- return s && s.ready !== void 0 ? new Promise((e) => {
82
+ const e = n.getFontFaceSet();
83
+ return e && e.ready !== void 0 ? new Promise((s) => {
82
84
  let a = !1;
83
85
  const i = () => {
84
- a || (a = !0, e());
86
+ a || (a = !0, s());
85
87
  };
86
- s.ready.then(() => i()).catch(() => i()), t > 0 && window.setTimeout(() => i(), t);
88
+ e.ready.then(() => i()).catch(() => i()), t > 0 && window.setTimeout(() => i(), t);
87
89
  }) : Promise.resolve();
88
90
  }
89
91
  }
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- (function(i,o){typeof exports=="object"&&typeof module<"u"?module.exports=o():typeof define=="function"&&define.amd?define(o):(i=typeof globalThis<"u"?globalThis:i||self).TextSlicer=o()})(this,function(){"use strict";class i{textElement;originalText;splitMode;cssVariables;dataAttributes;waitForFonts;fontReadyTimeout;stabilizeLayout;nowrapWords;useFlexWords;charIndexCounter=0;destroyed=!1;constructor(t={}){const{container:s=".text-slicer",splitMode:e="both",cssVariables:n=!1,dataAttributes:a=!1,waitForFonts:r=!1,fontReadyTimeout:l=1500,stabilizeLayout:h=!1,nowrapWords:d=!1,useFlexWords:c=!0}=t;if(this.textElement=typeof s=="string"?document.querySelector(s):s??null,!this.textElement)return this.originalText="",this.splitMode="both",this.cssVariables=!1,this.dataAttributes=!1,this.waitForFonts=!1,this.fontReadyTimeout=0,this.stabilizeLayout=!1,this.nowrapWords=!1,void(this.useFlexWords=!0);this.originalText=(this.textElement.textContent??"").trim(),this.splitMode=e,this.cssVariables=n,this.dataAttributes=a,this.waitForFonts=r,this.fontReadyTimeout=l,this.stabilizeLayout=h,this.nowrapWords=d,this.useFlexWords=c,this.originalText.length>0&&this.textElement.setAttribute("aria-label",this.originalText)}async init(){this.textElement&&(this.waitForFonts&&await i.waitFontsReady(this.fontReadyTimeout).catch(()=>{}),await i.nextFrame(),this.split())}destroy(){this.textElement&&!this.destroyed&&(this.textElement.innerHTML="",this.textElement.textContent=this.originalText,this.textElement.removeAttribute("aria-hidden"),this.destroyed=!0)}split(){if(!this.textElement)return;this.clear(),this.charIndexCounter=0;const t=document.createDocumentFragment(),s=this.originalText.split(" "),e=this.originalText.length;this.splitMode==="words"||this.splitMode==="both"?this.splitWords(t,s):this.splitMode==="chars"&&this.splitChars(t),this.textElement.appendChild(t),i.forceReflow(this.textElement),this.cssVariables&&(this.textElement.style.setProperty("--word-total",String(s.length)),this.textElement.style.setProperty("--char-total",String(e))),this.textElement.setAttribute("aria-hidden","false")}splitWords(t,s){s.forEach((e,n)=>{if(this.splitMode==="both"){const a=this.createWordSpan(n,e);for(const r of e)a.append(this.createCharSpan(r,!0));t.append(a)}else{const a=this.createWordSpan(n);a.append(document.createTextNode(e)),t.append(a)}n<s.length-1&&t.append(i.createSpaceSpan())})}splitChars(t){for(const s of this.originalText)t.append(this.createCharSpan(s,!1))}createWordSpan(t,s=""){const e=document.createElement("span");return e.classList.add("word"),this.dataAttributes&&e.setAttribute("data-word",s),this.cssVariables&&e.style.setProperty("--word-index",String(t)),(this.stabilizeLayout||this.useFlexWords)&&(i.applyWordLayout(e,this.useFlexWords),this.nowrapWords&&(e.style.whiteSpace="nowrap")),e}createCharSpan(t,s){const e=document.createElement("span");return e.textContent=t,this.dataAttributes&&e.setAttribute("data-char",t),t===" "?e.classList.add("whitespace"):(e.classList.add("char"),this.cssVariables&&e.style.setProperty("--char-index",String(this.charIndexCounter)),(this.stabilizeLayout||this.useFlexWords)&&i.applyCharLayout(e,s),this.charIndexCounter+=1),e}static createSpaceSpan(){const t=document.createElement("span");return t.classList.add("whitespace"),t.textContent=" ",t}clear(){this.textElement&&(this.textElement.innerHTML="")}static applyWordLayout(t,s){s?(t.style.display="inline-flex",t.style.flexWrap="nowrap",t.style.alignItems="baseline",t.style.verticalAlign="baseline",t.style.lineHeight="1em"):(t.style.display="inline-block",t.style.verticalAlign="baseline",t.style.lineHeight="1em"),t.style.backfaceVisibility="hidden"}static applyCharLayout(t,s){s?t.style.display="block":(t.style.display="inline-block",t.style.verticalAlign="baseline"),t.style.lineHeight="1em",t.style.willChange="transform",t.style.backfaceVisibility="hidden"}static forceReflow(t){t.offsetHeight}static nextFrame(){return new Promise(t=>requestAnimationFrame(()=>t()))}static getFontFaceSet(){const t=document;return typeof t.fonts=="object"&&t.fonts?t.fonts:null}static waitFontsReady(t){const s=i.getFontFaceSet();return s&&s.ready!==void 0?new Promise(e=>{let n=!1;const a=()=>{n||(n=!0,e())};s.ready.then(()=>a()).catch(()=>a()),t>0&&window.setTimeout(()=>a(),t)}):Promise.resolve()}}return i});
1
+ (function(s,r){typeof exports=="object"&&typeof module<"u"?module.exports=r():typeof define=="function"&&define.amd?define(r):(s=typeof globalThis<"u"?globalThis:s||self).TextSlicer=r()})(this,function(){"use strict";class s{textElement;originalText;splitMode;cssVariables;dataAttributes;waitForFonts;fontReadyTimeout;stabilizeLayout;nowrapWords;innerWrapper;charIndexCounter=0;destroyed=!1;constructor(t={}){const{container:e=".text-slicer",splitMode:i="both",cssVariables:a=!1,dataAttributes:n=!1,waitForFonts:o=!1,fontReadyTimeout:l=1500,stabilizeLayout:h=!1,nowrapWords:d=!1,innerWrapper:c=!0}=t;if(this.textElement=typeof e=="string"?document.querySelector(e):e??null,!this.textElement)return this.originalText="",this.splitMode="both",this.cssVariables=!1,this.dataAttributes=!1,this.waitForFonts=!1,this.fontReadyTimeout=0,this.stabilizeLayout=!1,this.nowrapWords=!1,void(this.innerWrapper=!0);this.originalText=(this.textElement.textContent??"").trim(),this.splitMode=i,this.cssVariables=a,this.dataAttributes=n,this.waitForFonts=o,this.fontReadyTimeout=l,this.stabilizeLayout=h,this.nowrapWords=d,this.innerWrapper=c,this.originalText.length>0&&this.textElement.setAttribute("aria-label",this.originalText)}async init(){this.textElement&&(this.waitForFonts&&await s.waitFontsReady(this.fontReadyTimeout).catch(()=>{}),await s.nextFrame(),this.split())}destroy(){this.textElement&&!this.destroyed&&(this.textElement.innerHTML="",this.textElement.textContent=this.originalText,this.textElement.removeAttribute("aria-hidden"),this.destroyed=!0)}split(){if(!this.textElement)return;this.clear(),this.charIndexCounter=0;const t=document.createDocumentFragment(),e=this.originalText.split(" "),i=this.originalText.length;this.splitMode==="words"||this.splitMode==="both"?this.splitWords(t,e):this.splitMode==="chars"&&this.splitChars(t),this.textElement.appendChild(t),s.forceReflow(this.textElement),this.cssVariables&&(this.textElement.style.setProperty("--word-total",String(e.length)),this.textElement.style.setProperty("--char-total",String(i))),this.textElement.setAttribute("aria-hidden","false")}splitWords(t,e){e.forEach((i,a)=>{if(this.splitMode==="both"){const n=this.createWordSpan(a,i);for(const o of i)n.append(this.createCharSpan(o));t.append(n)}else{const n=this.createWordSpan(a);n.append(document.createTextNode(i)),t.append(n)}a<e.length-1&&t.append(s.createSpaceSpan())})}splitChars(t){for(const e of this.originalText)t.append(this.createCharSpan(e))}createWordSpan(t,e=""){const i=document.createElement("span");return i.classList.add("word"),this.dataAttributes&&i.setAttribute("data-word",e),this.cssVariables&&i.style.setProperty("--word-index",String(t)),this.stabilizeLayout&&(s.applyStableInlineBox(i),this.nowrapWords&&(i.style.whiteSpace="nowrap")),i}createCharSpan(t){const e=document.createElement("span");if(t===" ")return e.classList.add("whitespace"),e.textContent=" ",e;if(e.classList.add("char"),this.cssVariables&&e.style.setProperty("--char-index",String(this.charIndexCounter)),this.dataAttributes&&e.setAttribute("data-char",t),this.stabilizeLayout&&s.applyStableInlineBox(e),this.innerWrapper){const i=document.createElement("span");i.classList.add("char-inner"),i.textContent=t,e.appendChild(i)}else e.textContent=t;return this.charIndexCounter+=1,e}static createSpaceSpan(){const t=document.createElement("span");return t.classList.add("whitespace"),t.textContent=" ",t}clear(){this.textElement&&(this.textElement.innerHTML="")}static applyStableInlineBox(t){t.style.display="inline-block",t.style.verticalAlign="baseline",t.style.lineHeight="1em",t.style.backfaceVisibility="hidden",t.style.willChange="transform"}static forceReflow(t){t.offsetHeight}static nextFrame(){return new Promise(t=>requestAnimationFrame(()=>t()))}static getFontFaceSet(){const t=document;return typeof t.fonts=="object"&&t.fonts?t.fonts:null}static waitFontsReady(t){const e=s.getFontFaceSet();return e&&e.ready!==void 0?new Promise(i=>{let a=!1;const n=()=>{a||(a=!0,i())};e.ready.then(()=>n()).catch(()=>n()),t>0&&window.setTimeout(()=>n(),t)}):Promise.resolve()}}return s});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "text-slicer",
3
- "version": "1.4.0-dev.2",
3
+ "version": "1.4.0-dev.4",
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",