Commit df333c7
authored
[Native] Replace
## Description
Removes the `display: contents` based button implementation and adds the
missing styling options on the existing implementation. This should
significantly improve the render & mount time of buttons since now it
requires a single view and a single shadow node instead of 2 views and 3
shadow nodes.
## Test plan
<details>
<summary>
Modified `Contents button` example
</summary>
```jsx
import React from 'react';
import { View, StyleSheet, Text, SafeAreaView } from 'react-native';
import {
GestureHandlerRootView,
ScrollView,
RectButton,
RawButton,
} from 'react-native-gesture-handler';
export default function ComplexUI() {
return (
<GestureHandlerRootView style={styles.container}>
<SafeAreaView style={styles.container}>
<ScrollView contentContainerStyle={styles.scrollContent}>
<Avatars />
<View style={styles.paddedContainer}>
<Gallery />
<SizeConstraints />
<FlexboxTests />
<PositioningTests />
<SpacingTests />
<VisualEffects />
<ComplexCombinations />
<Transforms />
</View>
</ScrollView>
</SafeAreaView>
</GestureHandlerRootView>
);
}
const colors = ['#782AEB', '#38ACDD', '#57B495', '#FF6259', '#FFD61E'];
function Avatars() {
return (
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
{colors.map((color) => (
<RectButton
key={color}
style={[styles.avatars, { backgroundColor: color }]}>
<Text style={styles.avatarLabel}>{color.slice(1, 3)}</Text>
</RectButton>
))}
</ScrollView>
);
}
function Gallery() {
return (
<View style={[styles.section]}>
<Text style={styles.sectionTitle}>Basic Gallery</Text>
<View style={[styles.gap]}>
<RectButton style={styles.fullWidthButton} />
<View style={[styles.row, styles.gap]}>
<RectButton style={styles.leftButton} />
<RectButton style={styles.rightButton} />
</View>
<RawButton underlayColor='red' style={[styles.fullWidthButton, { borderRadius: 20 }]} />
</View>
</View>
);
}
function SizeConstraints() {
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Size Constraints</Text>
<View style={[styles.row, styles.gap]}>
<RectButton style={styles.minMaxButton}>
<Text style={styles.buttonText}>Min/Max</Text>
</RectButton>
<RectButton style={styles.aspectRatioButton}>
<Text style={styles.buttonText}>1:1</Text>
</RectButton>
<RectButton style={styles.flexGrowButton}>
<Text style={styles.buttonText}>Flex</Text>
</RectButton>
</View>
</View>
);
}
function FlexboxTests() {
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Flexbox Layouts</Text>
<View style={styles.flexContainer}>
<RectButton style={styles.flexStart}>
<Text style={styles.buttonText}>Start</Text>
</RectButton>
<RectButton style={styles.flexCenter}>
<Text style={styles.buttonText}>Center</Text>
</RectButton>
<RectButton style={styles.flexEnd}>
<Text style={styles.buttonText}>End</Text>
</RectButton>
</View>
<View style={styles.flexWrapContainer}>
<RectButton style={styles.wrapItem}>
<Text style={styles.buttonText}>Wrap 1</Text>
</RectButton>
<RectButton style={styles.wrapItem}>
<Text style={styles.buttonText}>Wrap 2</Text>
</RectButton>
<RectButton style={styles.wrapItem}>
<Text style={styles.buttonText}>Wrap 3</Text>
</RectButton>
<RectButton style={styles.wrapItem}>
<Text style={styles.buttonText}>Wrap 4</Text>
</RectButton>
</View>
</View>
);
}
function PositioningTests() {
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Positioning</Text>
<View style={styles.positionContainer}>
<RectButton style={styles.zIndexButton}>
<Text style={styles.buttonText}>Z-Index</Text>
</RectButton>
<RectButton style={styles.absoluteButton}>
<Text style={styles.buttonText}>Absolute</Text>
</RectButton>
<RectButton style={styles.relativeButton}>
<Text style={styles.buttonText}>Relative</Text>
</RectButton>
</View>
</View>
);
}
function SpacingTests() {
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Spacing & Overflow</Text>
<View style={[styles.row, styles.gap]}>
<RectButton style={styles.paddingButton}>
<Text style={styles.buttonText}>Padding</Text>
</RectButton>
<RectButton style={styles.marginButton}>
<Text style={styles.buttonText}>Margin</Text>
</RectButton>
<RectButton style={styles.overflowButton}>
<Text style={styles.longText}>Overflow Hidden Test</Text>
</RectButton>
</View>
</View>
);
}
function VisualEffects() {
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Visual Effects</Text>
<View style={[styles.row, styles.gap]}>
<RectButton style={styles.shadowButton}>
<Text style={styles.buttonText}>Shadow</Text>
</RectButton>
<RectButton style={styles.opacityButton}>
<Text style={styles.buttonText}>Opacity</Text>
</RectButton>
</View>
</View>
);
}
function ComplexCombinations() {
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Complex Combinations</Text>
<View style={styles.complexGrid}>
<RectButton style={styles.complexButton1}>
<Text style={styles.buttonText}>Complex 1</Text>
</RectButton>
<RectButton style={styles.complexButton2}>
<Text style={styles.buttonText}>Complex 2</Text>
</RectButton>
<RectButton style={styles.complexButton3}>
<Text style={styles.buttonText}>Complex 3</Text>
</RectButton>
<RectButton style={styles.complexButton4}>
<Text style={styles.buttonText}>Complex 4</Text>
</RectButton>
</View>
</View>
);
}
function Transforms() {
return (
<View style={styles.section}>
<Text style={styles.sectionTitle}>Transform</Text>
<View style={styles.complexGrid}>
<RectButton style={styles.transformButton}>
<Text style={styles.buttonText}>Transform</Text>
</RectButton>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
scrollContent: {
paddingBottom: 50,
},
paddedContainer: {
padding: 16,
},
section: {
marginBottom: 30,
},
sectionTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 12,
color: '#333',
},
gap: {
gap: 10,
},
row: {
flexDirection: 'row',
},
// Avatar styles
avatars: {
width: 90,
height: 90,
borderWidth: 2,
borderColor: '#001A72',
borderTopLeftRadius: 30,
borderTopRightRadius: 5,
borderBottomLeftRadius: 5,
borderBottomRightRadius: 30,
marginHorizontal: 4,
alignItems: 'center',
justifyContent: 'center',
},
avatarLabel: {
color: '#F8F9FF',
fontSize: 24,
fontWeight: 'bold',
},
// Gallery styles
fullWidthButton: {
width: '100%',
height: 160,
backgroundColor: '#FF6259',
borderTopRightRadius: 40,
borderTopLeftRadius: 40,
borderWidth: 1,
borderColor: '#000',
},
leftButton: {
flex: 1,
height: 160,
backgroundColor: '#FFD61E',
borderBottomLeftRadius: 30,
borderWidth: 5,
borderBottomWidth: 16,
borderColor: '#000',
},
rightButton: {
flex: 1,
backgroundColor: '#782AEB',
height: 160,
borderBottomRightRadius: 30,
borderWidth: 8,
borderColor: '#000',
},
// Size constraint styles
minMaxButton: {
minWidth: 80,
maxWidth: 120,
minHeight: 40,
maxHeight: 80,
backgroundColor: '#38ACDD',
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center',
},
aspectRatioButton: {
width: 80,
aspectRatio: 1,
backgroundColor: '#57B495',
borderRadius: 40,
justifyContent: 'center',
alignItems: 'center',
},
flexGrowButton: {
flexGrow: 1,
height: 60,
backgroundColor: '#FF6259',
borderRadius: 15,
justifyContent: 'center',
alignItems: 'center',
},
// Flexbox styles
flexContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
height: 80,
backgroundColor: '#e0e0e0',
borderRadius: 10,
padding: 10,
marginBottom: 10,
},
flexStart: {
alignSelf: 'flex-start',
backgroundColor: '#782AEB',
padding: 10,
borderRadius: 5,
},
flexCenter: {
alignSelf: 'center',
backgroundColor: '#38ACDD',
padding: 10,
borderRadius: 5,
},
flexEnd: {
alignSelf: 'flex-end',
backgroundColor: '#57B495',
padding: 10,
borderRadius: 5,
},
flexWrapContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 5,
},
wrapItem: {
width: '48%',
height: 50,
backgroundColor: '#FFD61E',
borderRadius: 8,
justifyContent: 'center',
alignItems: 'center',
},
// Positioning styles
positionContainer: {
height: 80,
backgroundColor: '#e0e0e0',
borderRadius: 10,
position: 'relative',
},
absoluteButton: {
position: 'absolute',
top: 10,
right: 10,
backgroundColor: '#FF6259',
padding: 8,
borderRadius: 5,
},
relativeButton: {
position: 'relative',
top: 20,
left: 20,
backgroundColor: '#782AEB',
padding: 8,
borderRadius: 5,
},
zIndexButton: {
position: 'absolute',
top: 10,
left: 10,
zIndex: 10,
backgroundColor: '#57B495',
padding: 8,
borderRadius: 5,
},
// Spacing styles
paddingButton: {
flex: 1,
backgroundColor: '#38ACDD',
paddingVertical: 20,
paddingHorizontal: 15,
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center',
},
marginButton: {
flex: 1,
backgroundColor: '#FFD61E',
margin: 10,
padding: 10,
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center',
},
overflowButton: {
flex: 1,
height: 60,
backgroundColor: '#782AEB',
borderRadius: 10,
overflow: 'hidden',
justifyContent: 'center',
alignItems: 'center',
},
// Visual effect styles
shadowButton: {
flex: 1,
height: 60,
backgroundColor: '#FF6259',
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 8,
},
opacityButton: {
flex: 1,
height: 60,
backgroundColor: '#782AEB',
borderRadius: 10,
justifyContent: 'center',
alignItems: 'center',
opacity: 0.7,
},
// Complex combination styles
complexGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 10,
},
complexButton1: {
width: '48%',
height: 100,
backgroundColor: '#FF6259',
borderRadius: 20,
borderWidth: 2,
borderColor: '#782AEB',
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 2, height: 2 },
shadowOpacity: 0.2,
shadowRadius: 4,
elevation: 4,
marginBottom: 5,
},
complexButton2: {
width: '48%',
minHeight: 80,
maxHeight: 120,
backgroundColor: '#38ACDD',
borderTopLeftRadius: 30,
borderBottomRightRadius: 30,
paddingVertical: 15,
paddingHorizontal: 10,
justifyContent: 'center',
alignItems: 'center',
overflow: 'hidden',
},
complexButton3: {
width: '48%',
aspectRatio: 1.5,
backgroundColor: '#57B495',
borderRadius: 15,
borderWidth: 4,
borderColor: '#FFD61E',
justifyContent: 'center',
alignItems: 'center',
opacity: 0.9,
marginTop: 10,
},
complexButton4: {
width: '48%',
height: 80,
backgroundColor: '#FFD61E',
borderRadius: 10,
borderWidth: 1,
borderColor: '#FF6259',
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#782AEB',
shadowOffset: { width: 0, height: 6 },
shadowOpacity: 0.4,
shadowRadius: 10,
elevation: 10,
marginTop: 10,
},
// Transform styles
transformButton: {
width: '48%',
height: 100,
backgroundColor: '#38ACDD',
borderRadius: 15,
justifyContent: 'center',
alignItems: 'center',
transform: [{ translateX: 100 }, { rotate: '15deg' }, { scale: 1.1 }],
},
// Text styles
buttonText: {
color: 'white',
fontWeight: 'bold',
textAlign: 'center',
},
longText: {
color: 'white',
fontWeight: 'bold',
textAlign: 'center',
fontSize: 16,
},
});
```
</details>display: contents based buttons with a single-view implementation (#4044)1 parent ea83410 commit df333c7
21 files changed
Lines changed: 1113 additions & 711 deletions
File tree
- apps/common-app/src/new_api
- components/button_underlay
- packages/react-native-gesture-handler
- android/src/main/java/com/swmansion/gesturehandler
- react
- apple
- src
- components
- specs
Lines changed: 552 additions & 0 deletions
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| 30 | + | |
30 | 31 | | |
31 | 32 | | |
32 | 33 | | |
| |||
107 | 108 | | |
108 | 109 | | |
109 | 110 | | |
| 111 | + | |
110 | 112 | | |
111 | 113 | | |
112 | 114 | | |
| |||
Lines changed: 0 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
15 | 14 | | |
16 | 15 | | |
17 | 16 | | |
| |||
35 | 34 | | |
36 | 35 | | |
37 | 36 | | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | 37 | | |
42 | 38 | | |
43 | 39 | | |
44 | 40 | | |
45 | 41 | | |
46 | 42 | | |
47 | 43 | | |
48 | | - | |
49 | 44 | | |
50 | 45 | | |
51 | 46 | | |
| |||
0 commit comments