UNPKG

lucid-ui

Version:

A UI component library from AppNexus.

114 lines (113 loc) 4.29 kB
import React from 'react'; import PropTypes from 'react-peek/prop-types'; import DayPicker from 'react-day-picker'; import { lucidClassNames } from '../../util/style-helpers'; const { DateUtils } = DayPicker; const cx = lucidClassNames.bind('&-CalendarMonth'); const { bool, instanceOf, number, oneOf, string } = PropTypes; class CalendarMonth extends React.Component { constructor() { super(...arguments); this.modifierRange = (day) => { const { cursor, from, to, selectMode } = this.props; if (cursor) { if (selectMode === 'day') { return DateUtils.isSameDay(day, new Date(cursor)); } else if (from || to) { return DateUtils.isDayInRange(day, { from: new Date(selectMode === 'to' ? from : to), to: new Date(cursor), }); } return DateUtils.isSameDay(day, new Date(cursor)); } if (from && to) { return DateUtils.isDayInRange(day, { from: new Date(from), to: new Date(to), }); } return false; }; this.modifierFrom = (day) => { const { from } = this.props; return DateUtils.isSameDay(day, new Date(from)); }; this.modifierTo = (day) => { const { to } = this.props; return DateUtils.isSameDay(day, new Date(to)); }; } shouldComponentUpdate() { return this.props.shouldComponentUpdate; } render() { const { className, monthOffset, initialMonth, ...passThroughs } = this.props; // It can be tricky to increment months using JavaScript dates, this should // handle the edge cases. // http://stackoverflow.com/questions/499838/javascript-date-next-month const monthDate = new Date(initialMonth.getFullYear(), initialMonth.getMonth() + monthOffset, 1); return ( /**typescript boundary with this component is tricky to get right with the way passthrough works * the component is being rewritten in typescript. Going to punt on this for now * https://github.com/gpbl/react-day-picker/issues/942 */ //@ts-ignore React.createElement(DayPicker, Object.assign({ key: monthOffset, className: cx('&', className), initialMonth: monthDate, canChangeMonth: false, weekdaysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] }, passThroughs, { modifiers: { range: this.modifierRange, from: this.modifierFrom, to: this.modifierTo, ...passThroughs.modifiers, } }))); } } CalendarMonth._isPrivate = true; CalendarMonth.displayName = 'CalendarMonth'; CalendarMonth.peek = { description: ` A single calendar month based on \`react-day-picker\`. `, categories: ['helpers'], }; CalendarMonth.propTypes = { className: string ` Appended to the component-specific class names set on the root element. `, monthOffset: number ` The offset of the rendered month, where 0 is the \`initialMonth\`. Negative values will show previous months. `, initialMonth: instanceOf(Date) ` Sets the month of the calendar. The 0 value for the \`monthOffset\` prop refers to this month. `, cursor: instanceOf(Date) ` Set the cursor to target date. Primarily used to preview expected ranges when the cursor is on a target date. `, from: instanceOf(Date) ` Sets the start date in a date range. `, to: instanceOf(Date) ` Sets the end date in a date range. `, selectMode: oneOf(['day', 'from', 'to']) ` The next selection that is expected. Primarily used to preview expected ranges when the cursor is on a target date. `, shouldComponentUpdate: bool ` Used to skip re-rendering of this component when true. Primarily used for CalendarMonths which are rendered out of view. `, }; CalendarMonth.defaultProps = { monthOffset: 0, initialMonth: new Date(), cursor: null, from: null, to: null, selectMode: 'day', shouldComponentUpdate: true, }; export default CalendarMonth;