├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── button.js ├── index.js ├── overlay.js ├── package.json ├── screencasts └── demo.gif └── sheet.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.[aod] 2 | *.DS_Store 3 | .DS_Store 4 | *Thumbs.db 5 | *.iml 6 | .gradle 7 | .idea 8 | node_modules 9 | npm-debug.log 10 | /android/build 11 | /ios/**/*xcuserdata* 12 | /ios/**/*xcshareddata* 13 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | .DS_Store 3 | *Thumbs.db 4 | .gradle 5 | .idea 6 | *.iml 7 | npm-debug.log 8 | node_modules 9 | /android/build 10 | /ios/**/*xcuserdata* 11 | /ios/**/*xcshareddata* 12 | 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2015-2016 YunJiang.Fang <42550564@qq.com> 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native ActionSheet (remobile) 2 | A pure js ActionSheet like ios ActionSheet, support ios and android 3 | 4 | ## Installation 5 | ```sh 6 | npm install @remobile/react-native-action-sheet --save 7 | ``` 8 | 9 | ## Usage 10 | 11 | ### Example 12 | ```js 13 | 'use strict'; 14 | 15 | var React = require('react'); 16 | var ReactNative = require('react-native'); 17 | var { 18 | StyleSheet, 19 | TouchableOpacity, 20 | View, 21 | } = ReactNative; 22 | 23 | var ActionSheet = require('@remobile/react-native-action-sheet'); 24 | var Button = require('@remobile/react-native-simple-button'); 25 | 26 | module.exports = React.createClass({ 27 | getInitialState() { 28 | return { 29 | show: false 30 | }; 31 | }, 32 | onCancel() { 33 | this.setState({show:false}); 34 | }, 35 | onOpen() { 36 | this.setState({show:true}); 37 | }, 38 | render() { 39 | return ( 40 | 41 | 42 | 45 | Capture 46 | Photo 47 | Camera 48 | 49 | 50 | ); 51 | }, 52 | }); 53 | 54 | var styles = StyleSheet.create({ 55 | container: { 56 | flex: 1, 57 | justifyContent: 'center' 58 | }, 59 | }); 60 | ``` 61 | 62 | ## Screencasts 63 | 64 | ![loading](https://github.com/remobile/react-native-action-sheet/blob/master/screencasts/demo.gif) 65 | 66 | ##ActionSheet 67 | #### Props 68 | - `visible : PropTypes.boolean.isRequired` - must use state to control ActionSheet visible 69 | - `onCancel : PropTypes.func.isRequired` - use to hide ActionSheet 70 | - `cancelText : PropTypes.string` - default is 'Cancel' 71 | 72 | ##ActionSheet.Button 73 | #### Props 74 | - `buttonStyle : TouchableOpacity.propTypes.style` - set button style 75 | - `textStyle : Text.propTypes.style` - set button text style 76 | - `onPress : PropTypes.func` - callback for button click 77 | -------------------------------------------------------------------------------- /button.js: -------------------------------------------------------------------------------- 1 | /* 2 | * (The MIT License) 3 | * Copyright (c) 2015-2016 YunJiang.Fang <42550564@qq.com> 4 | */ 5 | 'use strict'; 6 | 7 | const React = require('react'); 8 | const ReactNative = require('react-native'); 9 | const { StyleSheet, Text, TouchableOpacity, View } = ReactNative; 10 | 11 | module.exports = React.createClass({ 12 | render: function () { 13 | return ( 14 | 18 | 19 | {this.props.children} 20 | 21 | 22 | ); 23 | }, 24 | }); 25 | 26 | const styles = StyleSheet.create({ 27 | buttonText: { 28 | color: '#0069d5', 29 | alignSelf: 'center', 30 | fontSize: 18, 31 | }, 32 | button: { 33 | height: 40, 34 | backgroundColor: 'white', 35 | borderColor: 'gray', 36 | borderBottomWidth: 1, 37 | alignSelf: 'stretch', 38 | justifyContent: 'center', 39 | }, 40 | }); 41 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const ReactNative = require('react-native'); 5 | const { 6 | StyleSheet, 7 | TouchableOpacity, 8 | View, 9 | } = ReactNative; 10 | 11 | const Button = require('./button.js'); 12 | const Overlay = require('./overlay.js'); 13 | const Sheet = require('./sheet.js'); 14 | 15 | module.exports = React.createClass({ 16 | getDefaultProps: function () { 17 | return { 18 | cancelText: 'Cancel', 19 | }; 20 | }, 21 | render () { 22 | return ( 23 | 24 | 25 | 28 | 29 | 30 | {this.props.children} 31 | 32 | 36 | 37 | 38 | 39 | ); 40 | }, 41 | }); 42 | module.exports.Button = Button; 43 | 44 | const styles = StyleSheet.create({ 45 | actionSheetContainer: { 46 | flex: 1, 47 | padding: 10, 48 | paddingBottom: 6, 49 | justifyContent: 'flex-end', 50 | backgroundColor: 'rgba(0, 0, 0, 0.5)', 51 | }, 52 | buttonContainer: { 53 | borderRadius:6, 54 | overflow: 'hidden', 55 | }, 56 | }); 57 | -------------------------------------------------------------------------------- /overlay.js: -------------------------------------------------------------------------------- 1 | /* 2 | * (The MIT License) 3 | * Copyright (c) 2015-2016 YunJiang.Fang <42550564@qq.com> 4 | */ 5 | 'use strict'; 6 | 7 | const React = require('react'); 8 | const ReactNative = require('react-native'); 9 | const { Animated, StyleSheet, View, Dimensions } = ReactNative; 10 | 11 | const DEFAULT_ANIMATE_TIME = 300; 12 | 13 | module.exports = React.createClass({ 14 | getInitialState () { 15 | return { 16 | fadeAnim: new Animated.Value(0), 17 | overlayStyle: styles.emptyOverlay, //on android opacity=0 also can cover screen, so use overlayStyle fix it 18 | }; 19 | }, 20 | onAnimatedEnd () { 21 | !this.props.visible && this.setState({ overlayStyle:styles.emptyOverlay }); 22 | }, 23 | componentWillReceiveProps (newProps) { 24 | newProps.visible && this.setState({ overlayStyle: styles.fullOverlay }); 25 | return Animated.timing(this.state.fadeAnim, { 26 | toValue: newProps.visible ? 1 : 0, 27 | duration: DEFAULT_ANIMATE_TIME, 28 | }).start(this.onAnimatedEnd); 29 | }, 30 | 31 | render () { 32 | return ( 33 | 34 | {this.props.children} 35 | 36 | ); 37 | }, 38 | }); 39 | 40 | const styles = StyleSheet.create({ 41 | fullOverlay: { 42 | top: 0, 43 | bottom: 0, 44 | left: 0, 45 | right: 0, 46 | backgroundColor: 'transparent', 47 | position: 'absolute', 48 | }, 49 | emptyOverlay: { 50 | backgroundColor: 'transparent', 51 | position: 'absolute', 52 | }, 53 | }); 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@remobile/react-native-action-sheet", 3 | "version": "1.0.2", 4 | "description": "A pure js ActionSheet like ios ActionSheet, support ios and android", 5 | "main": "index.js", 6 | "author": { 7 | "name": "YunJiang.Fang", 8 | "email": "42550564@qq.com" 9 | }, 10 | "license": "MIT", 11 | "keywords": [ 12 | "react-native", 13 | "react-component", 14 | "ios", 15 | "android", 16 | "action sheet", 17 | "ActionSheet", 18 | "animation", 19 | "remobile", 20 | "mobile" 21 | ], 22 | "homepage": "https://github.com/remobile/react-native-action-sheet", 23 | "bugs": { 24 | "url": "https://github.com/remobile/react-native-action-sheet/issues" 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "git://github.com/remobile/react-native-action-sheet.git" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /screencasts/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/remobile/react-native-action-sheet/cf9899fdedf3e8f4eb6a315ec3593d29419c0c0b/screencasts/demo.gif -------------------------------------------------------------------------------- /sheet.js: -------------------------------------------------------------------------------- 1 | /* 2 | * (The MIT License) 3 | * Copyright (c) 2015-2016 YunJiang.Fang <42550564@qq.com> 4 | */ 5 | 'use strict'; 6 | 7 | const React = require('react'); 8 | const ReactNative = require('react-native'); 9 | const { Animated, StyleSheet, View, Dimensions } = ReactNative; 10 | 11 | const DEFAULT_BOTTOM = -300; 12 | const DEFAULT_ANIMATE_TIME = 300; 13 | 14 | module.exports = React.createClass({ 15 | getInitialState: function () { 16 | return { 17 | bottom: new Animated.Value(DEFAULT_BOTTOM), 18 | }; 19 | }, 20 | componentWillReceiveProps: function (newProps) { 21 | return Animated.timing(this.state.bottom, { 22 | toValue: newProps.visible ? 0 : DEFAULT_BOTTOM, 23 | duration: DEFAULT_ANIMATE_TIME, 24 | }).start(); 25 | }, 26 | 27 | render: function () { 28 | return ( 29 | 30 | {this.props.children} 31 | 32 | ); 33 | }, 34 | }); 35 | --------------------------------------------------------------------------------