@mks2508/waapi-animation-primitives 0.1.0 → 0.3.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 +296 -72
- package/dist/index.cjs +49 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +207 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.cts +1692 -401
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +1692 -401
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -63
- package/dist/index.js.map +1 -1
- package/package.json +10 -7
package/README.md
CHANGED
|
@@ -1,18 +1,53 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# WAAPI Animation Primitives
|
|
2
4
|
|
|
3
|
-
React animation components using
|
|
5
|
+
**Lightweight, performant React animation components using Web Animations API**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@mks2508/waapi-animation-primitives)
|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
9
|
+
[](https://www.typescriptlang.org/)
|
|
10
|
+
[](https://react.dev/)
|
|
11
|
+
[](https://bundlephobia.com/package/@mks2508/waapi-animation-primitives)
|
|
12
|
+
|
|
13
|
+
[Features](#-features) • [Installation](#-installation) • [Components](#-components) • [Primitives](#-primitives) • [CSS System](#-css-system)
|
|
14
|
+
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- **Zero Dependencies** - Only React as a peer dependency
|
|
22
|
+
- **WAAPI Powered** - Native 60fps animations using Web Animations API
|
|
23
|
+
- **Fully Typed** - Built with TypeScript from the ground up
|
|
24
|
+
- **Accessible** - Respects `prefers-reduced-motion` automatically
|
|
25
|
+
- **Tree-Shakeable** - Debug code removed in production builds
|
|
26
|
+
- **CSS Variables** - Runtime customization without recompilation
|
|
27
|
+
- **Locale-Aware** - `Intl.ListFormat` support for localized separators
|
|
28
|
+
|
|
29
|
+
---
|
|
4
30
|
|
|
5
31
|
## Installation
|
|
6
32
|
|
|
7
33
|
```bash
|
|
34
|
+
# npm
|
|
8
35
|
npm install @mks2508/waapi-animation-primitives
|
|
36
|
+
|
|
37
|
+
# bun
|
|
38
|
+
bun add @mks2508/waapi-animation-primitives
|
|
39
|
+
|
|
40
|
+
# yarn
|
|
41
|
+
yarn add @mks2508/waapi-animation-primitives
|
|
9
42
|
```
|
|
10
43
|
|
|
44
|
+
---
|
|
45
|
+
|
|
11
46
|
## Components
|
|
12
47
|
|
|
13
48
|
### SlidingNumber
|
|
14
49
|
|
|
15
|
-
|
|
50
|
+
Animated number transitions with format preservation.
|
|
16
51
|
|
|
17
52
|
```tsx
|
|
18
53
|
import { SlidingNumber } from '@mks2508/waapi-animation-primitives';
|
|
@@ -24,14 +59,20 @@ import { SlidingNumber } from '@mks2508/waapi-animation-primitives';
|
|
|
24
59
|
/>
|
|
25
60
|
```
|
|
26
61
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
62
|
+
| Prop | Type | Default | Description |
|
|
63
|
+
|------|------|---------|-------------|
|
|
64
|
+
| `value` | `number` | *required* | The number to display |
|
|
65
|
+
| `duration` | `number` | `200` | Animation duration in ms |
|
|
66
|
+
| `format` | `FormatOptions` | `undefined` | Decimal separator options |
|
|
67
|
+
| `fontSize` | `string` | `"inherit"` | Font size CSS value |
|
|
68
|
+
| `fontWeight` | `string` | `"inherit"` | Font weight CSS value |
|
|
69
|
+
| `color` | `string` | `"inherit"` | Text color CSS value |
|
|
70
|
+
|
|
71
|
+
---
|
|
31
72
|
|
|
32
73
|
### SlidingText
|
|
33
74
|
|
|
34
|
-
|
|
75
|
+
Character or word-by-word text animations.
|
|
35
76
|
|
|
36
77
|
```tsx
|
|
37
78
|
import { SlidingText } from '@mks2508/waapi-animation-primitives';
|
|
@@ -40,24 +81,32 @@ import { SlidingText } from '@mks2508/waapi-animation-primitives';
|
|
|
40
81
|
text="Hello World"
|
|
41
82
|
mode="character"
|
|
42
83
|
direction="vertical"
|
|
84
|
+
staggerDelay={15}
|
|
85
|
+
blur={4}
|
|
43
86
|
/>
|
|
44
87
|
```
|
|
45
88
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
89
|
+
| Prop | Type | Default | Description |
|
|
90
|
+
|------|------|---------|-------------|
|
|
91
|
+
| `text` | `string` | *required* | Text to display |
|
|
92
|
+
| `mode` | `'character' \| 'word' \| 'none'` | `'character'` | Animation granularity |
|
|
93
|
+
| `direction` | `'vertical' \| 'horizontal'` | `'vertical'` | Animation direction |
|
|
94
|
+
| `duration` | `number` | `200` | Animation duration in ms |
|
|
95
|
+
| `staggerDelay` | `number` | `15` | Delay between tokens (ms) |
|
|
96
|
+
| `blur` | `number` | `0` | Blur effect amount (px) |
|
|
97
|
+
| `widthAnimation` | `boolean` | `false` | Animate width changes |
|
|
98
|
+
| `initial` | `boolean \| 'initial'` | `true` | Play animation on mount |
|
|
99
|
+
|
|
100
|
+
---
|
|
52
101
|
|
|
53
102
|
### AnimatedTokens
|
|
54
103
|
|
|
55
|
-
|
|
104
|
+
Animated token list with coordinated enter/exit transitions.
|
|
56
105
|
|
|
57
106
|
```tsx
|
|
58
|
-
import { AnimatedTokens } from '@mks2508/waapi-animation-primitives';
|
|
107
|
+
import { AnimatedTokens, Token } from '@mks2508/waapi-animation-primitives';
|
|
59
108
|
|
|
60
|
-
const tokens = [
|
|
109
|
+
const tokens: Token[] = [
|
|
61
110
|
{ id: '1', text: 'React' },
|
|
62
111
|
{ id: '2', text: 'TypeScript' },
|
|
63
112
|
{ id: '3', text: 'WAAPI' }
|
|
@@ -70,95 +119,270 @@ const tokens = [
|
|
|
70
119
|
/>
|
|
71
120
|
```
|
|
72
121
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
122
|
+
| Prop | Type | Default | Description |
|
|
123
|
+
|------|------|---------|-------------|
|
|
124
|
+
| `tokens` | `Token[]` | *required* | Array of `{ id, text }` |
|
|
125
|
+
| `maxVisible` | `number` | `undefined` | Max visible before "+N more" |
|
|
126
|
+
| `separator` | `string` | `", "` | Separator between tokens |
|
|
127
|
+
| `textAnimationMode` | `'character' \| 'word'` | `'character'` | Text animation mode |
|
|
128
|
+
| `textDirection` | `'vertical' \| 'horizontal'` | `'vertical'` | Text animation direction |
|
|
129
|
+
| `enableWidthAnimation` | `boolean` | `false` | Animate width changes |
|
|
130
|
+
| `placeholder` | `string` | `undefined` | Empty state text |
|
|
79
131
|
|
|
80
|
-
|
|
132
|
+
---
|
|
81
133
|
|
|
82
|
-
###
|
|
134
|
+
### TextFlow
|
|
135
|
+
|
|
136
|
+
> **Alias for `AnimatedTokensV2`** - Modern version with locale-aware separators and `Reorder` primitive integration.
|
|
83
137
|
|
|
84
138
|
```tsx
|
|
85
|
-
import {
|
|
139
|
+
import { TextFlow } from '@mks2508/waapi-animation-primitives';
|
|
140
|
+
|
|
141
|
+
// en-US: "React, TypeScript, and WAAPI"
|
|
142
|
+
// es-ES: "React, TypeScript y WAAPI"
|
|
143
|
+
<TextFlow
|
|
144
|
+
tokens={tokens}
|
|
145
|
+
locale="es"
|
|
146
|
+
listType="conjunction"
|
|
147
|
+
maxVisible={5}
|
|
148
|
+
/>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
| Prop | Type | Default | Description |
|
|
152
|
+
|------|------|---------|-------------|
|
|
153
|
+
| `tokens` | `Token[]` | *required* | Array of `{ id, text }` |
|
|
154
|
+
| `locale` | `string` | *browser* | Locale for separators |
|
|
155
|
+
| `listType` | `'conjunction' \| 'disjunction' \| 'unit'` | `'conjunction'` | List format type |
|
|
156
|
+
| `listStyle` | `'long' \| 'short' \| 'narrow'` | `'long'` | List format style |
|
|
157
|
+
| `separator` | `string` | `undefined` | Manual separator override |
|
|
158
|
+
| `maxVisible` | `number` | `undefined` | Max visible before "+N more" |
|
|
159
|
+
| `textAnimationMode` | `'character' \| 'word'` | `'character'` | Text animation mode |
|
|
160
|
+
| `textDirection` | `'vertical' \| 'horizontal'` | `'vertical'` | Text animation direction |
|
|
161
|
+
| `textStaggerDelay` | `number` | `15` | Stagger delay (ms) |
|
|
162
|
+
| `enableWidthAnimation` | `boolean` | `false` | Animate width changes |
|
|
163
|
+
| `placeholder` | `string` | `"No tokens"` | Empty state text |
|
|
86
164
|
|
|
87
|
-
|
|
88
|
-
TIMING.DURATION_ENTER // 200ms
|
|
89
|
-
TIMING.DURATION_EXIT // 180ms
|
|
165
|
+
---
|
|
90
166
|
|
|
91
|
-
|
|
92
|
-
EASINGS.EASE_OUT_CUBIC
|
|
167
|
+
## Primitives
|
|
93
168
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
169
|
+
### Reorder
|
|
170
|
+
|
|
171
|
+
Agnostic FLIP animation primitive for animated list reordering.
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
import { Reorder } from '@mks2508/waapi-animation-primitives';
|
|
175
|
+
|
|
176
|
+
function TodoList() {
|
|
177
|
+
const [todos, setTodos] = useState([
|
|
178
|
+
{ id: '1', text: 'Buy milk' },
|
|
179
|
+
{ id: '2', text: 'Write code' }
|
|
180
|
+
]);
|
|
181
|
+
|
|
182
|
+
const handleRemove = (id: string) => {
|
|
183
|
+
setTodos(prev => prev.filter(t => t.id !== id));
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
return (
|
|
187
|
+
<Reorder
|
|
188
|
+
layout="horizontal"
|
|
189
|
+
stagger={15}
|
|
190
|
+
onItemExit={handleRemove}
|
|
191
|
+
>
|
|
192
|
+
{todos.map(todo => (
|
|
193
|
+
<div key={todo.id}>{todo.text}</div>
|
|
194
|
+
))}
|
|
195
|
+
</Reorder>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
97
198
|
```
|
|
98
199
|
|
|
99
|
-
|
|
200
|
+
| Prop | Type | Default | Description |
|
|
201
|
+
|------|------|---------|-------------|
|
|
202
|
+
| `children` | `ReactNode` | *required* | Child elements to animate |
|
|
203
|
+
| `layout` | `'auto' \| 'horizontal' \| 'vertical' \| 'grid'` | `'auto'` | Layout arrangement |
|
|
204
|
+
| `autoAnimate` | `boolean` | `true` | Enable enter animations |
|
|
205
|
+
| `stagger` | `number \| { enter, exit }` | `undefined` | Stagger delay (ms) |
|
|
206
|
+
| `duration` | `number \| { enter, exit }` | `{ enter: 300, exit: 200 }` | Animation duration (ms) |
|
|
207
|
+
| `flipBehavior` | `FLIPBehavior` | `'smooth'` | FLIP animation strategy |
|
|
208
|
+
| `exitPositionStrategy` | `ExitPositionStrategy` | `'keep-pace'` | Exit positioning strategy |
|
|
209
|
+
| `onItemExit` | `(id: string) => void` | `undefined` | Exit animation start callback |
|
|
210
|
+
| `onItemEnter` | `(id: string) => void` | `undefined` | Enter animation complete callback |
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
### useReorder
|
|
100
215
|
|
|
101
|
-
|
|
216
|
+
Low-level hook for orchestration of FLIP animations.
|
|
102
217
|
|
|
103
218
|
```tsx
|
|
104
|
-
import {
|
|
219
|
+
import { useReorder } from '@mks2508/waapi-animation-primitives';
|
|
220
|
+
|
|
221
|
+
function ListManager() {
|
|
222
|
+
const reorder = useReorder({
|
|
223
|
+
enterDuration: 400,
|
|
224
|
+
exitDuration: 200,
|
|
225
|
+
flipDuration: 300,
|
|
226
|
+
onComplete: (id) => console.log('Done:', id)
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Register element
|
|
230
|
+
<div ref={el => reorder.registerElement('item-1', el)}>Item</div>
|
|
231
|
+
|
|
232
|
+
// Trigger animations
|
|
233
|
+
await reorder.startItemExit('item-1');
|
|
234
|
+
}
|
|
235
|
+
```
|
|
105
236
|
|
|
106
|
-
|
|
107
|
-
<DebugProvider>
|
|
108
|
-
<YourApp />
|
|
109
|
-
</DebugProvider>
|
|
237
|
+
---
|
|
110
238
|
|
|
111
|
-
|
|
112
|
-
|
|
239
|
+
### useListFormat
|
|
240
|
+
|
|
241
|
+
Hook wrapper for `Intl.ListFormat` with locale-aware separators.
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
import { useListFormat } from '@mks2508/waapi-animation-primitives';
|
|
245
|
+
|
|
246
|
+
const parts = useListFormat(
|
|
247
|
+
['React', 'TypeScript', 'WAAPI'],
|
|
248
|
+
{ locale: 'es', type: 'conjunction' }
|
|
249
|
+
);
|
|
250
|
+
// Returns: [{ type: 'element', index: 0, value: 'React' }, ...]
|
|
113
251
|
```
|
|
114
252
|
|
|
115
|
-
|
|
116
|
-
- Event logging with timestamps
|
|
117
|
-
- Animation timing analysis
|
|
118
|
-
- Style and position capture
|
|
119
|
-
- CSV export for analysis
|
|
253
|
+
---
|
|
120
254
|
|
|
121
|
-
|
|
255
|
+
## Core
|
|
122
256
|
|
|
123
|
-
|
|
257
|
+
### Animation Orchestrator
|
|
258
|
+
|
|
259
|
+
Low-level WAAPI orchestration for custom animations.
|
|
124
260
|
|
|
125
261
|
```tsx
|
|
126
|
-
import {
|
|
262
|
+
import { AnimationOrchestrator } from '@mks2508/waapi-animation-primitives';
|
|
127
263
|
|
|
128
|
-
|
|
129
|
-
|
|
264
|
+
const orchestrator = new AnimationOrchestrator({
|
|
265
|
+
flipDuration: 300,
|
|
266
|
+
flipEasing: 'cubic-bezier(0.2, 0, 0.2, 1)',
|
|
267
|
+
flipBehavior: 'smooth'
|
|
268
|
+
});
|
|
130
269
|
|
|
131
|
-
|
|
270
|
+
orchestrator.registerElement('id-1', element);
|
|
271
|
+
await orchestrator.startFlip();
|
|
132
272
|
```
|
|
133
273
|
|
|
134
|
-
|
|
274
|
+
---
|
|
135
275
|
|
|
136
|
-
|
|
276
|
+
## CSS System
|
|
137
277
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
278
|
+
All animation values are controlled via CSS variables.
|
|
279
|
+
|
|
280
|
+
### Override Globally
|
|
281
|
+
|
|
282
|
+
```css
|
|
283
|
+
:root {
|
|
284
|
+
/* Timing */
|
|
285
|
+
--waapi-duration-enter: 200ms;
|
|
286
|
+
--waapi-duration-exit: 180ms;
|
|
287
|
+
--waapi-duration-flip: 300ms;
|
|
288
|
+
--waapi-stagger-enter: 15ms;
|
|
289
|
+
|
|
290
|
+
/* Transforms */
|
|
291
|
+
--waapi-offset-y-enter: 8px;
|
|
292
|
+
--waapi-offset-y-exit: -8px;
|
|
293
|
+
--waapi-scale-exit: 0.95;
|
|
294
|
+
|
|
295
|
+
/* Effects */
|
|
296
|
+
--waapi-blur-enter: 4px;
|
|
297
|
+
--waapi-blur-exit: 2px;
|
|
298
|
+
|
|
299
|
+
/* Easings */
|
|
300
|
+
--waapi-ease-enter: cubic-bezier(0.33, 1, 0.68, 1);
|
|
301
|
+
--waapi-ease-exit: cubic-bezier(0.32, 0, 0.67, 0);
|
|
302
|
+
--waapi-ease-flip: cubic-bezier(0.2, 0, 0.2, 1);
|
|
303
|
+
}
|
|
141
304
|
```
|
|
142
|
-
- 24KB minified
|
|
143
|
-
- All debug code removed
|
|
144
|
-
- Optimized for production
|
|
145
305
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
306
|
+
### Override Per Component
|
|
307
|
+
|
|
308
|
+
```tsx
|
|
309
|
+
<div style={{ '--waapi-duration-enter': '500ms' }}>
|
|
310
|
+
<AnimatedTokens tokens={tokens} />
|
|
311
|
+
</div>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Programmatic Override
|
|
315
|
+
|
|
316
|
+
```tsx
|
|
317
|
+
import { CSS_VAR_NAMES } from '@mks2508/waapi-animation-primitives';
|
|
318
|
+
|
|
319
|
+
const customStyle = {
|
|
320
|
+
[CSS_VAR_NAMES.durationEnter]: '500ms',
|
|
321
|
+
[CSS_VAR_NAMES.blurEnter]: '8px',
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
<SlidingText text="Hello" style={customStyle} />
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## CSS Classes
|
|
330
|
+
|
|
331
|
+
| Class | Component | Description |
|
|
332
|
+
|-------|-----------|-------------|
|
|
333
|
+
| `.waapi-sliding-text-container` | SlidingText | Main container |
|
|
334
|
+
| `.waapi-sliding-text-token` | SlidingText | Individual character/word |
|
|
335
|
+
| `.waapi-sliding-number-container` | SlidingNumber | Main container |
|
|
336
|
+
| `.waapi-animated-tokens-container` | AnimatedTokens | Main container |
|
|
337
|
+
| `.waapi-token-wrapper` | AnimatedTokens | Token wrapper |
|
|
338
|
+
| `.waapi-token-separator` | AnimatedTokens | Separator |
|
|
339
|
+
| `.waapi-token-overflow` | AnimatedTokens | "+N more" counter |
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## Debug System
|
|
344
|
+
|
|
345
|
+
Development-only tools. Automatically tree-shaken in production.
|
|
346
|
+
|
|
347
|
+
```tsx
|
|
348
|
+
import { DebugProvider, useDebug } from '@mks2508/waapi-animation-primitives';
|
|
349
|
+
|
|
350
|
+
<DebugProvider>
|
|
351
|
+
<YourApp />
|
|
352
|
+
</DebugProvider>
|
|
353
|
+
|
|
354
|
+
// Access debug events
|
|
355
|
+
const { events, logEvent, exportToCSV } = useDebug();
|
|
149
356
|
```
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Accessibility
|
|
361
|
+
|
|
362
|
+
- **Reduced Motion**: Respects `prefers-reduced-motion` media query
|
|
363
|
+
- **High Contrast**: Reduces blur effects in high contrast mode
|
|
364
|
+
- **Print**: Disables animations for printing
|
|
365
|
+
|
|
366
|
+
---
|
|
153
367
|
|
|
154
368
|
## Browser Support
|
|
155
369
|
|
|
156
370
|
Requires browsers with Web Animations API support:
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
371
|
+
|
|
372
|
+
| Chrome | Firefox | Safari | Edge |
|
|
373
|
+
|--------|---------|--------|------|
|
|
374
|
+
| 84+ | 75+ | 13.1+ | 84+ |
|
|
375
|
+
|
|
376
|
+
---
|
|
161
377
|
|
|
162
378
|
## License
|
|
163
379
|
|
|
164
|
-
MIT
|
|
380
|
+
[MIT](./LICENSE) © MKS2508
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
<div align="center">
|
|
385
|
+
|
|
386
|
+
**[Documentation](#readme)** • **[npm](https://www.npmjs.com/package/@mks2508/waapi-animation-primitives)** • **[GitHub](https://github.com/mks2508/waapi-animation-primitives)**
|
|
387
|
+
|
|
388
|
+
</div>
|