Skip to content

Commit 8df590b

Browse files
feat(ios): add Fabric support (#657)
* Initial changes * test fabric in CI * Sending picker size to shadow node * Fix E2E config * Update Xcode in CI * Adding more comments * cleanup Co-authored-by: Alfonso Curbelo <alfonso.curbelo@coinbase.com>
1 parent 9e35e45 commit 8df590b

23 files changed

+573
-53
lines changed

.circleci/config.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
e2e_release_ios:
3434
executor:
3535
name: rn/macos
36-
xcode_version: '13.1.0'
36+
xcode_version: '14.0.0'
3737
steps:
3838
- checkout
3939
- run:
@@ -52,9 +52,6 @@ jobs:
5252
name: bundle js
5353
- rn/pod_install:
5454
pod_install_directory: 'example/ios'
55-
- run:
56-
command: curl https://raw.githubusercontent.com/facebook/react-native/6334ac35ac3cbc2c84b2d46d46ec118bf9bf714d/scripts/find-node.sh > node_modules/react-native/scripts/find-node.sh
57-
name: fix issue with nvm # will be fixed in RN 67 (https://github.com/react-native-community/upgrade-support/issues/138)
5855
- run:
5956
command: yarn detox:ios:build:release
6057
name: build app for e2e tests

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ DerivedData
2828
*.ipa
2929
*.xcuserstate
3030
project.xcworkspace
31+
IDEWorkspaceChecks.plist
3132

3233
#Detox
3334
#

CONTRIBUTING.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,30 @@ An existing Android emulator is required to match the name defined in `detox.con
6868
yarn detox:android:build:release
6969
yarn detox:android:test:release
7070
```
71+
72+
### Fabric
73+
74+
Fabric is the new React Native rendering system ([read more about it here](https://reactnative.dev/architecture/fabric-renderer)).
75+
76+
#### iOS
77+
78+
```
79+
yarn start
80+
cd "example/ios" && RCT_NEW_ARCH_ENABLED=1 npx pod-install && cd -
81+
yarn start:ios
82+
```
83+
84+
If you want to go back to the old renderer (Paper),
85+
remove `ios/build`, run `pod-install` without the `RCT_NEW_ARCH_ENABLED=1` and build again
86+
87+
```
88+
rm -r "example/ios/build"
89+
cd "example/ios" && npx pod-install && cd -
90+
yarn start:ios
91+
```
92+
93+
94+
#### Android
95+
96+
The date time picker does not have a native UI component for Android but a native module.
97+
([read more about native modules here](https://reactnative.dev/docs/native-modules-intro)).

RNDateTimePicker.podspec

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
require 'json'
22

3+
fabric_enabled = ENV['RCT_NEW_ARCH_ENABLED'] == '1'
4+
35
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
46

57
Pod::Spec.new do |s|
@@ -12,8 +14,35 @@ Pod::Spec.new do |s|
1214
s.homepage = package['homepage']
1315
s.platform = :ios, "11.0"
1416
s.source = { :git => "https://github.com/react-native-community/datetimepicker", :tag => "v#{s.version}" }
15-
s.source_files = "ios/*.{h,m}"
17+
s.source_files = "ios/**/*.{h,m,mm,cpp}"
1618
s.requires_arc = true
1719

18-
s.dependency "React-Core"
20+
if fabric_enabled
21+
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
22+
23+
s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
24+
s.pod_target_xcconfig = {
25+
'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/boost" "$(PODS_ROOT)/boost-for-react-native" "$(PODS_ROOT)/RCT-Folly"',
26+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
27+
}
28+
29+
s.dependency "React"
30+
s.dependency "React-RCTFabric"
31+
s.dependency "React-Codegen"
32+
s.dependency "RCT-Folly"
33+
s.dependency "RCTRequired"
34+
s.dependency "RCTTypeSafety"
35+
s.dependency "ReactCommon/turbomodule/core"
36+
37+
s.subspec "cpp" do |ss|
38+
ss.source_files = "cpp/**/*.{cpp,h}"
39+
ss.header_dir = "rndatetimepicker"
40+
ss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/cpp\"" }
41+
end
42+
43+
else
44+
s.exclude_files = "ios/fabric"
45+
46+
s.dependency "React-Core"
47+
end
1948
end
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
/**
3+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
4+
* and copied to the cpp directory to override the adopt function and set the size of the shadow node based
5+
* on the state.
6+
* @generated by codegen project: GenerateComponentDescriptorH.js
7+
*/
8+
9+
#pragma once
10+
11+
#include "ShadowNodes.h"
12+
#include <react/renderer/core/ConcreteComponentDescriptor.h>
13+
14+
namespace facebook {
15+
namespace react {
16+
17+
class RNDateTimePickerComponentDescriptor final : public ConcreteComponentDescriptor<RNDateTimePickerShadowNode> {
18+
public:
19+
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
20+
21+
void adopt(ShadowNode::Unshared const &shadowNode) const override {
22+
react_native_assert(std::dynamic_pointer_cast<RNDateTimePickerShadowNode>(shadowNode));
23+
auto pickerShadowNode = std::static_pointer_cast<RNDateTimePickerShadowNode>(shadowNode);
24+
25+
react_native_assert(
26+
std::dynamic_pointer_cast<YogaLayoutableShadowNode>(pickerShadowNode));
27+
auto layoutableShadowNode =
28+
std::static_pointer_cast<YogaLayoutableShadowNode>(pickerShadowNode);
29+
30+
auto state = std::static_pointer_cast<const RNDateTimePickerShadowNode::ConcreteState>(shadowNode->getState());
31+
auto stateData = state->getData();
32+
33+
if(stateData.frameSize.width != 0 && stateData.frameSize.height != 0) {
34+
layoutableShadowNode->setSize(Size{stateData.frameSize.width, stateData.frameSize.height});
35+
}
36+
37+
ConcreteComponentDescriptor::adopt(shadowNode);
38+
}
39+
};
40+
41+
} // namespace react
42+
} // namespace facebook
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Custom state to store frameSize that the component descriptor will use to modify the
3+
* shadow node layout.
4+
*/
5+
6+
#include "RNDateTimePickerState.h"
7+
8+
namespace facebook {
9+
namespace react {
10+
11+
} // namespace react
12+
} // namespace facebook
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Custom state to store frameSize that the component descriptor will use to modify the
3+
* shadow node layout.
4+
*/
5+
6+
#pragma once
7+
8+
#include <react/renderer/graphics/Geometry.h>
9+
10+
namespace facebook {
11+
namespace react {
12+
13+
class RNDateTimePickerState final {
14+
public:
15+
using Shared = std::shared_ptr<const RNDateTimePickerState>;
16+
RNDateTimePickerState(){};
17+
RNDateTimePickerState(Size frameSize_) : frameSize(frameSize_){};
18+
19+
Size frameSize{};
20+
};
21+
22+
} // namespace react
23+
} // namespace facebook
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
/**
3+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen)
4+
* and copied to the cpp directory to add custom state and set shadow node trait as a LeafYogaNode.
5+
*
6+
* @generated by codegen project: GenerateShadowNodeCpp.js
7+
*/
8+
9+
#include "ShadowNodes.h"
10+
11+
namespace facebook {
12+
namespace react {
13+
14+
extern const char RNDateTimePickerComponentName[] = "RNDateTimePicker";
15+
16+
} // namespace react
17+
} // namespace facebook
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
/**
3+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen)
4+
* and copied to the cpp directory to add custom state and set shadow node trait as a LeafYogaNode.
5+
*
6+
* @generated by codegen project: GenerateShadowNodeH.js
7+
*/
8+
9+
#pragma once
10+
11+
#include "RNDateTimePickerState.h"
12+
#include <react/renderer/components/RNDateTimePicker/EventEmitters.h>
13+
#include <react/renderer/components/RNDateTimePicker/Props.h>
14+
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
15+
#include <jsi/jsi.h>
16+
#include <react/renderer/core/LayoutContext.h>
17+
18+
namespace facebook {
19+
namespace react {
20+
21+
JSI_EXPORT extern const char RNDateTimePickerComponentName[];
22+
23+
/*
24+
* `ShadowNode` for <RNDateTimePicker> component.
25+
*/
26+
class JSI_EXPORT RNDateTimePickerShadowNode final : public ConcreteViewShadowNode<RNDateTimePickerComponentName, RNDateTimePickerProps, RNDateTimePickerEventEmitter, RNDateTimePickerState> {
27+
28+
public:
29+
using ConcreteViewShadowNode::ConcreteViewShadowNode;
30+
31+
static ShadowNodeTraits BaseTraits() {
32+
auto traits = ConcreteViewShadowNode::BaseTraits();
33+
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
34+
return traits;
35+
}
36+
};
37+
38+
} // namespace react
39+
} // namespace facebook

example/App.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
Switch,
1313
} from 'react-native';
1414
import DateTimePicker from '@react-native-community/datetimepicker';
15-
import SegmentedControl from '@react-native-segmented-control/segmented-control';
15+
import SegmentedControl from './SegmentedControl';
1616
import {Colors} from 'react-native/Libraries/NewAppScreen';
1717
import React, {useRef, useState} from 'react';
1818
import {Picker} from 'react-native-windows';

0 commit comments

Comments
 (0)