@grandgular/rive-angular 0.1.2 โ†’ 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 CHANGED
@@ -20,6 +20,7 @@ This library provides a **modern, Angular-native** way to integrate Rive animati
20
20
  - ๐ŸŒ **SSR-ready**: Full server-side rendering support
21
21
  - ๐Ÿงน **Automatic cleanup**: Proper resource management and lifecycle handling
22
22
  - ๐Ÿ“ฆ **File caching**: Built-in service for preloading and caching .riv files
23
+ - ๐Ÿ› ๏ธ **Developer Experience**: Built-in debug mode, validation, and detailed error codes
23
24
 
24
25
  ### Comparison with alternatives
25
26
 
@@ -36,6 +37,7 @@ This library provides a **modern, Angular-native** way to integrate Rive animati
36
37
  | SSR support | โœ… Full | โš ๏ธ Limited |
37
38
  | Performance | Optimized (zoneless) | Standard |
38
39
  | File caching | โœ… Built-in service | โŒ Manual |
40
+ | Validation | โœ… Built-in | โŒ None |
39
41
 
40
42
  #### vs. rive-react
41
43
 
@@ -140,6 +142,55 @@ export class InteractiveComponent {
140
142
  }
141
143
  ```
142
144
 
145
+ ### Text Runs
146
+
147
+ Rive text runs allow you to update text content at runtime. The library provides two approaches:
148
+
149
+ #### Declarative (Controlled Keys)
150
+
151
+ Use the `textRuns` input for reactive, template-driven text updates:
152
+
153
+ ```html
154
+ <rive-canvas
155
+ src="assets/hello.riv"
156
+ [textRuns]="{ greeting: userName(), subtitle: 'Welcome' }"
157
+ />
158
+ ```
159
+
160
+ Keys present in `textRuns` are **controlled** โ€” the input is the source of truth and will override any imperative changes.
161
+
162
+ #### Imperative (Uncontrolled Keys)
163
+
164
+ Use methods for reading values or managing keys not in `textRuns`:
165
+
166
+ ```typescript
167
+ riveRef = viewChild.required(RiveCanvasComponent);
168
+
169
+ // Read current value
170
+ const greeting = this.riveRef().getTextRunValue('greeting');
171
+
172
+ // Set uncontrolled key
173
+ this.riveRef().setTextRunValue('dynamicText', 'New value');
174
+ ```
175
+
176
+ #### Nested Text Runs
177
+
178
+ For text runs inside nested components, use the `AtPath` variants:
179
+
180
+ ```typescript
181
+ this.riveRef().setTextRunValueAtPath(
182
+ 'button_text',
183
+ 'Click Me',
184
+ 'NestedArtboard/ButtonComponent'
185
+ );
186
+ ```
187
+
188
+ #### Controlled vs Uncontrolled
189
+
190
+ - **Controlled**: Keys in `textRuns` input โ€” managed by Angular, input is source of truth
191
+ - **Uncontrolled**: Keys not in `textRuns` โ€” managed imperatively via methods
192
+ - **Warning**: Calling `setTextRunValue()` on a controlled key logs a warning and the change will be overwritten on next input update
193
+
143
194
  ### Preloading files with RiveFileService
144
195
 
145
196
  For better performance, you can preload and cache .riv files:
@@ -185,6 +236,75 @@ export class PreloadComponent {
185
236
  }
186
237
  ```
187
238
 
239
+ ## Debug Mode
240
+
241
+ The library provides a built-in debug mode to help you troubleshoot animations.
242
+
243
+ ### Global Configuration
244
+
245
+ Enable debug mode globally in your `app.config.ts`:
246
+
247
+ ```typescript
248
+ import { provideRiveDebug } from '@grandgular/rive-angular';
249
+
250
+ export const appConfig: ApplicationConfig = {
251
+ providers: [
252
+ provideRiveDebug({ logLevel: 'debug' })
253
+ ]
254
+ };
255
+ ```
256
+
257
+ Available log levels: `'none' | 'error' | 'warn' | 'info' | 'debug'`
258
+
259
+ ### Local Override
260
+
261
+ Enable debug mode for a specific component instance:
262
+
263
+ ```typescript
264
+ <rive-canvas
265
+ src="assets/animation.riv"
266
+ [debugMode]="true"
267
+ />
268
+ ```
269
+
270
+ When debug mode is enabled, the library will log:
271
+ - Loading progress and file details
272
+ - Available artboards, animations, and state machines
273
+ - Validation warnings (e.g., misspelled animation names)
274
+
275
+ ## Error Handling & Validation
276
+
277
+ The library validates your configuration against the loaded Rive file and provides structured error codes.
278
+
279
+ ### Validation
280
+
281
+ Validation errors (e.g., missing artboard or animation) are **non-fatal**. They are emitted via the `loadError` output but do not crash the application.
282
+
283
+ ```typescript
284
+ <rive-canvas
285
+ src="assets/anim.riv"
286
+ [artboard]="'WrongName'"
287
+ (loadError)="onError($event)"
288
+ />
289
+ ```
290
+
291
+ In this case, `onError` receives a `RiveValidationError` with code `RIVE_201`, and the library logs a warning with available artboard names.
292
+
293
+ ### Error Codes
294
+
295
+ | Code | Type | Description |
296
+ |------|------|-------------|
297
+ | `RIVE_101` | Load | File not found (404) |
298
+ | `RIVE_102` | Load | Invalid .riv file format |
299
+ | `RIVE_103` | Load | Network error |
300
+ | `RIVE_201` | Validation | Artboard not found |
301
+ | `RIVE_202` | Validation | Animation not found |
302
+ | `RIVE_203` | Validation | State machine not found |
303
+ | `RIVE_204` | Validation | Input/Trigger not found in State Machine |
304
+ | `RIVE_205` | Validation | Text run not found |
305
+ | `RIVE_301` | Config | No animation source provided |
306
+ | `RIVE_302` | Config | Invalid canvas element |
307
+
188
308
  ## API Reference
189
309
 
190
310
  ### RiveCanvasComponent
@@ -206,18 +326,22 @@ export class PreloadComponent {
206
326
  | `shouldUseIntersectionObserver` | `boolean` | `true` | Auto-pause when off-screen |
207
327
  | `shouldDisableRiveListeners` | `boolean` | `false` | Disable Rive event listeners |
208
328
  | `automaticallyHandleEvents` | `boolean` | `false` | Auto-handle Rive events (e.g., OpenUrlEvent) |
329
+ | `debugMode` | `boolean` | `undefined` | Enable verbose logging for this instance |
330
+ | `textRuns` | `Record<string, string>` | - | Declarative text run values. Keys present are controlled by input. |
209
331
 
210
332
  #### Outputs
211
333
 
212
334
  | Output | Type | Description |
213
335
  |--------|------|-------------|
214
336
  | `loaded` | `void` | Emitted when animation loads successfully |
215
- | `loadError` | `Error` | Emitted when animation fails to load |
337
+ | `loadError` | `Error` | Emitted when animation fails to load or validation errors occur |
216
338
  | `stateChange` | `RiveEvent` | Emitted on state machine state changes |
217
339
  | `riveEvent` | `RiveEvent` | Emitted for custom Rive events |
218
- | `riveReady` | `Rive` | Emitted when Rive instance is created |
340
+ | `riveReady` | `Rive` | Emitted when Rive instance is **fully loaded** and ready (after `loaded`) |
341
+
342
+ #### Public Signals (Readonly)
219
343
 
220
- #### Public Signals
344
+ All signals are **readonly** and cannot be mutated externally. Use the public methods to control the animation.
221
345
 
222
346
  | Signal | Type | Description |
223
347
  |--------|------|-------------|
@@ -226,6 +350,8 @@ export class PreloadComponent {
226
350
  | `isLoaded` | `Signal<boolean>` | Whether animation is loaded |
227
351
  | `riveInstance` | `Signal<Rive \| null>` | Direct access to Rive instance |
228
352
 
353
+ **Note:** Signals are readonly to prevent external mutation. Use component methods (`playAnimation()`, `pauseAnimation()`, etc.) to control the animation state.
354
+
229
355
  #### Public Methods
230
356
 
231
357
  | Method | Description |
@@ -236,6 +362,10 @@ export class PreloadComponent {
236
362
  | `reset()` | Reset animation to beginning |
237
363
  | `setInput(stateMachine: string, input: string, value: number \| boolean)` | Set state machine input value |
238
364
  | `fireTrigger(stateMachine: string, trigger: string)` | Fire state machine trigger |
365
+ | `getTextRunValue(name: string): string \| undefined` | Get text run value |
366
+ | `setTextRunValue(name: string, value: string)` | Set text run value (warns if key is controlled) |
367
+ | `getTextRunValueAtPath(name: string, path: string): string \| undefined` | Get nested text run value |
368
+ | `setTextRunValueAtPath(name: string, value: string, path: string)` | Set nested text run |
239
369
 
240
370
  ### RiveFileService
241
371
 
@@ -255,6 +385,7 @@ Service for preloading and caching .riv files.
255
385
  interface RiveFileParams {
256
386
  src?: string;
257
387
  buffer?: ArrayBuffer;
388
+ debug?: boolean;
258
389
  }
259
390
 
260
391
  interface RiveFileState {
@@ -277,26 +408,25 @@ The library is fully compatible with Angular Universal and server-side rendering
277
408
  2. **Preload files**: Use `RiveFileService` to preload and cache .riv files for instant display
278
409
  3. **Disable unnecessary listeners**: Set `shouldDisableRiveListeners` to `true` for decorative animations without interactivity
279
410
  4. **Use OnPush**: The component already uses `OnPush` change detection for optimal performance
411
+ 5. **Reactive updates**: The component now reactively updates layout when `fit` or `alignment` change without full reload
280
412
 
281
- ## Troubleshooting
282
-
283
- ### Animation not loading
284
-
285
- - Verify the .riv file path is correct
286
- - Check browser console for errors
287
- - Ensure `@rive-app/canvas` is installed
288
-
289
- ### State machine inputs not working
413
+ ## Recent Improvements (v0.2.0)
290
414
 
291
- - Verify state machine and input names match your .riv file
292
- - Check that the animation has loaded before calling `setInput` or `fireTrigger`
293
- - Use the `loaded` output to ensure timing
415
+ ### Quality & Stability
416
+ - โœ… **Readonly signals** prevent accidental state mutation
417
+ - โœ… **Dynamic DPR** support for multi-monitor setups
418
+ - โœ… **Reactive configuration** - all inputs trigger appropriate updates
419
+ - โœ… **Type-safe configuration** - eliminated unsafe type assertions
420
+ - โœ… **Fixed race conditions** in file service and cache management
421
+ - โœ… **Proper timing** - `riveReady` emits after full load
294
422
 
295
- ### Memory leaks with RiveFileService
423
+ ### Developer Experience
424
+ - ๐Ÿ› ๏ธ **Enhanced validation** with detailed error messages
425
+ - ๐Ÿ› **Comprehensive debugging** via `provideRiveDebug()`
426
+ - ๐Ÿ“ **Better error codes** for programmatic error handling
427
+ - ๐Ÿงช **Improved testability** with DI-based services
296
428
 
297
- - Always call `releaseFile` when done with a file
298
- - Use `DestroyRef.onDestroy` to auto-release files on component destroy
299
- - The service uses reference counting - files are only cleaned up when ref count reaches 0
429
+ See [CHANGELOG.md](./CHANGELOG.md) for complete details, migration guide, and all improvements.
300
430
 
301
431
  ## Requirements
302
432