UNPKG

zarm-web

Version:
239 lines (196 loc) 6.37 kB
import React, { Component } from 'react'; import classnames from 'classnames'; import Format from '../utils/format'; import isArray from '../utils/validate'; import LocaleReceiver from '../locale-provider/LocaleReceiver'; // 生成 [1, 2, 3, ...] 的序列 const getSequence = length => [...Array.from({ length }).keys()]; const CALENDAR_ROW_COUNT = getSequence(6); const CALENDAR_COL_COUNT = getSequence(7); const compareTime = (v1, v2) => new Date(v1) > new Date(v2); const isEqualTime = (v1, v2) => Format.date(v1, 'yyyy/M/d') === Format.date(v2, 'yyyy/M/d'); class CalendarDateTable extends Component { constructor(props) { super(props); this.getFirstDayOfWeek = current => { const date = new Date(`${current.year}/${current.month}/1`); let week = date.getDay(); if (week === 0) { week = 7; } return week; }; this.getNextMonth = current => { const result = {}; if (current.month === 12) { result.year = current.year + 1; result.month = 1; } else { result.year = current.year; result.month = current.month + 1; } return result; }; this.getPreMonth = current => { const result = {}; if (current.month === 1) { result.year = current.year - 1; result.month = 12; } else { result.year = current.year; result.month = current.month - 1; } return result; }; this.getDays = current => { return new Date(current.year, current.month, 0).getDate(); }; this.state = { current: props.current || new Date() }; } componentWillReceiveProps(nextProps) { if ('current' in nextProps) { this.setState({ current: nextProps.current }); } } // 渲染星期 // eslint-disable-next-line renderWeek() { const weekDays = []; const { prefixCls, locale } = this.props; const CALENDAR_WEEK_DAYS = locale.week_days; for (let i = 0; i < CALENDAR_COL_COUNT.length; i++) { weekDays[i] = CALENDAR_WEEK_DAYS[i]; } return React.createElement("thead", null, React.createElement("tr", null, weekDays.map((week, index) => React.createElement("th", { key: `weekdays-${index}`, className: `${prefixCls}-column`, title: locale.week_days_hints[index] }, week)))); } // 渲染日期 renderDate() { const { current: stateCurrent } = this.state; const dd = new Date(stateCurrent); const current = { year: dd.getFullYear(), month: dd.getMonth() + 1 }; const pre = this.getPreMonth(current); const next = this.getNextMonth(current); current.days = this.getDays(current); current.firstDayOfWeek = this.getFirstDayOfWeek(current); pre.days = this.getDays(pre); const dates = []; // 当月第一天不在周一时,前面日期用上个月的日期补齐 for (let i = pre.days; i > pre.days - current.firstDayOfWeek + 1; i--) { dates.unshift(this.renderDateCell({ year: pre.year, month: pre.month, date: i }, 'others')); } // 当月日期 for (let j = 1; j <= current.days; j++) { dates.push(this.renderDateCell({ year: current.year, month: current.month, date: j })); } // 当月最后一天不在周日时,后面日期用下个月的日期补齐 for (let k = 1; k <= CALENDAR_ROW_COUNT.length * CALENDAR_COL_COUNT.length - current.days - current.firstDayOfWeek + 1; k++) { dates.push(this.renderDateCell({ year: next.year, month: next.month, date: k }, 'others')); } const { prefixCls } = this.props; return React.createElement("tbody", null, CALENDAR_ROW_COUNT.map(m => React.createElement("tr", { key: `row-${m}`, role: "row" }, CALENDAR_COL_COUNT.map(n => { const index = m * CALENDAR_COL_COUNT.length + n; return React.createElement("td", { key: `column-${n}`, className: `${prefixCls}-cell`, role: "gridcell" }, dates[index]); })))); } // 渲染日期单元 renderDateCell(day, type) { const { value, onDateClick, min, max, prefixCls, selectedValue } = this.props; const fullDay = `${day.year}/${day.month}/${day.date}`; const displayDay = `${day.year}-${day.month}-${day.date}`; if (min || max) { const _min = Format.date(min, 'yyyy/M/d'); const _max = Format.date(max, 'yyyy/M/d'); const isSmall = new Date(fullDay) < new Date(_min); const isLarge = new Date(fullDay) > new Date(_max); if (isSmall || isLarge) { return React.createElement("span", { className: `${prefixCls}-text-disabled ${prefixCls}-text`, title: displayDay }, day.date); } } let isSelected = false; let isRange = false; if (selectedValue && isArray(selectedValue) && type !== 'others') { if (selectedValue.length === 2) { isRange = compareTime(fullDay, selectedValue[0]) && compareTime(selectedValue[1], fullDay); } isSelected = isEqualTime(selectedValue[0], fullDay) || isEqualTime(selectedValue[1], fullDay); } else { isSelected = isEqualTime(value, fullDay); } const cls = classnames(`${prefixCls}-text`, { [`${prefixCls}-text-others`]: type === 'others', [`${prefixCls}-text-selected`]: isSelected, [`${prefixCls}-text-range`]: isRange, [`${prefixCls}-text-today`]: new Date().toLocaleDateString() === new Date(fullDay).toLocaleDateString() }); return React.createElement("span", { className: cls, title: displayDay, onClick: () => onDateClick(fullDay) }, day.date); } // 获取第一天的星期 render() { const { visible, prefixCls } = this.props; const style = { display: visible ? 'none' : 'block' }; return React.createElement("div", { style: style }, React.createElement("table", { className: `${prefixCls}-table` }, this.renderWeek(), this.renderDate())); } } CalendarDateTable.defaultProps = { prefixCls: 'ui-calendar', defaultValue: '', value: '', min: '', max: '', onDateClick: () => {} }; export default LocaleReceiver('Calendar')(CalendarDateTable);