text-slicer 1.5.0-dev.5 → 1.5.0
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 +64 -134
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,168 +8,98 @@
|
|
|
8
8
|
|
|
9
9
|
</div>
|
|
10
10
|
|
|
11
|
-
<p align="center">
|
|
11
|
+
<p align="center">TextSlicer splits text within an HTML element into words and/or characters, wrapping each in individual spans. It provides flexible options, CSS variable integration, lifecycle management, and callbacks for post-render handling.</p>
|
|
12
|
+
<p align="center"><sup>1.5kB gzipped</sup></p>
|
|
12
13
|
<p align="center"><a href="https://codepen.io/ux-ui/full/vYMoGoG">Demo</a></p>
|
|
13
14
|
<br>
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
➠ **Install**
|
|
16
17
|
|
|
17
|
-
```
|
|
18
|
+
```console
|
|
18
19
|
yarn add text-slicer
|
|
19
|
-
# or
|
|
20
|
-
npm i text-slicer
|
|
21
20
|
```
|
|
22
21
|
<br>
|
|
23
22
|
|
|
24
|
-
|
|
23
|
+
➠ **Import**
|
|
25
24
|
|
|
26
|
-
```
|
|
25
|
+
```javascript
|
|
27
26
|
import { TextSlicer } from 'text-slicer';
|
|
28
|
-
|
|
29
|
-
const slicer = new TextSlicer({ container: '.text-slicer' });
|
|
30
|
-
|
|
31
|
-
slicer.init();
|
|
32
27
|
```
|
|
28
|
+
<br>
|
|
33
29
|
|
|
34
|
-
|
|
30
|
+
➠ **Usage**
|
|
35
31
|
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
const slicer = new TextSlicer({ container: el });
|
|
32
|
+
```javascript
|
|
33
|
+
const textSlicer = new TextSlicer();
|
|
39
34
|
|
|
40
|
-
|
|
41
|
-
});
|
|
35
|
+
textSlicer.init();
|
|
42
36
|
```
|
|
43
|
-
<br>
|
|
44
37
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
/** Freeze measured word widths to avoid reflow jitter on responsive layouts. Default: false */
|
|
60
|
-
freezeWordWidths?: boolean;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface TextSlicerMetrics {
|
|
64
|
-
wordTotal: number;
|
|
65
|
-
charTotal: number;
|
|
66
|
-
renderedAt: number;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface TextSlicerCallbacks {
|
|
70
|
-
onAfterRender?: (metrics: TextSlicerMetrics) => void;
|
|
71
|
-
}
|
|
38
|
+
<sub>Initialization with specified parameters</sub>
|
|
39
|
+
```javascript
|
|
40
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
41
|
+
const textSlicer = new TextSlicer({
|
|
42
|
+
container: '.text-slicer',
|
|
43
|
+
splitMode: 'both',
|
|
44
|
+
cssVariables: true,
|
|
45
|
+
dataAttributes: true,
|
|
46
|
+
}, {
|
|
47
|
+
onAfterRender: (metrics) => console.log(metrics)
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
textSlicer.init();
|
|
51
|
+
});
|
|
72
52
|
```
|
|
73
53
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
54
|
+
<sub>How to apply the TextSlicer class to all elements on a page</sub>
|
|
55
|
+
```javascript
|
|
56
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
57
|
+
document.querySelectorAll('.text-slicer').forEach((element) => {
|
|
58
|
+
const textSlicer = new TextSlicer({ container: element });
|
|
78
59
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
CLASSNAMES.whitespace // 'ts-whitespace'
|
|
83
|
-
|
|
84
|
-
// CSS variables placed on container and items (when cssVariables: true)
|
|
85
|
-
--word-total
|
|
86
|
-
--char-total
|
|
87
|
-
--word-index
|
|
88
|
-
--char-index
|
|
60
|
+
textSlicer.init();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
89
63
|
```
|
|
64
|
+
<br>
|
|
90
65
|
|
|
91
|
-
|
|
66
|
+
➠ **Options**
|
|
92
67
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
68
|
+
| Option | Type | Default | Description |
|
|
69
|
+
|:--------------------:|:-----------------------:|:------------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
70
|
+
| `container` | `HTMLElement \| string` | `undefined` | The target element or selector for text splitting. |
|
|
71
|
+
| `splitMode` | `'words' \| 'chars' \| 'both'` | `both` | Defines splitting mode: by words, characters, or both. |
|
|
72
|
+
| `cssVariables` | `boolean` | `false` | Enables CSS variables like `--word-index` and `--char-index` for each span. |
|
|
73
|
+
| `dataAttributes` | `boolean` | `false` | Adds `data-word` and `data-char` attributes for additional styling or scripting. |
|
|
74
|
+
| `keepWhitespaceNodes`| `boolean` | `true` | If `false`, whitespace nodes will be ignored when splitting characters. |
|
|
75
|
+
| `containerHeightVar` | `boolean` | `false` | If `true`, sets a dynamic CSS variable `--container-height` that updates on resize. |
|
|
96
76
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
- `init(): void` – Perform initial split.
|
|
100
|
-
- `reinit(newText?: string, nextOpts?: Partial<TextSlicerOptions>): void` – Update text and/or options and re-split.
|
|
101
|
-
- `updateOptions(next: Partial<TextSlicerOptions>): void` – Merge options and re-split (if mounted).
|
|
102
|
-
- `clear(): void` – Remove generated nodes and unfreeze widths.
|
|
103
|
-
- `split(): void` – (Re)build DOM (called internally by `init`/`reinit`/`updateOptions`).
|
|
104
|
-
- `destroy(): void` – Detach observers, clear DOM, and mark unmounted.
|
|
105
|
-
- `get metrics(): TextSlicerMetrics` – Read-only metrics collected on the last render.
|
|
106
|
-
|
|
107
|
-
### Options in detail
|
|
108
|
-
|
|
109
|
-
- `splitMode` – `'words' | 'chars' | 'both'`. When `'both'`, each word is wrapped and further split into graphemes.
|
|
110
|
-
- `cssVariables` – When `true`, indexes and totals are exposed as CSS custom properties for stagger animations.
|
|
111
|
-
- `dataAttributes` – When `true`, adds `data-word` / `data-char` attributes.
|
|
112
|
-
- `keepWhitespaceNodes` – When `true`, explicit whitespace nodes are inserted between words (class `ts-whitespace`).
|
|
113
|
-
- `freezeWordWidths` – When `true`, measured widths of `.ts-word` nodes are frozen (after fonts load + next frame) and
|
|
114
|
-
kept in sync on container/window resize to prevent layout jitter during animations.
|
|
115
|
-
|
|
116
|
-
### i18n-friendly grapheme splitting
|
|
117
|
-
|
|
118
|
-
Characters are split using `Intl.Segmenter` (when available) with `{ granularity: 'grapheme' }`, so compound emoji and
|
|
119
|
-
grapheme clusters render as expected. Environments without `Intl.Segmenter` gracefully fall back to `Array.from(text)`.
|
|
120
|
-
|
|
121
|
-
### Callbacks
|
|
122
|
-
|
|
123
|
-
```ts
|
|
124
|
-
const slicer = new TextSlicer(
|
|
125
|
-
{ container: '.title', cssVariables: true },
|
|
126
|
-
{
|
|
127
|
-
onAfterRender(metrics) {
|
|
128
|
-
// e.g. attach animation based on metrics.charTotal
|
|
129
|
-
console.log(metrics);
|
|
130
|
-
},
|
|
131
|
-
}
|
|
132
|
-
);
|
|
133
|
-
slicer.init();
|
|
134
|
-
```
|
|
77
|
+
<br>
|
|
135
78
|
|
|
136
|
-
|
|
79
|
+
➠ **Callbacks**
|
|
137
80
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
splitMode: 'both',
|
|
142
|
-
freezeWordWidths: true,
|
|
143
|
-
});
|
|
144
|
-
slicer.init();
|
|
145
|
-
```
|
|
81
|
+
| Callback | Arguments | Description |
|
|
82
|
+
|-----------------|-----------------------|---------------------------------------------------------------------------------------------------------|
|
|
83
|
+
| `onAfterRender` | `TextSlicerMetrics` | Invoked after rendering. Provides `wordTotal`, `charTotal`, and `renderedAt` timestamp. |
|
|
146
84
|
|
|
147
|
-
When enabled, widths are measured after fonts are ready and then frozen (`flex: 0 0 auto; width: <px>`). A `ResizeObserver`
|
|
148
|
-
watches the container and a `resize` handler remeasures on viewport changes.
|
|
149
85
|
<br>
|
|
150
86
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
/* stagger via CSS variables */
|
|
167
|
-
.ts-char {
|
|
168
|
-
transition-delay: calc(var(--char-index, 0) * 10ms);
|
|
169
|
-
}
|
|
170
|
-
```
|
|
87
|
+
➠ **API Methods**
|
|
88
|
+
|
|
89
|
+
| Method | Description |
|
|
90
|
+
|-------------------|--------------------------------------------------------------------------------------------------|
|
|
91
|
+
| `init()` | Initializes and renders text splitting. |
|
|
92
|
+
| `reinit(newText?, options?)` | Re-initializes with optional new text and updated options. |
|
|
93
|
+
| `clear()` | Clears all content inside the container element. |
|
|
94
|
+
| `split()` | Manually triggers splitting and rendering. |
|
|
95
|
+
| `destroy()` | Cleans up instance, observers, and styles. |
|
|
96
|
+
| `updateOptions()` | Updates options at runtime and re-renders if mounted. |
|
|
97
|
+
| `lockHeight()` | Locks container height to its measured value. |
|
|
98
|
+
| `unlockHeight()` | Unlocks container height. |
|
|
99
|
+
| `metrics` (getter)| Returns current metrics: `wordTotal`, `charTotal`, and `renderedAt`. |
|
|
100
|
+
|
|
171
101
|
<br>
|
|
172
102
|
|
|
173
|
-
|
|
103
|
+
➠ **License**
|
|
174
104
|
|
|
175
|
-
MIT
|
|
105
|
+
text-slicer is released under MIT license
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "text-slicer",
|
|
3
|
-
"version": "1.5.0
|
|
3
|
+
"version": "1.5.0",
|
|
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",
|