Skip to content

Commit b8ac9ea

Browse files
authored
[Native] Automatically unflatten detector children (#3963)
## Description On Android this requires #3962 to test, as the non-transparent views are never flattened. Automatically unflattens the child node of the detector component, so that setting `collapsable={false}` is no longer needed. ## Test plan Notce the lack of `collapsable={false}` on the detector's child. ```jsx import React from 'react'; import { StyleSheet, View } from 'react-native'; import { GestureDetector, GestureHandlerRootView, useTapGesture, } from 'react-native-gesture-handler'; export default function EmptyExample() { const tap = useTapGesture({ onActivate: () => { console.log('tap'); }, }); return ( <GestureHandlerRootView style={styles.container}> <GestureDetector gesture={tap}> <View style={{ flex: 1, backgroundColor: 'transparent' }} /> </GestureDetector> </GestureHandlerRootView> ); } const styles = StyleSheet.create({ container: { flex: 1, }, }); ```
1 parent 7e597d0 commit b8ac9ea

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

packages/react-native-gesture-handler/shared/shadowNodes/react/renderer/components/rngesturehandler_codegen/RNGestureHandlerDetectorShadowNode.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,24 @@ void RNGestureHandlerDetectorShadowNode::initialize() {
2828
children.size() == 1 &&
2929
"RNGestureHandlerDetector received more than one child");
3030

31-
const auto clonedChild = children[0]->clone({});
32-
replaceChild(*children[0], clonedChild);
31+
// Will clone the child and ensure it's not flattened
32+
replaceChild(*children[0], children[0], 0);
3333
}
3434
}
3535

36+
void RNGestureHandlerDetectorShadowNode::appendChild(
37+
const std::shared_ptr<const ShadowNode> &child) {
38+
YogaLayoutableShadowNode::appendChild(unflattenNode(child));
39+
}
40+
41+
void RNGestureHandlerDetectorShadowNode::replaceChild(
42+
const ShadowNode &oldChild,
43+
const std::shared_ptr<const ShadowNode> &newChild,
44+
size_t suggestedIndex) {
45+
YogaLayoutableShadowNode::replaceChild(
46+
oldChild, unflattenNode(newChild), suggestedIndex);
47+
}
48+
3649
void RNGestureHandlerDetectorShadowNode::layout(LayoutContext layoutContext) {
3750
// TODO: consider allowing more than one child and doing bounding box
3851
react_native_assert(getChildren().size() == 1);
@@ -69,4 +82,18 @@ void RNGestureHandlerDetectorShadowNode::layout(LayoutContext layoutContext) {
6982
mutableChild->setLayoutMetrics(childmetrics);
7083
}
7184

85+
std::shared_ptr<const ShadowNode>
86+
RNGestureHandlerDetectorShadowNode::unflattenNode(
87+
const std::shared_ptr<const ShadowNode> &node) {
88+
auto clonedNode = node->clone({});
89+
auto clonedNodeWithProtectedAccess =
90+
std::static_pointer_cast<RNGestureHandlerDetectorShadowNode>(clonedNode);
91+
92+
clonedNodeWithProtectedAccess->traits_.set(ShadowNodeTraits::FormsView);
93+
clonedNodeWithProtectedAccess->traits_.set(
94+
ShadowNodeTraits::FormsStackingContext);
95+
96+
return clonedNode;
97+
}
98+
7299
} // namespace facebook::react

packages/react-native-gesture-handler/shared/shadowNodes/react/renderer/components/rngesturehandler_codegen/RNGestureHandlerDetectorShadowNode.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,17 @@ class RNGestureHandlerDetectorShadowNode final
5353
initialize();
5454
}
5555

56+
void appendChild(const std::shared_ptr<const ShadowNode> &child) override;
57+
void replaceChild(
58+
const ShadowNode &oldChild,
59+
const std::shared_ptr<const ShadowNode> &newChild,
60+
size_t suggestedIndex = SIZE_MAX) override;
61+
5662
void layout(LayoutContext layoutContext) override;
5763

5864
private:
65+
std::shared_ptr<const ShadowNode> unflattenNode(
66+
const std::shared_ptr<const ShadowNode> &node);
5967
void initialize();
6068

6169
std::optional<LayoutMetrics> previousLayoutMetrics_;

0 commit comments

Comments
 (0)