git.iko.soy/rowtype-yoga/purescript-yoga-react-native
on main help sign in
commit6d6898536ce9c61a3abcaba66bddfd3295645de7 authorMark <mark.eibes@gmail.com> dateFri 13 Feb 2026, 22:49 (8 months ago) parentc10bae7
6 files changed+153−5
example-macos/macos/Podfile+2 example-macos/macos/Podfile.lock+5−1 example-macos/macos/YogaReactExample-macOS/RCTMacOSControlsManager.m+101 example-macos/macos/YogaReactExample.xcodeproj/project.pbxproj+8−4 src/Yoga/React/Native/MacOS/Rive.js+16 src/Yoga/React/Native/MacOS/Rive.purs+21
example-macos/macos/Podfile+2
@@ -12,6 +12,8 @@ target 'YogaReactExample-macOS' do
1212 platform :macos, '14.0'
1313 use_native_modules!
1414
15+ pod 'RiveRuntime'
16+
1517 # Flags change depending on the env values.
1618 flags = get_default_flags()
1719
example-macos/macos/Podfile.lock+5−1
@@ -2341,6 +2341,7 @@ PODS:
23412341 - React-perflogger (= 0.81.2)
23422342 - React-utils (= 0.81.2)
23432343 - SocketRocket
2344+ - RiveRuntime (6.15.0)
23442345 - RNFS (2.20.0):
23452346 - React-Core
23462347 - SocketRocket (0.7.1)
@@ -2419,12 +2420,14 @@ DEPENDENCIES:
24192420 - ReactAppDependencyProvider (from `build/generated/ios`)
24202421 - ReactCodegen (from `build/generated/ios`)
24212422 - ReactCommon/turbomodule/core (from `../node_modules/react-native-macos/ReactCommon`)
2423+ - RiveRuntime
24222424 - RNFS (from `../node_modules/react-native-fs`)
24232425 - SocketRocket (~> 0.7.1)
24242426 - Yoga (from `../node_modules/react-native-macos/ReactCommon/yoga`)
24252427
24262428SPEC REPOS:
24272429 trunk:
2430+ - RiveRuntime
24282431 - SocketRocket
24292432
24302433EXTERNAL SOURCES:
@@ -2648,10 +2651,11 @@ SPEC CHECKSUMS:
26482651 ReactAppDependencyProvider: c684b86721380f663bc9476d7fffce805ba93b22
26492652 ReactCodegen: 71eeba9793ebeafd39bc9695d007b79fd8cad15e
26502653 ReactCommon: 9f8189efbc1aa52926df2791a2e47b3340353849
2654+ RiveRuntime: 6c9f2f9e07e3411532e9187e1708d007468b87dd
26512655 RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8
26522656 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
26532657 Yoga: 6048a55441c73f8e3916a8eac6b83886708c77f9
26542658
2655−PODFILE CHECKSUM: 4e4a7b4f3235f9815ae59b6af6d1c119bfe10f28
2659+PODFILE CHECKSUM: 988a7b52a0acf4f7473dae1279d38519c954ed73
26562660
26572661COCOAPODS: 1.16.2
example-macos/macos/YogaReactExample-macOS/RCTMacOSControlsManager.m+101
@@ -2,6 +2,7 @@
22#import <React/RCTBridge.h>
33#import <AppKit/AppKit.h>
44#import <WebKit/WebKit.h>
5+@import RiveRuntime;
56
67// ============================================================
78// 1. NSButton
@@ -858,3 +859,103 @@ RCT_EXPORT_VIEW_PROPERTY(criticalValue, double)
858859RCT_EXPORT_MODULE(MacOSScrollView)
859860- (NSView *)view { return [[RCTNativeScrollView alloc] initWithFrame:CGRectZero]; }
860861@end
862+
863+// ============================================================
864+// 14. RiveView
865+// ============================================================
866+
867+@interface RCTNativeRiveView : NSView
868+@property (nonatomic, strong) RiveViewModel *viewModel;
869+@property (nonatomic, strong) RiveView *riveView;
870+@property (nonatomic, copy) NSString *resourceName;
871+@property (nonatomic, copy) NSString *url;
872+@property (nonatomic, copy) NSString *stateMachineName;
873+@property (nonatomic, copy) NSString *artboardName;
874+@property (nonatomic, assign) BOOL autoplay;
875+@end
876+
877+@implementation RCTNativeRiveView
878+
879+- (instancetype)initWithFrame:(NSRect)frame {
880+ if (self = [super initWithFrame:frame]) {
881+ _autoplay = YES;
882+ }
883+ return self;
884+}
885+
886+- (void)setResourceName:(NSString *)resourceName {
887+ if ([_resourceName isEqualToString:resourceName]) return;
888+ _resourceName = resourceName;
889+ [self loadFromResource];
890+}
891+
892+- (void)setUrl:(NSString *)url {
893+ if ([_url isEqualToString:url]) return;
894+ _url = url;
895+ [self loadFromURL];
896+}
897+
898+- (void)loadFromResource {
899+ if (_resourceName.length == 0) return;
900+ [self clearRiveView];
901+ _viewModel = [[RiveViewModel alloc]
902+ initWithFileName:_resourceName
903+ extension:@"riv"
904+ in:[NSBundle mainBundle]
905+ stateMachineName:_stateMachineName
906+ fit:contain
907+ alignment:center
908+ autoPlay:_autoplay
909+ artboardName:_artboardName
910+ loadCdn:YES
911+ customLoader:nil];
912+ [self attachRiveView];
913+}
914+
915+- (void)loadFromURL {
916+ if (_url.length == 0) return;
917+ [self clearRiveView];
918+ _viewModel = [[RiveViewModel alloc]
919+ initWithWebURL:_url
920+ stateMachineName:_stateMachineName
921+ fit:contain
922+ alignment:center
923+ autoPlay:_autoplay
924+ loadCdn:YES
925+ artboardName:_artboardName];
926+ [self attachRiveView];
927+}
928+
929+- (void)clearRiveView {
930+ if (_riveView) {
931+ [_riveView removeFromSuperview];
932+ _riveView = nil;
933+ }
934+ _viewModel = nil;
935+}
936+
937+- (void)attachRiveView {
938+ if (!_viewModel) return;
939+ _riveView = [_viewModel createRiveView];
940+ _riveView.frame = self.bounds;
941+ _riveView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
942+ [self addSubview:_riveView];
943+}
944+
945+- (NSSize)intrinsicContentSize { return NSMakeSize(NSViewNoIntrinsicMetric, NSViewNoIntrinsicMetric); }
946+- (void)layout {
947+ [super layout];
948+ _riveView.frame = self.bounds;
949+}
950+@end
951+
952+@interface RCTNativeRiveViewManager : RCTViewManager @end
953+@implementation RCTNativeRiveViewManager
954+RCT_EXPORT_MODULE(MacOSRiveView)
955+- (NSView *)view { return [[RCTNativeRiveView alloc] initWithFrame:CGRectZero]; }
956+RCT_EXPORT_VIEW_PROPERTY(resourceName, NSString)
957+RCT_EXPORT_VIEW_PROPERTY(url, NSString)
958+RCT_EXPORT_VIEW_PROPERTY(stateMachineName, NSString)
959+RCT_EXPORT_VIEW_PROPERTY(artboardName, NSString)
960+RCT_EXPORT_VIEW_PROPERTY(autoplay, BOOL)
961+@end
example-macos/macos/YogaReactExample.xcodeproj/project.pbxproj+8−4
@@ -11,11 +11,11 @@
1111 514201522437B4B40078DB4F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 514201512437B4B40078DB4F /* Assets.xcassets */; };
1212 514201552437B4B40078DB4F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 514201532437B4B40078DB4F /* Main.storyboard */; };
1313 514201582437B4B40078DB4F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 514201572437B4B40078DB4F /* main.m */; };
14+ 5D0045734F6C5D73F8546B05 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 2F264B867F71A9A4C58140DE /* PrivacyInfo.xcprivacy */; };
1415 AA0000012437B4B30078DB4F /* RCTSFSymbolViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AA0000002437B4B30078DB4F /* RCTSFSymbolViewManager.m */; };
1516 AA0000032437B4B30078DB4F /* RCTFinderViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AA0000022437B4B30078DB4F /* RCTFinderViewManager.m */; };
1617 AA0000052437B4B30078DB4F /* RCTNativeShowcaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AA0000042437B4B30078DB4F /* RCTNativeShowcaseManager.m */; };
1718 AA0000072437B4B30078DB4F /* RCTMacOSControlsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AA0000062437B4B30078DB4F /* RCTMacOSControlsManager.m */; };
18− 5D0045734F6C5D73F8546B05 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 2F264B867F71A9A4C58140DE /* PrivacyInfo.xcprivacy */; };
1919 BE70DEDEE32B54947FC49AFF /* libPods-YogaReactExample-macOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C3E14041CD325948C5922BE0 /* libPods-YogaReactExample-macOS.a */; };
2020 DEB487CCA36791EC34548205 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 2F264B867F71A9A4C58140DE /* PrivacyInfo.xcprivacy */; };
2121/* End PBXBuildFile section */
@@ -32,11 +32,11 @@
3232 514201562437B4B40078DB4F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3333 514201572437B4B40078DB4F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
3434 514201592437B4B40078DB4F /* YogaReactExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = YogaReactExample.entitlements; sourceTree = "<group>"; };
35+ 6219FEE28F8561D55869D1DF /* Pods-YogaReactExample-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YogaReactExample-macOS.release.xcconfig"; path = "Target Support Files/Pods-YogaReactExample-macOS/Pods-YogaReactExample-macOS.release.xcconfig"; sourceTree = "<group>"; };
3536 AA0000002437B4B30078DB4F /* RCTSFSymbolViewManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTSFSymbolViewManager.m; sourceTree = "<group>"; };
3637 AA0000022437B4B30078DB4F /* RCTFinderViewManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTFinderViewManager.m; sourceTree = "<group>"; };
3738 AA0000042437B4B30078DB4F /* RCTNativeShowcaseManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTNativeShowcaseManager.m; sourceTree = "<group>"; };
3839 AA0000062437B4B30078DB4F /* RCTMacOSControlsManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTMacOSControlsManager.m; sourceTree = "<group>"; };
39− 6219FEE28F8561D55869D1DF /* Pods-YogaReactExample-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-YogaReactExample-macOS.release.xcconfig"; path = "Target Support Files/Pods-YogaReactExample-macOS/Pods-YogaReactExample-macOS.release.xcconfig"; sourceTree = "<group>"; };
4040 C3E14041CD325948C5922BE0 /* libPods-YogaReactExample-macOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-YogaReactExample-macOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
4141 ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
4242/* End PBXFileReference section */
@@ -272,10 +272,12 @@
272272 inputPaths = (
273273 "${PODS_ROOT}/Target Support Files/Pods-YogaReactExample-macOS/Pods-YogaReactExample-macOS-frameworks.sh",
274274 "${PODS_ROOT}/hermes-engine/destroot/Library/Frameworks/macosx/hermes.framework",
275+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/RiveRuntime/RiveRuntime.framework/RiveRuntime",
275276 );
276277 name = "[CP] Embed Pods Frameworks";
277278 outputPaths = (
278279 "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
280+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RiveRuntime.framework",
279281 );
280282 runOnlyForDeploymentPostprocessing = 0;
281283 shellPath = /bin/sh;
@@ -310,6 +312,7 @@
310312 "${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
311313 "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
312314 "${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle",
315+ "${PODS_CONFIGURATION_BUILD_DIR}/RiveRuntime/runtime_ios_privacy.bundle",
313316 "${PODS_CONFIGURATION_BUILD_DIR}/boost/boost_privacy.bundle",
314317 "${PODS_CONFIGURATION_BUILD_DIR}/glog/glog_privacy.bundle",
315318 );
@@ -318,6 +321,7 @@
318321 "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
319322 "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
320323 "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle",
324+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/runtime_ios_privacy.bundle",
321325 "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/boost_privacy.bundle",
322326 "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/glog_privacy.bundle",
323327 );
@@ -410,8 +414,8 @@
410414 baseConfigurationReference = 21189D06A4C5925B17F3369D /* Pods-YogaReactExample-macOS.debug.xcconfig */;
411415 buildSettings = {
412416 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
413− CODE_SIGN_ENTITLEMENTS = "YogaReactExample-macOS/YogaReactExample.entitlements";
414417 CLANG_ENABLE_MODULES = YES;
418+ CODE_SIGN_ENTITLEMENTS = "YogaReactExample-macOS/YogaReactExample.entitlements";
415419 CURRENT_PROJECT_VERSION = 1;
416420 DEAD_CODE_STRIPPING = NO;
417421 INFOPLIST_FILE = "YogaReactExample-macos/Info.plist";
@@ -435,8 +439,8 @@
435439 baseConfigurationReference = 6219FEE28F8561D55869D1DF /* Pods-YogaReactExample-macOS.release.xcconfig */;
436440 buildSettings = {
437441 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
438− CODE_SIGN_ENTITLEMENTS = "YogaReactExample-macOS/YogaReactExample.entitlements";
439442 CLANG_ENABLE_MODULES = YES;
443+ CODE_SIGN_ENTITLEMENTS = "YogaReactExample-macOS/YogaReactExample.entitlements";
440444 CURRENT_PROJECT_VERSION = 1;
441445 INFOPLIST_FILE = "YogaReactExample-macos/Info.plist";
442446 LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
src/Yoga/React/Native/MacOS/Rive.jsnew file+16
@@ -0,0 +1,16 @@
1+import {
2+ View,
3+ Platform,
4+ UIManager,
5+ requireNativeComponent,
6+} from "react-native";
7+
8+var c = View;
9+if (Platform.OS === "macos") {
10+ try {
11+ if (UIManager.getViewManagerConfig("MacOSRiveView"))
12+ c = requireNativeComponent("MacOSRiveView");
13+ } catch (e) {}
14+}
15+
16+export const _nativeRiveViewImpl = c;
src/Yoga/React/Native/MacOS/Rive.pursnew file+21
@@ -0,0 +1,21 @@
1+module Yoga.React.Native.MacOS.Rive (nativeRiveView, nativeRiveView_, NativeRiveViewAttributes) where
2+
3+import React.Basic (ReactComponent)
4+import Yoga.React.Native.Attributes (BaseAttributes)
5+import Yoga.React.Native.Internal (FFINativeComponent, FFINativeComponent_, createNativeElement, createNativeElement_)
6+
7+foreign import _nativeRiveViewImpl :: forall props. ReactComponent props
8+
9+nativeRiveView :: FFINativeComponent NativeRiveViewAttributes
10+nativeRiveView = createNativeElement _nativeRiveViewImpl
11+
12+nativeRiveView_ :: FFINativeComponent_ NativeRiveViewAttributes
13+nativeRiveView_ = createNativeElement_ _nativeRiveViewImpl
14+
15+type NativeRiveViewAttributes = BaseAttributes
16+ ( resourceName :: String
17+ , url :: String
18+ , artboardName :: String
19+ , stateMachineName :: String
20+ , autoplay :: Boolean
21+ )