Skip to content

Commit 7a4f774

Browse files
j-piaseckim-bert
andauthored
[Native] display: contents based button styling (#3634)
## Description Changes the button implementation of the native `GestureHandlerButton` component, not to re-export the button component. Instead, it provides a "sandwich" implementation based on `display: contents`. The issues we had with the styling of the buttons in the past stemmed from it extending `ViewGroup` instead of `ReactViewGroup`. This cannot be changed due to the difference in handling of `onTouchEvent`. We experimented with wrapping the button with a `View` in the past, but properly handling layout turned out to be quite a challenge. Hopefully, with the addition of `display: contents`, this will be easier now. This PR changes the structure of the button to be: - `RNGestureHandlerButtonWrapperNativeComponent` - `View` - `ButtonComponent` The styles passed from the user are split into two categories: - visual only - affecting layout Those affecting the layout need to be set on the button itself, while visual changes need to be set on the View wrapping it. Exceptions are: `zIndex`, `transform`, and `transformOrigin`, which need to be on the View. `zIndex` because the View is being rendered in the hierarchy at the level the button would be expected, and transforms to properly calculate touch coordinate transforms. ### Why not just `ButtonComponent`? We need a `View` component as its parent to handle all styles that React Native supports properly. ### Why not just `ButtonComponent` wrapped with `View`? In order for the view to always match the layout of the button, we need to set it at the shadow node level. Shadow nodes only have references to their children, not their parents. To have access to the layout of the button and the ability to copy it to the view wrapping it, there needs to be one more node as the parent of that subtree. That node is responsible for making sure that the size and positioning of the View match the Button. The native components for the wrapper serve no purpose, since it's being rendered with `display: contents`, but RN doesn't know that - there needs to be something it can link to. ## Test plan See the `ContentsButton` file --------- Co-authored-by: Michał Bert <63123542+m-bert@users.noreply.github.com>
1 parent 3da9a68 commit 7a4f774

18 files changed

Lines changed: 1054 additions & 7 deletions

apps/basic-example/ios/Podfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2919,7 +2919,7 @@ SPEC CHECKSUMS:
29192919
FBLazyVector: a293a88992c4c33f0aee184acab0b64a08ff9458
29202920
fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd
29212921
glog: 5683914934d5b6e4240e497e0f4a3b42d1854183
2922-
hermes-engine: db854ab6e74b584dc130d3ed0be3425726bac226
2922+
hermes-engine: eec912f8a125ae0d3ad67b2e7b81a227319aa13b
29232923
RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669
29242924
RCTDeprecation: 2b70c6e3abe00396cefd8913efbf6a2db01a2b36
29252925
RCTRequired: f3540eee8094231581d40c5c6d41b0f170237a81
@@ -2993,7 +2993,7 @@ SPEC CHECKSUMS:
29932993
RNReanimated: 987d0b9af435441cc2ebc2a32ad06cafe8777d4e
29942994
RNWorklets: 12b2d7cdcb48acbdd0b324d1fa810f849089bd7b
29952995
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
2996-
Yoga: 6ca93c8c13f56baeec55eb608577619b17a4d64e
2996+
Yoga: 7a9f26c70daf0b08d82ec2f862e9a8872442129e
29972997

29982998
PODFILE CHECKSUM: ecce038d8e4749ee17b7dea28be0590cdc8b4836
29992999

apps/basic-example/src/App.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Navigator from './Navigator';
77
import Text from './Text';
88
import NativeDetector from './NativeDetector';
99
import RuntimeDecoration from './RuntimeDecoration';
10+
import ContentsButton from './ContentsButton';
1011

1112
const EXAMPLES = [
1213
{
@@ -21,6 +22,10 @@ const EXAMPLES = [
2122
name: 'Native Detector',
2223
component: NativeDetector,
2324
},
25+
{
26+
name: 'Contents Button',
27+
component: ContentsButton,
28+
},
2429
];
2530

2631
const Stack = Navigator.create();

0 commit comments

Comments
 (0)