From 9a86b0e26501744b1c64ed67c87f01f7e67effa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Fazekas?= Date: Thu, 18 Dec 2025 17:30:09 +0100 Subject: [PATCH] feat: add DataBinding example with interactive controls Port DataBinding example from old rive-react-native with modal UI for string, number, and color property controls. Adds @navigation alias for cross-platform header button support. --- example/package.json | 1 + example/src/navigation.ts | 1 + example/src/pages/DataBinding.tsx | 432 +++++++++++++++++++ example/src/pages/RiveDataBindingExample.tsx | 132 ------ example/src/pages/index.ts | 2 +- example/tsconfig.json | 10 + expo-example/navigation.ts | 1 + expo-example/package.json | 1 + expo-example/tsconfig.json | 1 + yarn.lock | 9 + 10 files changed, 457 insertions(+), 133 deletions(-) create mode 100644 example/src/navigation.ts create mode 100644 example/src/pages/DataBinding.tsx delete mode 100644 example/src/pages/RiveDataBindingExample.tsx create mode 100644 example/tsconfig.json create mode 100644 expo-example/navigation.ts diff --git a/example/package.json b/example/package.json index f73d6cc5..9792985c 100644 --- a/example/package.json +++ b/example/package.json @@ -10,6 +10,7 @@ "build:ios": "react-native build-ios --mode Debug" }, "dependencies": { + "@react-native-community/slider": "^5.1.1", "@react-native-picker/picker": "^2.11.4", "@react-navigation/native": "^7.1.9", "@react-navigation/stack": "^7.3.2", diff --git a/example/src/navigation.ts b/example/src/navigation.ts new file mode 100644 index 00000000..1d0da216 --- /dev/null +++ b/example/src/navigation.ts @@ -0,0 +1 @@ +export { useNavigation } from '@react-navigation/native'; diff --git a/example/src/pages/DataBinding.tsx b/example/src/pages/DataBinding.tsx new file mode 100644 index 00000000..2b8dd61d --- /dev/null +++ b/example/src/pages/DataBinding.tsx @@ -0,0 +1,432 @@ +import { useEffect, useState, useRef } from 'react'; +import { + ScrollView, + StyleSheet, + View, + TextInput, + Text, + Modal, + Button, +} from 'react-native'; +import { + Fit, + RiveView, + RiveColor, + useRiveFile, + useViewModelInstance, + useRiveColor, + useRiveNumber, + useRiveString, + useRiveTrigger, +} from '@rive-app/react-native'; +import Slider from '@react-native-community/slider'; +import { useNavigation } from '@navigation'; +import type { Metadata } from '../helpers/metadata'; + +export default function DataBinding() { + const navigation = useNavigation(); + const { riveFile } = useRiveFile(require('../../assets/rive/rewards.riv')); + const viewModelInstance = useViewModelInstance(riveFile); + + const { value: buttonText, setValue: setButtonText } = useRiveString( + 'Button/State_1', + viewModelInstance + ); + const { value: lives, setValue: setLives } = useRiveNumber( + 'Energy_Bar/Lives', + viewModelInstance + ); + const { value: barColor, setValue: setBarColor } = useRiveColor( + 'Energy_Bar/Bar_Color', + viewModelInstance + ); + const { value: price, setValue: setPrice } = useRiveNumber( + 'Price_Value', + viewModelInstance + ); + const { value: coinValue } = useRiveNumber( + 'Coin/Item_Value', + viewModelInstance + ); + + useRiveTrigger('Button/Pressed', viewModelInstance, { + onTrigger: () => console.log('Button pressed'), + }); + + useEffect(() => { + if (coinValue !== undefined) { + console.log('coinValue changed:', coinValue); + } + }, [coinValue]); + + const [isOpen, setIsOpen] = useState(false); + + useEffect(() => { + navigation.setOptions({ + // eslint-disable-next-line react/no-unstable-nested-components + headerRight: () => ( +