UNPKG

imrc-datetime-picker

Version:

(Improved) React component datetime picker by momentjs

203 lines (181 loc) 5.74 kB
import React, { Component } from "react"; const moment = require("moment-jalaali"); import classNames from "classnames/bind"; import { chunk, range, convertNumToPersian } from "../utils"; import classes from "../sass"; class Year extends Component { constructor(props) { super(props); const { isSolar } = props; this.state = { moment: props.moment, yearStr: isSolar ? "jYear" : "year" }; } componentWillReceiveProps(props) { const { isSolar } = props; this.setState({ moment: props.moment, yearStr: isSolar ? "jYear" : "year" }); } changePeriod = dir => { const _moment = this.state.moment.clone(); const { yearStr } = this.state; this.setState({ moment: _moment[dir === "prev" ? "subtract" : "add"](10, yearStr) }); }; select = (year, isDisabled) => { if (isDisabled) return; const _moment = this.state.moment.clone(); const { yearStr } = this.state; _moment[yearStr](year); this.setState({ moment: _moment, selected: _moment }); this.props.onSelect(_moment); }; _renderYear = year => { const now = moment(); const _moment = this.state.moment; const { yearStr } = this.state; const firstYear = Math.floor(_moment[yearStr]() / 10) * 10; const { maxDate, minDate, selected, range, rangeAt, dateLimit, lang } = this.props; const currentYear = _moment.clone()[yearStr](year); const start = selected && range ? selected.start ? currentYear.isSame(selected.start, yearStr) : false : false; const end = selected && range ? selected.end ? currentYear.isSame(selected.end, yearStr) : false : false; const between = selected && range ? selected.start && selected.end ? currentYear.isBetween(selected.start, selected.end, yearStr) : false : false; const isSelected = selected ? range ? selected[rangeAt] ? selected[rangeAt][yearStr]() === year : false : selected[yearStr]() === year : false; const disabledMax = maxDate ? year > maxDate[yearStr]() : false; const disabledMin = minDate ? year < minDate[yearStr]() : false; let disabled = false; let limited = false; if (range) { if (rangeAt === "start" && selected && selected.end) { disabled = selected.end && currentYear.isAfter(selected.end, "day"); } else if (rangeAt === "end" && selected && selected.start) { disabled = selected.start && currentYear.isBefore(selected.start, "day"); } } if (dateLimit && range) { const limitKey = Object.keys(dateLimit)[0]; const limitValue = dateLimit[limitKey]; let minLimitedDate, maxLimitedDate; if (selected) { if (rangeAt === "start" && selected.start && selected.end) { maxLimitedDate = selected.end.clone(); minLimitedDate = maxLimitedDate .clone() .subtract(limitValue, limitKey); } else if (rangeAt === "end" && selected.start && selected.end) { minLimitedDate = selected.start.clone(); maxLimitedDate = minLimitedDate.clone().add(limitValue, limitKey); } if (minLimitedDate && maxLimitedDate) { limited = !currentYear.isBetween( minLimitedDate, maxLimitedDate, "day", rangeAt === "start" ? "(]" : "[)" ); } } } const isDisabled = disabledMax || disabledMin || disabled || limited; const className = classNames({ [classes["selected"]]: isSelected, [classes["now"]]: now[yearStr]() === year, [classes["prev"]]: firstYear - 1 === year, [classes["next"]]: firstYear + 10 === year, [classes["disabled"]]: isDisabled, [classes["start"]]: start, [classes["end"]]: end, [classes["between"]]: between }); return ( <td key={year} className={className} onClick={this.select.bind(this, year, isDisabled)} > {lang == "fa" ? convertNumToPersian(year) : year} </td> ); }; render() { const _moment = this.state.moment; const { yearStr } = this.state; const { style, lang } = this.props; const firstYear = Math.floor(_moment[yearStr]() / 10) * 10; const years = range(firstYear - 1, firstYear + 11); return ( <div className={classes["calendar-years"]} style={style}> <div className={classes["calendar-nav"]}> <button type="button" className="prev-month" onClick={this.changePeriod.bind(this, "prev")} > <i className={`${classes["icon"]} ${classes["icon-angle-left"]}`} /> </button> <span className={`${classes["current-date"]} ${classes["disabled"]}`}> {lang == "fa" ? `${convertNumToPersian(firstYear)} - ${convertNumToPersian( firstYear + 9 )}` : `${firstYear} - ${firstYear + 9}`} </span> <button type="button" className="next-month" onClick={this.changePeriod.bind(this, "next")} > <i className={`${classes["icon"]} ${classes["icon-angle-right"]}`} /> </button> </div> <table> <tbody> {chunk(years, 4).map((_years, idx) => { return <tr key={idx}>{_years.map(this._renderYear)}</tr>; })} </tbody> </table> </div> ); } } export default Year;