Skip to content

Commit 0c07a4e

Browse files
committed
What are you? A button sandwitch.
1 parent d9dc96c commit 0c07a4e

File tree

3 files changed

+76
-15
lines changed

3 files changed

+76
-15
lines changed

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

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* @generated by codegen project: GenerateShadowNodeCpp.js
1010
*/
1111

12+
#include <react/renderer/components/rngesturehandler_codegen/ShadowNodes.h>
13+
1214
#include "RNGestureHandlerButtonWrapperShadowNode.h"
1315

1416
namespace facebook::react {
@@ -22,38 +24,70 @@ void RNGestureHandlerButtonWrapperShadowNode::initialize() {
2224

2325
// When the button wrapper is cloned and has a child node, the child node
2426
// should be cloned as well to ensure it is mutable.
27+
if (!getChildren().empty()) {
28+
prepareChildren();
29+
}
30+
}
31+
32+
void RNGestureHandlerButtonWrapperShadowNode::prepareChildren() {
2533
const auto &children = getChildren();
26-
if (!children.empty()) {
27-
react_native_assert(
28-
children.size() == 1 &&
29-
"RNGestureHandlerButtonWrapper received more than one child");
34+
react_native_assert(
35+
children.size() == 1 &&
36+
"RNGestureHandlerButtonWrapper received more than one child");
3037

31-
const auto clonedChild = children[0]->clone({});
32-
replaceChild(*children[0], clonedChild);
33-
}
38+
const auto directChild = children[0];
39+
react_native_assert(
40+
directChild->getChildren().size() == 1 &&
41+
"RNGestureHandlerButtonWrapper received more than one grandchild");
42+
43+
const auto clonedChild = directChild->clone({});
44+
45+
const auto childWithProtectedAccess =
46+
std::static_pointer_cast<RNGestureHandlerButtonWrapperShadowNode>(
47+
clonedChild);
48+
childWithProtectedAccess->traits_.unset(ShadowNodeTraits::ForceFlattenView);
49+
50+
replaceChild(*directChild, clonedChild);
51+
52+
const auto grandChild = clonedChild->getChildren()[0];
53+
const auto clonedGrandChild = grandChild->clone({});
54+
clonedChild->replaceChild(*grandChild, clonedGrandChild);
55+
}
56+
57+
void RNGestureHandlerButtonWrapperShadowNode::appendChild(
58+
const ShadowNode::Shared &child) {
59+
YogaLayoutableShadowNode::appendChild(child);
60+
prepareChildren();
3461
}
3562

3663
void RNGestureHandlerButtonWrapperShadowNode::layout(
3764
LayoutContext layoutContext) {
3865
YogaLayoutableShadowNode::layout(layoutContext);
39-
// TODO: consider allowing more than one child and doing bounding box
4066
react_native_assert(getChildren().size() == 1);
67+
react_native_assert(getChildren()[0]->getChildren().size() == 1);
4168

4269
auto child = std::static_pointer_cast<const YogaLayoutableShadowNode>(
4370
getChildren()[0]);
71+
auto grandChild = std::static_pointer_cast<const YogaLayoutableShadowNode>(
72+
child->getChildren()[0]);
4473

4574
child->ensureUnsealed();
75+
grandChild->ensureUnsealed();
76+
4677
auto mutableChild = std::const_pointer_cast<YogaLayoutableShadowNode>(child);
78+
auto mutableGrandChild =
79+
std::const_pointer_cast<YogaLayoutableShadowNode>(grandChild);
4780

4881
// TODO: figure out the correct way to setup metrics between button wrapper
4982
// and the child
50-
auto metrics = child->getLayoutMetrics();
51-
metrics.frame = child->getLayoutMetrics().frame;
83+
auto metrics = grandChild->getLayoutMetrics();
5284
setLayoutMetrics(metrics);
5385

54-
auto childmetrics = child->getLayoutMetrics();
55-
childmetrics.frame.origin = Point{};
56-
mutableChild->setLayoutMetrics(childmetrics);
86+
auto metricsNoOrigin = grandChild->getLayoutMetrics();
87+
metricsNoOrigin.frame.origin = Point{};
88+
89+
mutableChild->setLayoutMetrics(metricsNoOrigin);
90+
mutableGrandChild->setLayoutMetrics(metricsNoOrigin);
5791
}
5892

5993
} // namespace facebook::react

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@ class RNGestureHandlerButtonWrapperShadowNode final
4949
}
5050

5151
void layout(LayoutContext layoutContext) override;
52+
void appendChild(const ShadowNode::Shared &child) override;
5253

5354
private:
5455
void initialize();
56+
void prepareChildren();
5557
};
5658

5759
} // namespace facebook::react
Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
1-
import { HostComponent } from 'react-native';
1+
import { HostComponent, StyleSheet, View } from 'react-native';
22
import type { RawButtonProps } from './GestureButtonsProps';
33
import RNGestureHandlerButtonNativeComponent from '../specs/RNGestureHandlerButtonNativeComponent';
4+
import RNGestureHandlerButtonWrapperNativeComponent from '../specs/RNGestureHandlerButtonWrapperNativeComponent';
45

5-
export default RNGestureHandlerButtonNativeComponent as HostComponent<RawButtonProps>;
6+
const ButtonComponent =
7+
RNGestureHandlerButtonNativeComponent as HostComponent<RawButtonProps>;
8+
9+
export default function GestureHandlerButton({
10+
style,
11+
...rest
12+
}: RawButtonProps) {
13+
const flattenedStyle = StyleSheet.flatten(style);
14+
15+
const { width, height, ...restStyle } = flattenedStyle;
16+
17+
return (
18+
<RNGestureHandlerButtonWrapperNativeComponent style={styles.contents}>
19+
<View collapsable={false} style={[styles.contents, restStyle]}>
20+
<ButtonComponent {...rest} style={{ width, height }} />
21+
</View>
22+
</RNGestureHandlerButtonWrapperNativeComponent>
23+
);
24+
}
25+
26+
const styles = StyleSheet.create({
27+
contents: {
28+
display: 'contents',
29+
},
30+
});

0 commit comments

Comments
 (0)