fetta 1.5.0 → 1.5.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/README.md +108 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Fetta
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Text splitting that keeps kerning intact.
|
|
4
4
|
|
|
5
5
|
Split text into characters, words, and lines while preserving the original typography. Works with any animation library.
|
|
6
6
|
|
|
@@ -8,17 +8,17 @@ Split text into characters, words, and lines while preserving the original typog
|
|
|
8
8
|
|
|
9
9
|
- **Kerning Compensation** — Maintains original character spacing when splitting by chars
|
|
10
10
|
- **Nested Elements** — Preserves `<a>`, `<em>`, `<strong>` and other inline elements with all attributes
|
|
11
|
-
- **Line Detection** —
|
|
11
|
+
- **Line Detection** — Groups words into rendered lines
|
|
12
12
|
- **Dash Handling** — Allows text to wrap naturally after em-dashes, en-dashes, hyphens, and slashes
|
|
13
13
|
- **Auto Re-split** — Re-splits on container resize
|
|
14
|
-
- **Auto
|
|
14
|
+
- **Auto Revert** — Restores original HTML after animations
|
|
15
15
|
- **Masking** — Wrap elements in clip containers for reveal animations
|
|
16
16
|
- **Emoji Support** — Properly handles compound emojis and complex Unicode characters
|
|
17
17
|
- **Accessible** — Automatic screen reader support, even when splitting text with nested links or emphasis
|
|
18
18
|
- **TypeScript** — Full type definitions included
|
|
19
19
|
- **React Component** — Declarative wrapper for React projects
|
|
20
|
-
- **
|
|
21
|
-
- **Library Agnostic** — Works with Motion, GSAP, or any animation library
|
|
20
|
+
- **Viewport Triggers** — Scroll enter/leave callbacks with configurable thresholds in React
|
|
21
|
+
- **Library Agnostic** — Works with Motion, GSAP, CSS, or any animation library
|
|
22
22
|
|
|
23
23
|
## Installation
|
|
24
24
|
|
|
@@ -27,9 +27,10 @@ npm install fetta
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
**Bundle size** (minified + brotli)
|
|
30
|
-
- `fetta`: ~
|
|
31
|
-
- `fetta/react`: ~
|
|
32
|
-
- `fetta/motion`: ~
|
|
30
|
+
- `fetta`: ~7.17 kB
|
|
31
|
+
- `fetta/react`: ~8.66 kB
|
|
32
|
+
- `fetta/motion`: ~15.93 kB
|
|
33
|
+
- `fetta/helpers`: ~765 B
|
|
33
34
|
|
|
34
35
|
## Quick Start
|
|
35
36
|
|
|
@@ -140,7 +141,7 @@ layers.cleanup(); // removes clones/wrappers, keeps split DOM
|
|
|
140
141
|
| `cloneOffset.axis` | `"x" \| "y"` | `"y"` | Axis used for initial clone offset |
|
|
141
142
|
| `cloneOffset.direction` | `"start" \| "end"` | `"start"` | Offset direction (`start` => negative) |
|
|
142
143
|
| `cloneOffset.distance` | `string` | `"100%"` | Offset distance |
|
|
143
|
-
| `trackClassName` / `cloneClassName` | `string \| (ctx) => string` | — | Class names (static or per-item) |
|
|
144
|
+
| `trackClassName` / `cloneClassName` | `string \| (ctx) => string \| undefined` | — | Class names (static or per-item) |
|
|
144
145
|
| `trackStyle` / `cloneStyle` | `object \| (ctx) => object` | — | Inline styles (static or per-item) |
|
|
145
146
|
|
|
146
147
|
For reveal/swap effects, use matching `mask` in `splitText` (`"chars"`, `"words"`, or `"lines"`).
|
|
@@ -404,6 +405,104 @@ splitText(element, { type: 'chars', propIndex: true });
|
|
|
404
405
|
</SplitText>
|
|
405
406
|
```
|
|
406
407
|
|
|
408
|
+
### Motion (`fetta/motion`)
|
|
409
|
+
|
|
410
|
+
#### Basic Variants
|
|
411
|
+
|
|
412
|
+
```tsx
|
|
413
|
+
import { SplitText } from 'fetta/motion';
|
|
414
|
+
import { stagger } from 'motion';
|
|
415
|
+
|
|
416
|
+
<SplitText
|
|
417
|
+
variants={{
|
|
418
|
+
hidden: { opacity: 0, y: 20, filter: 'blur(6px)' },
|
|
419
|
+
visible: { opacity: 1, y: 0, filter: 'blur(0px)' },
|
|
420
|
+
}}
|
|
421
|
+
initial="hidden"
|
|
422
|
+
animate="visible"
|
|
423
|
+
transition={{ duration: 0.6, delay: stagger(0.04) }}
|
|
424
|
+
options={{ type: 'words' }}
|
|
425
|
+
>
|
|
426
|
+
<h1>Hello World</h1>
|
|
427
|
+
</SplitText>
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
#### Line-Aware Stagger
|
|
431
|
+
|
|
432
|
+
```tsx
|
|
433
|
+
import { SplitText } from 'fetta/motion';
|
|
434
|
+
import { stagger } from 'motion';
|
|
435
|
+
|
|
436
|
+
<SplitText
|
|
437
|
+
delayScope="local"
|
|
438
|
+
variants={{
|
|
439
|
+
hidden: { chars: { opacity: 0 } },
|
|
440
|
+
visible: {
|
|
441
|
+
chars: ({ lineIndex }) => ({
|
|
442
|
+
opacity: 1,
|
|
443
|
+
transition: {
|
|
444
|
+
duration: 0.3,
|
|
445
|
+
delay: stagger(0.015, {
|
|
446
|
+
startDelay: lineIndex * 0.2,
|
|
447
|
+
from: lineIndex % 2 === 0 ? "first" : "last",
|
|
448
|
+
}),
|
|
449
|
+
},
|
|
450
|
+
}),
|
|
451
|
+
},
|
|
452
|
+
}}
|
|
453
|
+
initial="hidden"
|
|
454
|
+
animate="visible"
|
|
455
|
+
options={{ type: "chars,lines" }}
|
|
456
|
+
>
|
|
457
|
+
<p>Line-aware per-character animation</p>
|
|
458
|
+
</SplitText>
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
#### Scroll-Driven Reveal
|
|
462
|
+
|
|
463
|
+
```tsx
|
|
464
|
+
import { SplitText } from 'fetta/motion';
|
|
465
|
+
|
|
466
|
+
<SplitText
|
|
467
|
+
initialStyles={{ chars: { opacity: 0.2 } }}
|
|
468
|
+
whileScroll={{
|
|
469
|
+
chars: ({ globalIndex }) => ({
|
|
470
|
+
opacity: 1,
|
|
471
|
+
transition: {
|
|
472
|
+
duration: 0.3,
|
|
473
|
+
at: globalIndex * 0.025,
|
|
474
|
+
ease: "linear",
|
|
475
|
+
},
|
|
476
|
+
}),
|
|
477
|
+
}}
|
|
478
|
+
scroll={{ offset: ["start 90%", "start 10%"] }}
|
|
479
|
+
options={{ type: "chars" }}
|
|
480
|
+
>
|
|
481
|
+
<p>Characters fade in with scroll progress</p>
|
|
482
|
+
</SplitText>
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
#### Hover Interaction
|
|
486
|
+
|
|
487
|
+
```tsx
|
|
488
|
+
import { SplitText } from 'fetta/motion';
|
|
489
|
+
import { stagger } from 'motion';
|
|
490
|
+
|
|
491
|
+
<SplitText
|
|
492
|
+
variants={{
|
|
493
|
+
rest: { chars: { opacity: 0.85, y: 0 } },
|
|
494
|
+
hover: { chars: { opacity: 1, y: -6 } },
|
|
495
|
+
}}
|
|
496
|
+
initial="rest"
|
|
497
|
+
animate="rest"
|
|
498
|
+
whileHover="hover"
|
|
499
|
+
transition={{ duration: 0.25, delay: stagger(0.01) }}
|
|
500
|
+
options={{ type: 'chars' }}
|
|
501
|
+
>
|
|
502
|
+
<p>Hover this text</p>
|
|
503
|
+
</SplitText>
|
|
504
|
+
```
|
|
505
|
+
|
|
407
506
|
## CSS Classes
|
|
408
507
|
|
|
409
508
|
Default classes applied to split elements:
|