Files
react-native/ReactCommon/fabric/components/view/ViewShadowNode.cpp
T
Valentin Shergin ca6700f3c3 Fabric: ViewProps::zIndex now is optional<int> to be able store auto
Summary:
In W3C standard, `zIndex` prop can have `auto` value which is the default.
In classic React Native and in Fabric before this diff, the default value was `0`. The only difference between `auto` and `0` is that nodes with `auto` do not form stacking context whereas nodes with `0` (or any other numeric value) do. This worked fine in pre-Fabric RN where every view always formed staking context but in Fabric we need to finally implement it right.

https://developer.mozilla.org/en-US/docs/Web/CSS/z-index
https://stackoverflow.com/a/57892072/496389

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D22403383

fbshipit-source-id: 6532d180a00f22bde763e3ebadd6683b344a0672
2020-07-26 22:05:45 -07:00

82 lines
2.4 KiB
C++

/*
* 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 "ViewShadowNode.h"
#include <react/components/view/primitives.h>
namespace facebook {
namespace react {
char const ViewComponentName[] = "View";
ViewShadowNode::ViewShadowNode(
ShadowNodeFragment const &fragment,
ShadowNodeFamily::Shared const &family,
ShadowNodeTraits traits)
: ConcreteViewShadowNode(fragment, family, traits) {
initialize();
}
ViewShadowNode::ViewShadowNode(
ShadowNode const &sourceShadowNode,
ShadowNodeFragment const &fragment)
: ConcreteViewShadowNode(sourceShadowNode, fragment) {
initialize();
}
static bool isColorMeaningful(SharedColor const &color) noexcept {
if (!color) {
return false;
}
return colorComponentsFromColor(color).alpha > 0;
}
void ViewShadowNode::initialize() noexcept {
auto &viewProps = static_cast<ViewProps const &>(*props_);
bool formsStackingContext = !viewProps.collapsable ||
viewProps.pointerEvents == PointerEventsMode::None ||
!viewProps.nativeId.empty() || viewProps.accessible ||
viewProps.opacity != 1.0 || viewProps.transform != Transform{} ||
viewProps.elevation != 0 ||
(viewProps.zIndex.has_value() &&
viewProps.yogaStyle.positionType() == YGPositionTypeAbsolute) ||
viewProps.yogaStyle.display() == YGDisplayNone ||
viewProps.getClipsContentToBounds() ||
isColorMeaningful(viewProps.shadowColor) ||
viewProps.importantForAccessibility != ImportantForAccessibility::Auto;
bool formsView = isColorMeaningful(viewProps.backgroundColor) ||
isColorMeaningful(viewProps.foregroundColor) ||
!(viewProps.yogaStyle.border() == YGStyle::Edges{});
formsView = formsView || formsStackingContext;
#ifdef ANDROID
// Force `formsStackingContext` trait for nodes which have `formsView`.
// TODO: T63560216 Investigate why/how `formsView` entangled with
// `formsStackingContext`.
formsStackingContext = formsStackingContext || formsView;
#endif
if (formsView) {
traits_.set(ShadowNodeTraits::Trait::FormsView);
} else {
traits_.unset(ShadowNodeTraits::Trait::FormsView);
}
if (formsStackingContext) {
traits_.set(ShadowNodeTraits::Trait::FormsStackingContext);
} else {
traits_.unset(ShadowNodeTraits::Trait::FormsStackingContext);
}
}
} // namespace react
} // namespace facebook