text-slicer 0.2.0 → 0.2.1
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/.eslintrc.json +7 -3
- package/README.md +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/index.module.js +6 -0
- package/dist/index.module.js.map +1 -1
- package/package.json +5 -3
- package/src/index.ts +8 -4
- package/tsconfig.json +6 -0
package/.eslintrc.json
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"env": {
|
|
3
3
|
"browser": true,
|
|
4
|
-
"
|
|
4
|
+
"es2022": true
|
|
5
5
|
},
|
|
6
6
|
"extends": [
|
|
7
|
-
"airbnb-base"
|
|
7
|
+
"airbnb-base",
|
|
8
|
+
"plugin:@typescript-eslint/recommended"
|
|
8
9
|
],
|
|
10
|
+
"parser": "@typescript-eslint/parser",
|
|
9
11
|
"parserOptions": {
|
|
10
12
|
"ecmaVersion": "latest",
|
|
11
|
-
"sourceType": "module"
|
|
13
|
+
"sourceType": "module",
|
|
14
|
+
"project": "./tsconfig.json"
|
|
12
15
|
},
|
|
16
|
+
"plugins": ["@typescript-eslint"],
|
|
13
17
|
"rules": {
|
|
14
18
|
"max-len": [
|
|
15
19
|
"off",
|
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>
|
|
13
|
+
<p align="center"><sup>850B 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.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAAA,qBAAM,UAAU;
|
|
1
|
+
{"mappings":"AAAA,qBAAM,UAAU;gBAaK,OAAO,GAAE;QAC1B,SAAS,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;QACjC,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;QACvC,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,cAAc,CAAC,EAAE,OAAO,CAAC;KACrB;IAqBC,KAAK,IAAI,IAAI;IA0Gb,IAAI,IAAI,IAAI;CAGpB;AAED,eAAe,UAAU,CAAC","sources":["src/src/index.ts","src/index.ts"],"sourcesContent":[null,"class TextSlicer {\n private readonly textElement: HTMLElement | null;\n\n private originalText: string;\n\n private readonly splitMode: 'words' | 'chars' | 'both';\n\n private readonly cssVariables: boolean;\n\n private readonly dataAttributes: boolean;\n\n private charIndexCounter: number;\n\n public constructor(options: {\n container?: HTMLElement | string;\n splitMode?: 'words' | 'chars' | 'both';\n cssVariables?: boolean;\n dataAttributes?: boolean;\n } = {}) {\n this.textElement = options.container instanceof HTMLElement\n ? options.container\n : document.querySelector(options.container || '.text-slicer');\n\n if (!this.textElement) {\n this.originalText = '';\n this.splitMode = 'both';\n this.cssVariables = false;\n this.dataAttributes = false;\n this.charIndexCounter = 0;\n return;\n }\n\n this.originalText = this.textElement.textContent?.trim() || '';\n this.splitMode = options.splitMode || 'both';\n this.cssVariables = options.cssVariables || false;\n this.dataAttributes = options.dataAttributes || false;\n this.charIndexCounter = 0;\n }\n\n public split(): void {\n if (!this.textElement) return;\n\n this.clear();\n this.charIndexCounter = 0;\n\n const fragment = document.createDocumentFragment();\n const words = this.originalText.split(' ');\n const charCount = this.originalText.length;\n\n if (this.splitMode === 'words' || this.splitMode === 'both') {\n this.splitWords(fragment, words);\n } else if (this.splitMode === 'chars') {\n this.splitChars(fragment);\n }\n\n this.textElement.appendChild(fragment);\n\n if (this.cssVariables) {\n this.textElement.style.setProperty('--word-total', words.length.toString());\n this.textElement.style.setProperty('--char-total', charCount.toString());\n }\n }\n\n private splitWords(fragment: DocumentFragment, words: string[]): void {\n words.forEach((word, wordIndex) => {\n if (this.splitMode === 'both') {\n const wordSpan = this.createWordSpan(wordIndex, word);\n\n word.split('').forEach((char) => {\n const charSpan = this.createCharSpan(char);\n wordSpan.append(charSpan);\n });\n\n fragment.append(wordSpan);\n } else {\n const wordSpan = this.createWordSpan(wordIndex);\n wordSpan.append(document.createTextNode(word));\n fragment.append(wordSpan);\n }\n\n if (wordIndex < words.length - 1) {\n fragment.append(TextSlicer.createSpaceSpan());\n }\n });\n }\n\n private splitChars(fragment: DocumentFragment): void {\n this.originalText.split('').forEach((char) => {\n const charSpan = this.createCharSpan(char);\n fragment.append(charSpan);\n });\n }\n\n private createWordSpan(index: number, word: string = ''): HTMLElement {\n const wordSpan = document.createElement('span');\n wordSpan.classList.add('word');\n\n if (this.dataAttributes) {\n wordSpan.setAttribute('data-word', word);\n }\n\n if (this.cssVariables) {\n wordSpan.style.setProperty('--word-index', index.toString());\n }\n\n return wordSpan;\n }\n\n private createCharSpan(char: string): HTMLElement {\n const charSpan = document.createElement('span');\n charSpan.textContent = char;\n\n if (this.dataAttributes) {\n charSpan.setAttribute('data-char', char);\n }\n\n if (char === ' ') {\n charSpan.classList.add('whitespace');\n } else {\n charSpan.classList.add('char');\n\n if (this.cssVariables) {\n charSpan.style.setProperty('--char-index', this.charIndexCounter.toString());\n }\n\n this.charIndexCounter += 1;\n }\n\n return charSpan;\n }\n\n private static createSpaceSpan(): HTMLElement {\n const spaceSpan = document.createElement('span');\n spaceSpan.classList.add('whitespace');\n spaceSpan.textContent = ' ';\n\n return spaceSpan;\n }\n\n private clear(): void {\n if (this.textElement) {\n this.textElement.innerHTML = '';\n }\n }\n\n public init(): void {\n this.split();\n }\n}\n\nexport default TextSlicer;\n"],"names":[],"version":3,"file":"index.d.ts.map"}
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,12 @@ $parcel$defineInteropFlag(module.exports);
|
|
|
11
11
|
|
|
12
12
|
$parcel$export(module.exports, "default", function () { return $a196c1ed25598f0e$export$2e2bcd8739ae039; });
|
|
13
13
|
class $a196c1ed25598f0e$var$TextSlicer {
|
|
14
|
+
textElement;
|
|
15
|
+
originalText;
|
|
16
|
+
splitMode;
|
|
17
|
+
cssVariables;
|
|
18
|
+
dataAttributes;
|
|
19
|
+
charIndexCounter;
|
|
14
20
|
constructor(options = {}){
|
|
15
21
|
this.textElement = options.container instanceof HTMLElement ? options.container : document.querySelector(options.container || ".text-slicer");
|
|
16
22
|
if (!this.textElement) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;;;;;AAAA,MAAM;
|
|
1
|
+
{"mappings":"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","sources":["src/index.ts"],"sourcesContent":["class TextSlicer {\n private readonly textElement: HTMLElement | null;\n\n private originalText: string;\n\n private readonly splitMode: 'words' | 'chars' | 'both';\n\n private readonly cssVariables: boolean;\n\n private readonly dataAttributes: boolean;\n\n private charIndexCounter: number;\n\n public constructor(options: {\n container?: HTMLElement | string;\n splitMode?: 'words' | 'chars' | 'both';\n cssVariables?: boolean;\n dataAttributes?: boolean;\n } = {}) {\n this.textElement = options.container instanceof HTMLElement\n ? options.container\n : document.querySelector(options.container || '.text-slicer');\n\n if (!this.textElement) {\n this.originalText = '';\n this.splitMode = 'both';\n this.cssVariables = false;\n this.dataAttributes = false;\n this.charIndexCounter = 0;\n return;\n }\n\n this.originalText = this.textElement.textContent?.trim() || '';\n this.splitMode = options.splitMode || 'both';\n this.cssVariables = options.cssVariables || false;\n this.dataAttributes = options.dataAttributes || false;\n this.charIndexCounter = 0;\n }\n\n public split(): void {\n if (!this.textElement) return;\n\n this.clear();\n this.charIndexCounter = 0;\n\n const fragment = document.createDocumentFragment();\n const words = this.originalText.split(' ');\n const charCount = this.originalText.length;\n\n if (this.splitMode === 'words' || this.splitMode === 'both') {\n this.splitWords(fragment, words);\n } else if (this.splitMode === 'chars') {\n this.splitChars(fragment);\n }\n\n this.textElement.appendChild(fragment);\n\n if (this.cssVariables) {\n this.textElement.style.setProperty('--word-total', words.length.toString());\n this.textElement.style.setProperty('--char-total', charCount.toString());\n }\n }\n\n private splitWords(fragment: DocumentFragment, words: string[]): void {\n words.forEach((word, wordIndex) => {\n if (this.splitMode === 'both') {\n const wordSpan = this.createWordSpan(wordIndex, word);\n\n word.split('').forEach((char) => {\n const charSpan = this.createCharSpan(char);\n wordSpan.append(charSpan);\n });\n\n fragment.append(wordSpan);\n } else {\n const wordSpan = this.createWordSpan(wordIndex);\n wordSpan.append(document.createTextNode(word));\n fragment.append(wordSpan);\n }\n\n if (wordIndex < words.length - 1) {\n fragment.append(TextSlicer.createSpaceSpan());\n }\n });\n }\n\n private splitChars(fragment: DocumentFragment): void {\n this.originalText.split('').forEach((char) => {\n const charSpan = this.createCharSpan(char);\n fragment.append(charSpan);\n });\n }\n\n private createWordSpan(index: number, word: string = ''): HTMLElement {\n const wordSpan = document.createElement('span');\n wordSpan.classList.add('word');\n\n if (this.dataAttributes) {\n wordSpan.setAttribute('data-word', word);\n }\n\n if (this.cssVariables) {\n wordSpan.style.setProperty('--word-index', index.toString());\n }\n\n return wordSpan;\n }\n\n private createCharSpan(char: string): HTMLElement {\n const charSpan = document.createElement('span');\n charSpan.textContent = char;\n\n if (this.dataAttributes) {\n charSpan.setAttribute('data-char', char);\n }\n\n if (char === ' ') {\n charSpan.classList.add('whitespace');\n } else {\n charSpan.classList.add('char');\n\n if (this.cssVariables) {\n charSpan.style.setProperty('--char-index', this.charIndexCounter.toString());\n }\n\n this.charIndexCounter += 1;\n }\n\n return charSpan;\n }\n\n private static createSpaceSpan(): HTMLElement {\n const spaceSpan = document.createElement('span');\n spaceSpan.classList.add('whitespace');\n spaceSpan.textContent = ' ';\n\n return spaceSpan;\n }\n\n private clear(): void {\n if (this.textElement) {\n this.textElement.innerHTML = '';\n }\n }\n\n public init(): void {\n this.split();\n }\n}\n\nexport default TextSlicer;\n"],"names":[],"version":3,"file":"index.js.map"}
|
package/dist/index.module.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
class $643fcf18b2d2e76f$var$TextSlicer {
|
|
2
|
+
textElement;
|
|
3
|
+
originalText;
|
|
4
|
+
splitMode;
|
|
5
|
+
cssVariables;
|
|
6
|
+
dataAttributes;
|
|
7
|
+
charIndexCounter;
|
|
2
8
|
constructor(options = {}){
|
|
3
9
|
this.textElement = options.container instanceof HTMLElement ? options.container : document.querySelector(options.container || ".text-slicer");
|
|
4
10
|
if (!this.textElement) {
|
package/dist/index.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAAA,MAAM;
|
|
1
|
+
{"mappings":"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","sources":["src/index.ts"],"sourcesContent":["class TextSlicer {\n private readonly textElement: HTMLElement | null;\n\n private originalText: string;\n\n private readonly splitMode: 'words' | 'chars' | 'both';\n\n private readonly cssVariables: boolean;\n\n private readonly dataAttributes: boolean;\n\n private charIndexCounter: number;\n\n public constructor(options: {\n container?: HTMLElement | string;\n splitMode?: 'words' | 'chars' | 'both';\n cssVariables?: boolean;\n dataAttributes?: boolean;\n } = {}) {\n this.textElement = options.container instanceof HTMLElement\n ? options.container\n : document.querySelector(options.container || '.text-slicer');\n\n if (!this.textElement) {\n this.originalText = '';\n this.splitMode = 'both';\n this.cssVariables = false;\n this.dataAttributes = false;\n this.charIndexCounter = 0;\n return;\n }\n\n this.originalText = this.textElement.textContent?.trim() || '';\n this.splitMode = options.splitMode || 'both';\n this.cssVariables = options.cssVariables || false;\n this.dataAttributes = options.dataAttributes || false;\n this.charIndexCounter = 0;\n }\n\n public split(): void {\n if (!this.textElement) return;\n\n this.clear();\n this.charIndexCounter = 0;\n\n const fragment = document.createDocumentFragment();\n const words = this.originalText.split(' ');\n const charCount = this.originalText.length;\n\n if (this.splitMode === 'words' || this.splitMode === 'both') {\n this.splitWords(fragment, words);\n } else if (this.splitMode === 'chars') {\n this.splitChars(fragment);\n }\n\n this.textElement.appendChild(fragment);\n\n if (this.cssVariables) {\n this.textElement.style.setProperty('--word-total', words.length.toString());\n this.textElement.style.setProperty('--char-total', charCount.toString());\n }\n }\n\n private splitWords(fragment: DocumentFragment, words: string[]): void {\n words.forEach((word, wordIndex) => {\n if (this.splitMode === 'both') {\n const wordSpan = this.createWordSpan(wordIndex, word);\n\n word.split('').forEach((char) => {\n const charSpan = this.createCharSpan(char);\n wordSpan.append(charSpan);\n });\n\n fragment.append(wordSpan);\n } else {\n const wordSpan = this.createWordSpan(wordIndex);\n wordSpan.append(document.createTextNode(word));\n fragment.append(wordSpan);\n }\n\n if (wordIndex < words.length - 1) {\n fragment.append(TextSlicer.createSpaceSpan());\n }\n });\n }\n\n private splitChars(fragment: DocumentFragment): void {\n this.originalText.split('').forEach((char) => {\n const charSpan = this.createCharSpan(char);\n fragment.append(charSpan);\n });\n }\n\n private createWordSpan(index: number, word: string = ''): HTMLElement {\n const wordSpan = document.createElement('span');\n wordSpan.classList.add('word');\n\n if (this.dataAttributes) {\n wordSpan.setAttribute('data-word', word);\n }\n\n if (this.cssVariables) {\n wordSpan.style.setProperty('--word-index', index.toString());\n }\n\n return wordSpan;\n }\n\n private createCharSpan(char: string): HTMLElement {\n const charSpan = document.createElement('span');\n charSpan.textContent = char;\n\n if (this.dataAttributes) {\n charSpan.setAttribute('data-char', char);\n }\n\n if (char === ' ') {\n charSpan.classList.add('whitespace');\n } else {\n charSpan.classList.add('char');\n\n if (this.cssVariables) {\n charSpan.style.setProperty('--char-index', this.charIndexCounter.toString());\n }\n\n this.charIndexCounter += 1;\n }\n\n return charSpan;\n }\n\n private static createSpaceSpan(): HTMLElement {\n const spaceSpan = document.createElement('span');\n spaceSpan.classList.add('whitespace');\n spaceSpan.textContent = ' ';\n\n return spaceSpan;\n }\n\n private clear(): void {\n if (this.textElement) {\n this.textElement.innerHTML = '';\n }\n }\n\n public init(): void {\n this.split();\n }\n}\n\nexport default TextSlicer;\n"],"names":[],"version":3,"file":"index.module.js.map"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "text-slicer",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
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",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"scripts": {
|
|
17
17
|
"clean": "rm -rf dist .parcel-cache",
|
|
18
18
|
"build": "yarn clean && parcel build",
|
|
19
|
-
"lint:js": "eslint
|
|
19
|
+
"lint:js": "eslint **/*.{ts,js}",
|
|
20
20
|
"lintfix": "yarn lint:js --fix"
|
|
21
21
|
},
|
|
22
22
|
"browserslist": "> 0.5%, last 2 versions, not dead",
|
|
@@ -26,10 +26,12 @@
|
|
|
26
26
|
"types": "dist/index.d.ts",
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@parcel/packager-ts": "2.12.0",
|
|
29
|
-
"@parcel/transformer-sass": "2.12.0",
|
|
30
29
|
"@parcel/transformer-typescript-types": "2.12.0",
|
|
30
|
+
"@typescript-eslint/eslint-plugin": "^7.11.0",
|
|
31
|
+
"@typescript-eslint/parser": "^7.11.0",
|
|
31
32
|
"eslint": "^7.32.0 || ^8.57.0",
|
|
32
33
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
34
|
+
"eslint-plugin-import": "^2.29.1",
|
|
33
35
|
"parcel": "^2.12.0",
|
|
34
36
|
"typescript": "^5.4.5"
|
|
35
37
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
class TextSlicer {
|
|
2
2
|
private readonly textElement: HTMLElement | null;
|
|
3
|
+
|
|
3
4
|
private originalText: string;
|
|
5
|
+
|
|
4
6
|
private readonly splitMode: 'words' | 'chars' | 'both';
|
|
7
|
+
|
|
5
8
|
private readonly cssVariables: boolean;
|
|
9
|
+
|
|
6
10
|
private readonly dataAttributes: boolean;
|
|
11
|
+
|
|
7
12
|
private charIndexCounter: number;
|
|
8
13
|
|
|
9
14
|
public constructor(options: {
|
|
@@ -12,10 +17,9 @@ class TextSlicer {
|
|
|
12
17
|
cssVariables?: boolean;
|
|
13
18
|
dataAttributes?: boolean;
|
|
14
19
|
} = {}) {
|
|
15
|
-
this.textElement =
|
|
16
|
-
options.container
|
|
17
|
-
|
|
18
|
-
: document.querySelector(options.container || '.text-slicer');
|
|
20
|
+
this.textElement = options.container instanceof HTMLElement
|
|
21
|
+
? options.container
|
|
22
|
+
: document.querySelector(options.container || '.text-slicer');
|
|
19
23
|
|
|
20
24
|
if (!this.textElement) {
|
|
21
25
|
this.originalText = '';
|