Skip to content

Commit e5f8f7c

Browse files
chore: attempt reproducing modal layout issues on new arch
1 parent 084a723 commit e5f8f7c

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

Diff for: packages/rn-tester/js/examples/Modal/ModalExample.js

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
1212

1313
import ModalOnShow from './ModalOnShow';
14+
import ModalInSequence from './ModalInSequence';
1415
import ModalPresentation from './ModalPresentation';
1516

1617
export const displayName: ?string = undefined;
@@ -22,4 +23,5 @@ export const description = 'Component for presenting modal views.';
2223
export const examples: Array<RNTesterModuleExample> = [
2324
ModalPresentation,
2425
ModalOnShow,
26+
ModalInSequence,
2527
];
+161
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
* @format
9+
*/
10+
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
11+
12+
import * as React from 'react';
13+
import {useState} from 'react';
14+
import {Modal, Pressable, StyleSheet, Text, View} from 'react-native';
15+
16+
function causeJSThreadBlocking() {
17+
const intervalId = setInterval(() => {
18+
const start = Date.now();
19+
while (Date.now() - start < 20) {
20+
// Blocking operation
21+
Math.random() * Math.random();
22+
}
23+
}, 16);
24+
setTimeout(() => {
25+
clearInterval(intervalId);
26+
}, 10000);
27+
}
28+
29+
function ModalInSequence(): React.Node {
30+
const [firstModalVisible, setFirstModalVisible] = useState(false);
31+
const [secondModalVisible, setSecondModalVisible] = useState(false);
32+
33+
const showSecondHideFirst = () => {
34+
setFirstModalVisible(false);
35+
setSecondModalVisible(true);
36+
};
37+
38+
return (
39+
<View style={styles.container}>
40+
<Modal
41+
key="first"
42+
animationType="slide"
43+
transparent={true}
44+
visible={firstModalVisible}
45+
onRequestClose={() => setFirstModalVisible(false)}>
46+
<View
47+
onLayout={e => {
48+
causeJSThreadBlocking();
49+
console.log('modal first', e.nativeEvent.layout);
50+
}}
51+
style={[styles.centeredView, styles.modalBackdrop]}>
52+
<View style={styles.modalView}>
53+
<Text style={styles.modalText}>This is the first modal</Text>
54+
<Pressable
55+
style={[styles.button, styles.buttonClose]}
56+
onPress={async () => {
57+
// await new Promise(resolve => setTimeout(resolve, 100));
58+
setFirstModalVisible(false);
59+
}}>
60+
<Text style={styles.textStyle}>Close Modal</Text>
61+
</Pressable>
62+
<Pressable
63+
style={[styles.button, styles.buttonOpen]}
64+
onPress={showSecondHideFirst}>
65+
<Text style={styles.textStyle}>Show Second Modal</Text>
66+
</Pressable>
67+
</View>
68+
</View>
69+
</Modal>
70+
71+
<Modal
72+
key="second"
73+
animationType="slide"
74+
transparent={true}
75+
visible={secondModalVisible}
76+
onRequestClose={() => setSecondModalVisible(false)}>
77+
<View
78+
onLayout={e => {
79+
console.log('modal second', e.nativeEvent.layout);
80+
}}
81+
style={[styles.centeredView, styles.modalBackdrop]}>
82+
<View style={styles.modalView}>
83+
<Text style={styles.modalText}>This is the second modal</Text>
84+
<Pressable
85+
style={[styles.button, styles.buttonClose]}
86+
onPress={() => setSecondModalVisible(false)}>
87+
<Text style={styles.textStyle}>Close Modal</Text>
88+
</Pressable>
89+
</View>
90+
</View>
91+
</Modal>
92+
93+
<Pressable
94+
style={[styles.button, styles.buttonOpen]}
95+
onPress={() => setFirstModalVisible(true)}>
96+
<Text style={styles.textStyle}>Show First Modal</Text>
97+
</Pressable>
98+
</View>
99+
);
100+
}
101+
102+
const styles = StyleSheet.create({
103+
container: {
104+
display: 'flex',
105+
alignItems: 'center',
106+
paddingVertical: 30,
107+
},
108+
centeredView: {
109+
flex: 1,
110+
justifyContent: 'center',
111+
alignItems: 'center',
112+
},
113+
modalBackdrop: {
114+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
115+
},
116+
modalView: {
117+
backgroundColor: 'white',
118+
margin: 20,
119+
borderRadius: 20,
120+
padding: 35,
121+
alignItems: 'center',
122+
shadowColor: '#000',
123+
shadowOffset: {
124+
width: 0,
125+
height: 2,
126+
},
127+
shadowOpacity: 0.25,
128+
shadowRadius: 4,
129+
elevation: 5,
130+
},
131+
modalText: {
132+
marginBottom: 15,
133+
textAlign: 'center',
134+
},
135+
button: {
136+
borderRadius: 20,
137+
padding: 10,
138+
marginVertical: 10,
139+
elevation: 2,
140+
minWidth: 150,
141+
},
142+
buttonOpen: {
143+
backgroundColor: '#F194FF',
144+
},
145+
buttonClose: {
146+
backgroundColor: '#2196F3',
147+
},
148+
textStyle: {
149+
color: 'white',
150+
fontWeight: 'bold',
151+
textAlign: 'center',
152+
},
153+
});
154+
155+
export default ({
156+
title: 'Modal In Sequence',
157+
name: 'modalSequence',
158+
description:
159+
'Example of showing two modals in sequence with a busy JS thread',
160+
render: (): React.Node => <ModalInSequence />,
161+
}: RNTesterModuleExample);

0 commit comments

Comments
 (0)