Skip to content

Commit

Permalink
feat: adds useModal prop wrap action sheet in a modal
Browse files Browse the repository at this point in the history
Fixes #169
  • Loading branch information
BrodaNoel authored May 6, 2020
1 parent d85c167 commit 9ed955d
Showing 5 changed files with 67 additions and 8 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -102,7 +102,7 @@ The same options available on React Native's [ActionSheetIOS](https://facebook.g
| -----------------| -------| -------- | ------- |
| anchor | number | No | |

#### `anchor` (optional)
#### `anchor` (optional)
iPad only option that allows for docking the action sheet to a node. See [ShowActionSheetButton.tsx](/example/ShowActionSheetButton.tsx) for an example on how to implement this.

### Android/Web-Only Props
@@ -120,6 +120,7 @@ The below props allow modification of the Android ActionSheet. They have no effe
| showSeparators | boolean | No | false |
| containerStyle | ViewStyle | No | |
| separatorStyle | ViewStyle | No | |
| useModal | boolean | No | false |

#### `icons` (optional)

@@ -146,6 +147,9 @@ Apply any view style props to the container rather than use the default look (e.
#### `separatorStyle`: (optional)
Modify the look of the separators rather than use the default look.

#### `useModal`: (optional)
Wrap the ActionSheet with a Modal, in order to show in front of other Modals that were already opened ([issue reference](https://github.com/expo/react-native-action-sheet/issues/164)).

## Try it out

Try it in Expo: https://expo.io/@community/react-native-action-sheet-example
41 changes: 39 additions & 2 deletions example/App.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import * as React from 'react';
import { StyleSheet, Text, View, ScrollView, SafeAreaView } from 'react-native';
import {
Modal,
StyleSheet,
Text,
View,
ScrollView,
SafeAreaView,
TouchableOpacity,
} from 'react-native';
import {
ActionSheetProvider,
connectActionSheet,
ActionSheetOptions,
ActionSheetProps,
} from '@expo/react-native-action-sheet';
import ShowActionSheetButton from './ShowActionSheetButton';
@@ -12,11 +19,13 @@ type Props = ActionSheetProps;

interface State {
selectedIndex: number | null;
isModalOpen: boolean;
}

class App extends React.Component<Props, State> {
state: State = {
selectedIndex: null,
isModalOpen: false,
};

_updateSelectionText = (selectedIndex: number) => {
@@ -36,6 +45,10 @@ class App extends React.Component<Props, State> {
return <Text style={styles.sectionHeaderText}>{text}</Text>;
};

_toggleModal = () => {
this.setState({ isModalOpen: !this.state.isModalOpen });
};

_renderButtons() {
const { showActionSheetWithOptions } = this.props;
return (
@@ -117,6 +130,26 @@ class App extends React.Component<Props, State> {
onSelection={this._updateSelectionText}
showActionSheetWithOptions={showActionSheetWithOptions}
/>
{this._renderSectionHeader('Special Cases')}
<TouchableOpacity onPress={this._toggleModal}>
<Text style={styles.link}>Open Modal</Text>
</TouchableOpacity>
{this.state.isModalOpen && (
<Modal>
<View style={{ flex: 1, padding: 30 }}>
<ShowActionSheetButton
useModal
title="Options Only"
onSelection={this._updateSelectionText}
showActionSheetWithOptions={showActionSheetWithOptions}
/>

<TouchableOpacity onPress={this._toggleModal}>
<Text style={styles.link}>Close Modal</Text>
</TouchableOpacity>
</View>
</Modal>
)}
</View>
);
}
@@ -184,4 +217,8 @@ const styles = StyleSheet.create({
fontSize: 16,
marginTop: 20,
},
link: {
fontSize: 15,
textDecorationLine: 'underline',
},
});
7 changes: 6 additions & 1 deletion example/ShowActionSheetButton.tsx
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ const icon = (name: string) => <MaterialIcons key={name} name={name} size={24} /
interface Props {
title: string;
showActionSheetWithOptions: (
optons: ActionSheetOptions,
options: ActionSheetOptions,
callback: (buttonIndex: number) => void
) => void;
onSelection: (index: number) => void;
@@ -18,6 +18,7 @@ interface Props {
withSeparators?: boolean;
withCustomStyles?: boolean;
withAnchor?: boolean;
useModal?: boolean;
}

// A custom button that shows examples of different share sheet configurations
@@ -30,6 +31,7 @@ export default class ShowActionSheetButton extends React.PureComponent<Props> {
withCustomStyles: false,
withAnchor: false,
onSelection: null,
useModal: false,
};

_anchorRef = React.createRef<Button>();
@@ -44,6 +46,7 @@ export default class ShowActionSheetButton extends React.PureComponent<Props> {
withCustomStyles,
onSelection,
showActionSheetWithOptions,
useModal,
} = this.props;

// Same interface as https://facebook.github.io/react-native/docs/actionsheetios.html
@@ -110,6 +113,8 @@ export default class ShowActionSheetButton extends React.PureComponent<Props> {
messageTextStyle,
// Android only,
containerStyle,
// Android only,
useModal,
},
(buttonIndex: number) => {
// Do something here depending on the button index selected
20 changes: 16 additions & 4 deletions src/ActionSheet/index.tsx
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ import {
Animated,
BackHandler,
Easing,
Modal,
StyleSheet,
TouchableWithoutFeedback,
View,
@@ -53,7 +54,8 @@ export default class ActionSheet extends React.Component<Props, State> {
(this._actionSheetHeight = nativeEvent.layout.height);

render() {
const { isVisible, overlayOpacity } = this.state;
const { isVisible, overlayOpacity, options } = this.state;
const useModal = options ? options.useModal === true : false;
const overlay = isVisible ? (
<Animated.View
style={[
@@ -71,8 +73,18 @@ export default class ActionSheet extends React.Component<Props, State> {
flex: 1,
}}>
{React.Children.only(this.props.children)}
{overlay}
{isVisible ? this._renderSheet() : null}
{isVisible && !useModal && (
<React.Fragment>
{overlay}
{this._renderSheet()}
</React.Fragment>
)}
{isVisible && useModal && (
<Modal animationType="none" transparent={true} onRequestClose={this._selectCancelButton}>
{overlay}
{this._renderSheet()}
</Modal>
)}
</View>
);
}
@@ -143,7 +155,7 @@ export default class ActionSheet extends React.Component<Props, State> {
}

showActionSheetWithOptions = (options: ActionSheetOptions, onSelect: (i: number) => void) => {
const { isVisible, isAnimating, overlayOpacity, sheetOpacity } = this.state;
const { isVisible, overlayOpacity, sheetOpacity } = this.state;

if (isVisible) {
this._deferNextShow = this.showActionSheetWithOptions.bind(this, options, onSelect);
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -26,4 +26,5 @@ export interface ActionSheetOptions extends ActionSheetIOSOptions {
showSeparators?: boolean;
containerStyle?: ViewStyle;
separatorStyle?: ViewStyle;
useModal?: boolean;
}

0 comments on commit 9ed955d

Please sign in to comment.