mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Migrate MVP SafeAreaView to Fabric
Reviewed By: shergin Differential Revision: D17736209 fbshipit-source-id: e70c309f2599cdcb8f234d96915546032b71d223
This commit is contained in:
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";
|
||||
|
||||
Reference in new issue
Block a user