Skip to content

Instantly share code, notes, and snippets.

@mmazzarolo
Created September 13, 2016 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmazzarolo/d2d88305a4fb4a51a1e76e91bae3c31b to your computer and use it in GitHub Desktop.
Save mmazzarolo/d2d88305a4fb4a51a1e76e91bae3c31b to your computer and use it in GitHub Desktop.
IOS ActionSheet DatePicker
import React, { Component, PropTypes } from 'react'
import { DatePickerIOS, Text, TouchableOpacity, View } from 'react-native'
import { noop } from 'lodash'
import CustomModal from '../CustomModal'
import styles from './CustomDatePickerIOS.style'
export default class CustomDatePickerIOS extends Component {
static propTypes = {
visible: PropTypes.bool,
onConfirm: PropTypes.func,
onCancel: PropTypes.func,
title: PropTypes.string,
mode: PropTypes.oneOf(['date', 'time'])
}
static defaultProps = {
visible: false,
onConfirm: noop,
onCancel: noop,
title: 'Pick a date',
mode: 'date'
}
state = {
date: new Date()
}
_handleConfirm = () => this.props.onConfirm(this.state.date)
render () {
const { onCancel, visible, title, mode } = this.props
return (
<CustomModal visible={visible}>
<View style={styles.container}>
<View style={styles.datepickerContainer}>
<View style={styles.titleContainer}>
<Text style={styles.title}>{title}</Text>
</View>
<DatePickerIOS
date={this.state.date}
mode={mode}
onDateChange={(date) => this.setState({ date })}
/>
<TouchableOpacity style={styles.confirmButton} onPress={this._handleConfirm}>
<Text style={styles.confirmText}>Save</Text>
</TouchableOpacity>
</View>
<TouchableOpacity style={styles.cancelButton} onPress={onCancel}>
<Text style={styles.cancelText}>Cancel</Text>
</TouchableOpacity>
</View>
</CustomModal>
)
}
}
import { StyleSheet } from 'react-native'
const BORDER_RADIUS = 14
export default StyleSheet.create({
container: {
margin: 20
},
datepickerContainer: {
backgroundColor: 'white',
borderRadius: 14
},
titleContainer: {
borderBottomColor: 'rgba(0, 0, 0, 0.1)',
borderBottomWidth: 1,
padding: 12,
borderTopLeftRadius: BORDER_RADIUS,
borderTopRightRadius: BORDER_RADIUS
},
title: {
textAlign: 'center',
color: 'grey',
fontSize: 20
},
confirmButton: {
borderTopColor: 'rgba(0, 0, 0, 0.1)',
borderTopWidth: 1,
padding: 10,
borderBottomLeftRadius: BORDER_RADIUS,
borderBottomRightRadius: BORDER_RADIUS
},
confirmText: {
textAlign: 'center',
color: '#2E93FC',
fontSize: 24,
fontWeight: '500',
backgroundColor: 'transparent'
},
cancelButton: {
marginTop: 20,
backgroundColor: 'white',
padding: 10,
borderRadius: BORDER_RADIUS
},
cancelText: {
textAlign: 'center',
color: '#2E93FC',
fontSize: 24,
fontWeight: '700',
backgroundColor: 'transparent'
}
})
/* eslint-disable no-return-assign */
import React, { Component, PropTypes } from 'react'
import { Modal } from 'react-native'
import { View } from 'react-native-animatable'
import styles from './CustomModal.style.js'
export default class CustomModal extends Component {
static propTypes = {
visible: PropTypes.bool,
children: PropTypes.node
}
static defaultProps = {
visible: false
}
state = {
visible: false
}
componentWillReceiveProps (nextProps) {
if (!this.state.visible && nextProps.visible) {
this.setState({ visible: true })
}
}
componentDidUpdate (prevProps, prevState) {
// On modal open request slide the view up and fade in the backdrop
if (this.state.visible && !prevState.visible) {
this._open()
// On modal close request slide the view down and fade out the backdrop
} else if (!this.props.visible && prevProps.visible) {
this._close()
}
}
_open = () => {
this.backdropRef.transitionTo({ opacity: 0.70 })
this.contentRef.slideInUp(300)
}
_close = () => {
this.backdropRef.transitionTo({ opacity: 0 })
this.contentRef.slideOutDown(300)
.then(() => this.setState({ visible: false }))
}
render () {
const { children } = this.props
const { visible } = this.state
return (
<Modal
transparent={true}
animationType={'none'}
{...this.props}
visible={visible}
>
<View ref={(ref) => this.backdropRef = ref} style={styles.backdrop} />
<View ref={(ref) => this.contentRef = ref} style={styles.content}>
{children}
</View>
</Modal>
)
}
}
import { Dimensions, StyleSheet } from 'react-native'
const DEVICE_WIDTH = Dimensions.get('window').width
const DEVICE_HEIGHT = Dimensions.get('window').height
export default StyleSheet.create({
backdrop: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
height: DEVICE_HEIGHT,
width: DEVICE_WIDTH,
opacity: 0,
backgroundColor: 'black'
},
content: {
flex: 1,
justifyContent: 'flex-end'
}
})
@mmazzarolo
Copy link
Author

    <CustomDatePickerIOS
      title={'Pick a date'}
      visible={this.state.isDatePickerVisible}
      onConfirm={(date) => this.setState({ date, isDatePickerVisible: false })}
      onCancel={() => this.setState({ isDatePickerVisible: false })}
      mode={'date'}
    />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment