Migrate MVP SafeAreaView to Fabric

Reviewed By: shergin

Differential Revision: D17736209

fbshipit-source-id: e70c309f2599cdcb8f234d96915546032b71d223
This commit is contained in:
Samuel Susla authored and Facebook Github Bot committed 2019-10-04 07:07:36 -07:00
1 parent ae3f7a7616
commit 07fd3125c8
11 files changed
+297 -4

No files matched your search

@@ -23,6 +23,7 @@ type NativeProps = $ReadOnly<{|
emulateUnlessSupported?: WithDefault<boolean, false>,
|}>;
export default (codegenNativeComponent<NativeProps>(
'RCTSafeAreaView',
): HostComponent<NativeProps>);
export default (codegenNativeComponent<NativeProps>('SafeAreaView', {
paperComponentName: 'RCTSafeAreaView',
interfaceOnly: true,
}): HostComponent<NativeProps>);
@@ -0,0 +1,21 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import <React/RCTViewComponentView.h>
NS_ASSUME_NONNULL_BEGIN
/**
* UIView class for root <SafeAreaView> component.
*/
@interface RCTSafeAreaViewComponentView : RCTViewComponentView
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,81 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTSafeAreaViewComponentView.h"
#import <react/components/safeareaview/SafeAreaViewComponentDescriptor.h>
#import <react/components/safeareaview/SafeAreaViewState.h>
#import "RCTConversions.h"
using namespace facebook::react;
static UIScrollView *findScrollView(UIView *view, uint recursionDepth = 0)
{
if (recursionDepth >= 3) {
return NULL;
}
if ([view isKindOfClass:[UIScrollView class]]) {
return (UIScrollView *)view;
}
if (view.subviews.count >= 1) {
for (UIView *subview in view.subviews) {
UIScrollView *scrollView = findScrollView(subview.subviews.firstObject, recursionDepth + 1);
if (scrollView) {
return scrollView;
}
}
}
return NULL;
}
@implementation RCTSafeAreaViewComponentView {
SafeAreaViewShadowNode::ConcreteState::Shared _state;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
static const auto defaultProps = std::make_shared<const SafeAreaViewProps>();
_props = defaultProps;
self.clipsToBounds = YES;
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
UIScrollView *scrollView = findScrollView(self);
if (scrollView && CGSizeEqualToSize(scrollView.bounds.size, self.bounds.size)) {
[scrollView setContentInset:self.safeAreaInsets];
} else {
if (_state != nullptr) {
CGSize size = self.bounds.size;
size.height -= self.safeAreaInsets.bottom;
auto newState = SafeAreaViewState{RCTSizeFromCGSize(size)};
_state->updateState(std::move(newState));
}
}
}
#pragma mark - RCTComponentViewProtocol
- (void)updateState:(facebook::react::State::Shared const &)state
oldState:(facebook::react::State::Shared const &)oldState
{
_state = std::static_pointer_cast<const SafeAreaViewShadowNode::ConcreteState>(state);
}
+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<SafeAreaViewComponentDescriptor>();
}
@end
@@ -23,6 +23,7 @@
#import "RCTParagraphComponentView.h"
#import "RCTPullToRefreshViewComponentView.h"
#import "RCTRootComponentView.h"
#import "RCTSafeAreaViewComponentView.h"
#import "RCTScrollViewComponentView.h"
#import "RCTSliderComponentView.h"
#import "RCTSwitchComponentView.h"
@@ -53,6 +54,7 @@ using namespace facebook::react;
[componentViewFactory registerComponentViewClass:[RCTUnimplementedNativeComponentView class]];
[componentViewFactory registerComponentViewClass:[RCTModalHostViewComponentView class]];
[componentViewFactory registerComponentViewClass:[RCTARTSurfaceViewComponentView class]];
[componentViewFactory registerComponentViewClass:[RCTSafeAreaViewComponentView class]];
auto providerRegistry = &componentViewFactory->_providerRegistry;
@@ -0,0 +1,47 @@
load("@fbsource//tools/build_defs/apple:flag_defs.bzl", "get_debug_preprocessor_flags")
load(
"//tools/build_defs/oss:rn_defs.bzl",
"APPLE",
"get_apple_compiler_flags",
"get_apple_inspector_flags",
"react_native_xplat_target",
"rn_xplat_cxx_library",
"subdir_glob",
)
APPLE_COMPILER_FLAGS = get_apple_compiler_flags()
rn_xplat_cxx_library(
name = "safeareaview",
srcs = glob(
["**/*.cpp"],
),
headers = [],
header_namespace = "",
exported_headers = subdir_glob(
[
("", "*.h"),
],
prefix = "react/components/safeareaview",
),
compiler_flags = [
"-fexceptions",
"-frtti",
"-std=c++14",
"-Wall",
],
fbobjc_compiler_flags = APPLE_COMPILER_FLAGS,
fbobjc_preprocessor_flags = get_debug_preprocessor_flags() + get_apple_inspector_flags(),
force_static = True,
labels = ["supermodule:ios/isolation/infra.react_native"],
platforms = (APPLE),
preprocessor_flags = [
"-DLOG_TAG=\"ReactNative\"",
"-DWITH_FBSYSTRACE=1",
],
visibility = ["PUBLIC"],
deps = [
react_native_xplat_target("fabric/core:core"),
"fbsource//xplat/js/react-native-github:generated_components-rncore",
],
)
@@ -0,0 +1,50 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/components/safeareaview/SafeAreaViewShadowNode.h>
#include <react/core/ConcreteComponentDescriptor.h>
namespace facebook {
namespace react {
/*
* Descriptor for <SafeAreaView> component.
*/
class SafeAreaViewComponentDescriptor final
: public ConcreteComponentDescriptor<SafeAreaViewShadowNode> {
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
void adopt(UnsharedShadowNode shadowNode) const override {
assert(std::dynamic_pointer_cast<SafeAreaViewShadowNode>(shadowNode));
auto safeAreaViewShadowNode =
std::static_pointer_cast<SafeAreaViewShadowNode>(shadowNode);
assert(std::dynamic_pointer_cast<YogaLayoutableShadowNode>(
safeAreaViewShadowNode));
auto layoutableShadowNode =
std::static_pointer_cast<YogaLayoutableShadowNode>(
safeAreaViewShadowNode);
auto state =
std::static_pointer_cast<const SafeAreaViewShadowNode::ConcreteState>(
shadowNode->getState());
auto stateData = state->getData();
if (stateData.safeAreaSize.width != 0 &&
stateData.safeAreaSize.height != 0) {
layoutableShadowNode->setSize(
Size{stateData.safeAreaSize.width, stateData.safeAreaSize.height});
layoutableShadowNode->setPositionType(YGPositionTypeAbsolute);
}
ConcreteComponentDescriptor::adopt(shadowNode);
}
};
} // namespace react
} // namespace facebook
@@ -0,0 +1,16 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "SafeAreaViewShadowNode.h"
namespace facebook {
namespace react {
extern const char SafeAreaViewComponentName[] = "SafeAreaView";
} // namespace react
} // namespace facebook
@@ -0,0 +1,32 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/components/rncore/EventEmitters.h>
#include <react/components/rncore/Props.h>
#include <react/components/safeareaview/SafeAreaViewState.h>
#include <react/components/view/ConcreteViewShadowNode.h>
namespace facebook {
namespace react {
extern const char SafeAreaViewComponentName[];
/*
* `ShadowNode` for <SafeAreaView> component.
*/
class SafeAreaViewShadowNode final : public ConcreteViewShadowNode<
SafeAreaViewComponentName,
SafeAreaViewProps,
ViewEventEmitter,
SafeAreaViewState> {
using ConcreteViewShadowNode::ConcreteViewShadowNode;
};
} // namespace react
} // namespace facebook
@@ -0,0 +1,12 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "SafeAreaViewState.h"
namespace facebook {
namespace react {} // namespace react
} // namespace facebook
@@ -0,0 +1,31 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <react/graphics/Geometry.h>
namespace facebook {
namespace react {
/*
* State for <SafeAreaView> component.
*/
class SafeAreaViewState final {
public:
using Shared = std::shared_ptr<const SafeAreaViewState>;
SafeAreaViewState(){};
SafeAreaViewState(Size screenSize_) : safeAreaSize(screenSize_){};
const Size safeAreaSize{};
#pragma mark - Getters
};
} // namespace react
} // namespace facebook
@@ -111,7 +111,7 @@ static std::string componentNameByReactViewName(std::string viewName) {
// We need this temporarily for testing purposes until we have proper
// implementation of core components.
if (viewName == "SafeAreaView" || viewName == "ScrollContentView" ||
if (viewName == "ScrollContentView" ||
viewName == "AndroidHorizontalScrollContentView" // Android
) {
return "View";