1import React, { Component } from 'react';
2import { StyleSheet, Button, View, TextInput } from 'react-native';
3import { Screen, ScreenStack } from 'react-native-screens';
4
5type StackProps = {
6  renderScreen: (key: string) => JSX.Element;
7};
8
9type StackState = {
10  stack: string[];
11  transitioning: number;
12};
13
14const COLORS = ['azure', 'pink', 'cyan'];
15
16export class Stack extends Component<StackProps, StackState> {
17  state = {
18    stack: ['azure'],
19    transitioning: 0,
20  };
21
22  push(key: string) {
23    const { stack } = this.state;
24    this.setState({ stack: [...stack, key], transitioning: 1 });
25  }
26
27  pop() {
28    const { stack } = this.state;
29    this.setState({ transitioning: 0, stack: stack.slice(0, -1) });
30  }
31
32  remove(index: number) {
33    const { stack } = this.state;
34    this.setState({ stack: stack.filter((v, idx) => idx !== index) });
35  }
36
37  removeByKey(key: string) {
38    const { stack } = this.state;
39    this.setState({ stack: stack.filter(v => key !== v) });
40  }
41
42  renderScreen = (key: string) => {
43    return (
44      <Screen
45        style={StyleSheet.absoluteFill}
46        key={key}
47        stackAnimation="fade"
48        stackPresentation="push"
49        active={1}
50        onDismissed={() => this.removeByKey(key)}>
51        {this.props.renderScreen(key)}
52      </Screen>
53    );
54  };
55
56  render() {
57    const screens = this.state.stack.map(this.renderScreen);
58    return <ScreenStack style={styles.container}>{screens}</ScreenStack>;
59  }
60}
61
62class App extends Component {
63  stackRef = React.createRef<Stack>();
64
65  renderScreen = (key: string) => {
66    const index = COLORS.indexOf(key);
67    const color = key;
68    const pop = index > 0 ? () => this.stackRef.current?.pop() : null;
69    const push = index < 2 ? () => this.stackRef.current?.push(COLORS[index + 1]) : null;
70    const remove = index > 1 ? () => this.stackRef.current?.remove(1) : null;
71
72    return (
73      <View
74        style={{
75          flex: 1,
76          backgroundColor: color,
77          alignItems: 'center',
78          justifyContent: 'center',
79          // margin: index * 40,
80        }}>
81        <View
82          style={{
83            position: 'absolute',
84            top: 110,
85            left: 0,
86            width: 80,
87            height: 80,
88            backgroundColor: 'black',
89          }}
90        />
91        {pop && <Button title="Pop" onPress={pop} />}
92        {push && <Button title="Push" onPress={push} />}
93        {remove && <Button title="Remove middle screen" onPress={remove} />}
94        <TextInput placeholder="Hello" style={styles.textInput} />
95        <View style={{ height: 100, backgroundColor: 'red', width: '70%' }} />
96      </View>
97    );
98  };
99
100  render() {
101    return <Stack ref={this.stackRef} renderScreen={this.renderScreen} />;
102  }
103}
104
105const styles = StyleSheet.create({
106  container: {
107    flex: 1,
108    justifyContent: 'center',
109    alignItems: 'center',
110    backgroundColor: '#F5FCFF',
111  },
112  textInput: {
113    backgroundColor: 'white',
114    borderWidth: 1,
115    padding: 10,
116    marginHorizontal: 20,
117    alignSelf: 'stretch',
118    borderColor: 'black',
119  },
120});
121
122export default App;
123