bee-datepicker
Version:
DatePicker ui component for react
233 lines (214 loc) • 6.44 kB
JSX
import React from 'react';
import PropTypes from 'prop-types';
import toFragment from 'rc-util/lib/Children/mapSelf';
import MonthPanel from '../month/MonthPanel';
import YearPanel from '../year/YearPanel';
import DecadePanel from '../decade/DecadePanel';
function goMonth(direction) {
const next = this.props.value.clone();
next.add(direction, 'months');
this.props.onValueChange(next);
}
function goYear(direction) {
const next = this.props.value.clone();
next.add(direction, 'years');
this.props.onValueChange(next);
}
function showIf(condition, el) {
return condition ? el : null;
}
export default class CalendarHeader extends React.Component {
static propTypes = {
prefixCls: PropTypes.string,
value: PropTypes.object,
onValueChange: PropTypes.func,
showTimePicker: PropTypes.bool,
onPanelChange: PropTypes.func,
locale: PropTypes.object,
enablePrev: PropTypes.any,
enableNext: PropTypes.any,
disabledMonth: PropTypes.func,
renderFooter: PropTypes.func,
onMonthSelect: PropTypes.func,
}
static defaultProps = {
enableNext: 1,
enablePrev: 1,
onPanelChange() { },
onValueChange() { },
}
constructor(props) {
super(props);
this.nextMonth = goMonth.bind(this, 1);
this.previousMonth = goMonth.bind(this, -1);
this.nextYear = goYear.bind(this, 1);
this.previousYear = goYear.bind(this, -1);
this.state = { yearPanelReferer: null };
}
onMonthSelect = (value) => {
this.props.onPanelChange(value, 'date');
if (this.props.onMonthSelect) {
this.props.onMonthSelect(value);
} else {
this.props.onValueChange(value);
}
}
onYearSelect = (value) => {
const referer = this.state.yearPanelReferer;
this.setState({ yearPanelReferer: null });
this.props.onPanelChange(value, referer);
this.props.onValueChange(value);
}
onDecadeSelect = (value) => {
this.props.onPanelChange(value, 'year');
this.props.onValueChange(value);
}
monthYearElement = (showTimePicker) => {
const props = this.props;
const prefixCls = props.prefixCls;
const locale = props.locale;
const value = props.value;
const localeData = value.localeData && value.localeData();
const monthBeforeYear = locale.monthBeforeYear;
const selectClassName = `${prefixCls}-${monthBeforeYear ? 'my-select' : 'ym-select'}`;
const timeClassName = showTimePicker ? ` ${prefixCls}-time-status` : '';
const year = (<a
className={`${prefixCls}-year-select${timeClassName}`}
role="button"
onClick={showTimePicker ? null : () => this.showYearPanel('date')}
title={showTimePicker ? null : locale.yearSelect}
>
{value.format(locale.yearFormat)}
</a>);
const month = (<a
className={`${prefixCls}-month-select${timeClassName}`}
role="button"
onClick={showTimePicker ? null : this.showMonthPanel}
title={showTimePicker ? null : locale.monthSelect}
>
{locale.monthFormat ? value.format(locale.monthFormat) : localeData.monthsShort(value)}
</a>);
let day;
if (showTimePicker) {
day = (<a
className={`${prefixCls}-day-select${timeClassName}`}
role="button"
>
{value.format(locale.dayFormat)}
</a>);
}
let my = [];
if (monthBeforeYear) {
my = [month, day, year];
} else {
my = [year, month, day];
}
return (<span className={selectClassName}>
{toFragment(my)}
</span>);
}
showMonthPanel = () => {
// null means that users' interaction doesn't change value
this.props.onPanelChange(null, 'month');
}
showYearPanel = (referer) => {
this.setState({ yearPanelReferer: referer });
this.props.onPanelChange(null, 'year');
}
showDecadePanel = () => {
this.props.onPanelChange(null, 'decade');
}
render() {
const { props } = this;
const {
prefixCls,
locale,
mode,
value,
showTimePicker,
enableNext,
enablePrev,
disabledMonth,
renderFooter,
onChange,
onClear,
showMonthInput
} = props;
let panel = null;
if (mode === 'month') {
panel = (
<MonthPanel
showDateInput={true}
locale={locale}
showMonthInput={showMonthInput}
defaultValue={value}
rootPrefixCls={prefixCls}
onSelect={this.onMonthSelect}
onYearPanelShow={() => this.showYearPanel('month')}
disabledDate={disabledMonth}
cellRender={props.monthCellRender}
contentRender={props.monthCellContentRender}
renderFooter={renderFooter}
onChange={onChange}
onClear={onClear}
value={value}
/>
);
}
if (mode === 'year') {
panel = (
<YearPanel
locale={locale}
defaultValue={value}
rootPrefixCls={prefixCls}
onSelect={this.onYearSelect}
onDecadePanelShow={this.showDecadePanel}
renderFooter={renderFooter}
/>
);
}
if (mode === 'decade') {
panel = (
<DecadePanel
locale={locale}
defaultValue={value}
rootPrefixCls={prefixCls}
onSelect={this.onDecadeSelect}
renderFooter={renderFooter}
/>
);
}
return (<div className={`${prefixCls}-header`}>
<div style={{ position: 'relative' }} className={`${prefixCls}-header-btns`}>
{showIf(enablePrev && !showTimePicker,
<a
className={`${prefixCls}-prev-year-btn`}
role="button"
onClick={this.previousYear}
title={locale.previousYear}
/>)}
{showIf(enablePrev && !showTimePicker,
<a
className={`${prefixCls}-prev-month-btn`}
role="button"
onClick={this.previousMonth}
title={locale.previousMonth}
/>)}
{this.monthYearElement(showTimePicker)}
{showIf(enableNext && !showTimePicker,
<a
className={`${prefixCls}-next-month-btn`}
onClick={this.nextMonth}
title={locale.nextMonth}
/>)}
{showIf(enableNext && !showTimePicker,
<a
className={`${prefixCls}-next-year-btn`}
onClick={this.nextYear}
title={locale.nextYear}
/>)}
</div>
{panel}
</div>);
}
}