Created
February 24, 2019 19:41
-
-
Save varunon9/8b2a97394da92fd66f914c43c7945afe to your computer and use it in GitHub Desktop.
react-native-toggle-calendar- customized calendar built on top of react-native-calendars to support horizontal and grid calendar view
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; | |
import PropTypes from 'prop-types'; | |
const weekDaysNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; | |
class CalendarDayComponent extends React.Component { | |
constructor(props) { | |
super(props); | |
this.onDayPress = this.onDayPress.bind(this); | |
} | |
getContentStyle() { | |
const { state, marking = {}, date, current } = this.props; | |
const style= { | |
content: {}, | |
text: { | |
color: '#181c26' | |
} | |
}; | |
if (marking.soldOut) { | |
style.text.color = '#fff'; | |
style.content.backgroundColor = '#e35052'; | |
style.content.borderRadius = 50; | |
} else if (marking.blocked) { | |
style.text.color = '#fff'; | |
style.content.backgroundColor = '#c1c2c1'; | |
style.content.borderRadius = 50; | |
} else if (state === 'disabled') { | |
style.text.color = '#c1c2c1'; | |
} else if (state === 'today') { | |
style.text.color = '#fff'; | |
style.content.backgroundColor = '#216bc9'; | |
style.content.borderRadius = 50; | |
} else if (current === date.dateString) { | |
style.content.borderRadius = 50; | |
style.content.borderWidth = 1; | |
style.content.borderColor = '#216bc9'; | |
} | |
return style; | |
} | |
getFooterTextStyle() { | |
const { marking = {} } = this.props; | |
const style = { | |
color: '#c1c2c1' | |
}; | |
if (marking.inventory > 0) { | |
style.color = '#4caf50'; | |
} | |
return style; | |
} | |
getInventoryCount() { | |
const { marking = {} } = this.props; | |
if (typeof marking === 'object') { | |
if (marking.inventory >= 0) { | |
return marking.inventory; | |
} | |
} | |
return 'NA'; | |
} | |
onDayPress() { | |
this.props.onPress(this.props.date); | |
} | |
render() { | |
const contentStyle = this.getContentStyle(); | |
return ( | |
<View style={styles.container}> | |
<View style={styles.header}> | |
{ | |
this.props.horizontal ? | |
<Text style={styles.weekName} numberOfLines={1}> | |
{ | |
weekDaysNames[this.props.date.weekDay] | |
} | |
</Text> | |
: | |
null | |
} | |
</View> | |
<TouchableOpacity | |
style={[styles.content, contentStyle.content]} | |
onPress={this.onDayPress} | |
> | |
<Text style={[styles.contentText, contentStyle.text]}> | |
{String(this.props.children)} | |
</Text> | |
</TouchableOpacity> | |
<View> | |
<Text style={this.getFooterTextStyle()}> | |
{this.getInventoryCount()} | |
</Text> | |
</View> | |
</View> | |
); | |
} | |
} | |
CalendarDayComponent.propTypes = { | |
children: PropTypes.any, | |
state: PropTypes.string, | |
marking: PropTypes.any, | |
horizontal: PropTypes.bool, | |
date: PropTypes.object, | |
onPress: PropTypes.func.isRequired, | |
current: PropTypes.string | |
}; | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1, | |
justifyContent: 'center', | |
alignItems: 'center', | |
marginLeft: 7, | |
marginRight: 7 | |
}, | |
weekName: { | |
width: 32, | |
textAlign: 'center', | |
fontSize: 12, | |
textTransform: 'uppercase', | |
fontWeight: 'bold', | |
color: '#7c7c7c' | |
}, | |
content: { | |
width: 36, | |
height: 36, | |
justifyContent: 'center', | |
alignItems: 'center' | |
}, | |
contentText: { | |
fontSize: 18 | |
} | |
}); | |
export default CalendarDayComponent; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { | |
View, Text, StyleSheet, Image, TouchableOpacity | |
} from 'react-native'; | |
import PropTypes from 'prop-types'; | |
const weekDaysNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; | |
class CalendarHeaderComponent extends React.Component { | |
constructor(props) { | |
super(props); | |
} | |
render() { | |
return ( | |
<View style={styles.container}> | |
<View style={styles.header}> | |
<Text style={styles.dateText}> | |
{this.props.headerData.calendarDate} | |
</Text> | |
<TouchableOpacity | |
style={styles.iconContainer} | |
onPress={this.props.onPressArrowLeft} | |
> | |
<Image | |
style={[styles.icon, styles.leftIcon]} | |
source={require('../../images/arrow.png')} | |
/> | |
</TouchableOpacity> | |
<TouchableOpacity | |
style={styles.iconContainer} | |
onPress={this.props.onPressArrowRight} | |
> | |
<Image | |
style={styles.icon} | |
source={require('../../images/arrow.png')} | |
/> | |
</TouchableOpacity> | |
<TouchableOpacity | |
style={[ | |
styles.iconContainer, { | |
opacity: this.props.horizontal ? 0.2 : 1 | |
} | |
]} | |
onPress={this.props.onPressListView} | |
disabled={this.props.horizontal} | |
> | |
<Image | |
style={styles.icon} | |
source={require('../../images/list.png')} | |
/> | |
</TouchableOpacity> | |
<TouchableOpacity | |
style={[ | |
styles.iconContainer, { | |
opacity: this.props.horizontal ? 1 : 0.2 | |
} | |
]} | |
onPress={this.props.onPressGridView} | |
disabled={!this.props.horizontal} | |
> | |
<Image | |
style={styles.icon} | |
source={require('../../images/grid.png')} | |
/> | |
</TouchableOpacity> | |
</View> | |
{ | |
// not showing week day in case of horizontal calendar, this will be handled by day component | |
this.props.horizontal ? | |
null | |
: | |
<View style={styles.week}> | |
{weekDaysNames.map((day, index) => ( | |
<Text key={index} style={styles.weekName} numberOfLines={1}> | |
{day} | |
</Text> | |
))} | |
</View> | |
} | |
</View> | |
); | |
} | |
} | |
CalendarHeaderComponent.propTypes = { | |
headerData: PropTypes.object.isRequired, | |
horizontal: PropTypes.bool, | |
onPressArrowRight: PropTypes.func.isRequired, | |
onPressArrowLeft: PropTypes.func.isRequired, | |
onPressListView: PropTypes.func.isRequired, | |
onPressGridView: PropTypes.func.isRequired | |
}; | |
const styles = StyleSheet.create({ | |
container: { | |
flex: 1 | |
}, | |
header: { | |
flexDirection: 'row', | |
padding: 12, | |
backgroundColor: '#eceef1' | |
}, | |
week: { | |
marginTop: 7, | |
flexDirection: 'row', | |
justifyContent: 'space-around' | |
}, | |
weekName: { | |
marginTop: 2, | |
marginBottom: 7, | |
width: 32, | |
textAlign: 'center', | |
fontSize: 12, | |
textTransform: 'uppercase', | |
fontWeight: 'bold', | |
color: '#7c7c7c' | |
}, | |
dateText: { | |
flex: 6, | |
fontSize: 18 | |
}, | |
iconContainer: { | |
flex: 1, | |
justifyContent: 'center', | |
alignItems: 'center' | |
}, | |
leftIcon: { | |
transform: [{ rotate: '180deg' }] | |
}, | |
icon: { | |
width: 24, | |
height: 24 | |
} | |
}); | |
export default CalendarHeaderComponent; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import { View } from 'react-native'; | |
import { Calendar } from 'react-native-calendars'; | |
import moment from 'moment'; | |
import CalendarDayComponent from './CalendarDayComponent'; | |
import CalendarHeaderComponent from './CalendarHeaderComponent'; | |
let calendarDate = moment(); | |
class ViewInventoryMain extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
calendarDate: calendarDate.format('YYYY-MM-DD'), | |
horizontal: false | |
}; | |
this.onPressArrowLeft = this.onPressArrowLeft.bind(this); | |
this.onPressArrowRight = this.onPressArrowRight.bind(this); | |
this.onPressListView = this.onPressListView.bind(this); | |
this.onPressGridView = this.onPressGridView.bind(this); | |
this.onDayPress = this.onDayPress.bind(this); | |
} | |
onPressArrowLeft() { | |
calendarDate = calendarDate.add(-1, 'month'); | |
this.updateCalendarDate(); | |
} | |
onPressArrowRight() { | |
calendarDate = calendarDate.add(1, 'month'); | |
this.updateCalendarDate(); | |
} | |
onPressListView() { | |
this.setState({ horizontal: true }); | |
} | |
onPressGridView() { | |
this.setState({ horizontal: false }); | |
} | |
onDayPress(date) { | |
calendarDate = moment(date.dateString); | |
this.updateCalendarDate(); | |
} | |
updateCalendarDate() { | |
this.setState({ | |
calendarDate: calendarDate.format('YYYY-MM-DD') | |
}); | |
} | |
render() { | |
return ( | |
<View style={{ flex: 1 }}> | |
<Calendar | |
current={this.state.calendarDate} | |
dayComponent={CalendarDayComponent} | |
calendarHeaderComponent={CalendarHeaderComponent} | |
headerData={{ | |
calendarDate: calendarDate.format('DD MMM, YYYY') | |
}} | |
style={{ | |
paddingLeft: 0, paddingRight: 0 | |
}} | |
onPressArrowLeft={this.onPressArrowLeft} | |
onPressArrowRight={this.onPressArrowRight} | |
onPressListView={this.onPressListView} | |
onPressGridView={this.onPressGridView} | |
markedDates={{ | |
'2019-02-23': {soldOut: false, blocked: false, inventory: 2}, | |
'2019-02-24': {soldOut: false, blocked: false, inventory: 2}, | |
'2019-02-25': {soldOut: false, blocked: true, inventory: 0}, | |
'2019-02-26': {soldOut: true, blocked: true, inventory: 2} | |
}} | |
horizontal={this.state.horizontal} | |
onDayPress={this.onDayPress} | |
/> | |
</View> | |
); | |
} | |
} | |
export default ViewInventoryMain; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment