├── src ├── index.js └── Halfcard.js ├── package.json └── README.md /src/index.js: -------------------------------------------------------------------------------- 1 | import Halfcard from './Halfcard' 2 | 3 | export default Halfcard 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rn-halfcard", 3 | "version": "1.0.4", 4 | "description": "Halfcard component for react native", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/chethann/rn-halfcard.git" 12 | }, 13 | "keywords": [ 14 | "react", 15 | "react-native", 16 | "halfcard" 17 | ], 18 | "author": "chethann12793@gmail.com", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/chethann/rn-halfcard/issues" 22 | }, 23 | "homepage": "https://github.com/chethann/rn-halfcard#readme" 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rn-halfcard 2 | Halfcard for React Native. 3 | A flexible Halfcard component for React native with callbacks and adjustable slide duration! 4 | 5 | # Demo 6 | ![rn-halfcard Demo](https://github.com/chethann/demo-images/blob/master/halfcard-demo.gif) 7 | 8 | # Usage 9 | 10 | ```javascript 11 | this.my_halfcard = component} 13 | slideDuration={500} 14 | onShow={this.onShow} 15 | onClose={this.onCloseModalOne}> 16 | {this.myHalfcardContent()} 17 | 18 | ``` 19 | 20 | Any valid React Native View can be passed as content of the halfcard. 21 | To open the halfcard call ```this.my_halfcard.show() ``` method and to close call ```this.my_halfcard.close() ``` method. 22 | 23 | ### Installation 24 | - `npm install --save rn-halfcard` 25 | 26 | License 27 | ---- 28 | MIT 29 | -------------------------------------------------------------------------------- /src/Halfcard.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { 3 | Animated, 4 | Modal, 5 | TouchableHighlight, 6 | Dimensions, 7 | StyleSheet, 8 | Keyboard, 9 | View } from 'react-native' 10 | 11 | const styles = StyleSheet.create({ 12 | overlay: { 13 | flexGrow: 1, 14 | backgroundColor: 'rgb(0,0,0)', 15 | }, 16 | 17 | content: { 18 | position: 'absolute', 19 | left: 0, 20 | right: 0, 21 | }, 22 | 23 | container: { flexGrow: 1 }, 24 | }) 25 | 26 | class Halfcard extends Component { 27 | 28 | constructor (props) { 29 | super(props) 30 | const { height } = Dimensions.get('window') 31 | this.animateHeight = this.props.height || height 32 | this.state = { 33 | modalVisible: false, 34 | position: new Animated.Value(-1 * this.animateHeight), 35 | opacity: new Animated.Value(0), 36 | } 37 | this.hideModal = this.hideModal.bind(this) 38 | } 39 | 40 | componentDidMount () { 41 | this.isComponentMounted = true 42 | } 43 | 44 | componentWillUnmount () { 45 | this.isComponentMounted = false 46 | } 47 | 48 | setModalVisible (visible) { 49 | this.setState({ modalVisible: visible }) 50 | } 51 | 52 | animateUp () { 53 | const slideAnimation = Animated.timing( 54 | this.state.position, 55 | { 56 | toValue: 0, 57 | duration: this.props.slideDuration || 300, 58 | }, 59 | ) 60 | 61 | const fadeAnimation = Animated.timing( 62 | this.state.opacity, 63 | { 64 | toValue: 0.4, 65 | duration: this.props.slideDuration || 300, 66 | useNativeDriver: true, 67 | }, 68 | ) 69 | 70 | Animated.parallel([ slideAnimation, fadeAnimation ]).start() 71 | } 72 | 73 | animateDown () { 74 | const slideDownTo = -1 * this.animateHeight 75 | const slideAnimation = Animated.timing( 76 | this.state.position, 77 | { 78 | toValue: this.props.slideDownTo || slideDownTo, 79 | duration: this.props.slideDuration || 300, 80 | }, 81 | ) 82 | 83 | const fadeAnimation = Animated.timing( 84 | this.state.opacity, 85 | { 86 | toValue: 0, 87 | duration: this.props.slideDuration || 300, 88 | useNativeDriver: true, 89 | }, 90 | ) 91 | 92 | Animated.parallel([ slideAnimation, fadeAnimation ]).start(() => { 93 | this.props.onClose && this.props.onClose() 94 | this.setModalVisible(false) 95 | }) 96 | } 97 | 98 | close () { 99 | if (!this.isComponentMounted) 100 | return 101 | this.props.onCloseStart && this.props.onCloseStart() 102 | this.animateDown() 103 | Keyboard.dismiss() 104 | } 105 | 106 | show () { 107 | if (!this.isComponentMounted) 108 | return 109 | this.setModalVisible(true) 110 | this.animateUp() 111 | } 112 | 113 | render () { 114 | const heightStyle = this.props.height ? { height: this.props.height } : {} 115 | const containerStyle = { opacity: this.state.opacity, flexGrow: 1 } 116 | return ( 117 | 118 | 124 | 125 | 126 | 130 | 131 | 132 | 133 | 134 | 135 | {this.props.children} 136 | 137 | 138 | 139 | 140 | ) 141 | } 142 | } 143 | 144 | Halfcard.propTypes = { 145 | height: React.PropTypes.number, 146 | slideDownTo: React.PropTypes.number, 147 | onShow: React.PropTypes.func, 148 | onClose: React.PropTypes.func, 149 | children: React.PropTypes.object, 150 | slideDuration: React.PropTypes.number, 151 | onCloseStart: React.PropTypes.func, 152 | } 153 | 154 | export default Halfcard 155 | --------------------------------------------------------------------------------