You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
233 lines
6.6 KiB
233 lines
6.6 KiB
import * as React from 'react';
|
|
import { polyfill } from 'react-lifecycles-compat';
|
|
import TimePickerPanel from 'rc-time-picker/lib/Panel';
|
|
import classNames from 'classnames';
|
|
import * as moment from 'moment';
|
|
import enUS from './locale/en_US';
|
|
import interopDefault from '../_util/interopDefault';
|
|
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
|
import { generateShowHourMinuteSecond } from '../time-picker';
|
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
|
import warning from '../_util/warning';
|
|
|
|
type PickerType = 'date' | 'week' | 'month';
|
|
|
|
interface PickerMap {
|
|
[name: string]: string;
|
|
}
|
|
|
|
const DEFAULT_FORMAT: PickerMap = {
|
|
date: 'YYYY-MM-DD',
|
|
dateTime: 'YYYY-MM-DD HH:mm:ss',
|
|
week: 'gggg-wo',
|
|
month: 'YYYY-MM',
|
|
};
|
|
|
|
const LOCALE_FORMAT_MAPPING: PickerMap = {
|
|
date: 'dateFormat',
|
|
dateTime: 'dateTimeFormat',
|
|
week: 'weekFormat',
|
|
month: 'monthFormat',
|
|
};
|
|
|
|
function getColumns({ showHour, showMinute, showSecond, use12Hours }: any) {
|
|
let column = 0;
|
|
if (showHour) {
|
|
column += 1;
|
|
}
|
|
if (showMinute) {
|
|
column += 1;
|
|
}
|
|
if (showSecond) {
|
|
column += 1;
|
|
}
|
|
if (use12Hours) {
|
|
column += 1;
|
|
}
|
|
return column;
|
|
}
|
|
|
|
function checkValidate(value: any, propName: string) {
|
|
const values: any[] = Array.isArray(value) ? value : [value];
|
|
values.forEach(val => {
|
|
if (!val) return;
|
|
|
|
warning(
|
|
!interopDefault(moment).isMoment(val) || val.isValid(),
|
|
'DatePicker',
|
|
`\`${propName}\` provides invalidate moment time. If you want to set empty value, use \`null\` instead.`,
|
|
);
|
|
});
|
|
}
|
|
|
|
export default function wrapPicker(Picker: React.ComponentClass<any>, pickerType: PickerType): any {
|
|
class PickerWrapper extends React.Component<any, any> {
|
|
static defaultProps = {
|
|
transitionName: 'slide-up',
|
|
popupStyle: {},
|
|
onChange() {},
|
|
onOk() {},
|
|
onOpenChange() {},
|
|
locale: {},
|
|
};
|
|
|
|
static getDerivedStateFromProps({ value, defaultValue }: any) {
|
|
checkValidate(defaultValue, 'defaultValue');
|
|
checkValidate(value, 'value');
|
|
return {};
|
|
}
|
|
|
|
// Since we need call `getDerivedStateFromProps` for check. Need leave an empty `state` here.
|
|
state = {};
|
|
|
|
private picker: any;
|
|
|
|
componentDidMount() {
|
|
const { autoFocus, disabled } = this.props;
|
|
if (autoFocus && !disabled) {
|
|
this.focus();
|
|
}
|
|
}
|
|
|
|
savePicker = (node: any) => {
|
|
this.picker = node;
|
|
};
|
|
|
|
getDefaultLocale = () => {
|
|
const result = {
|
|
...enUS,
|
|
...this.props.locale,
|
|
};
|
|
result.lang = {
|
|
...result.lang,
|
|
...(this.props.locale || {}).lang,
|
|
};
|
|
return result;
|
|
};
|
|
|
|
handleOpenChange = (open: boolean) => {
|
|
const { onOpenChange } = this.props;
|
|
onOpenChange(open);
|
|
};
|
|
|
|
handleFocus: React.FocusEventHandler<HTMLInputElement> = e => {
|
|
const { onFocus } = this.props;
|
|
if (onFocus) {
|
|
onFocus(e);
|
|
}
|
|
};
|
|
|
|
handleBlur: React.FocusEventHandler<HTMLInputElement> = e => {
|
|
const { onBlur } = this.props;
|
|
if (onBlur) {
|
|
onBlur(e);
|
|
}
|
|
};
|
|
|
|
handleMouseEnter: React.MouseEventHandler<HTMLInputElement> = e => {
|
|
const { onMouseEnter } = this.props;
|
|
if (onMouseEnter) {
|
|
onMouseEnter(e);
|
|
}
|
|
};
|
|
|
|
handleMouseLeave: React.MouseEventHandler<HTMLInputElement> = e => {
|
|
const { onMouseLeave } = this.props;
|
|
if (onMouseLeave) {
|
|
onMouseLeave(e);
|
|
}
|
|
};
|
|
|
|
focus() {
|
|
this.picker.focus();
|
|
}
|
|
|
|
blur() {
|
|
this.picker.blur();
|
|
}
|
|
|
|
renderPicker = (locale: any, localeCode: string) => {
|
|
const { format, showTime } = this.props;
|
|
const mergedPickerType = showTime ? `${pickerType}Time` : pickerType;
|
|
const mergedFormat =
|
|
format ||
|
|
locale[LOCALE_FORMAT_MAPPING[mergedPickerType]] ||
|
|
DEFAULT_FORMAT[mergedPickerType];
|
|
|
|
return (
|
|
<ConfigConsumer>
|
|
{({ getPrefixCls, getPopupContainer: getContextPopupContainer }: ConfigConsumerProps) => {
|
|
const {
|
|
prefixCls: customizePrefixCls,
|
|
inputPrefixCls: customizeInputPrefixCls,
|
|
getCalendarContainer,
|
|
size,
|
|
disabled,
|
|
} = this.props;
|
|
const getPopupContainer = getCalendarContainer || getContextPopupContainer;
|
|
const prefixCls = getPrefixCls('calendar', customizePrefixCls);
|
|
const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls);
|
|
const pickerClass = classNames(`${prefixCls}-picker`, {
|
|
[`${prefixCls}-picker-${size}`]: !!size,
|
|
});
|
|
const pickerInputClass = classNames(`${prefixCls}-picker-input`, inputPrefixCls, {
|
|
[`${inputPrefixCls}-lg`]: size === 'large',
|
|
[`${inputPrefixCls}-sm`]: size === 'small',
|
|
[`${inputPrefixCls}-disabled`]: disabled,
|
|
});
|
|
|
|
const timeFormat = (showTime && showTime.format) || 'HH:mm:ss';
|
|
const rcTimePickerProps = {
|
|
...generateShowHourMinuteSecond(timeFormat),
|
|
format: timeFormat,
|
|
use12Hours: showTime && showTime.use12Hours,
|
|
};
|
|
const columns = getColumns(rcTimePickerProps);
|
|
const timePickerCls = `${prefixCls}-time-picker-column-${columns}`;
|
|
const timePicker = showTime ? (
|
|
<TimePickerPanel
|
|
{...rcTimePickerProps}
|
|
{...showTime}
|
|
prefixCls={`${prefixCls}-time-picker`}
|
|
className={timePickerCls}
|
|
placeholder={locale.timePickerLocale.placeholder}
|
|
transitionName="slide-up"
|
|
onEsc={() => {}}
|
|
/>
|
|
) : null;
|
|
|
|
return (
|
|
<Picker
|
|
{...this.props}
|
|
getCalendarContainer={getPopupContainer}
|
|
format={mergedFormat}
|
|
ref={this.savePicker}
|
|
pickerClass={pickerClass}
|
|
pickerInputClass={pickerInputClass}
|
|
locale={locale}
|
|
localeCode={localeCode}
|
|
timePicker={timePicker}
|
|
onOpenChange={this.handleOpenChange}
|
|
onFocus={this.handleFocus}
|
|
onBlur={this.handleBlur}
|
|
onMouseEnter={this.handleMouseEnter}
|
|
onMouseLeave={this.handleMouseLeave}
|
|
/>
|
|
);
|
|
}}
|
|
</ConfigConsumer>
|
|
);
|
|
};
|
|
|
|
render() {
|
|
return (
|
|
<LocaleReceiver componentName="DatePicker" defaultLocale={this.getDefaultLocale}>
|
|
{this.renderPicker}
|
|
</LocaleReceiver>
|
|
);
|
|
}
|
|
}
|
|
|
|
polyfill(PickerWrapper);
|
|
return PickerWrapper;
|
|
}
|
|
|