UNPKG

react-event-calendar

Version:

React JS component that will display supplied event data within a calendar view of a given month.

288 lines (234 loc) 11.8 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _calendarBase = require('calendar-base'); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _CalendarDay = require('./components/CalendarDay'); var _CalendarDay2 = _interopRequireDefault(_CalendarDay); var _CalendarEvent = require('./components/CalendarEvent'); var _CalendarEvent2 = _interopRequireDefault(_CalendarEvent); var _CalendarTitle = require('./components/CalendarTitle'); var _CalendarTitle2 = _interopRequireDefault(_CalendarTitle); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var EventCalendar = function (_React$Component) { _inherits(EventCalendar, _React$Component); function EventCalendar(props) { _classCallCheck(this, EventCalendar); var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(EventCalendar).call(this, props)); _this._eventTargets = {}; _this.state = { today: _this.getToday() }; _this.calendar = new _calendarBase.Calendar({ siblingMonths: true }); // Bind methods _this.getCalendarDays = _this.getCalendarDays.bind(_this); _this.getDaysWithEvents = _this.getDaysWithEvents.bind(_this); _this.getEventMeta = _this.getEventMeta.bind(_this); _this.getToday = _this.getToday.bind(_this); return _this; } _createClass(EventCalendar, [{ key: 'getToday', value: function getToday() { var today = new Date(); return { day: today.getDate(), month: today.getMonth(), year: today.getFullYear() }; } }, { key: 'getCalendarDays', value: function getCalendarDays() { var _this2 = this; return this.calendar.getCalendar(this.props.year, this.props.month).map(function (day) { day.eventSlots = Array(_this2.props.maxEventSlots).fill(false); return day; }); } }, { key: 'getEventMeta', value: function getEventMeta(days, eventStart, eventEnd) { var eventStartInView = this.calendar.isDateSelected(eventStart); var eventEndInView = this.calendar.isDateSelected(eventEnd); var firstDayOfMonth = days[0]; var lastDayOfMonth = days[days.length - 1]; var eventMeta = { // Asserts Event is visible in this month view isVisibleInView: false, visibleEventLength: days.length, // Returns the index (interval from first visible day) of [...days] of event's first "visible" day firstVisibleDayIndex: eventStartInView ? _calendarBase.Calendar.interval(firstDayOfMonth, eventStart) - 1 : 0 }; // Asserts Event is visible in this month view if (eventStartInView || eventEndInView) { // Asserts event's first or last day is visible in this month view eventMeta.isVisibleInView = true; } else if (eventStart.month < this.props.month && eventEnd.month > this.props.month) { // Asserts at least part of month is eventMeta.isVisibleInView = true; } // Determine the visible length of the event during the month if (eventStartInView && eventEndInView) { eventMeta.visibleEventLength = _calendarBase.Calendar.interval(eventStart, eventEnd); } else if (!eventStartInView && eventEndInView) { eventMeta.visibleEventLength = _calendarBase.Calendar.interval(firstDayOfMonth, eventEnd); } else if (eventStartInView && !eventEndInView) { eventMeta.visibleEventLength = _calendarBase.Calendar.interval(eventStart, lastDayOfMonth); } return eventMeta; } }, { key: 'getDaysWithEvents', value: function getDaysWithEvents() { var _this3 = this; // Get all the days in this months calendar view // Sibling Months included var days = this.getCalendarDays(); // Set Range Limits on calendar this.calendar.setStartDate(days[0]); this.calendar.setEndDate(days[days.length - 1]); // Iterate over each of the supplied events this.props.events.forEach(function (eventItem) { var eventStart = _this3.getCalendarDayObject(eventItem.start); var eventEnd = _this3.getCalendarDayObject(eventItem.end); var eventMeta = _this3.getEventMeta(days, eventStart, eventEnd); if (eventMeta.isVisibleInView) { var eventLength = eventMeta.visibleEventLength; var eventSlotIndex = days[eventMeta.firstVisibleDayIndex].eventSlots.indexOf(false); var dayIndex = 0; // For each day in the event while (dayIndex < eventLength) { // Clone the event object so we acn add day specfic data var eventData = Object.assign({}, eventItem); if (dayIndex === 0) { // Flag first day of event eventData.isFirstDay = true; } if (dayIndex === eventLength - 1) { // Flag last day of event eventData.isLastDay = true; } if (!eventData.isFirstDay || !eventData.isLastDay) { // Flag between day of event eventData.isBetweenDay = true; } // Apply Event Data to the correct slot for that day days[eventMeta.firstVisibleDayIndex + dayIndex].eventSlots[eventSlotIndex] = eventData; // Move to next day of event dayIndex++; } } }); return days; } }, { key: 'getCalendarDayObject', value: function getCalendarDayObject(date) { var dateArray = date.split('-'); return { year: dateArray[0], // Subtract 1 from month to allow for human declared months month: dateArray[1] - 1, day: dateArray[2] }; } }, { key: 'getLastIndexOfEvent', value: function getLastIndexOfEvent(slots) { var lastIndexOfEvent = slots.map(function (slot, index) { return slot !== false ? index : false; }).filter(function (element) { return element; }).pop(); return lastIndexOfEvent < 3 || lastIndexOfEvent === undefined ? 2 : lastIndexOfEvent; } }, { key: 'getSerializedDay', value: function getSerializedDay(day) { return [day.weekDay, day.day, day.month, day.year].join(''); } }, { key: 'renderDaysOfTheWeek', value: function renderDaysOfTheWeek() { return this.props.daysOfTheWeek.map(function (title, index) { return _react2.default.createElement(_CalendarTitle2.default, { key: 'title_' + index, title: title }); }); } }, { key: 'renderEvents', value: function renderEvents(day) { var _this4 = this; // Trim excess slots var eventSlots = day.eventSlots.slice(0, this.getLastIndexOfEvent(day.eventSlots) + 1); return eventSlots.map(function (eventData, index) { return _react2.default.createElement(_CalendarEvent2.default, { key: 'event_' + index + _this4.getSerializedDay(day), day: day, eventData: eventData, onClick: _this4.props.onEventClick, onMouseOut: _this4.props.onEventMouseOut, onMouseOver: _this4.props.onEventMouseOver, wrapTitle: _this4.props.wrapTitle }); }); } }, { key: 'renderCalendarDays', value: function renderCalendarDays() { var _this5 = this; return this.getDaysWithEvents().map(function (day, index) { var isToday = _calendarBase.Calendar.interval(day, _this5.state.today) === 1; var events = _this5.renderEvents(day); return _react2.default.createElement(_CalendarDay2.default, { key: 'day_' + _this5.getSerializedDay(day), day: day, events: events, isToday: isToday, onClick: _this5.props.onDayClick }); }); } }, { key: 'render', value: function render() { return _react2.default.createElement( 'div', { className: 'flexContainer' }, this.renderDaysOfTheWeek(), this.renderCalendarDays() ); } }]); return EventCalendar; }(_react2.default.Component); EventCalendar.propTypes = { daysOfTheWeek: _react2.default.PropTypes.array, events: _react2.default.PropTypes.array, maxEventSlots: _react2.default.PropTypes.number, month: _react2.default.PropTypes.number.isRequired, onEventClick: _react2.default.PropTypes.func, onEventMouseOut: _react2.default.PropTypes.func, onEventMouseOver: _react2.default.PropTypes.func, onDayClick: _react2.default.PropTypes.func, wrapTitle: _react2.default.PropTypes.bool, year: _react2.default.PropTypes.number.isRequired }; EventCalendar.defaultProps = { daysOfTheWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], events: [], wrapTitle: true, maxEventSlots: 10 }; exports.default = EventCalendar;