From 0cdc246b6873fdd4039803de63be85a7058be5cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Fazekas?= Date: Fri, 7 Nov 2025 09:45:55 +0100 Subject: [PATCH] feat: allow RiveView to be called with a file argument --- src/core/RiveView.tsx | 75 +++++++++++++++++++++++++++++++++++++ src/index.tsx | 3 +- src/specs/RiveView.nitro.ts | 4 -- 3 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 src/core/RiveView.tsx diff --git a/src/core/RiveView.tsx b/src/core/RiveView.tsx new file mode 100644 index 00000000..21527922 --- /dev/null +++ b/src/core/RiveView.tsx @@ -0,0 +1,75 @@ +import type { HybridViewProps } from 'react-native-nitro-modules'; +import type { RiveFile } from '../specs/RiveFile.nitro'; +import '../specs/RiveView.nitro'; +import type { Alignment } from './Alignment'; +import type { Fit } from './Fit'; +import { NitroRiveView } from 'react-native-rive'; +import type { ReferencedAssets } from '../hooks/useRiveFile'; +import type { RiveFileInput } from '../../lib/typescript/src'; +import { useRiveFile } from '../hooks/useRiveFile'; +import { ActivityIndicator, Text } from 'react-native'; +import type { ComponentProps } from 'react'; + +export interface RiveViewProps + extends Omit, 'file'> { + /** Name of the artboard to display from the Rive file */ + artboardName?: string; + /** Name of the state machine to play */ + stateMachineName?: string; + /** Whether to automatically bind the state machine and artboard */ + autoBind?: boolean; + /** Whether to automatically start playing the state machine */ + autoPlay?: boolean; + /** The Rive file to be displayed */ + file: RiveFile | RiveFileInput; + /** How the Rive graphic should be aligned within its container */ + alignment?: Alignment; + /** How the Rive graphic should fit within its container */ + fit?: Fit; + /** The scale factor to apply to the Rive graphic when using Fit.Layout */ + layoutScaleFactor?: number; + /** Referenced assets for out-of-band asset loading */ + referencedAssets?: ReferencedAssets; +} + +function isNitroFile(file: RiveFile | RiveFileInput): file is RiveFile { + return ( + typeof file === 'object' && + '__type' in file && + file.__type === 'HybridObject' + ); +} + +function RiveViewWithFileInput( + props: Omit & { + file: RiveFileInput; + referencedAssets?: ReferencedAssets; + } +) { + const { file, referencedAssets, ...rest } = props; + const { riveFile, isLoading, error } = useRiveFile(file, referencedAssets); + + if (isLoading) { + return ; + } else if (error != null) { + return {error}; + } else { + return ; + } +} + +export function RiveView(props: RiveViewProps) { + const { file, referencedAssets, ...rest } = props; + + if (isNitroFile(file)) { + return ; + } else { + return ( + + ); + } +} diff --git a/src/index.tsx b/src/index.tsx index 659e1301..12b86ccf 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -46,7 +46,7 @@ export function multiply(a: number, b: number): number { * - play(): Starts playing the animation * - pause(): Pauses the animation */ -export const RiveView = getHostComponent( +export const NitroRiveView = getHostComponent( 'RiveView', () => RiveViewConfig ) as ReactNativeView; @@ -78,3 +78,4 @@ export { useRiveColor } from './hooks/useRiveColor'; export { useRiveTrigger } from './hooks/useRiveTrigger'; export { useRiveFile } from './hooks/useRiveFile'; export { type RiveFileInput } from './hooks/useRiveFile'; +export { RiveView } from './core/RiveView'; diff --git a/src/specs/RiveView.nitro.ts b/src/specs/RiveView.nitro.ts index aaa3a890..09eb6d6d 100644 --- a/src/specs/RiveView.nitro.ts +++ b/src/specs/RiveView.nitro.ts @@ -105,8 +105,4 @@ export type RiveViewTSMethods = Exclude & { onEventListener(onEvent: (event: RiveEvent) => void): void; }; -/** - * Type definition for the RiveView component. - * Combines RiveViewProps and RiveViewMethods with the HybridView type. - */ export type RiveView = HybridView;