@mks2508/waapi-animation-primitives 0.2.0 → 0.3.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 CHANGED
@@ -1,20 +1,53 @@
1
+ <div align="center">
2
+
1
3
  # WAAPI Animation Primitives
2
4
 
3
- React animation components using the Web Animations API. Zero dependencies beyond React.
5
+ **Lightweight, performant React animation components using Web Animations API**
6
+
7
+ [![npm version](https://badge.fury.io/js/%40mks2508%2Fwaapi-animation-primitives.svg)](https://www.npmjs.com/package/@mks2508/waapi-animation-primitives)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.6-blue)](https://www.typescriptlang.org/)
10
+ [![React](https://img.shields.io/badge/React-16.8%2B-blue)](https://react.dev/)
11
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/%40mks2508%2Fwaapi-animation-primitives)](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
9
- # or
36
+
37
+ # bun
10
38
  bun add @mks2508/waapi-animation-primitives
39
+
40
+ # yarn
41
+ yarn add @mks2508/waapi-animation-primitives
11
42
  ```
12
43
 
44
+ ---
45
+
13
46
  ## Components
14
47
 
15
48
  ### SlidingNumber
16
49
 
17
- Animates number changes with smooth transitions.
50
+ Animated number transitions with format preservation.
18
51
 
19
52
  ```tsx
20
53
  import { SlidingNumber } from '@mks2508/waapi-animation-primitives';
@@ -26,14 +59,20 @@ import { SlidingNumber } from '@mks2508/waapi-animation-primitives';
26
59
  />
27
60
  ```
28
61
 
29
- **Props:**
30
- - `value` (number) - The number to display
31
- - `duration` (number, optional) - Animation duration in ms (default: 200)
32
- - `format` (object, optional) - Formatting options for decimals and separators
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
+ ---
33
72
 
34
73
  ### SlidingText
35
74
 
36
- Animates text changes character by character.
75
+ Character or word-by-word text animations.
37
76
 
38
77
  ```tsx
39
78
  import { SlidingText } from '@mks2508/waapi-animation-primitives';
@@ -42,24 +81,32 @@ import { SlidingText } from '@mks2508/waapi-animation-primitives';
42
81
  text="Hello World"
43
82
  mode="character"
44
83
  direction="vertical"
84
+ staggerDelay={15}
85
+ blur={4}
45
86
  />
46
87
  ```
47
88
 
48
- **Props:**
49
- - `text` (string) - Text to display
50
- - `mode` ('character' | 'word' | 'none') - Animation granularity
51
- - `direction` ('vertical' | 'horizontal') - Animation direction
52
- - `duration` (number, optional) - Animation duration in ms
53
- - `staggerDelay` (number, optional) - Delay between character animations
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
+ ---
54
101
 
55
102
  ### AnimatedTokens
56
103
 
57
- Manages a list of animated tokens with enter/exit transitions.
104
+ Animated token list with coordinated enter/exit transitions.
58
105
 
59
106
  ```tsx
60
- import { AnimatedTokens } from '@mks2508/waapi-animation-primitives';
107
+ import { AnimatedTokens, Token } from '@mks2508/waapi-animation-primitives';
61
108
 
62
- const tokens = [
109
+ const tokens: Token[] = [
63
110
  { id: '1', text: 'React' },
64
111
  { id: '2', text: 'TypeScript' },
65
112
  { id: '3', text: 'WAAPI' }
@@ -72,16 +119,165 @@ const tokens = [
72
119
  />
73
120
  ```
74
121
 
75
- **Props:**
76
- - `tokens` (Token[]) - Array of `{ id: string, text: string }`
77
- - `maxVisible` (number, optional) - Maximum visible tokens before showing "+N more"
78
- - `separator` (string, optional) - Separator between tokens (default: ", ")
79
- - `textAnimationMode` ('character' | 'word' | 'none') - How text animates
80
- - `enableWidthAnimation` (boolean, optional) - Animate width changes
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 |
131
+
132
+ ---
133
+
134
+ ### TextFlow
135
+
136
+ > **Alias for `AnimatedTokensV2`** - Modern version with locale-aware separators and `Reorder` primitive integration.
137
+
138
+ ```tsx
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 |
164
+
165
+ ---
166
+
167
+ ## Primitives
168
+
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
+ }
198
+ ```
199
+
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
215
+
216
+ Low-level hook for orchestration of FLIP animations.
217
+
218
+ ```tsx
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
+ ```
236
+
237
+ ---
238
+
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' }, ...]
251
+ ```
252
+
253
+ ---
254
+
255
+ ## Core
256
+
257
+ ### Animation Orchestrator
258
+
259
+ Low-level WAAPI orchestration for custom animations.
260
+
261
+ ```tsx
262
+ import { AnimationOrchestrator } from '@mks2508/waapi-animation-primitives';
263
+
264
+ const orchestrator = new AnimationOrchestrator({
265
+ flipDuration: 300,
266
+ flipEasing: 'cubic-bezier(0.2, 0, 0.2, 1)',
267
+ flipBehavior: 'smooth'
268
+ });
269
+
270
+ orchestrator.registerElement('id-1', element);
271
+ await orchestrator.startFlip();
272
+ ```
273
+
274
+ ---
81
275
 
82
- ## CSS Variables (Customization)
276
+ ## CSS System
83
277
 
84
- All animation values are controlled via CSS variables. Override them to customize animations:
278
+ All animation values are controlled via CSS variables.
279
+
280
+ ### Override Globally
85
281
 
86
282
  ```css
87
283
  :root {
@@ -94,7 +290,6 @@ All animation values are controlled via CSS variables. Override them to customiz
94
290
  /* Transforms */
95
291
  --waapi-offset-y-enter: 8px;
96
292
  --waapi-offset-y-exit: -8px;
97
- --waapi-offset-x: 16px;
98
293
  --waapi-scale-exit: 0.95;
99
294
 
100
295
  /* Effects */
@@ -108,7 +303,7 @@ All animation values are controlled via CSS variables. Override them to customiz
108
303
  }
109
304
  ```
110
305
 
111
- ### Override per Component
306
+ ### Override Per Component
112
307
 
113
308
  ```tsx
114
309
  <div style={{ '--waapi-duration-enter': '500ms' }}>
@@ -119,7 +314,7 @@ All animation values are controlled via CSS variables. Override them to customiz
119
314
  ### Programmatic Override
120
315
 
121
316
  ```tsx
122
- import { CSS_VAR_NAMES, cssVar } from '@mks2508/waapi-animation-primitives';
317
+ import { CSS_VAR_NAMES } from '@mks2508/waapi-animation-primitives';
123
318
 
124
319
  const customStyle = {
125
320
  [CSS_VAR_NAMES.durationEnter]: '500ms',
@@ -129,119 +324,25 @@ const customStyle = {
129
324
  <SlidingText text="Hello" style={customStyle} />
130
325
  ```
131
326
 
132
- ## CSS Classes
327
+ ---
133
328
 
134
- All components use prefixed CSS classes for styling:
329
+ ## CSS Classes
135
330
 
136
331
  | Class | Component | Description |
137
332
  |-------|-----------|-------------|
138
333
  | `.waapi-sliding-text-container` | SlidingText | Main container |
139
334
  | `.waapi-sliding-text-token` | SlidingText | Individual character/word |
335
+ | `.waapi-sliding-number-container` | SlidingNumber | Main container |
140
336
  | `.waapi-animated-tokens-container` | AnimatedTokens | Main container |
141
337
  | `.waapi-token-wrapper` | AnimatedTokens | Token wrapper |
142
- | `.waapi-token-separator` | AnimatedTokens | Separator between tokens |
143
- | `.waapi-token-placeholder` | AnimatedTokens | Placeholder text |
144
-
145
- ### State Classes
146
-
147
- - `.enter-from` - Initial enter state
148
- - `.enter-to` - Final enter state
149
- - `.exit-active` - Exit animation active
150
- - `.exit-completed` - Element ready for removal
151
-
152
- ## Architecture (SSOT)
153
-
154
- The library uses a Single Source of Truth architecture:
155
-
156
- ```
157
- animationUtils.ts (constants: TIMING, EASINGS, etc.)
158
-
159
- cssTokens.ts (generates CSS variables)
160
-
161
- ┌───┴───┐
162
- ↓ ↓
163
- CSS Components
164
- ```
165
-
166
- ### Animation Constants
167
-
168
- ```tsx
169
- import { TIMING, EASINGS, PRESETS } from '@mks2508/waapi-animation-primitives';
170
-
171
- TIMING.ENTER_DURATION // 200
172
- TIMING.EXIT_DURATION // 180
173
- TIMING.FLIP_DURATION // 300
174
-
175
- EASINGS.EASE_OUT_CUBIC // 'cubic-bezier(0.33, 1, 0.68, 1)'
176
- EASINGS.SPRING_GENTLE // 'linear(0, 0.009, ...)'
177
- ```
178
-
179
- ### CSS Tokens System
180
-
181
- ```tsx
182
- import {
183
- CSS_VAR_NAMES,
184
- CSS_VAR_VALUES,
185
- generateCSSVariables,
186
- generateResponsiveCSS,
187
- } from '@mks2508/waapi-animation-primitives';
188
-
189
- // Get CSS variable name with type safety
190
- CSS_VAR_NAMES.durationEnter // '--waapi-duration-enter'
191
-
192
- // Get all default values
193
- CSS_VAR_VALUES // { '--waapi-duration-enter': '200ms', ... }
194
-
195
- // Generate CSS string
196
- generateCSSVariables() // ':root { --waapi-duration-enter: 200ms; ... }'
197
- ```
198
-
199
- ## Headless Mode
200
-
201
- For complete control, use the style objects directly:
202
-
203
- ```tsx
204
- import {
205
- slidingTextStyles,
206
- animatedTokensStyles,
207
- getSlidingTextTokenStyle,
208
- } from '@mks2508/waapi-animation-primitives';
209
-
210
- // Base container styles
211
- slidingTextStyles.container
338
+ | `.waapi-token-separator` | AnimatedTokens | Separator |
339
+ | `.waapi-token-overflow` | AnimatedTokens | "+N more" counter |
212
340
 
213
- // Get token style for specific state
214
- getSlidingTextTokenStyle('enter-from', 'vertical')
215
-
216
- // Responsive styles
217
- import { getResponsiveTokenStyles } from '@mks2508/waapi-animation-primitives';
218
- const styles = getResponsiveTokenStyles(); // Auto-detects mobile/reduced-motion
219
- ```
220
-
221
- ## CSS Injection Control
222
-
223
- CSS variables are auto-injected. Control this behavior:
224
-
225
- ```tsx
226
- import {
227
- injectCSSVariables,
228
- removeCSSVariables,
229
- reinjectCSSVariables,
230
- } from '@mks2508/waapi-animation-primitives';
231
-
232
- // Manual injection
233
- injectCSSVariables();
234
-
235
- // Remove (for testing/cleanup)
236
- removeCSSVariables();
237
-
238
- // Force re-inject (after dynamic changes)
239
- reinjectCSSVariables();
240
- ```
341
+ ---
241
342
 
242
343
  ## Debug System
243
344
 
244
- Development-only debugging tools. Automatically tree-shaken in production.
345
+ Development-only tools. Automatically tree-shaken in production.
245
346
 
246
347
  ```tsx
247
348
  import { DebugProvider, useDebug } from '@mks2508/waapi-animation-primitives';
@@ -250,49 +351,38 @@ import { DebugProvider, useDebug } from '@mks2508/waapi-animation-primitives';
250
351
  <YourApp />
251
352
  </DebugProvider>
252
353
 
253
- // Access debug tools
354
+ // Access debug events
254
355
  const { events, logEvent, exportToCSV } = useDebug();
255
356
  ```
256
357
 
257
- ### Choreography Tracker
258
-
259
- ```tsx
260
- import { choreographyTracker } from '@mks2508/waapi-animation-primitives';
261
-
262
- choreographyTracker.startAnimation('anim-1', 'flip', 'element-1', 300);
263
- choreographyTracker.endAnimation('anim-1');
264
-
265
- const summary = choreographyTracker.getSummary();
266
- ```
358
+ ---
267
359
 
268
360
  ## Accessibility
269
361
 
270
- The library automatically supports:
271
-
272
362
  - **Reduced Motion**: Respects `prefers-reduced-motion` media query
273
363
  - **High Contrast**: Reduces blur effects in high contrast mode
274
- - **Print**: Disables all animations for printing
275
-
276
- ## Build Variants
364
+ - **Print**: Disables animations for printing
277
365
 
278
- **Production** (default):
279
- ```bash
280
- bun run build
281
- ```
282
-
283
- **Debug**:
284
- ```bash
285
- bun run build:debug
286
- ```
366
+ ---
287
367
 
288
368
  ## Browser Support
289
369
 
290
370
  Requires browsers with Web Animations API support:
291
- - Chrome 84+
292
- - Firefox 75+
293
- - Safari 13.1+
294
- - Edge 84+
371
+
372
+ | Chrome | Firefox | Safari | Edge |
373
+ |--------|---------|--------|------|
374
+ | 84+ | 75+ | 13.1+ | 84+ |
375
+
376
+ ---
295
377
 
296
378
  ## License
297
379
 
298
- 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>