text-slicer 1.5.0-dev.1 → 1.5.0-dev.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/dist/index.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g={splitMode:"both",cssVariables:!1,dataAttributes:!1,keepWhitespaceNodes:!0,lockContainerHeight:!1},h=Object.freeze({word:"ts-word",char:"ts-char",whitespace:"ts-whitespace"}),o=" ",r=()=>typeof window<"u"&&typeof document<"u",c=t=>{const e=Intl.Segmenter;if(typeof e=="function"){const s=new e("en",{granularity:"grapheme"});return Array.from(s.segment(t),i=>i.segment)}return Array.from(t)},l=t=>t.split(o),a=t=>{const e={};return Object.keys(t).forEach(s=>{const i=t[s];i!==void 0&&(e[s]=i)}),e};exports.CLASSNAMES=h,exports.TextSlicer=class{el;original;opts;callbacks;charIndex;mounted;heightLocked=!1;lockedHeightPx=null;constructor(t={},e){const s=(i=t.container,r()&&i?typeof i=="string"?document.querySelector(i):i:null);var i;this.el=s,this.original=(n=>!!n&&typeof HTMLElement<"u"&&n instanceof HTMLElement)(s)?s.textContent?.toString()??"":"",this.opts={...g,...a(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.opts.lockContainerHeight&&this.freezeHeight(),this.split())}reinit(t,e){if(this.el){if(typeof t=="string"&&(this.original=t),e){const s=this.opts.lockContainerHeight;this.opts={...this.opts,...a(e)},!s&&this.opts.lockContainerHeight?this.freezeHeight():s&&!this.opts.lockContainerHeight&&this.unfreezeHeight()}this.opts.lockContainerHeight&&this.freezeHeight(),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=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.callbacks?.onAfterRender?.(this.metrics)}destroy(){this.el&&(this.clear(),this.mounted=!1,this.unfreezeHeight())}updateOptions(t){const e=this.opts.lockContainerHeight;this.opts={...this.opts,...a(t)},!e&&this.opts.lockContainerHeight?this.freezeHeight():e&&!this.opts.lockContainerHeight&&this.unfreezeHeight(),this.mounted&&this.split()}freezeHeight(){if(!this.el||!r())return;const t=this.el.getBoundingClientRect(),e=Math.max(0,Math.round(t.height));e&&(this.heightLocked&&this.lockedHeightPx===e||(this.el.style.height=`${e}px`,this.el.style.overflow="hidden",this.heightLocked=!0,this.lockedHeightPx=e))}unfreezeHeight(){this.el&&r()&&(this.heightLocked&&(this.el.style.height="",this.el.style.overflow=""),this.heightLocked=!1,this.lockedHeightPx=null)}appendWords(t,e){e.forEach((s,i)=>{if(this.opts.splitMode==="both"){const n=this.createWordSpan(i,s);for(const d of c(s)){const p=this.createCharSpan(d);n.append(p)}t.append(n)}else{const n=this.createWordSpan(i);n.append(document.createTextNode(s)),t.append(n)}i<e.length-1&&t.append(this.createSpaceSpan())})}appendChars(t,e){for(const s of c(e)){const i=this.createCharSpan(s);t.append(i)}}createWordSpan(t,e=""){const s=document.createElement("span");return s.classList.add(h.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(h.whitespace),this.opts.keepWhitespaceNodes||(e.textContent=o)):(e.classList.add(h.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(h.whitespace),t.textContent=o,t}};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g={splitMode:"both",cssVariables:!1,dataAttributes:!1,keepWhitespaceNodes:!0,containerHeightVar:!1},n=Object.freeze({word:"ts-word",char:"ts-char",whitespace:"ts-whitespace"}),a=" ",h="--container-height",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),i=>i.segment)}return Array.from(t)},l=t=>t.split(a),o=t=>{const e={};return Object.keys(t).forEach(s=>{const i=t[s];i!==void 0&&(e[s]=i)}),e};exports.CLASSNAMES=n,exports.TextSlicer=class{el;original;opts;callbacks;charIndex;mounted;heightLocked;constructor(t={},e){const s=u(t.container);this.el=s,this.original=(i=>!!i&&typeof HTMLElement<"u"&&i instanceof HTMLElement)(s)?s.textContent?.toString()??"":"",this.opts={...g,...o(t)},this.callbacks=e,this.charIndex=0,this.mounted=!1,this.heightLocked=!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,...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=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.opts.containerHeightVar&&this.applyContainerHeightVar(),this.callbacks?.onAfterRender?.(this.metrics)}destroy(){this.el&&(this.clear(),this.unlockHeight(),this.opts.containerHeightVar&&this.el.style.removeProperty(h),this.mounted=!1)}updateOptions(t){this.opts={...this.opts,...o(t)},this.mounted&&this.split()}lockHeight(){if(!this.el)return;const t=this.measureHeight();t>0&&(this.el.style.height=`${t}px`,this.heightLocked=!0)}unlockHeight(){this.el&&(this.el.style.removeProperty("height"),this.heightLocked=!1)}appendWords(t,e){e.forEach((s,i)=>{if(this.opts.splitMode==="both"){const r=this.createWordSpan(i,s);for(const p of c(s)){const d=this.createCharSpan(p);r.append(d)}t.append(r)}else{const r=this.createWordSpan(i);r.append(document.createTextNode(s)),t.append(r)}i<e.length-1&&t.append(this.createSpaceSpan())})}appendChars(t,e){for(const s of c(e)){const i=this.createCharSpan(s);t.append(i)}}createWordSpan(t,e=""){const s=document.createElement("span");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}createCharSpan(t){const e=document.createElement("span");return e.textContent=t,this.opts.dataAttributes&&e.setAttribute("data-char",t),t===a?(e.classList.add(n.whitespace),this.opts.keepWhitespaceNodes||(e.textContent=a)):(e.classList.add(n.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(n.whitespace),t.textContent=a,t}measureHeight(){return this.el?Math.round(Math.max(this.el.scrollHeight,this.el.getBoundingClientRect().height)):0}applyContainerHeightVar(){if(!this.el)return;const t=this.measureHeight();this.el.style.setProperty(h,`${t}px`)}};
package/dist/index.d.ts CHANGED
@@ -5,8 +5,7 @@ export interface TextSlicerOptions {
5
5
  cssVariables?: boolean;
6
6
  dataAttributes?: boolean;
7
7
  keepWhitespaceNodes?: boolean;
8
- /** При true фиксирует текущую высоту контейнера при init()/reinit(). */
9
- lockContainerHeight?: boolean;
8
+ containerHeightVar?: boolean;
10
9
  }
11
10
  export interface TextSlicerMetrics {
12
11
  wordTotal: number;
@@ -28,10 +27,7 @@ export declare class TextSlicer {
28
27
  private callbacks;
29
28
  private charIndex;
30
29
  private mounted;
31
- /** Флаг, зафиксирована ли высота сейчас. */
32
30
  private heightLocked;
33
- /** Последнее зафиксированное значение высоты (в px). */
34
- private lockedHeightPx;
35
31
  constructor(options?: TextSlicerOptions, callbacks?: TextSlicerCallbacks);
36
32
  get metrics(): TextSlicerMetrics;
37
33
  init(): void;
@@ -40,19 +36,13 @@ export declare class TextSlicer {
40
36
  split(): void;
41
37
  destroy(): void;
42
38
  updateOptions(next: Partial<TextSlicerOptions>): void;
43
- /**
44
- * Фиксирует текущую высоту контейнера (в px) и скрывает переполнение.
45
- * Идемпотентно: повторный вызов без изменения высоты не трогает стили.
46
- */
47
- freezeHeight(): void;
48
- /**
49
- * Снимает фиксацию высоты контейнера.
50
- * Возвращает инлайн-стили height/overflow к значениям по умолчанию.
51
- */
52
- unfreezeHeight(): void;
39
+ lockHeight(): void;
40
+ unlockHeight(): void;
53
41
  private appendWords;
54
42
  private appendChars;
55
43
  private createWordSpan;
56
44
  private createCharSpan;
57
45
  private createSpaceSpan;
46
+ private measureHeight;
47
+ private applyContainerHeightVar;
58
48
  }
package/dist/index.es.js CHANGED
@@ -1,46 +1,38 @@
1
- const u = { splitMode: "both", cssVariables: !1, dataAttributes: !1, keepWhitespaceNodes: !0, lockContainerHeight: !1 }, o = Object.freeze({ word: "ts-word", char: "ts-char", whitespace: "ts-whitespace" }), r = " ", a = () => typeof window < "u" && typeof document < "u", l = (n) => {
1
+ const u = { splitMode: "both", cssVariables: !1, dataAttributes: !1, keepWhitespaceNodes: !0, containerHeightVar: !1 }, a = Object.freeze({ word: "ts-word", char: "ts-char", whitespace: "ts-whitespace" }), h = " ", c = "--container-height", m = (i) => typeof window > "u" || typeof document > "u" ? null : i ? typeof i == "string" ? document.querySelector(i) : i : null, l = (i) => {
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(i), (s) => s.segment);
6
6
  }
7
- return Array.from(n);
8
- }, d = (n) => n.split(r), c = (n) => {
7
+ return Array.from(i);
8
+ }, p = (i) => i.split(h), o = (i) => {
9
9
  const t = {};
10
- return Object.keys(n).forEach((e) => {
11
- const s = n[e];
10
+ return Object.keys(i).forEach((e) => {
11
+ const s = i[e];
12
12
  s !== void 0 && (t[e] = s);
13
13
  }), t;
14
14
  };
15
- class f {
15
+ class y {
16
16
  el;
17
17
  original;
18
18
  opts;
19
19
  callbacks;
20
20
  charIndex;
21
21
  mounted;
22
- heightLocked = !1;
23
- lockedHeightPx = null;
22
+ heightLocked;
24
23
  constructor(t = {}, e) {
25
- const s = (i = t.container, a() && i ? typeof i == "string" ? document.querySelector(i) : i : null);
26
- var i;
27
- this.el = s, this.original = ((h) => !!h && typeof HTMLElement < "u" && h instanceof HTMLElement)(s) ? s.textContent?.toString() ?? "" : "", this.opts = { ...u, ...c(t) }, this.callbacks = e, this.charIndex = 0, this.mounted = !1;
24
+ const s = m(t.container);
25
+ this.el = s, this.original = ((r) => !!r && typeof HTMLElement < "u" && r instanceof HTMLElement)(s) ? s.textContent?.toString() ?? "" : "", this.opts = { ...u, ...o(t) }, this.callbacks = e, this.charIndex = 0, this.mounted = !1, this.heightLocked = !1;
28
26
  }
29
27
  get metrics() {
30
28
  const t = this.original;
31
- return { wordTotal: t.length ? d(t).length : 0, charTotal: t.length, renderedAt: Date.now() };
29
+ return { wordTotal: t.length ? p(t).length : 0, charTotal: t.length, renderedAt: Date.now() };
32
30
  }
33
31
  init() {
34
- this.el && (this.mounted = !0, this.opts.lockContainerHeight && this.freezeHeight(), this.split());
32
+ this.el && (this.mounted = !0, this.split());
35
33
  }
36
34
  reinit(t, e) {
37
- if (this.el) {
38
- if (typeof t == "string" && (this.original = t), e) {
39
- const s = this.opts.lockContainerHeight;
40
- this.opts = { ...this.opts, ...c(e) }, !s && this.opts.lockContainerHeight ? this.freezeHeight() : s && !this.opts.lockContainerHeight && this.unfreezeHeight();
41
- }
42
- this.opts.lockContainerHeight && this.freezeHeight(), this.split();
43
- }
35
+ this.el && (typeof t == "string" && (this.original = t), e && (this.opts = { ...this.opts, ...o(e) }), this.split());
44
36
  }
45
37
  clear() {
46
38
  this.el && this.el.replaceChildren();
@@ -48,60 +40,67 @@ class f {
48
40
  split() {
49
41
  if (!this.el) return;
50
42
  this.clear(), this.charIndex = 0;
51
- const t = this.original, e = document.createDocumentFragment(), s = d(t);
52
- 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);
43
+ const t = this.original, e = document.createDocumentFragment(), s = p(t);
44
+ 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.opts.containerHeightVar && this.applyContainerHeightVar(), this.callbacks?.onAfterRender?.(this.metrics);
53
45
  }
54
46
  destroy() {
55
- this.el && (this.clear(), this.mounted = !1, this.unfreezeHeight());
47
+ this.el && (this.clear(), this.unlockHeight(), this.opts.containerHeightVar && this.el.style.removeProperty(c), this.mounted = !1);
56
48
  }
57
49
  updateOptions(t) {
58
- const e = this.opts.lockContainerHeight;
59
- this.opts = { ...this.opts, ...c(t) }, !e && this.opts.lockContainerHeight ? this.freezeHeight() : e && !this.opts.lockContainerHeight && this.unfreezeHeight(), this.mounted && this.split();
50
+ this.opts = { ...this.opts, ...o(t) }, this.mounted && this.split();
60
51
  }
61
- freezeHeight() {
62
- if (!this.el || !a()) return;
63
- const t = this.el.getBoundingClientRect(), e = Math.max(0, Math.round(t.height));
64
- e && (this.heightLocked && this.lockedHeightPx === e || (this.el.style.height = `${e}px`, this.el.style.overflow = "hidden", this.heightLocked = !0, this.lockedHeightPx = e));
52
+ lockHeight() {
53
+ if (!this.el) return;
54
+ const t = this.measureHeight();
55
+ t > 0 && (this.el.style.height = `${t}px`, this.heightLocked = !0);
65
56
  }
66
- unfreezeHeight() {
67
- this.el && a() && (this.heightLocked && (this.el.style.height = "", this.el.style.overflow = ""), this.heightLocked = !1, this.lockedHeightPx = null);
57
+ unlockHeight() {
58
+ this.el && (this.el.style.removeProperty("height"), this.heightLocked = !1);
68
59
  }
69
60
  appendWords(t, e) {
70
- e.forEach((s, i) => {
61
+ e.forEach((s, r) => {
71
62
  if (this.opts.splitMode === "both") {
72
- const h = this.createWordSpan(i, s);
73
- for (const p of l(s)) {
74
- const g = this.createCharSpan(p);
75
- h.append(g);
63
+ const n = this.createWordSpan(r, s);
64
+ for (const d of l(s)) {
65
+ const g = this.createCharSpan(d);
66
+ n.append(g);
76
67
  }
77
- t.append(h);
68
+ t.append(n);
78
69
  } else {
79
- const h = this.createWordSpan(i);
80
- h.append(document.createTextNode(s)), t.append(h);
70
+ const n = this.createWordSpan(r);
71
+ n.append(document.createTextNode(s)), t.append(n);
81
72
  }
82
- i < e.length - 1 && t.append(this.createSpaceSpan());
73
+ r < e.length - 1 && t.append(this.createSpaceSpan());
83
74
  });
84
75
  }
85
76
  appendChars(t, e) {
86
77
  for (const s of l(e)) {
87
- const i = this.createCharSpan(s);
88
- t.append(i);
78
+ const r = this.createCharSpan(s);
79
+ t.append(r);
89
80
  }
90
81
  }
91
82
  createWordSpan(t, e = "") {
92
83
  const s = document.createElement("span");
93
- 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;
84
+ 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;
94
85
  }
95
86
  createCharSpan(t) {
96
87
  const e = document.createElement("span");
97
- return e.textContent = t, this.opts.dataAttributes && e.setAttribute("data-char", t), t === r ? (e.classList.add(o.whitespace), this.opts.keepWhitespaceNodes || (e.textContent = r)) : (e.classList.add(o.char), this.opts.cssVariables && e.style.setProperty("--char-index", String(this.charIndex)), this.charIndex += 1), e;
88
+ return e.textContent = t, this.opts.dataAttributes && e.setAttribute("data-char", t), t === h ? (e.classList.add(a.whitespace), this.opts.keepWhitespaceNodes || (e.textContent = h)) : (e.classList.add(a.char), this.opts.cssVariables && e.style.setProperty("--char-index", String(this.charIndex)), this.charIndex += 1), e;
98
89
  }
99
90
  createSpaceSpan() {
100
91
  const t = document.createElement("span");
101
- return t.classList.add(o.whitespace), t.textContent = r, t;
92
+ return t.classList.add(a.whitespace), t.textContent = h, t;
93
+ }
94
+ measureHeight() {
95
+ return this.el ? Math.round(Math.max(this.el.scrollHeight, this.el.getBoundingClientRect().height)) : 0;
96
+ }
97
+ applyContainerHeightVar() {
98
+ if (!this.el) return;
99
+ const t = this.measureHeight();
100
+ this.el.style.setProperty(c, `${t}px`);
102
101
  }
103
102
  }
104
103
  export {
105
- o as CLASSNAMES,
106
- f as TextSlicer
104
+ a as CLASSNAMES,
105
+ y as TextSlicer
107
106
  };
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- (function(o,h){typeof exports=="object"&&typeof module<"u"?h(exports):typeof define=="function"&&define.amd?define(["exports"],h):h((o=typeof globalThis<"u"?globalThis:o||self).TextSlicer={})})(this,function(o){"use strict";const h={splitMode:"both",cssVariables:!1,dataAttributes:!1,keepWhitespaceNodes:!0,lockContainerHeight:!1},r=Object.freeze({word:"ts-word",char:"ts-char",whitespace:"ts-whitespace"}),a=" ",c=()=>typeof window<"u"&&typeof document<"u",d=t=>{const e=Intl.Segmenter;if(typeof e=="function"){const s=new e("en",{granularity:"grapheme"});return Array.from(s.segment(t),i=>i.segment)}return Array.from(t)},p=t=>t.split(a),l=t=>{const e={};return Object.keys(t).forEach(s=>{const i=t[s];i!==void 0&&(e[s]=i)}),e};o.CLASSNAMES=r,o.TextSlicer=class{el;original;opts;callbacks;charIndex;mounted;heightLocked=!1;lockedHeightPx=null;constructor(t={},e){const s=(i=t.container,c()&&i?typeof i=="string"?document.querySelector(i):i:null);var i;this.el=s,this.original=(n=>!!n&&typeof HTMLElement<"u"&&n instanceof HTMLElement)(s)?s.textContent?.toString()??"":"",this.opts={...h,...l(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.opts.lockContainerHeight&&this.freezeHeight(),this.split())}reinit(t,e){if(this.el){if(typeof t=="string"&&(this.original=t),e){const s=this.opts.lockContainerHeight;this.opts={...this.opts,...l(e)},!s&&this.opts.lockContainerHeight?this.freezeHeight():s&&!this.opts.lockContainerHeight&&this.unfreezeHeight()}this.opts.lockContainerHeight&&this.freezeHeight(),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,this.unfreezeHeight())}updateOptions(t){const e=this.opts.lockContainerHeight;this.opts={...this.opts,...l(t)},!e&&this.opts.lockContainerHeight?this.freezeHeight():e&&!this.opts.lockContainerHeight&&this.unfreezeHeight(),this.mounted&&this.split()}freezeHeight(){if(!this.el||!c())return;const t=this.el.getBoundingClientRect(),e=Math.max(0,Math.round(t.height));e&&(this.heightLocked&&this.lockedHeightPx===e||(this.el.style.height=`${e}px`,this.el.style.overflow="hidden",this.heightLocked=!0,this.lockedHeightPx=e))}unfreezeHeight(){this.el&&c()&&(this.heightLocked&&(this.el.style.height="",this.el.style.overflow=""),this.heightLocked=!1,this.lockedHeightPx=null)}appendWords(t,e){e.forEach((s,i)=>{if(this.opts.splitMode==="both"){const n=this.createWordSpan(i,s);for(const g of d(s)){const u=this.createCharSpan(g);n.append(u)}t.append(n)}else{const n=this.createWordSpan(i);n.append(document.createTextNode(s)),t.append(n)}i<e.length-1&&t.append(this.createSpaceSpan())})}appendChars(t,e){for(const s of d(e)){const i=this.createCharSpan(s);t.append(i)}}createWordSpan(t,e=""){const s=document.createElement("span");return s.classList.add(r.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(r.whitespace),this.opts.keepWhitespaceNodes||(e.textContent=a)):(e.classList.add(r.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(r.whitespace),t.textContent=a,t}},Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})});
1
+ (function(n,r){typeof exports=="object"&&typeof module<"u"?r(exports):typeof define=="function"&&define.amd?define(["exports"],r):r((n=typeof globalThis<"u"?globalThis:n||self).TextSlicer={})})(this,function(n){"use strict";const r={splitMode:"both",cssVariables:!1,dataAttributes:!1,keepWhitespaceNodes:!0,containerHeightVar:!1},o=Object.freeze({word:"ts-word",char:"ts-char",whitespace:"ts-whitespace"}),h=" ",l="--container-height",u=t=>typeof window>"u"||typeof document>"u"?null:t?typeof t=="string"?document.querySelector(t):t:null,p=t=>{const e=Intl.Segmenter;if(typeof e=="function"){const s=new e("en",{granularity:"grapheme"});return Array.from(s.segment(t),i=>i.segment)}return Array.from(t)},d=t=>t.split(h),c=t=>{const e={};return Object.keys(t).forEach(s=>{const i=t[s];i!==void 0&&(e[s]=i)}),e};n.CLASSNAMES=o,n.TextSlicer=class{el;original;opts;callbacks;charIndex;mounted;heightLocked;constructor(t={},e){const s=u(t.container);this.el=s,this.original=(i=>!!i&&typeof HTMLElement<"u"&&i instanceof HTMLElement)(s)?s.textContent?.toString()??"":"",this.opts={...r,...c(t)},this.callbacks=e,this.charIndex=0,this.mounted=!1,this.heightLocked=!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,...c(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=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.opts.containerHeightVar&&this.applyContainerHeightVar(),this.callbacks?.onAfterRender?.(this.metrics)}destroy(){this.el&&(this.clear(),this.unlockHeight(),this.opts.containerHeightVar&&this.el.style.removeProperty(l),this.mounted=!1)}updateOptions(t){this.opts={...this.opts,...c(t)},this.mounted&&this.split()}lockHeight(){if(!this.el)return;const t=this.measureHeight();t>0&&(this.el.style.height=`${t}px`,this.heightLocked=!0)}unlockHeight(){this.el&&(this.el.style.removeProperty("height"),this.heightLocked=!1)}appendWords(t,e){e.forEach((s,i)=>{if(this.opts.splitMode==="both"){const a=this.createWordSpan(i,s);for(const g of p(s)){const f=this.createCharSpan(g);a.append(f)}t.append(a)}else{const a=this.createWordSpan(i);a.append(document.createTextNode(s)),t.append(a)}i<e.length-1&&t.append(this.createSpaceSpan())})}appendChars(t,e){for(const s of p(e)){const i=this.createCharSpan(s);t.append(i)}}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===h?(e.classList.add(o.whitespace),this.opts.keepWhitespaceNodes||(e.textContent=h)):(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=h,t}measureHeight(){return this.el?Math.round(Math.max(this.el.scrollHeight,this.el.getBoundingClientRect().height)):0}applyContainerHeightVar(){if(!this.el)return;const t=this.measureHeight();this.el.style.setProperty(l,`${t}px`)}},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.5.0-dev.1",
3
+ "version": "1.5.0-dev.2",
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",