diff --git a/README.md b/README.md index df4dd67..73cd16f 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ format24h | PropTypes.boolean | Use format 24hour or 12hour formatHeader | PropTypes.string | Header date format upperCaseHeader | PropTypes.boolean | Sets date header as uppercase (default false) headerStyle | PropTypes.object | Header style +hiddenHeader| PropTypes.boolean | Hidden Header (default false) renderEvent | PropTypes.function | Function return a component to render event `renderEvent={(event) => {event.title}}` eventTapped | PropTypes.function | Function on event press dateChanged | PropTypes.function | Function on date change. Passes new date as a string formatted as 'YYYY-MM-DD' diff --git a/src/DayView.js b/src/DayView.js index 663bd3d..4b554ac 100644 --- a/src/DayView.js +++ b/src/DayView.js @@ -1,9 +1,9 @@ // @flow -import { View, Text, ScrollView, TouchableOpacity } from 'react-native'; -import populateEvents from './Packer'; -import React from 'react'; -import moment from 'moment'; -import _ from 'lodash'; +import { View, Text, ScrollView, TouchableOpacity } from "react-native"; +import populateEvents from "./Packer"; +import React from "react"; +import moment from "moment"; +import _ from "lodash"; const LEFT_MARGIN = 60 - 1; // const RIGHT_MARGIN = 10 @@ -24,7 +24,7 @@ export default class DayView extends React.PureComponent { const width = props.width - LEFT_MARGIN; const packedEvents = populateEvents(props.events, width, props.start); let initPosition = - _.min(_.map(packedEvents, 'top')) - + _.min(_.map(packedEvents, "top")) - this.calendarHeight / (props.end - props.start); initPosition = initPosition < 0 ? 0 : initPosition; this.state = { @@ -33,7 +33,7 @@ export default class DayView extends React.PureComponent { }; } - componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps) { const width = nextProps.width - LEFT_MARGIN; this.setState({ packedEvents: populateEvents(nextProps.events, width, nextProps.start), @@ -86,14 +86,18 @@ export default class DayView extends React.PureComponent { let timeText; if (i === start) { timeText = ``; - } else if (i < 12) { - timeText = !format24h ? `${i} AM` : i; + } else if (i < 10) { + timeText = !format24h ? `0${i}:00 AM` : `0${i}:00`; + } else if (i == 10 || i == 11) { + timeText = !format24h ? `${i}:00 AM` : `${i}:00`; } else if (i === 12) { - timeText = !format24h ? `${i} PM` : i; + timeText = !format24h ? `${i}:00 PM` : `${i}:00`; } else if (i === 24) { - timeText = !format24h ? `12 AM` : 0; + timeText = !format24h ? `12:00 AM` : `00:00`; + } else if (i < 22) { + timeText = !format24h ? `0${i - 12}:00 PM` : `${i}:00`; } else { - timeText = !format24h ? `${i - 12} PM` : i; + timeText = !format24h ? `${i - 12}:00 PM` : `${i}:00`; } const { width, styles } = this.props; return [ @@ -152,37 +156,36 @@ export default class DayView extends React.PureComponent { // Fixing the number of lines for the event title makes this calculation easier. // However it would make sense to overflow the title to a new line if needed const numberOfLines = Math.floor(event.height / TEXT_LINE_HEIGHT); - const formatTime = this.props.format24h ? 'HH:mm' : 'hh:mm A'; + const formatTime = this.props.format24h ? "HH:mm" : "hh:mm A"; return ( - this._onEventTapped(this.props.events[event.index]) - } - key={i} style={[styles.event, style, event.color && eventColor]} + onPress={() => this._onEventTapped(this.props.events[event.index])} + key={i} + style={[styles.event, style, event.color && eventColor]} > {this.props.renderEvent ? ( this.props.renderEvent(event) ) : ( - {event.title || 'Event'} + {event.title || "Event"} {numberOfLines > 1 ? ( - {event.summary || ' '} + {event.summary || " "} ) : null} {numberOfLines > 2 ? ( - {moment(event.start).format(formatTime)} -{' '} + {moment(event.start).format(formatTime)} -{" "} {moment(event.end).format(formatTime)} ) : null} - + )} ); @@ -199,7 +202,7 @@ export default class DayView extends React.PureComponent { const { styles } = this.props; return ( (this._scrollView = ref)} + ref={(ref) => (this._scrollView = ref)} contentContainerStyle={[ styles.contentStyle, { width: this.props.width }, diff --git a/src/EventCalendar.js b/src/EventCalendar.js index 778fb41..b39de0d 100644 --- a/src/EventCalendar.js +++ b/src/EventCalendar.js @@ -5,14 +5,14 @@ import { TouchableOpacity, Image, Text, -} from 'react-native'; -import _ from 'lodash'; -import moment from 'moment'; -import React from 'react'; +} from "react-native"; +import _ from "lodash"; +import moment from "moment"; +import React from "react"; -import styleConstructor from './style'; +import styleConstructor from "./style"; -import DayView from './DayView'; +import DayView from "./DayView"; export default class EventCalendar extends React.Component { constructor(props) { @@ -43,7 +43,7 @@ export default class EventCalendar extends React.Component { static defaultProps = { size: 30, initDate: new Date(), - formatHeader: 'DD MMMM YYYY', + formatHeader: "DD MMMM YYYY", }; _getItemLayout(data, index) { @@ -54,13 +54,13 @@ export default class EventCalendar extends React.Component { _getItem(events, index) { const date = moment(this.props.initDate).add( index - this.props.size, - 'days' + "days" ); - return _.filter(events, event => { + return _.filter(events, (event) => { const eventStartTime = moment(event.start); return ( - eventStartTime >= date.clone().startOf('day') && - eventStartTime <= date.clone().endOf('day') + eventStartTime >= date.clone().startOf("day") && + eventStartTime <= date.clone().endOf("day") ); }); } @@ -75,43 +75,46 @@ export default class EventCalendar extends React.Component { end = 24, formatHeader, upperCaseHeader = false, + hiddenHeader = false, } = this.props; - const date = moment(initDate).add(index - this.props.size, 'days'); + const date = moment(initDate).add(index - this.props.size, "days"); const leftIcon = this.props.headerIconLeft ? ( - this.props.headerIconLeft + this.props.headerIconLeft ) : ( - + ); const rightIcon = this.props.headerIconRight ? ( - this.props.headerIconRight + this.props.headerIconRight ) : ( - + ); let headerText = upperCaseHeader - ? date.format(formatHeader || 'DD MMMM YYYY').toUpperCase() - : date.format(formatHeader || 'DD MMMM YYYY'); + ? date.format(formatHeader || "DD MMMM YYYY").toUpperCase() + : date.format(formatHeader || "DD MMMM YYYY"); return ( - - + - {leftIcon} - - - {headerText} - - + {leftIcon} + + + {headerText} + + - {rightIcon} - - + > + {rightIcon} + + + )} @@ -198,14 +196,14 @@ export default class EventCalendar extends React.Component { pagingEnabled renderItem={this._renderItem.bind(this)} style={{ width: width }} - onMomentumScrollEnd={event => { + onMomentumScrollEnd={(event) => { const index = parseInt(event.nativeEvent.contentOffset.x / width); const date = moment(this.props.initDate).add( index - this.props.size, - 'days' + "days" ); if (this.props.dateChanged) { - this.props.dateChanged(date.format('YYYY-MM-DD')); + this.props.dateChanged(date.format("YYYY-MM-DD")); } this.setState({ index, date }); }} diff --git a/src/style.js b/src/style.js index 484fc1f..714481f 100644 --- a/src/style.js +++ b/src/style.js @@ -1,5 +1,5 @@ // @flow -import { Platform, StyleSheet } from 'react-native'; +import { Platform, StyleSheet } from "react-native"; // const eventPaddingLeft = 4 const leftMargin = 50 - 1; @@ -8,11 +8,11 @@ export default function styleConstructor(theme = {}, calendarHeight) { let style = { container: { flex: 1, - backgroundColor: '#ffff', + backgroundColor: "#ffff", ...theme.container, }, contentStyle: { - backgroundColor: '#ffff', + backgroundColor: "#ffff", height: calendarHeight + 10, ...theme.contentStyle, }, @@ -21,15 +21,15 @@ export default function styleConstructor(theme = {}, calendarHeight) { height: 50, borderTopWidth: 1, borderBottomWidth: 1, - borderColor: '#E6E8F0', - backgroundColor: '#F5F5F6', - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'stretch', + borderColor: "#E6E8F0", + backgroundColor: "#F5F5F6", + flexDirection: "row", + justifyContent: "space-between", + alignItems: "stretch", ...theme.header, }, headerTextContainer: { - justifyContent: 'center', + justifyContent: "center", }, headerText: { fontSize: 16, @@ -38,19 +38,19 @@ export default function styleConstructor(theme = {}, calendarHeight) { arrow: { width: 15, height: 15, - resizeMode: 'contain', + resizeMode: "contain", }, arrowButton: { width: 50, - alignItems: 'center', - justifyContent: 'center', + alignItems: "center", + justifyContent: "center", ...theme.arrowButton, }, event: { - position: 'absolute', - backgroundColor: '#F0F4FF', + position: "absolute", + backgroundColor: "#F0F4FF", opacity: 0.8, - borderColor: '#DDE5FD', + borderColor: "#DDE5FD", borderWidth: 1, borderRadius: 5, paddingLeft: 4, @@ -58,52 +58,52 @@ export default function styleConstructor(theme = {}, calendarHeight) { flex: 1, paddingTop: 5, paddingBottom: 0, - flexDirection: 'column', - alignItems: 'flex-start', - overflow: 'hidden', + flexDirection: "column", + alignItems: "flex-start", + overflow: "hidden", ...theme.event, }, eventTitle: { - color: '#615B73', - fontWeight: '600', + color: "#615B73", + fontWeight: "600", minHeight: 15, ...theme.eventTitle, }, eventSummary: { - color: '#615B73', + color: "#615B73", fontSize: 12, - flexWrap: 'wrap', + flexWrap: "wrap", ...theme.eventSummary, }, eventTimes: { marginTop: 3, fontSize: 10, - fontWeight: 'bold', - color: '#615B73', - flexWrap: 'wrap', + fontWeight: "bold", + color: "#615B73", + flexWrap: "wrap", ...theme.eventTimes, }, line: { height: 1, - position: 'absolute', + position: "absolute", left: leftMargin, - backgroundColor: 'rgb(216,216,216)', + backgroundColor: "rgb(216,216,216)", ...theme.line, }, lineNow: { height: 1, - position: 'absolute', + position: "absolute", left: leftMargin, - backgroundColor: 'red', + backgroundColor: "red", ...theme.lineNow, }, timeLabel: { - position: 'absolute', - left: 15, - color: 'rgb(170,170,170)', + position: "absolute", + left: 10, + color: "rgb(170,170,170)", fontSize: 10, - fontFamily: Platform.OS === 'ios' ? 'Helvetica Neue' : 'Roboto', - fontWeight: '500', + fontFamily: Platform.OS === "ios" ? "Helvetica Neue" : "Roboto", + fontWeight: "500", ...theme.timeLabel, }, };