1import { ActionSheetProvider, connectActionSheet } from '@expo/react-native-action-sheet';
2import React from 'react';
3import {
4  ActionSheetIOS,
5  Platform,
6  ScrollView,
7  StyleSheet,
8  Text,
9  TouchableOpacity,
10  TouchableOpacityProps,
11  View,
12} from 'react-native';
13
14import ShowActionSheetButton from '../components/ShowActionSheetButton';
15import { Colors } from '../constants';
16
17const Button: React.FunctionComponent<TouchableOpacityProps> = (props) => {
18  return (
19    <TouchableOpacity
20      onPress={props.onPress}
21      style={{
22        paddingHorizontal: 15,
23        paddingVertical: 10,
24        borderRadius: 3,
25        backgroundColor: Colors.tintColor,
26        marginRight: 10,
27      }}>
28      <Text
29        style={{
30          color: '#fff',
31        }}>
32        {props.children}
33      </Text>
34    </TouchableOpacity>
35  );
36};
37
38const ActionSheetProviderScreen = () => (
39  <ActionSheetProvider>
40    <App />
41  </ActionSheetProvider>
42);
43
44function ActionSheetScreen() {
45  return (
46    <ScrollView>
47      <ActionSheetProviderScreen />
48      {Platform.OS === 'ios' && <ActionSheetIOSExample />}
49    </ScrollView>
50  );
51}
52
53function ActionSheetIOSExample() {
54  const showActionSheet = () => {
55    ActionSheetIOS.showActionSheetWithOptions(
56      {
57        options: ['Option 0', 'Option 1', 'Delete', 'Cancel'],
58        cancelButtonIndex: 3,
59        destructiveButtonIndex: 2,
60      },
61      (buttonIndex) => {
62        console.log({ buttonIndex });
63      }
64    );
65  };
66
67  const showShareSheet = () => {
68    ActionSheetIOS.showShareActionSheetWithOptions(
69      {
70        url: 'https://expo.dev',
71        message: 'message to go with the shared url',
72        subject: 'a subject to go in the email heading',
73      },
74      (error) => alert(error),
75      (success, method) => {
76        if (success) {
77          alert(`Shared via ${method}`);
78        }
79      }
80    );
81  };
82
83  return (
84    <View style={{ flexDirection: 'row', padding: 10 }}>
85      <Button onPress={showActionSheet}>Action sheet</Button>
86
87      <Button onPress={showShareSheet}>Share sheet</Button>
88    </View>
89  );
90}
91
92ActionSheetScreen.navigationOptions = {
93  title: 'Action Sheet',
94};
95
96export default ActionSheetScreen;
97
98interface State {
99  selectedIndex?: number;
100}
101
102// @ts-ignore
103@connectActionSheet
104class App extends React.Component<{ showActionSheetWithOptions?: any }, State> {
105  readonly state: State = {};
106
107  _updateSelectionText = (selectedIndex: number) => {
108    this.setState({ selectedIndex });
109  };
110
111  _renderSelectionText() {
112    const { selectedIndex } = this.state;
113    const text =
114      selectedIndex === undefined ? 'No Option Selected' : `Option #${selectedIndex + 1} Selected`;
115
116    return <Text style={styles.selectionText}>{text}</Text>;
117  }
118
119  _renderSectionHeader(text: string) {
120    return <Text style={styles.sectionHeaderText}>{text}</Text>;
121  }
122
123  _renderButtons() {
124    const { showActionSheetWithOptions } = this.props;
125    return (
126      <View style={{ alignItems: 'center' }}>
127        {this._renderSectionHeader('Universal Options')}
128        <ShowActionSheetButton
129          title="Options Only"
130          onSelection={this._updateSelectionText}
131          showActionSheetWithOptions={showActionSheetWithOptions}
132        />
133        <ShowActionSheetButton
134          title="Title"
135          withTitle
136          onSelection={this._updateSelectionText}
137          showActionSheetWithOptions={showActionSheetWithOptions}
138        />
139        <ShowActionSheetButton
140          title="Title & Message"
141          withTitle
142          withMessage
143          onSelection={this._updateSelectionText}
144          showActionSheetWithOptions={showActionSheetWithOptions}
145        />
146        {this._renderSectionHeader('Android-Only Options')}
147        <ShowActionSheetButton
148          title="Icons"
149          withIcons
150          onSelection={this._updateSelectionText}
151          showActionSheetWithOptions={showActionSheetWithOptions}
152        />
153        <ShowActionSheetButton
154          title="Title, Message, & Icons"
155          withTitle
156          withMessage
157          withIcons
158          onSelection={this._updateSelectionText}
159          showActionSheetWithOptions={showActionSheetWithOptions}
160        />
161        <ShowActionSheetButton
162          title="Use Separators"
163          withTitle
164          withIcons
165          withSeparators
166          onSelection={this._updateSelectionText}
167          showActionSheetWithOptions={showActionSheetWithOptions}
168        />
169        <ShowActionSheetButton
170          title="Custom Styles"
171          withTitle
172          withMessage
173          withIcons
174          withCustomStyles
175          onSelection={this._updateSelectionText}
176          showActionSheetWithOptions={showActionSheetWithOptions}
177        />
178      </View>
179    );
180  }
181
182  render() {
183    return (
184      <ScrollView style={styles.flex} contentContainerStyle={styles.contentContainer}>
185        <Text style={styles.headerText}>
186          {'Hello!\n\nThis is a simple example app to demonstrate @expo/react-native-action-sheet.'}
187        </Text>
188        {this._renderButtons()}
189        {this._renderSelectionText()}
190        <Text style={styles.notes}>
191          Note: Icons and custom text styles are only available on Android and web. Separators can
192          only be toggled on Android or web; they always show on iOS.
193        </Text>
194      </ScrollView>
195    );
196  }
197}
198
199const styles = StyleSheet.create({
200  flex: {
201    flex: 1,
202  },
203  contentContainer: {
204    padding: 16,
205    paddingVertical: 20,
206  },
207  headerText: {
208    textAlign: 'center',
209    fontSize: 16,
210    marginBottom: 10,
211  },
212  notes: {
213    marginTop: 32,
214  },
215  sectionHeaderText: {
216    color: 'orange',
217    textAlign: 'center',
218    fontWeight: 'bold',
219    fontSize: 20,
220    marginTop: 20,
221    marginBottom: 10,
222  },
223  selectionText: {
224    textAlign: 'center',
225    color: 'blue',
226    fontSize: 16,
227    marginTop: 20,
228  },
229});
230