提交 fd1d54cf 编写于 作者: A afc163

Merge pull request #1298 from ant-design/refactor-datepicker-hoc

refactor: remove mixin
import React from 'react';
import defaultLocale from './locale/zh_CN';
import DateTimeFormat from 'gregorian-calendar-format';
import GregorianCalendar from 'gregorian-calendar';
export default {
contextTypes: {
antLocale: React.PropTypes.object,
},
getLocale() {
let locale = defaultLocale;
if (this.context.antLocale && this.context.antLocale.DatePicker) {
locale = this.context.antLocale.DatePicker;
}
// 统一合并为完整的 Locale
const result = { ...locale, ...this.props.locale };
result.lang = { ...locale.lang, ...this.props.locale.lang };
return result;
},
getFormatter() {
if (!this.formats) {
this.formats = {};
}
const formats = this.formats;
const format = this.props.format;
if (formats[format]) {
return formats[format];
}
formats[format] = new DateTimeFormat(format, this.getLocale().lang.format);
return formats[format];
},
parseDateFromValue(value) {
if (value) {
if (typeof value === 'string') {
return this.getFormatter().parse(value, { locale: this.getLocale() });
} else if (value instanceof Date) {
let date = new GregorianCalendar(this.getLocale());
date.setTime(+value);
return date;
}
}
return value;
},
// remove input readonly warning
handleInputChange() {
},
toggleOpen(e) {
this.setState({
open: e.open
});
},
};
......@@ -2,83 +2,61 @@ import React from 'react';
import GregorianCalendar from 'gregorian-calendar';
import RangeCalendar from 'rc-calendar/lib/RangeCalendar';
import DatePicker from 'rc-calendar/lib/Picker';
import TimePicker from 'rc-time-picker';
import classNames from 'classnames';
import PickerMixin from './PickerMixin';
export default React.createClass({
getDefaultProps() {
return {
defaultValue: [],
format: 'yyyy-MM-dd',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
transitionName: 'slide-up',
popupStyle: {},
onChange() {
},
onOk() {
},
locale: {},
align: {
offset: [0, -9],
},
open: false
};
},
getInitialState() {
const { value, defaultValue } = this.props;
const { value, defaultValue, parseDateFromValue } = this.props;
const start = (value && value[0]) || defaultValue[0];
const end = (value && value[1]) || defaultValue[1];
return {
value: [
this.parseDateFromValue(start),
this.parseDateFromValue(end)
parseDateFromValue(start),
parseDateFromValue(end)
]
};
},
mixins: [PickerMixin],
componentWillReceiveProps(nextProps) {
if ('value' in nextProps) {
const value = nextProps.value || [];
const start = this.parseDateFromValue(value[0]);
const end = this.parseDateFromValue(value[1]);
const start = nextProps.parseDateFromValue(value[0]);
const end = nextProps.parseDateFromValue(value[1]);
this.setState({
value: [start, end]
});
}
},
handleChange(value) {
if (!('value' in this.props)) {
const props = this.props;
if (!('value' in props)) {
this.setState({ value });
}
const startDate = value[0] ? new Date(value[0].getTime()) : null;
const endDate = value[1] ? new Date(value[1].getTime()) : null;
const startDateString = value[0] ? this.getFormatter().format(value[0]) : '';
const endDateString = value[1] ? this.getFormatter().format(value[1]) : '';
this.props.onChange([startDate, endDate], [startDateString, endDateString]);
const startDateString = value[0] ? props.getFormatter().format(value[0]) : '';
const endDateString = value[1] ? props.getFormatter().format(value[1]) : '';
props.props.onChange([startDate, endDate], [startDateString, endDateString]);
},
render() {
const locale = this.getLocale();
const props = this.props;
const locale = props.locale;
// 以下两行代码
// 给没有初始值的日期选择框提供本地化信息
// 否则会以周日开始排
let defaultCalendarValue = new GregorianCalendar(locale);
defaultCalendarValue.setTime(Date.now());
const { disabledDate, showTime, size, startPlaceholder, endPlaceholder, getCalendarContainer,
const { disabledDate, showTime, startPlaceholder, endPlaceholder, getCalendarContainer,
transitionName, disabled, popupStyle, align, style, onOk } = this.props;
const state = this.state;
let timePicker = null;
if (showTime) {
timePicker = (<TimePicker
prefixCls="ant-time-picker"
placeholder={locale.lang.timePlaceholder}
transitionName="slide-up" />);
}
const calendarClassName = classNames({
['ant-calendar-time']: showTime,
});
......@@ -91,7 +69,7 @@ export default React.createClass({
onOk: this.handleChange,
};
if (timePicker) {
if (props.timePicker) {
pickerChangeHandler.onChange = (value) => {
// Click clear button
if (value === null || value.length === 0) {
......@@ -106,7 +84,7 @@ export default React.createClass({
<RangeCalendar
prefixCls="ant-calendar"
className={calendarClassName}
timePicker={timePicker}
timePicker={props.timePicker}
disabledDate={disabledDate}
dateInputPlaceholder={[startPlaceholder, endPlaceholder]}
locale={locale.lang}
......@@ -116,19 +94,7 @@ export default React.createClass({
/>
);
const pickerClass = classNames({
'ant-calendar-picker': true,
'ant-calendar-picker-open': state.open
});
const pickerInputClass = classNames({
'ant-calendar-range-picker': true,
'ant-input': true,
'ant-input-lg': size === 'large',
'ant-input-sm': size === 'small',
});
return (<span className={pickerClass} style={style}>
return (<span className={props.pickerClass} style={style}>
<DatePicker
transitionName={transitionName}
disabled={disabled}
......@@ -138,8 +104,8 @@ export default React.createClass({
style={popupStyle}
align={align}
getCalendarContainer={getCalendarContainer}
onOpen={this.toggleOpen}
onClose={this.toggleOpen}
onOpen={props.toggleOpen}
onClose={props.toggleOpen}
{...pickerChangeHandler}
>
{
......@@ -147,18 +113,18 @@ export default React.createClass({
const start = value[0];
const end = value[1];
return (
<span className={pickerInputClass} disabled={disabled}>
<span className={props.pickerInputClass} disabled={disabled}>
<input
disabled={disabled}
onChange={this.handleInputChange}
value={start && this.getFormatter().format(start)}
onChange={props.handleInputChange}
value={start && props.getFormatter().format(start)}
placeholder={startPlaceholder}
className="ant-calendar-range-picker-input" />
<span className="ant-calendar-range-picker-separator"> ~ </span>
<input
disabled={disabled}
onChange={this.handleInputChange}
value={end && this.getFormatter().format(end)}
onChange={props.handleInputChange}
value={end && props.getFormatter().format(end)}
placeholder={endPlaceholder}
className="ant-calendar-range-picker-input" />
<span className="ant-calendar-picker-icon" />
......
......@@ -2,51 +2,33 @@ import React from 'react';
import MonthCalendar from 'rc-calendar/lib/MonthCalendar';
import RcDatePicker from 'rc-calendar/lib/Picker';
import GregorianCalendar from 'gregorian-calendar';
import TimePicker from 'rc-time-picker';
import classNames from 'classnames';
import PickerMixin from './PickerMixin';
export default function createPicker(TheCalendar, defaultFormat) {
export default function createPicker(TheCalendar) {
return React.createClass({
getDefaultProps() {
return {
format: defaultFormat || 'yyyy-MM-dd',
transitionName: 'slide-up',
popupStyle: {},
onChange() {
},
onOk() {
},
locale: {},
align: {
offset: [0, -9],
},
open: false,
};
},
getInitialState() {
return {
value: this.parseDateFromValue(this.props.value || this.props.defaultValue)
value: this.props.parseDateFromValue(this.props.value || this.props.defaultValue)
};
},
mixins: [PickerMixin],
componentWillReceiveProps(nextProps) {
if ('value' in nextProps) {
this.setState({
value: this.parseDateFromValue(nextProps.value)
value: nextProps.parseDateFromValue(nextProps.value)
});
}
},
handleChange(value) {
if (!('value' in this.props)) {
const props = this.props;
if (!('value' in props)) {
this.setState({ value });
}
const timeValue = value ? new Date(value.getTime()) : null;
this.props.onChange(timeValue, value ? this.getFormatter().format(value) : '');
props.onChange(timeValue, value ? props.getFormatter().format(value) : '');
},
render() {
const props = this.props;
const locale = this.getLocale();
const locale = props.locale;
// 以下两行代码
// 给没有初始值的日期选择框提供本地化信息
// 否则会以周日开始排
......@@ -56,12 +38,6 @@ export default function createPicker(TheCalendar, defaultFormat) {
const placeholder = ('placeholder' in props)
? props.placeholder : locale.lang.placeholder;
const timePicker = props.showTime ? (<TimePicker
prefixCls="ant-time-picker"
placeholder={locale.lang.timePlaceholder}
transitionName="slide-up" />)
: null;
const disabledTime = props.showTime ? props.disabledTime : null;
const calendarClassName = classNames({
......@@ -93,7 +69,7 @@ export default function createPicker(TheCalendar, defaultFormat) {
disabledDate={props.disabledDate}
disabledTime={disabledTime}
locale={locale.lang}
timePicker={timePicker}
timePicker={props.timePicker}
defaultValue={defaultCalendarValue}
dateInputPlaceholder={placeholder}
prefixCls="ant-calendar"
......@@ -101,18 +77,6 @@ export default function createPicker(TheCalendar, defaultFormat) {
{...calendarHandler} />
);
const pickerClass = classNames({
'ant-calendar-picker': true,
'ant-calendar-picker-open': this.state.open,
});
const inputClass = classNames({
'ant-calendar-picker-input': true,
'ant-input': true,
'ant-input-lg': props.size === 'large',
'ant-input-sm': props.size === 'small',
});
// default width for showTime
const pickerStyle = {};
if (props.showTime) {
......@@ -120,7 +84,7 @@ export default function createPicker(TheCalendar, defaultFormat) {
}
return (
<span className={pickerClass} style={{ ...pickerStyle, ...props.style }}>
<span className={props.pickerClass} style={{ ...pickerStyle, ...props.style }}>
<RcDatePicker
transitionName={props.transitionName}
disabled={props.disabled}
......@@ -130,8 +94,8 @@ export default function createPicker(TheCalendar, defaultFormat) {
style={props.popupStyle}
align={props.align}
getCalendarContainer={props.getCalendarContainer}
onOpen={this.toggleOpen}
onClose={this.toggleOpen}
onOpen={props.toggleOpen}
onClose={props.toggleOpen}
{...pickerChangeHandler}
>
{
......@@ -140,10 +104,10 @@ export default function createPicker(TheCalendar, defaultFormat) {
<span>
<input
disabled={props.disabled}
onChange={this.handleInputChange}
value={value && this.getFormatter().format(value)}
onChange={props.handleInputChange}
value={value && props.getFormatter().format(value)}
placeholder={placeholder}
className={inputClass} />
className={props.pickerInputClass} />
<span className="ant-calendar-picker-icon" />
</span>
);
......
import RcCalendar from 'rc-calendar';
import MonthCalendar from 'rc-calendar/lib/MonthCalendar';
import createPicker from './createPicker';
import wrapPicker from './wrapPicker';
import RangePicker from './RangePicker';
import Calendar from './Calendar';
const DatePicker = createPicker(RcCalendar);
const MonthPicker = createPicker(MonthCalendar, 'yyyy-MM');
const DatePicker = wrapPicker(createPicker(RcCalendar));
const MonthPicker = wrapPicker(createPicker(MonthCalendar), 'yyyy-MM');
DatePicker.Calendar = Calendar;
DatePicker.RangePicker = RangePicker;
DatePicker.RangePicker = wrapPicker(RangePicker, 'yyyy-MM-dd');
DatePicker.MonthPicker = MonthPicker;
export default DatePicker;
import React, { PropTypes } from 'react';
import TimePicker from 'rc-time-picker';
import DateTimeFormat from 'gregorian-calendar-format';
import GregorianCalendar from 'gregorian-calendar';
import classNames from 'classnames';
import defaultLocale from './locale/zh_CN';
export default function wrapPicker(Picker, defaultFormat) {
return class PickerWrapper extends React.Component {
static defaultProps = {
format: defaultFormat || 'yyyy-MM-dd',
transitionName: 'slide-up',
popupStyle: {},
onChange() {},
onOk() {},
locale: {},
align: {
offset: [0, -9],
},
open: false
}
static contextTypes = {
antLocale: PropTypes.object,
}
constructor(props) {
super(props);
this.state = {};
}
// remove input readonly warning
handleInputChange() {}
getLocale() {
const props = this.props;
let locale = defaultLocale;
const context = this.context;
if (context.antLocale && context.antLocale.DatePicker) {
locale = context.antLocale.DatePicker;
}
// 统一合并为完整的 Locale
const result = { ...locale, ...props.locale };
result.lang = { ...locale.lang, ...props.locale.lang };
return result;
}
getFormatter = () => {
if (!this.formats) {
this.formats = {};
}
const formats = this.formats;
const format = this.props.format;
if (formats[format]) {
return formats[format];
}
formats[format] = new DateTimeFormat(format, this.getLocale().lang.format);
return formats[format];
}
parseDateFromValue = (value) => {
if (value) {
if (typeof value === 'string') {
return this.getFormatter().parse(value, { locale: this.getLocale() });
} else if (value instanceof Date) {
let date = new GregorianCalendar(this.getLocale());
date.setTime(+value);
return date;
}
}
return value;
}
toggleOpen = (e) => {
this.setState({
open: e.open
});
}
render() {
const props = this.props;
const state = this.state;
const pickerClass = classNames({
'ant-calendar-picker': true,
'ant-calendar-picker-open': state.open
});
const pickerInputClass = classNames({
'ant-calendar-range-picker': true,
'ant-input': true,
'ant-input-lg': props.size === 'large',
'ant-input-sm': props.size === 'small',
});
const locale = this.getLocale();
const timePicker = props.showTime ? (
<TimePicker
prefixCls="ant-time-picker"
placeholder={locale.lang.timePlaceholder}
transitionName="slide-up" />
) : null;
return (
<Picker
{...this.props}
pickerClass={pickerClass}
pickerInputClass={pickerInputClass}
locale={locale}
timePicker={timePicker}
toggleOpen={this.toggleOpen}
handleInputChange={this.handleInputChange}
getFormatter={this.getFormatter}
parseDateFromValue={this.parseDateFromValue}
/>
);
}
};
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册