This MR adds the capability to annotate Compose function parameters with @ReactNativeProp to make them settable from React Native.
Android
For Android, supporting props is straight-forward. Each prop gets a setter annotated with @ReactProp in the generated SimpleViewManager<ComposeView> subclass (see React Native docs on this). The setter emits a value into shared flow which is passed into the compose function.
Secondly, when React Native picked which props exist via the RCT_EXPORT_VIEW_PROPERTY methods it calls the method directly the UIView returned by the view manager (you can circumvent this using RCT_CUSTOM_VIEW_PROPERTY but it is true at least for callback props). Now we run into the second Kotlin / Objective-C interop problem: We can not create a class in Kotlin ios source sets that subclasses an Objective-C type (UIView in this case) and add methods to it that are callable from Objective-C. So we also need to generate the UIView subclass as Objective-C code and add the Compose view as a subview to it.
So on iOS we have 3 components:
The generated RCTViewManager subclass which configures the prop configs
The generated UIView subclass which provides properties for callback props
A generated ReactNativeIOSViewManager which provides the glue code between the Objective-C RCTViewManager and UIView and the Kotlin Compose view.
We generate all Objecitve-C code in one header and one implementation file that the library user has to include in their XCode project.
Future work
Generate TypeScript interface and code for the native view
This MR adds the capability to annotate Compose function parameters with @ReactNativeProp to make them settable from React Native.
Android
For Android, supporting props is straight-forward. Each prop gets a setter annotated with
@ReactProp
in the generatedSimpleViewManager<ComposeView>
subclass (see React Native docs on this). The setter emits a value into shared flow which is passed into the compose function.For callback parameters of the compose function we generate implementations of the callback according to the React Native Android view manager event docs.
By generating all this into the view manager everything works out of the box.
iOS
On iOS, this is much more tricky.
Firstly, React Native requires the that you add
RCT_EXPORT_VIEW_PROPERTY
on yourRCTViewManager
implementation which under hood creates a class methodpropConfig_<name>
. There is no way to write a Kotlin class in ios source sets so that it has class methods so we need to get rid of the Kotlin subclassing ofRCTViewManager
(and remove the interop) and instead generate the subclass in Objective-C code so we can set the class methods properly.Secondly, when React Native picked which props exist via the
RCT_EXPORT_VIEW_PROPERTY
methods it calls the method directly theUIView
returned by the view manager (you can circumvent this usingRCT_CUSTOM_VIEW_PROPERTY
but it is true at least for callback props). Now we run into the second Kotlin / Objective-C interop problem: We can not create a class in Kotlin ios source sets that subclasses an Objective-C type (UIView
in this case) and add methods to it that are callable from Objective-C. So we also need to generate theUIView
subclass as Objective-C code and add the Compose view as a subview to it.So on iOS we have 3 components:
RCTViewManager
subclass which configures the prop configsUIView
subclass which provides properties for callback propsReactNativeIOSViewManager
which provides the glue code between the Objective-CRCTViewManager
andUIView
and the Kotlin Compose view.We generate all Objecitve-C code in one header and one implementation file that the library user has to include in their XCode project.
Future work