From 1e23d7bccb0aca80de7acd3b2c680e580257cb21 Mon Sep 17 00:00:00 2001 From: Dominic Go <18517029+dominicstop@users.noreply.github.com> Date: Fri, 7 Jun 2024 19:02:16 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=AB=20Update:=20`RNIModalView`=20Scaff?= =?UTF-8?q?olding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/src/App.tsx | 10 +- ios/RNIModalView/RNIModalView.mm | 5 +- ios/RNIModalView/RNIModalViewDelegate.swift | 171 ++++++++++++++++++ ios/RNIModalView/RNIModalViewManager.m | 8 - ios/RNIModalView/RNIModalViewManager.mm | 33 ++++ src/index.tsx | 4 +- .../RNIModalView/RNIModalView.tsx | 41 +++++ .../RNIModalViewNativeComponent.ts | 2 +- .../RNIModalView/RNIModalViewTypes.ts | 33 ++++ src/native_components/RNIModalView/index.ts | 3 +- 10 files changed, 293 insertions(+), 17 deletions(-) delete mode 100644 ios/RNIModalView/RNIModalViewManager.m create mode 100644 ios/RNIModalView/RNIModalViewManager.mm create mode 100644 src/native_components/RNIModalView/RNIModalView.tsx create mode 100644 src/native_components/RNIModalView/RNIModalViewTypes.ts diff --git a/example/src/App.tsx b/example/src/App.tsx index 361ad8b6..91f70edf 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,12 +1,16 @@ import * as React from 'react'; -import { StyleSheet, View } from 'react-native'; -import { IosModalView } from 'react-native-ios-modal'; +import { StyleSheet, View, Text } from 'react-native'; +import { RNIModalView } from 'react-native-ios-modal'; export default function App() { return ( - + + + Hello World + + ); } diff --git a/ios/RNIModalView/RNIModalView.mm b/ios/RNIModalView/RNIModalView.mm index 68ad2325..0b1e0a95 100644 --- a/ios/RNIModalView/RNIModalView.mm +++ b/ios/RNIModalView/RNIModalView.mm @@ -9,8 +9,10 @@ #import "react-native-ios-modal/Swift.h" #import + #import + #import #import @@ -69,8 +71,7 @@ - (void)initCommon { + (Class)viewDelegateClass { - return nil; - //return [RNIDummyTestViewDelegate class]; + return [RNIModalViewDelegate class]; } // MARK: - Fabric diff --git a/ios/RNIModalView/RNIModalViewDelegate.swift b/ios/RNIModalView/RNIModalViewDelegate.swift index e2746965..68dc2970 100644 --- a/ios/RNIModalView/RNIModalViewDelegate.swift +++ b/ios/RNIModalView/RNIModalViewDelegate.swift @@ -5,5 +5,176 @@ // Created by Dominic Go on 6/6/24. // +import UIKit import react_native_ios_utilities +import DGSwiftUtilities +@objc(RNIModalViewDelegate) +public final class RNIModalViewDelegate: UIView, RNIContentView { + + public static var propKeyPathMap: Dictionary> { + return [:]; + }; + + public enum Events: String, CaseIterable { + case placeholderEvent; + } + + // MARK: Properties + // ---------------- + + var _didSendEvents = false; + + // MARK: - Properties - RNIContentViewDelegate + // ------------------------------------------- + + public weak var parentReactView: RNIContentViewParentDelegate?; + + // MARK: Properties - Props + // ------------------------ + + public var reactProps: NSDictionary = [:]; + + // TBA + + // MARK: Init + // ---------- + + public override init(frame: CGRect) { + super.init(frame: frame); + }; + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented"); + } + + // MARK: Functions + // --------------- + + public override func didMoveToWindow() { + guard self.window != nil, + let parentReactView = self.parentReactView + else { return }; + + DispatchQueue.main.asyncAfter(deadline: .now() + 10){ + parentReactView.setSize(.init(width: 300, height: 300)); + }; + }; + + func _setupContent(){ + self.backgroundColor = .systemPink; + + let label = UILabel(); + label.text = "Fabric View (sort of) in Swift"; + + label.translatesAutoresizingMaskIntoConstraints = false; + self.addSubview(label); + + NSLayoutConstraint.activate([ + label.centerXAnchor.constraint( + equalTo: self.centerXAnchor + ), + label.centerYAnchor.constraint( + equalTo: self.centerYAnchor + ), + ]); + }; +}; + +extension RNIModalViewDelegate: RNIContentViewDelegate { + + public typealias KeyPathRoot = RNIModalViewDelegate; + + // MARK: Paper + Fabric + // -------------------- + + public func notifyOnInit(sender: RNIContentViewParentDelegate) { + self._setupContent(); + }; + + public func notifyOnMountChildComponentView( + sender: RNIContentViewParentDelegate, + childComponentView: UIView, + index: NSInteger, + superBlock: () -> Void + ) { + #if !RCT_NEW_ARCH_ENABLED + superBlock(); + #endif + + // Note: Window might not be available yet + self.addSubview(childComponentView); + }; + + public func notifyOnUnmountChildComponentView( + sender: RNIContentViewParentDelegate, + childComponentView: UIView, + index: NSInteger, + superBlock: () -> Void + ) { + #if !RCT_NEW_ARCH_ENABLED + superBlock(); + #endif + + } + + public func notifyDidSetProps(sender: RNIContentViewParentDelegate) { + // no-op + }; + + public func notifyOnUpdateLayoutMetrics( + sender: RNIContentViewParentDelegate, + oldLayoutMetrics: RNILayoutMetrics, + newLayoutMetrics: RNILayoutMetrics + ) { + // no-op + }; + + public func notifyOnViewCommandRequest( + sender: RNIContentViewParentDelegate, + forCommandName commandName: String, + withCommandArguments commandArguments: NSDictionary, + resolve resolveBlock: (NSDictionary) -> Void, + reject rejectBlock: (String) -> Void + ) { + // no-op + }; + + // MARK: Fabric Only + // ----------------- + + #if RCT_NEW_ARCH_ENABLED + public func notifyOnUpdateProps( + sender: RNIContentViewParentDelegate, + oldProps: NSDictionary, + newProps: NSDictionary + ) { + // no-op + }; + + public func notifyOnUpdateState( + sender: RNIContentViewParentDelegate, + oldState: NSDictionary?, + newState: NSDictionary + ) { + // no-op + }; + + public func notifyOnFinalizeUpdates( + sender: RNIContentViewParentDelegate, + updateMaskRaw: Int, + updateMask: RNIComponentViewUpdateMask + ) { + // no-op + }; + + public func notifyOnPrepareForReuse(sender: RNIContentViewParentDelegate) { + // no-op + }; + #else + + // MARK: - Paper Only + // ------------------ + + #endif +}; diff --git a/ios/RNIModalView/RNIModalViewManager.m b/ios/RNIModalView/RNIModalViewManager.m deleted file mode 100644 index 4a4fdaca..00000000 --- a/ios/RNIModalView/RNIModalViewManager.m +++ /dev/null @@ -1,8 +0,0 @@ -// -// RNIModalViewManager.m -// react-native-ios-modal -// -// Created by Dominic Go on 6/6/24. -// - -#import diff --git a/ios/RNIModalView/RNIModalViewManager.mm b/ios/RNIModalView/RNIModalViewManager.mm new file mode 100644 index 00000000..9ec41266 --- /dev/null +++ b/ios/RNIModalView/RNIModalViewManager.mm @@ -0,0 +1,33 @@ +// +// RNIModalViewManager.m +// react-native-ios-modal +// +// Created by Dominic Go on 6/6/24. +// + +#import "RNIModalView.h" +#import + +#import "react-native-ios-utilities/RNIBaseViewUtils.h" + +#import "RCTBridge.h" +#import +#import + + +@interface RNIModalViewManager : RCTViewManager +@end + +@implementation RNIModalViewManager + +RCT_EXPORT_MODULE(RNIModalView) + +#ifndef RCT_NEW_ARCH_ENABLED +- (UIView *)view +{ + return [[RNIModalView new] initWithBridge:self.bridge]; +} +#endif + +@end + diff --git a/src/index.tsx b/src/index.tsx index 014a0cfe..7875e5da 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,2 +1,2 @@ -export { default as IosModalView } from './IosModalViewNativeComponent'; -export * from './IosModalViewNativeComponent'; +// TEMP +export * from './native_components/RNIModalView'; diff --git a/src/native_components/RNIModalView/RNIModalView.tsx b/src/native_components/RNIModalView/RNIModalView.tsx new file mode 100644 index 00000000..547efff2 --- /dev/null +++ b/src/native_components/RNIModalView/RNIModalView.tsx @@ -0,0 +1,41 @@ +import * as React from 'react'; + +import { RNIModalNativeView } from './RNIModalNativeView'; + +import type { + RNIContextMenuViewProps, + RNIModalViewRef, + StateReactTag, + StateViewID +} from './RNIModalViewTypes'; + +export const RNIModalView = React.forwardRef< + RNIModalViewRef, + RNIContextMenuViewProps +>((props, ref) => { + + const [viewID, setViewID] = React.useState(); + const [reactTag, setReactTag] = React.useState(); + + React.useImperativeHandle(ref, () => ({ + getReactTag: () => { + return reactTag; + }, + getViewID: () => { + return viewID; + }, + })); + + return ( + { + setViewID(event.nativeEvent.viewID); + setReactTag(event.nativeEvent.reactTag); + props.onDidSetViewID?.(event); + }} + > + {props.children} + + ); +}); \ No newline at end of file diff --git a/src/native_components/RNIModalView/RNIModalViewNativeComponent.ts b/src/native_components/RNIModalView/RNIModalViewNativeComponent.ts index 54d12d63..ad522901 100644 --- a/src/native_components/RNIModalView/RNIModalViewNativeComponent.ts +++ b/src/native_components/RNIModalView/RNIModalViewNativeComponent.ts @@ -2,7 +2,7 @@ import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNati import type { HostComponent, ViewProps } from 'react-native'; interface NativeProps extends ViewProps { -} +}; export default codegenNativeComponent('RNIModalView', { excludedPlatforms: ['android'], diff --git a/src/native_components/RNIModalView/RNIModalViewTypes.ts b/src/native_components/RNIModalView/RNIModalViewTypes.ts new file mode 100644 index 00000000..574a23a6 --- /dev/null +++ b/src/native_components/RNIModalView/RNIModalViewTypes.ts @@ -0,0 +1,33 @@ +import type { PropsWithChildren } from "react"; +import type { ViewProps } from "react-native"; + +import type { OnDidSetViewIDEventPayload } from "react-native-ios-utilities"; +import type { RNIModalNativeViewProps } from "./RNIModalNativeView"; + +export type StateViewID = OnDidSetViewIDEventPayload['viewID'] | undefined; +export type StateReactTag = OnDidSetViewIDEventPayload['reactTag'] | undefined; + +export type RNIModalViewRef = { + getViewID: () => StateViewID; + getReactTag: () => StateReactTag; +}; + +export type RNIModalViewInheritedOptionalProps = Partial>; + +export type RNIModalViewInheritedRequiredProps = {}; + +export type RNIModalViewInheritedProps = + RNIModalViewInheritedOptionalProps + & RNIModalViewInheritedRequiredProps; + +export type RNIModalViewBaseProps = { + // TBA +}; + +export type RNIContextMenuViewProps = PropsWithChildren< + RNIModalViewInheritedProps + & RNIModalViewBaseProps + & ViewProps +>; \ No newline at end of file diff --git a/src/native_components/RNIModalView/index.ts b/src/native_components/RNIModalView/index.ts index 8dfb91a8..01502d3f 100644 --- a/src/native_components/RNIModalView/index.ts +++ b/src/native_components/RNIModalView/index.ts @@ -1 +1,2 @@ -export * from './RNIModalNativeView'; \ No newline at end of file +export * from './RNIModalView'; +export * from './RNIModalViewTypes'; \ No newline at end of file