@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.
- package/lib/module/hooks/useViewModelInstance.js +97 -12
- package/lib/module/hooks/useViewModelInstance.js.map +1 -1
- package/lib/typescript/src/hooks/useViewModelInstance.d.ts +82 -13
- package/lib/typescript/src/hooks/useViewModelInstance.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/hooks/useViewModelInstance.ts +198 -35
|
@@ -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 &&
|
|
21
|
+
return source !== null && 'getViewModelInstance' in source;
|
|
7
22
|
}
|
|
8
23
|
function isRiveFile(source) {
|
|
9
|
-
return source !== null &&
|
|
24
|
+
return source !== null && 'defaultArtboardViewModel' in source;
|
|
10
25
|
}
|
|
11
|
-
function createInstance(source,
|
|
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
|
-
|
|
27
|
-
|
|
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 (
|
|
37
|
-
vmi = source.createInstanceByName(
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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","
|
|
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":";;AAAA,SAASA,OAAO,EAAEC,SAAS,EAAEC,MAAM,QAAQ,OAAO;AAIlD,SAASC,WAAW,QAAQ,wBAAqB;AACjD,SAASC,cAAc,QAAQ,wBAAqB;;AA0BpD;AACA;AACA;;AAOA;AACA;AACA;;AAUA;AACA;AACA;AACA;;AAiCA,SAASC,aAAaA,CAACC,MAA8B,EAAyB;EAC5E,OAAOA,MAAM,KAAK,IAAI,IAAI,sBAAsB,IAAIA,MAAM;AAC5D;AAEA,SAASC,UAAUA,CAACD,MAA8B,EAAsB;EACtE,OAAOA,MAAM,KAAK,IAAI,IAAI,0BAA0B,IAAIA,MAAM;AAChE;AAQA,SAASE,cAAcA,CACrBF,MAA8B,EAC9BG,YAAgC,EAChCC,YAAgC,EAChCC,aAAiC,EACjCC,MAAe,EACO;EACtB,IAAI,CAACN,MAAM,EAAE;IACX,OAAO;MAAEO,QAAQ,EAAE,IAAI;MAAEC,YAAY,EAAE;IAAM,CAAC;EAChD;EAEA,IAAIT,aAAa,CAACC,MAAM,CAAC,EAAE;IACzB,MAAMS,GAAG,GAAGT,MAAM,CAACU,oBAAoB,CAAC,CAAC;IACzC,OAAO;MAAEH,QAAQ,EAAEE,GAAG,IAAI,IAAI;MAAED,YAAY,EAAE;IAAM,CAAC;EACvD;EAEA,IAAIP,UAAU,CAACD,MAAM,CAAC,EAAE;IACtB,IAAIW,SAAgC;IACpC,IAAIN,aAAa,EAAE;MACjBM,SAAS,GAAGX,MAAM,CAACY,eAAe,CAACP,aAAa,CAAC;MACjD,IAAI,CAACM,SAAS,EAAE;QACd,OAAO;UACLJ,QAAQ,EAAE,IAAI;UACdC,YAAY,EAAE,KAAK;UACnBK,KAAK,EAAE,cAAcR,aAAa;QACpC,CAAC;MACH;IACF,CAAC,MAAM;MACLM,SAAS,GAAGX,MAAM,CAACc,wBAAwB,CACzCV,YAAY,GAAGN,cAAc,CAACM,YAAY,CAAC,GAAGW,SAChD,CAAC;MACD,IAAI,CAACJ,SAAS,EAAE;QACd,IAAIP,YAAY,EAAE;UAChB,OAAO;YACLG,QAAQ,EAAE,IAAI;YACdC,YAAY,EAAE,KAAK;YACnBK,KAAK,EAAE,aAAaT,YAAY;UAClC,CAAC;QACH;QACA,OAAO;UAAEG,QAAQ,EAAE,IAAI;UAAEC,YAAY,EAAE;QAAM,CAAC;MAChD;IACF;IACA,MAAMC,GAAG,GAAGN,YAAY,GACpBQ,SAAS,CAACK,oBAAoB,CAACb,YAAY,CAAC,GAC5CQ,SAAS,CAACM,qBAAqB,CAAC,CAAC;IACrC,IAAI,CAACR,GAAG,IAAIN,YAAY,EAAE;MACxB,OAAO;QACLI,QAAQ,EAAE,IAAI;QACdC,YAAY,EAAE,KAAK;QACnBK,KAAK,EAAE,uBAAuBV,YAAY;MAC5C,CAAC;IACH;IACA,OAAO;MAAEI,QAAQ,EAAEE,GAAG,IAAI,IAAI;MAAED,YAAY,EAAE;IAAK,CAAC;EACtD;;EAEA;EACA,IAAIC,GAAkC;EACtC,IAAIN,YAAY,EAAE;IAChBM,GAAG,GAAGT,MAAM,CAACgB,oBAAoB,CAACb,YAAY,CAAC;IAC/C,IAAI,CAACM,GAAG,EAAE;MACR,OAAO;QACLF,QAAQ,EAAE,IAAI;QACdC,YAAY,EAAE,KAAK;QACnBK,KAAK,EAAE,uBAAuBV,YAAY;MAC5C,CAAC;IACH;EACF,CAAC,MAAM,IAAIG,MAAM,EAAE;IACjBG,GAAG,GAAGT,MAAM,CAACE,cAAc,CAAC,CAAC;EAC/B,CAAC,MAAM;IACLO,GAAG,GAAGT,MAAM,CAACiB,qBAAqB,CAAC,CAAC;EACtC;EACA,OAAO;IAAEV,QAAQ,EAAEE,GAAG,IAAI,IAAI;IAAED,YAAY,EAAE;EAAK,CAAC;AACtD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUA;;AAUA;;AAUA;AACA,OAAO,SAASU,oBAAoBA,CAClClB,MAA8B,EAC9BmB,MAGiC,EACP;EAC1B,MAAMC,gBAAgB,GAAID,MAAM,EAC5BhB,YAAY;EAChB,MAAMkB,qBAAqB,GAAIF,MAAM,EAAoCG,IAAI;EAC7E,MAAMnB,YAAY,GAAGiB,gBAAgB,IAAIC,qBAAqB;EAC9D,MAAMjB,YAAY,GAAIe,MAAM,EACxBf,YAAY;EAChB,MAAMC,aAAa,GAAIc,MAAM,EACzBd,aAAa;EACjB,MAAMC,MAAM,GACTa,MAAM,EAAsDb,MAAM,IACnE,KAAK;EACP,MAAMiB,QAAQ,GAAGJ,MAAM,EAAEI,QAAQ,IAAI,KAAK;EAC1C,MAAMC,MAAM,GAAGL,MAAM,EAAEK,MAAM;EAE7B,MAAMC,eAAe,GAAG7B,MAAM,CAGpB,IAAI,CAAC;EAEf,MAAM8B,MAAM,GAAGhC,OAAO,CAAC,MAAM;IAC3B,MAAMiC,OAAO,GAAGzB,cAAc,CAC5BF,MAAM,EACNG,YAAY,EACZC,YAAY,EACZC,aAAa,EACbC,MACF,CAAC;IACD,IAAIqB,OAAO,CAACpB,QAAQ,IAAIiB,MAAM,EAAE;MAC9BA,MAAM,CAACG,OAAO,CAACpB,QAAQ,CAAC;IAC1B;IACA,OAAOoB,OAAO;IACd;EACF,CAAC,EAAE,CAAC3B,MAAM,EAAEG,YAAY,EAAEC,YAAY,EAAEC,aAAa,EAAEC,MAAM,CAAC,CAAC;;EAE/D;EACA,IACEmB,eAAe,CAACG,OAAO,IACvBH,eAAe,CAACG,OAAO,CAACrB,QAAQ,KAAKmB,MAAM,CAACnB,QAAQ,IACpDkB,eAAe,CAACG,OAAO,CAACpB,YAAY,IACpCiB,eAAe,CAACG,OAAO,CAACrB,QAAQ,EAChC;IACAV,WAAW,CAAC4B,eAAe,CAACG,OAAO,CAACrB,QAAQ,CAAC;EAC/C;EACAkB,eAAe,CAACG,OAAO,GAAGF,MAAM;;EAEhC;EACA/B,SAAS,CAAC,MAAM;IACd,OAAO,MAAM;MACX,IACE8B,eAAe,CAACG,OAAO,EAAEpB,YAAY,IACrCiB,eAAe,CAACG,OAAO,CAACrB,QAAQ,EAChC;QACAV,WAAW,CAAC4B,eAAe,CAACG,OAAO,CAACrB,QAAQ,CAAC;QAC7CkB,eAAe,CAACG,OAAO,GAAG,IAAI;MAChC;IACF,CAAC;EACH,CAAC,EAAE,EAAE,CAAC;EAEN,IAAIL,QAAQ,IAAIG,MAAM,CAACnB,QAAQ,KAAK,IAAI,EAAE;IACxC,MAAM,IAAIsB,KAAK,CACbH,MAAM,CAACb,KAAK,GACR,yBAAyBa,MAAM,CAACb,KAAK,EAAE,GACvC,yDAAyD,GACzD,iEACN,CAAC;EACH;EAEA,OAAOa,MAAM,CAACnB,QAAQ;AACxB","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
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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;
|
|
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
|
@@ -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
|
-
|
|
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
|
-
|
|
105
|
+
instanceName: string | undefined,
|
|
106
|
+
artboardName: string | undefined,
|
|
107
|
+
viewModelName: string | undefined,
|
|
49
108
|
useNew: boolean
|
|
50
|
-
):
|
|
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
|
-
|
|
62
|
-
|
|
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 (
|
|
69
|
-
vmi = source.createInstanceByName(
|
|
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
|
|
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:
|
|
134
|
-
params:
|
|
254
|
+
source: RiveFile,
|
|
255
|
+
params: UseViewModelInstanceFileParams & { required: true }
|
|
135
256
|
): ViewModelInstance;
|
|
136
257
|
export function useViewModelInstance(
|
|
137
|
-
source:
|
|
138
|
-
params?:
|
|
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?:
|
|
285
|
+
params?:
|
|
286
|
+
| UseViewModelInstanceFileParams
|
|
287
|
+
| UseViewModelInstanceViewModelParams
|
|
288
|
+
| UseViewModelInstanceRefParams
|
|
143
289
|
): ViewModelInstance | null {
|
|
144
|
-
const
|
|
145
|
-
|
|
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(
|
|
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,
|
|
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
|
-
|
|
190
|
-
|
|
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
|
|