text-slicer 1.5.0-dev.2 → 1.5.0-dev.3

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,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`)}};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u={splitMode:"both",cssVariables:!1,dataAttributes:!1,keepWhitespaceNodes:!0,containerHeightVar:!1},n=Object.freeze({word:"ts-word",char:"ts-char",whitespace:"ts-whitespace"}),a=" ",o="--container-height",c="ts-measuring",m=t=>typeof window>"u"||typeof document>"u"?null:t?typeof t=="string"?document.querySelector(t):t:null,l=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),h=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=m(t.container);this.el=s,this.original=(i=>!!i&&typeof HTMLElement<"u"&&i instanceof HTMLElement)(s)?s.textContent?.toString()??"":"",this.opts={...u,...h(t)},this.callbacks=e,this.charIndex=0,this.mounted=!1,this.heightLocked=!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.opts.containerHeightVar&&this.applyContainerHeightVar(),this.callbacks?.onAfterRender?.(this.metrics)}destroy(){this.el&&(this.clear(),this.unlockHeight(),this.opts.containerHeightVar&&this.el.style.removeProperty(o),this.mounted=!1)}updateOptions(t){this.opts={...this.opts,...h(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 d of l(s)){const g=this.createCharSpan(d);r.append(g)}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 l(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(){if(!this.el)return 0;this.el.classList.add(c),this.el.offsetHeight;let t=this.el.clientHeight||this.el.offsetHeight||0;return t||(t=Math.round(this.el.getBoundingClientRect().height)),this.el.classList.remove(c),Math.max(0,Math.ceil(t))}applyContainerHeightVar(){if(!this.el)return;const t=this.measureHeight();this.el.style.setProperty(o,`${t}px`)}};
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
+ /** Добавлять CSS-переменную с высотой контейнера: --container-height */
8
9
  containerHeightVar?: boolean;
9
10
  }
10
11
  export interface TextSlicerMetrics {
@@ -36,13 +37,17 @@ export declare class TextSlicer {
36
37
  split(): void;
37
38
  destroy(): void;
38
39
  updateOptions(next: Partial<TextSlicerOptions>): void;
40
+ /** Зафиксировать текущую высоту контейнера */
39
41
  lockHeight(): void;
42
+ /** Снять фиксацию высоты контейнера */
40
43
  unlockHeight(): void;
41
44
  private appendWords;
42
45
  private appendChars;
43
46
  private createWordSpan;
44
47
  private createCharSpan;
45
48
  private createSpaceSpan;
49
+ /** Измеряем layout-высоту, игнорируя визуальные трансформы потомков (фиксы для iOS Safari) */
46
50
  private measureHeight;
51
+ /** Записать переменную --container-height */
47
52
  private applyContainerHeightVar;
48
53
  }
package/dist/index.es.js CHANGED
@@ -1,11 +1,11 @@
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) => {
1
+ const m = { 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", l = "ts-measuring", f = (i) => typeof window > "u" || typeof document > "u" ? null : i ? typeof i == "string" ? document.querySelector(i) : i : null, p = (i) => {
2
2
  const t = Intl.Segmenter;
3
3
  if (typeof t == "function") {
4
4
  const e = new t("en", { granularity: "grapheme" });
5
5
  return Array.from(e.segment(i), (s) => s.segment);
6
6
  }
7
7
  return Array.from(i);
8
- }, p = (i) => i.split(h), o = (i) => {
8
+ }, d = (i) => i.split(h), o = (i) => {
9
9
  const t = {};
10
10
  return Object.keys(i).forEach((e) => {
11
11
  const s = i[e];
@@ -21,12 +21,12 @@ class y {
21
21
  mounted;
22
22
  heightLocked;
23
23
  constructor(t = {}, e) {
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;
24
+ const s = f(t.container);
25
+ this.el = s, this.original = ((r) => !!r && typeof HTMLElement < "u" && r instanceof HTMLElement)(s) ? s.textContent?.toString() ?? "" : "", this.opts = { ...m, ...o(t) }, this.callbacks = e, this.charIndex = 0, this.mounted = !1, this.heightLocked = !1;
26
26
  }
27
27
  get metrics() {
28
28
  const t = this.original;
29
- return { wordTotal: t.length ? p(t).length : 0, charTotal: t.length, renderedAt: Date.now() };
29
+ return { wordTotal: t.length ? d(t).length : 0, charTotal: t.length, renderedAt: Date.now() };
30
30
  }
31
31
  init() {
32
32
  this.el && (this.mounted = !0, this.split());
@@ -40,7 +40,7 @@ class y {
40
40
  split() {
41
41
  if (!this.el) return;
42
42
  this.clear(), this.charIndex = 0;
43
- const t = this.original, e = document.createDocumentFragment(), s = p(t);
43
+ const t = this.original, e = document.createDocumentFragment(), s = d(t);
44
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);
45
45
  }
46
46
  destroy() {
@@ -61,9 +61,9 @@ class y {
61
61
  e.forEach((s, r) => {
62
62
  if (this.opts.splitMode === "both") {
63
63
  const n = this.createWordSpan(r, s);
64
- for (const d of l(s)) {
65
- const g = this.createCharSpan(d);
66
- n.append(g);
64
+ for (const g of p(s)) {
65
+ const u = this.createCharSpan(g);
66
+ n.append(u);
67
67
  }
68
68
  t.append(n);
69
69
  } else {
@@ -74,7 +74,7 @@ class y {
74
74
  });
75
75
  }
76
76
  appendChars(t, e) {
77
- for (const s of l(e)) {
77
+ for (const s of p(e)) {
78
78
  const r = this.createCharSpan(s);
79
79
  t.append(r);
80
80
  }
@@ -92,7 +92,10 @@ class y {
92
92
  return t.classList.add(a.whitespace), t.textContent = h, t;
93
93
  }
94
94
  measureHeight() {
95
- return this.el ? Math.round(Math.max(this.el.scrollHeight, this.el.getBoundingClientRect().height)) : 0;
95
+ if (!this.el) return 0;
96
+ this.el.classList.add(l), this.el.offsetHeight;
97
+ let t = this.el.clientHeight || this.el.offsetHeight || 0;
98
+ return t || (t = Math.round(this.el.getBoundingClientRect().height)), this.el.classList.remove(l), Math.max(0, Math.ceil(t));
96
99
  }
97
100
  applyContainerHeightVar() {
98
101
  if (!this.el) return;
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
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"})});
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",p="ts-measuring",g=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),i=>i.segment)}return Array.from(t)},u=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=g(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?u(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=u(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 f of d(s)){const m=this.createCharSpan(f);a.append(m)}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 d(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(){if(!this.el)return 0;this.el.classList.add(p),this.el.offsetHeight;let t=this.el.clientHeight||this.el.offsetHeight||0;return t||(t=Math.round(this.el.getBoundingClientRect().height)),this.el.classList.remove(p),Math.max(0,Math.ceil(t))}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.2",
3
+ "version": "1.5.0-dev.3",
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",