@rive-app/react-native 0.2.0 → 0.2.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.
@@ -2,13 +2,28 @@
2
2
 
3
3
  import { useMemo, useEffect, useRef } from 'react';
4
4
  import { callDispose } from "../core/callDispose.js";
5
+ import { ArtboardByName } from "../specs/ArtboardBy.js";
6
+
7
+ /**
8
+ * Use the ViewModel assigned to the default artboard.
9
+ */
10
+
11
+ /**
12
+ * Use the ViewModel assigned to a specific artboard.
13
+ */
14
+
15
+ /**
16
+ * Use a ViewModel by name (file-wide lookup).
17
+ * ViewModels are defined at the file level, not per-artboard.
18
+ */
19
+
5
20
  function isRiveViewRef(source) {
6
- return source !== null && source !== undefined && 'getViewModelInstance' in source;
21
+ return source !== null && 'getViewModelInstance' in source;
7
22
  }
8
23
  function isRiveFile(source) {
9
- return source !== null && source !== undefined && 'defaultArtboardViewModel' in source;
24
+ return source !== null && 'defaultArtboardViewModel' in source;
10
25
  }
11
- function createInstance(source, name, useNew) {
26
+ function createInstance(source, instanceName, artboardName, viewModelName, useNew) {
12
27
  if (!source) {
13
28
  return {
14
29
  instance: null,
@@ -23,8 +38,40 @@ function createInstance(source, name, useNew) {
23
38
  };
24
39
  }
25
40
  if (isRiveFile(source)) {
26
- const viewModel = source.defaultArtboardViewModel();
27
- const vmi = viewModel?.createDefaultInstance();
41
+ let viewModel;
42
+ if (viewModelName) {
43
+ viewModel = source.viewModelByName(viewModelName);
44
+ if (!viewModel) {
45
+ return {
46
+ instance: null,
47
+ needsDispose: false,
48
+ error: `ViewModel '${viewModelName}' not found`
49
+ };
50
+ }
51
+ } else {
52
+ viewModel = source.defaultArtboardViewModel(artboardName ? ArtboardByName(artboardName) : undefined);
53
+ if (!viewModel) {
54
+ if (artboardName) {
55
+ return {
56
+ instance: null,
57
+ needsDispose: false,
58
+ error: `Artboard '${artboardName}' not found or has no ViewModel`
59
+ };
60
+ }
61
+ return {
62
+ instance: null,
63
+ needsDispose: false
64
+ };
65
+ }
66
+ }
67
+ const vmi = instanceName ? viewModel.createInstanceByName(instanceName) : viewModel.createDefaultInstance();
68
+ if (!vmi && instanceName) {
69
+ return {
70
+ instance: null,
71
+ needsDispose: false,
72
+ error: `ViewModel instance '${instanceName}' not found`
73
+ };
74
+ }
28
75
  return {
29
76
  instance: vmi ?? null,
30
77
  needsDispose: true
@@ -33,8 +80,15 @@ function createInstance(source, name, useNew) {
33
80
 
34
81
  // ViewModel source
35
82
  let vmi;
36
- if (name) {
37
- vmi = source.createInstanceByName(name);
83
+ if (instanceName) {
84
+ vmi = source.createInstanceByName(instanceName);
85
+ if (!vmi) {
86
+ return {
87
+ instance: null,
88
+ needsDispose: false,
89
+ error: `ViewModel instance '${instanceName}' not found`
90
+ };
91
+ }
38
92
  } else if (useNew) {
39
93
  vmi = source.createInstance();
40
94
  } else {
@@ -50,7 +104,7 @@ function createInstance(source, name, useNew) {
50
104
  * Hook for getting a ViewModelInstance from a RiveFile, ViewModel, or RiveViewRef.
51
105
  *
52
106
  * @param source - The RiveFile, ViewModel, or RiveViewRef to get an instance from
53
- * @param params - Configuration for which instance to retrieve (only used with ViewModel)
107
+ * @param params - Configuration for which instance to retrieve
54
108
  * @returns The ViewModelInstance or null if not found
55
109
  *
56
110
  * @example
@@ -62,6 +116,27 @@ function createInstance(source, name, useNew) {
62
116
  *
63
117
  * @example
64
118
  * ```tsx
119
+ * // From RiveFile with specific instance name
120
+ * const { riveFile } = useRiveFile(require('./animation.riv'));
121
+ * const instance = useViewModelInstance(riveFile, { instanceName: 'PersonInstance' });
122
+ * ```
123
+ *
124
+ * @example
125
+ * ```tsx
126
+ * // From RiveFile with specific ViewModel name
127
+ * const { riveFile } = useRiveFile(require('./animation.riv'));
128
+ * const instance = useViewModelInstance(riveFile, { viewModelName: 'Settings' });
129
+ * ```
130
+ *
131
+ * @example
132
+ * ```tsx
133
+ * // From RiveFile with specific artboard
134
+ * const { riveFile } = useRiveFile(require('./animation.riv'));
135
+ * const instance = useViewModelInstance(riveFile, { artboardName: 'MainArtboard' });
136
+ * ```
137
+ *
138
+ * @example
139
+ * ```tsx
65
140
  * // From RiveViewRef (get auto-bound instance)
66
141
  * const { riveViewRef, setHybridRef } = useRive();
67
142
  * const instance = useViewModelInstance(riveViewRef);
@@ -100,21 +175,31 @@ function createInstance(source, name, useNew) {
100
175
  * // Values are already set here
101
176
  * ```
102
177
  */
178
+ // RiveFile overloads
179
+
180
+ // ViewModel overloads
181
+
182
+ // RiveViewRef overloads
103
183
 
184
+ // Implementation
104
185
  export function useViewModelInstance(source, params) {
105
- const name = params?.name;
186
+ const fileInstanceName = params?.instanceName;
187
+ const viewModelInstanceName = params?.name;
188
+ const instanceName = fileInstanceName ?? viewModelInstanceName;
189
+ const artboardName = params?.artboardName;
190
+ const viewModelName = params?.viewModelName;
106
191
  const useNew = params?.useNew ?? false;
107
192
  const required = params?.required ?? false;
108
193
  const onInit = params?.onInit;
109
194
  const prevInstanceRef = useRef(null);
110
195
  const result = useMemo(() => {
111
- const created = createInstance(source, name, useNew);
196
+ const created = createInstance(source, instanceName, artboardName, viewModelName, useNew);
112
197
  if (created.instance && onInit) {
113
198
  onInit(created.instance);
114
199
  }
115
200
  return created;
116
201
  // eslint-disable-next-line react-hooks/exhaustive-deps -- onInit excluded intentionally
117
- }, [source, name, useNew]);
202
+ }, [source, instanceName, artboardName, viewModelName, useNew]);
118
203
 
119
204
  // Dispose previous instance if it changed and needed disposal
120
205
  if (prevInstanceRef.current && prevInstanceRef.current.instance !== result.instance && prevInstanceRef.current.needsDispose && prevInstanceRef.current.instance) {
@@ -132,7 +217,7 @@ export function useViewModelInstance(source, params) {
132
217
  };
133
218
  }, []);
134
219
  if (required && result.instance === null) {
135
- throw new Error('useViewModelInstance: Failed to get ViewModelInstance. ' + 'Ensure the source has a valid ViewModel and instance available.');
220
+ throw new Error(result.error ? `useViewModelInstance: ${result.error}` : 'useViewModelInstance: Failed to get ViewModelInstance. ' + 'Ensure the source has a valid ViewModel and instance available.');
136
221
  }
137
222
  return result.instance;
138
223
  }
@@ -1 +1 @@
1
- {"version":3,"names":["useMemo","useEffect","useRef","callDispose","isRiveViewRef","source","undefined","isRiveFile","createInstance","name","useNew","instance","needsDispose","vmi","getViewModelInstance","viewModel","defaultArtboardViewModel","createDefaultInstance","createInstanceByName","useViewModelInstance","params","required","onInit","prevInstanceRef","result","created","current","Error"],"sourceRoot":"../../../src","sources":["hooks/useViewModelInstance.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["useMemo","useEffect","useRef","callDispose","ArtboardByName","isRiveViewRef","source","isRiveFile","createInstance","instanceName","artboardName","viewModelName","useNew","instance","needsDispose","vmi","getViewModelInstance","viewModel","viewModelByName","error","defaultArtboardViewModel","undefined","createInstanceByName","createDefaultInstance","useViewModelInstance","params","fileInstanceName","viewModelInstanceName","name","required","onInit","prevInstanceRef","result","created","current","Error"],"sourceRoot":"../../../src","sources":["hooks/useViewModelInstance.ts"],"mappings":"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","ignoreList":[]}
@@ -1,15 +1,7 @@
1
1
  import type { ViewModel, ViewModelInstance } from '../specs/ViewModel.nitro';
2
2
  import type { RiveFile } from '../specs/RiveFile.nitro';
3
3
  import type { RiveViewRef } from '../index';
4
- export interface UseViewModelInstanceParams {
5
- /**
6
- * Get a specifically named instance from the ViewModel.
7
- */
8
- name?: string;
9
- /**
10
- * Create a new (blank) instance from the ViewModel.
11
- */
12
- useNew?: boolean;
4
+ interface UseViewModelInstanceBaseParams {
13
5
  /**
14
6
  * If true, throws an error when the instance cannot be obtained.
15
7
  * This is useful with Error Boundaries and ensures TypeScript knows
@@ -23,12 +15,60 @@ export interface UseViewModelInstanceParams {
23
15
  */
24
16
  onInit?: (instance: ViewModelInstance) => void;
25
17
  }
26
- type ViewModelSource = ViewModel | RiveFile | RiveViewRef;
18
+ interface UseViewModelInstanceFileBaseParams extends UseViewModelInstanceBaseParams {
19
+ /**
20
+ * The ViewModel instance name (uses `createInstanceByName()`).
21
+ * If not provided, creates the default instance.
22
+ */
23
+ instanceName?: string;
24
+ }
25
+ /**
26
+ * Use the ViewModel assigned to the default artboard.
27
+ */
28
+ interface UseViewModelInstanceFileDefault extends UseViewModelInstanceFileBaseParams {
29
+ artboardName?: never;
30
+ viewModelName?: never;
31
+ }
32
+ /**
33
+ * Use the ViewModel assigned to a specific artboard.
34
+ */
35
+ interface UseViewModelInstanceFileByArtboard extends UseViewModelInstanceFileBaseParams {
36
+ /**
37
+ * Get the ViewModel assigned to this artboard.
38
+ */
39
+ artboardName: string;
40
+ viewModelName?: never;
41
+ }
42
+ /**
43
+ * Use a ViewModel by name (file-wide lookup).
44
+ * ViewModels are defined at the file level, not per-artboard.
45
+ */
46
+ interface UseViewModelInstanceFileByViewModelName extends UseViewModelInstanceFileBaseParams {
47
+ artboardName?: never;
48
+ /**
49
+ * The name of the ViewModel to use (uses `viewModelByName()`).
50
+ * ViewModels are defined at the file level and looked up by name across the entire file.
51
+ */
52
+ viewModelName: string;
53
+ }
54
+ export type UseViewModelInstanceFileParams = UseViewModelInstanceFileDefault | UseViewModelInstanceFileByArtboard | UseViewModelInstanceFileByViewModelName;
55
+ export interface UseViewModelInstanceViewModelParams extends UseViewModelInstanceBaseParams {
56
+ /**
57
+ * The ViewModel instance name (uses `createInstanceByName()`).
58
+ * If not provided, creates the default instance.
59
+ */
60
+ name?: string;
61
+ /**
62
+ * Create a new (blank) instance from the ViewModel.
63
+ */
64
+ useNew?: boolean;
65
+ }
66
+ export type UseViewModelInstanceRefParams = UseViewModelInstanceBaseParams;
27
67
  /**
28
68
  * Hook for getting a ViewModelInstance from a RiveFile, ViewModel, or RiveViewRef.
29
69
  *
30
70
  * @param source - The RiveFile, ViewModel, or RiveViewRef to get an instance from
31
- * @param params - Configuration for which instance to retrieve (only used with ViewModel)
71
+ * @param params - Configuration for which instance to retrieve
32
72
  * @returns The ViewModelInstance or null if not found
33
73
  *
34
74
  * @example
@@ -40,6 +80,27 @@ type ViewModelSource = ViewModel | RiveFile | RiveViewRef;
40
80
  *
41
81
  * @example
42
82
  * ```tsx
83
+ * // From RiveFile with specific instance name
84
+ * const { riveFile } = useRiveFile(require('./animation.riv'));
85
+ * const instance = useViewModelInstance(riveFile, { instanceName: 'PersonInstance' });
86
+ * ```
87
+ *
88
+ * @example
89
+ * ```tsx
90
+ * // From RiveFile with specific ViewModel name
91
+ * const { riveFile } = useRiveFile(require('./animation.riv'));
92
+ * const instance = useViewModelInstance(riveFile, { viewModelName: 'Settings' });
93
+ * ```
94
+ *
95
+ * @example
96
+ * ```tsx
97
+ * // From RiveFile with specific artboard
98
+ * const { riveFile } = useRiveFile(require('./animation.riv'));
99
+ * const instance = useViewModelInstance(riveFile, { artboardName: 'MainArtboard' });
100
+ * ```
101
+ *
102
+ * @example
103
+ * ```tsx
43
104
  * // From RiveViewRef (get auto-bound instance)
44
105
  * const { riveViewRef, setHybridRef } = useRive();
45
106
  * const instance = useViewModelInstance(riveViewRef);
@@ -78,9 +139,17 @@ type ViewModelSource = ViewModel | RiveFile | RiveViewRef;
78
139
  * // Values are already set here
79
140
  * ```
80
141
  */
81
- export declare function useViewModelInstance(source: ViewModelSource, params: UseViewModelInstanceParams & {
142
+ export declare function useViewModelInstance(source: RiveFile, params: UseViewModelInstanceFileParams & {
143
+ required: true;
144
+ }): ViewModelInstance;
145
+ export declare function useViewModelInstance(source: RiveFile | null, params?: UseViewModelInstanceFileParams): ViewModelInstance | null;
146
+ export declare function useViewModelInstance(source: ViewModel, params: UseViewModelInstanceViewModelParams & {
147
+ required: true;
148
+ }): ViewModelInstance;
149
+ export declare function useViewModelInstance(source: ViewModel | null, params?: UseViewModelInstanceViewModelParams): ViewModelInstance | null;
150
+ export declare function useViewModelInstance(source: RiveViewRef, params: UseViewModelInstanceRefParams & {
82
151
  required: true;
83
152
  }): ViewModelInstance;
84
- export declare function useViewModelInstance(source: ViewModelSource | null, params?: UseViewModelInstanceParams): ViewModelInstance | null;
153
+ export declare function useViewModelInstance(source: RiveViewRef | null, params?: UseViewModelInstanceRefParams): ViewModelInstance | null;
85
154
  export {};
86
155
  //# sourceMappingURL=useViewModelInstance.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useViewModelInstance.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useViewModelInstance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAChD;AAED,KAAK,eAAe,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAgD1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,0BAA0B,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GACtD,iBAAiB,CAAC;AACrB,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,eAAe,GAAG,IAAI,EAC9B,MAAM,CAAC,EAAE,0BAA0B,GAClC,iBAAiB,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"useViewModelInstance.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useViewModelInstance.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAI5C,UAAU,8BAA8B;IACtC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAChD;AAED,UAAU,kCACR,SAAQ,8BAA8B;IACtC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,UAAU,+BACR,SAAQ,kCAAkC;IAC1C,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,aAAa,CAAC,EAAE,KAAK,CAAC;CACvB;AAED;;GAEG;AACH,UAAU,kCACR,SAAQ,kCAAkC;IAC1C;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,KAAK,CAAC;CACvB;AAED;;;GAGG;AACH,UAAU,uCACR,SAAQ,kCAAkC;IAC1C,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,8BAA8B,GACtC,+BAA+B,GAC/B,kCAAkC,GAClC,uCAAuC,CAAC;AAE5C,MAAM,WAAW,mCACf,SAAQ,8BAA8B;IACtC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,6BAA6B,GAAG,8BAA8B,CAAC;AA4F3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AAEH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,8BAA8B,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GAC1D,iBAAiB,CAAC;AACrB,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,QAAQ,GAAG,IAAI,EACvB,MAAM,CAAC,EAAE,8BAA8B,GACtC,iBAAiB,GAAG,IAAI,CAAC;AAG5B,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,mCAAmC,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GAC/D,iBAAiB,CAAC;AACrB,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,GAAG,IAAI,EACxB,MAAM,CAAC,EAAE,mCAAmC,GAC3C,iBAAiB,GAAG,IAAI,CAAC;AAG5B,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,6BAA6B,GAAG;IAAE,QAAQ,EAAE,IAAI,CAAA;CAAE,GACzD,iBAAiB,CAAC;AACrB,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,MAAM,CAAC,EAAE,6BAA6B,GACrC,iBAAiB,GAAG,IAAI,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rive-app/react-native",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Rive React Native",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -3,16 +3,9 @@ import type { ViewModel, ViewModelInstance } from '../specs/ViewModel.nitro';
3
3
  import type { RiveFile } from '../specs/RiveFile.nitro';
4
4
  import type { RiveViewRef } from '../index';
5
5
  import { callDispose } from '../core/callDispose';
6
+ import { ArtboardByName } from '../specs/ArtboardBy';
6
7
 
7
- export interface UseViewModelInstanceParams {
8
- /**
9
- * Get a specifically named instance from the ViewModel.
10
- */
11
- name?: string;
12
- /**
13
- * Create a new (blank) instance from the ViewModel.
14
- */
15
- useNew?: boolean;
8
+ interface UseViewModelInstanceBaseParams {
16
9
  /**
17
10
  * If true, throws an error when the instance cannot be obtained.
18
11
  * This is useful with Error Boundaries and ensures TypeScript knows
@@ -27,27 +20,93 @@ export interface UseViewModelInstanceParams {
27
20
  onInit?: (instance: ViewModelInstance) => void;
28
21
  }
29
22
 
23
+ interface UseViewModelInstanceFileBaseParams
24
+ extends UseViewModelInstanceBaseParams {
25
+ /**
26
+ * The ViewModel instance name (uses `createInstanceByName()`).
27
+ * If not provided, creates the default instance.
28
+ */
29
+ instanceName?: string;
30
+ }
31
+
32
+ /**
33
+ * Use the ViewModel assigned to the default artboard.
34
+ */
35
+ interface UseViewModelInstanceFileDefault
36
+ extends UseViewModelInstanceFileBaseParams {
37
+ artboardName?: never;
38
+ viewModelName?: never;
39
+ }
40
+
41
+ /**
42
+ * Use the ViewModel assigned to a specific artboard.
43
+ */
44
+ interface UseViewModelInstanceFileByArtboard
45
+ extends UseViewModelInstanceFileBaseParams {
46
+ /**
47
+ * Get the ViewModel assigned to this artboard.
48
+ */
49
+ artboardName: string;
50
+ viewModelName?: never;
51
+ }
52
+
53
+ /**
54
+ * Use a ViewModel by name (file-wide lookup).
55
+ * ViewModels are defined at the file level, not per-artboard.
56
+ */
57
+ interface UseViewModelInstanceFileByViewModelName
58
+ extends UseViewModelInstanceFileBaseParams {
59
+ artboardName?: never;
60
+ /**
61
+ * The name of the ViewModel to use (uses `viewModelByName()`).
62
+ * ViewModels are defined at the file level and looked up by name across the entire file.
63
+ */
64
+ viewModelName: string;
65
+ }
66
+
67
+ export type UseViewModelInstanceFileParams =
68
+ | UseViewModelInstanceFileDefault
69
+ | UseViewModelInstanceFileByArtboard
70
+ | UseViewModelInstanceFileByViewModelName;
71
+
72
+ export interface UseViewModelInstanceViewModelParams
73
+ extends UseViewModelInstanceBaseParams {
74
+ /**
75
+ * The ViewModel instance name (uses `createInstanceByName()`).
76
+ * If not provided, creates the default instance.
77
+ */
78
+ name?: string;
79
+ /**
80
+ * Create a new (blank) instance from the ViewModel.
81
+ */
82
+ useNew?: boolean;
83
+ }
84
+
85
+ export type UseViewModelInstanceRefParams = UseViewModelInstanceBaseParams;
86
+
30
87
  type ViewModelSource = ViewModel | RiveFile | RiveViewRef;
31
88
 
32
89
  function isRiveViewRef(source: ViewModelSource | null): source is RiveViewRef {
33
- return (
34
- source !== null && source !== undefined && 'getViewModelInstance' in source
35
- );
90
+ return source !== null && 'getViewModelInstance' in source;
36
91
  }
37
92
 
38
93
  function isRiveFile(source: ViewModelSource | null): source is RiveFile {
39
- return (
40
- source !== null &&
41
- source !== undefined &&
42
- 'defaultArtboardViewModel' in source
43
- );
94
+ return source !== null && 'defaultArtboardViewModel' in source;
44
95
  }
45
96
 
97
+ type CreateInstanceResult = {
98
+ instance: ViewModelInstance | null;
99
+ needsDispose: boolean;
100
+ error?: string;
101
+ };
102
+
46
103
  function createInstance(
47
104
  source: ViewModelSource | null,
48
- name: string | undefined,
105
+ instanceName: string | undefined,
106
+ artboardName: string | undefined,
107
+ viewModelName: string | undefined,
49
108
  useNew: boolean
50
- ): { instance: ViewModelInstance | null; needsDispose: boolean } {
109
+ ): CreateInstanceResult {
51
110
  if (!source) {
52
111
  return { instance: null, needsDispose: false };
53
112
  }
@@ -58,15 +117,55 @@ function createInstance(
58
117
  }
59
118
 
60
119
  if (isRiveFile(source)) {
61
- const viewModel = source.defaultArtboardViewModel();
62
- const vmi = viewModel?.createDefaultInstance();
120
+ let viewModel: ViewModel | undefined;
121
+ if (viewModelName) {
122
+ viewModel = source.viewModelByName(viewModelName);
123
+ if (!viewModel) {
124
+ return {
125
+ instance: null,
126
+ needsDispose: false,
127
+ error: `ViewModel '${viewModelName}' not found`,
128
+ };
129
+ }
130
+ } else {
131
+ viewModel = source.defaultArtboardViewModel(
132
+ artboardName ? ArtboardByName(artboardName) : undefined
133
+ );
134
+ if (!viewModel) {
135
+ if (artboardName) {
136
+ return {
137
+ instance: null,
138
+ needsDispose: false,
139
+ error: `Artboard '${artboardName}' not found or has no ViewModel`,
140
+ };
141
+ }
142
+ return { instance: null, needsDispose: false };
143
+ }
144
+ }
145
+ const vmi = instanceName
146
+ ? viewModel.createInstanceByName(instanceName)
147
+ : viewModel.createDefaultInstance();
148
+ if (!vmi && instanceName) {
149
+ return {
150
+ instance: null,
151
+ needsDispose: false,
152
+ error: `ViewModel instance '${instanceName}' not found`,
153
+ };
154
+ }
63
155
  return { instance: vmi ?? null, needsDispose: true };
64
156
  }
65
157
 
66
158
  // ViewModel source
67
159
  let vmi: ViewModelInstance | undefined;
68
- if (name) {
69
- vmi = source.createInstanceByName(name);
160
+ if (instanceName) {
161
+ vmi = source.createInstanceByName(instanceName);
162
+ if (!vmi) {
163
+ return {
164
+ instance: null,
165
+ needsDispose: false,
166
+ error: `ViewModel instance '${instanceName}' not found`,
167
+ };
168
+ }
70
169
  } else if (useNew) {
71
170
  vmi = source.createInstance();
72
171
  } else {
@@ -79,7 +178,7 @@ function createInstance(
79
178
  * Hook for getting a ViewModelInstance from a RiveFile, ViewModel, or RiveViewRef.
80
179
  *
81
180
  * @param source - The RiveFile, ViewModel, or RiveViewRef to get an instance from
82
- * @param params - Configuration for which instance to retrieve (only used with ViewModel)
181
+ * @param params - Configuration for which instance to retrieve
83
182
  * @returns The ViewModelInstance or null if not found
84
183
  *
85
184
  * @example
@@ -91,6 +190,27 @@ function createInstance(
91
190
  *
92
191
  * @example
93
192
  * ```tsx
193
+ * // From RiveFile with specific instance name
194
+ * const { riveFile } = useRiveFile(require('./animation.riv'));
195
+ * const instance = useViewModelInstance(riveFile, { instanceName: 'PersonInstance' });
196
+ * ```
197
+ *
198
+ * @example
199
+ * ```tsx
200
+ * // From RiveFile with specific ViewModel name
201
+ * const { riveFile } = useRiveFile(require('./animation.riv'));
202
+ * const instance = useViewModelInstance(riveFile, { viewModelName: 'Settings' });
203
+ * ```
204
+ *
205
+ * @example
206
+ * ```tsx
207
+ * // From RiveFile with specific artboard
208
+ * const { riveFile } = useRiveFile(require('./animation.riv'));
209
+ * const instance = useViewModelInstance(riveFile, { artboardName: 'MainArtboard' });
210
+ * ```
211
+ *
212
+ * @example
213
+ * ```tsx
94
214
  * // From RiveViewRef (get auto-bound instance)
95
215
  * const { riveViewRef, setHybridRef } = useRive();
96
216
  * const instance = useViewModelInstance(riveViewRef);
@@ -129,20 +249,55 @@ function createInstance(
129
249
  * // Values are already set here
130
250
  * ```
131
251
  */
252
+ // RiveFile overloads
132
253
  export function useViewModelInstance(
133
- source: ViewModelSource,
134
- params: UseViewModelInstanceParams & { required: true }
254
+ source: RiveFile,
255
+ params: UseViewModelInstanceFileParams & { required: true }
135
256
  ): ViewModelInstance;
136
257
  export function useViewModelInstance(
137
- source: ViewModelSource | null,
138
- params?: UseViewModelInstanceParams
258
+ source: RiveFile | null,
259
+ params?: UseViewModelInstanceFileParams
260
+ ): ViewModelInstance | null;
261
+
262
+ // ViewModel overloads
263
+ export function useViewModelInstance(
264
+ source: ViewModel,
265
+ params: UseViewModelInstanceViewModelParams & { required: true }
266
+ ): ViewModelInstance;
267
+ export function useViewModelInstance(
268
+ source: ViewModel | null,
269
+ params?: UseViewModelInstanceViewModelParams
139
270
  ): ViewModelInstance | null;
271
+
272
+ // RiveViewRef overloads
273
+ export function useViewModelInstance(
274
+ source: RiveViewRef,
275
+ params: UseViewModelInstanceRefParams & { required: true }
276
+ ): ViewModelInstance;
277
+ export function useViewModelInstance(
278
+ source: RiveViewRef | null,
279
+ params?: UseViewModelInstanceRefParams
280
+ ): ViewModelInstance | null;
281
+
282
+ // Implementation
140
283
  export function useViewModelInstance(
141
284
  source: ViewModelSource | null,
142
- params?: UseViewModelInstanceParams
285
+ params?:
286
+ | UseViewModelInstanceFileParams
287
+ | UseViewModelInstanceViewModelParams
288
+ | UseViewModelInstanceRefParams
143
289
  ): ViewModelInstance | null {
144
- const name = params?.name;
145
- const useNew = params?.useNew ?? false;
290
+ const fileInstanceName = (params as { instanceName?: string } | undefined)
291
+ ?.instanceName;
292
+ const viewModelInstanceName = (params as { name?: string } | undefined)?.name;
293
+ const instanceName = fileInstanceName ?? viewModelInstanceName;
294
+ const artboardName = (params as UseViewModelInstanceFileParams | undefined)
295
+ ?.artboardName;
296
+ const viewModelName = (params as UseViewModelInstanceFileParams | undefined)
297
+ ?.viewModelName;
298
+ const useNew =
299
+ (params as UseViewModelInstanceViewModelParams | undefined)?.useNew ??
300
+ false;
146
301
  const required = params?.required ?? false;
147
302
  const onInit = params?.onInit;
148
303
 
@@ -152,13 +307,19 @@ export function useViewModelInstance(
152
307
  } | null>(null);
153
308
 
154
309
  const result = useMemo(() => {
155
- const created = createInstance(source, name, useNew);
310
+ const created = createInstance(
311
+ source,
312
+ instanceName,
313
+ artboardName,
314
+ viewModelName,
315
+ useNew
316
+ );
156
317
  if (created.instance && onInit) {
157
318
  onInit(created.instance);
158
319
  }
159
320
  return created;
160
321
  // eslint-disable-next-line react-hooks/exhaustive-deps -- onInit excluded intentionally
161
- }, [source, name, useNew]);
322
+ }, [source, instanceName, artboardName, viewModelName, useNew]);
162
323
 
163
324
  // Dispose previous instance if it changed and needed disposal
164
325
  if (
@@ -186,8 +347,10 @@ export function useViewModelInstance(
186
347
 
187
348
  if (required && result.instance === null) {
188
349
  throw new Error(
189
- 'useViewModelInstance: Failed to get ViewModelInstance. ' +
190
- 'Ensure the source has a valid ViewModel and instance available.'
350
+ result.error
351
+ ? `useViewModelInstance: ${result.error}`
352
+ : 'useViewModelInstance: Failed to get ViewModelInstance. ' +
353
+ 'Ensure the source has a valid ViewModel and instance available.'
191
354
  );
192
355
  }
193
356