add date-picker demo
parent
041fd349a4
commit
c953ca07bb
|
@ -1,3 +1,5 @@
|
|||
import isPlainObject from 'lodash.isplainobject'
|
||||
|
||||
const camelizeRE = /-(\w)/g
|
||||
const camelize = (str) => {
|
||||
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
|
||||
|
@ -176,7 +178,15 @@ export function filterEmpty (children = []) {
|
|||
return children.filter(c => c.tag || c.text.trim() !== '')
|
||||
}
|
||||
const initDefaultProps = (propTypes, defaultProps) => {
|
||||
Object.keys(defaultProps).forEach(k => { propTypes[k] = propTypes[k].def(defaultProps[k]) })
|
||||
Object.keys(defaultProps).forEach(k => {
|
||||
if (propTypes[k]) {
|
||||
propTypes[k].def && (propTypes[k] = propTypes[k].def(defaultProps[k]))
|
||||
} else {
|
||||
throw new Error(
|
||||
`not have ${k} prop`,
|
||||
)
|
||||
}
|
||||
})
|
||||
return propTypes
|
||||
}
|
||||
|
||||
|
@ -186,11 +196,16 @@ export function mergeProps () {
|
|||
args.forEach((p, i) => {
|
||||
for (const [k, v] of Object.entries(p)) {
|
||||
props[k] = props[k] || {}
|
||||
Object.assign(props[k], v)
|
||||
if (isPlainObject(v)) {
|
||||
Object.assign(props[k], v)
|
||||
} else {
|
||||
props[k] = v
|
||||
}
|
||||
}
|
||||
})
|
||||
return props
|
||||
}
|
||||
|
||||
export {
|
||||
hasProp,
|
||||
filterProps,
|
||||
|
|
|
@ -1,366 +0,0 @@
|
|||
/* tslint:disable jsx-no-multiline-js */
|
||||
import * as React from 'react';
|
||||
import * as moment from 'moment';
|
||||
import RangeCalendar from 'rc-calendar/lib/RangeCalendar';
|
||||
import RcDatePicker from 'rc-calendar/lib/Picker';
|
||||
import classNames from 'classnames';
|
||||
import Icon from '../icon';
|
||||
import warning from '../_util/warning';
|
||||
import callMoment from '../_util/callMoment';
|
||||
import { RangePickerValue, RangePickerPresetRange } from './interface';
|
||||
|
||||
export interface RangePickerState {
|
||||
value?: RangePickerValue;
|
||||
showDate?: RangePickerValue;
|
||||
open?: boolean;
|
||||
hoverValue?: RangePickerValue;
|
||||
}
|
||||
|
||||
function getShowDateFromValue(value: RangePickerValue) {
|
||||
const [start, end] = value;
|
||||
// value could be an empty array, then we should not reset showDate
|
||||
if (!start && !end) {
|
||||
return;
|
||||
}
|
||||
const newEnd = end && end.isSame(start, 'month') ? end.clone().add(1, 'month') : end;
|
||||
return [start, newEnd] as RangePickerValue;
|
||||
}
|
||||
|
||||
function formatValue(value: moment.Moment | undefined, format: string): string {
|
||||
return (value && value.format(format)) || '';
|
||||
}
|
||||
|
||||
function pickerValueAdapter(value?: moment.Moment | RangePickerValue): RangePickerValue | undefined {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value;
|
||||
}
|
||||
return [value, value.clone().add(1, 'month')];
|
||||
}
|
||||
|
||||
function isEmptyArray(arr: any) {
|
||||
if (Array.isArray(arr)) {
|
||||
return arr.length === 0 || arr.every(i => !i);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function fixLocale(value: RangePickerValue | undefined, localeCode: string) {
|
||||
if (!localeCode) {
|
||||
return;
|
||||
}
|
||||
if (!value || value.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (value[0]) {
|
||||
value[0]!.locale(localeCode);
|
||||
}
|
||||
if (value[1]) {
|
||||
value[1]!.locale(localeCode);
|
||||
}
|
||||
}
|
||||
|
||||
export default class RangePicker extends React.Component<any, RangePickerState> {
|
||||
static defaultProps = {
|
||||
prefixCls: 'ant-calendar',
|
||||
allowClear: true,
|
||||
showToday: false,
|
||||
};
|
||||
|
||||
private picker: HTMLSpanElement;
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
const value = props.value || props.defaultValue || [];
|
||||
if (
|
||||
value[0] && !moment.isMoment(value[0]) ||
|
||||
value[1] && !moment.isMoment(value[1])
|
||||
) {
|
||||
throw new Error(
|
||||
'The value/defaultValue of RangePicker must be a moment object array after `antd@2.0`, ' +
|
||||
'see: https://u.ant.design/date-picker-value',
|
||||
);
|
||||
}
|
||||
const pickerValue = !value || isEmptyArray(value) ? props.defaultPickerValue : value;
|
||||
this.state = {
|
||||
value,
|
||||
showDate: pickerValueAdapter(pickerValue || callMoment(moment)),
|
||||
open: props.open,
|
||||
hoverValue: [],
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: any) {
|
||||
if ('value' in nextProps) {
|
||||
const state = this.state;
|
||||
const value = nextProps.value || [];
|
||||
this.setState({
|
||||
value,
|
||||
showDate: getShowDateFromValue(value) || state.showDate,
|
||||
});
|
||||
}
|
||||
if ('open' in nextProps) {
|
||||
this.setState({
|
||||
open: nextProps.open,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
clearSelection = (e: React.MouseEvent<HTMLElement>) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.setState({ value: [] });
|
||||
this.handleChange([]);
|
||||
}
|
||||
|
||||
clearHoverValue = () => this.setState({ hoverValue: [] });
|
||||
|
||||
handleChange = (value: RangePickerValue) => {
|
||||
const props = this.props;
|
||||
if (!('value' in props)) {
|
||||
this.setState(({ showDate }) => ({
|
||||
value,
|
||||
showDate: getShowDateFromValue(value) || showDate,
|
||||
}));
|
||||
}
|
||||
props.onChange(value, [
|
||||
formatValue(value[0], props.format),
|
||||
formatValue(value[1], props.format),
|
||||
]);
|
||||
}
|
||||
|
||||
handleOpenChange = (open: boolean) => {
|
||||
if (!('open' in this.props)) {
|
||||
this.setState({ open });
|
||||
}
|
||||
|
||||
if (open === false) {
|
||||
this.clearHoverValue();
|
||||
}
|
||||
|
||||
const { onOpenChange } = this.props;
|
||||
if (onOpenChange) {
|
||||
onOpenChange(open);
|
||||
}
|
||||
}
|
||||
|
||||
handleShowDateChange = (showDate: RangePickerValue) => this.setState({ showDate });
|
||||
|
||||
handleHoverChange = (hoverValue: any) => this.setState({ hoverValue });
|
||||
|
||||
handleRangeMouseLeave = () => {
|
||||
if (this.state.open) {
|
||||
this.clearHoverValue();
|
||||
}
|
||||
}
|
||||
|
||||
handleCalendarInputSelect = (value: RangePickerValue) => {
|
||||
if (!value[0]) {
|
||||
return;
|
||||
}
|
||||
this.setState(({ showDate }) => ({
|
||||
value,
|
||||
showDate: getShowDateFromValue(value) || showDate,
|
||||
}));
|
||||
}
|
||||
|
||||
handleRangeClick = (value: RangePickerPresetRange) => {
|
||||
if (typeof value === 'function') {
|
||||
value = value();
|
||||
}
|
||||
|
||||
this.setValue(value, true);
|
||||
|
||||
const { onOk } = this.props;
|
||||
if (onOk) {
|
||||
onOk(value);
|
||||
}
|
||||
}
|
||||
|
||||
setValue(value: RangePickerValue, hidePanel?: boolean) {
|
||||
this.handleChange(value);
|
||||
if ((hidePanel || !this.props.showTime) && !('open' in this.props)) {
|
||||
this.setState({ open: false });
|
||||
}
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.picker.focus();
|
||||
}
|
||||
|
||||
blur() {
|
||||
this.picker.blur();
|
||||
}
|
||||
|
||||
savePicker = (node: HTMLSpanElement) => {
|
||||
this.picker = node;
|
||||
}
|
||||
|
||||
renderFooter = (...args: any[]) => {
|
||||
const { prefixCls, ranges, renderExtraFooter } = this.props;
|
||||
if (!ranges && !renderExtraFooter) {
|
||||
return null;
|
||||
}
|
||||
const customFooter = renderExtraFooter ? (
|
||||
<div className={`${prefixCls}-footer-extra`} key="extra">
|
||||
{renderExtraFooter(...args)}
|
||||
</div>
|
||||
) : null;
|
||||
const operations = Object.keys(ranges || {}).map((range) => {
|
||||
const value = ranges[range];
|
||||
return (
|
||||
<a
|
||||
key={range}
|
||||
onClick={() => this.handleRangeClick(value)}
|
||||
onMouseEnter={() => this.setState({ hoverValue: value })}
|
||||
onMouseLeave={this.handleRangeMouseLeave}
|
||||
>
|
||||
{range}
|
||||
</a>
|
||||
);
|
||||
});
|
||||
const rangeNode = (
|
||||
<div className={`${prefixCls}-footer-extra ${prefixCls}-range-quick-selector`} key="range">
|
||||
{operations}
|
||||
</div>
|
||||
);
|
||||
return [rangeNode, customFooter];
|
||||
}
|
||||
|
||||
render() {
|
||||
const { state, props } = this;
|
||||
const { value, showDate, hoverValue, open } = state;
|
||||
const {
|
||||
prefixCls, popupStyle, style,
|
||||
disabledDate, disabledTime,
|
||||
showTime, showToday,
|
||||
ranges, onOk, locale, localeCode, format,
|
||||
dateRender, onCalendarChange,
|
||||
} = props;
|
||||
|
||||
fixLocale(value, localeCode);
|
||||
fixLocale(showDate, localeCode);
|
||||
|
||||
warning(!('onOK' in props), 'It should be `RangePicker[onOk]`, instead of `onOK`!');
|
||||
|
||||
const calendarClassName = classNames({
|
||||
[`${prefixCls}-time`]: showTime,
|
||||
[`${prefixCls}-range-with-ranges`]: ranges,
|
||||
});
|
||||
|
||||
// 需要选择时间时,点击 ok 时才触发 onChange
|
||||
let pickerChangeHandler = {
|
||||
onChange: this.handleChange,
|
||||
};
|
||||
let calendarProps: any = {
|
||||
onOk: this.handleChange,
|
||||
};
|
||||
if (props.timePicker) {
|
||||
pickerChangeHandler.onChange = changedValue => this.handleChange(changedValue);
|
||||
} else {
|
||||
calendarProps = {};
|
||||
}
|
||||
if ('mode' in props) {
|
||||
calendarProps.mode = props.mode;
|
||||
}
|
||||
|
||||
const startPlaceholder = ('placeholder' in props)
|
||||
? props.placeholder[0] : locale.lang.rangePlaceholder[0];
|
||||
const endPlaceholder = ('placeholder' in props)
|
||||
? props.placeholder[1] : locale.lang.rangePlaceholder[1];
|
||||
|
||||
const calendar = (
|
||||
<RangeCalendar
|
||||
{...calendarProps}
|
||||
onChange={onCalendarChange}
|
||||
format={format}
|
||||
prefixCls={prefixCls}
|
||||
className={calendarClassName}
|
||||
renderFooter={this.renderFooter}
|
||||
timePicker={props.timePicker}
|
||||
disabledDate={disabledDate}
|
||||
disabledTime={disabledTime}
|
||||
dateInputPlaceholder={[startPlaceholder, endPlaceholder]}
|
||||
locale={locale.lang}
|
||||
onOk={onOk}
|
||||
dateRender={dateRender}
|
||||
value={showDate}
|
||||
onValueChange={this.handleShowDateChange}
|
||||
hoverValue={hoverValue}
|
||||
onHoverChange={this.handleHoverChange}
|
||||
onPanelChange={props.onPanelChange}
|
||||
showToday={showToday}
|
||||
onInputSelect={this.handleCalendarInputSelect}
|
||||
/>
|
||||
);
|
||||
|
||||
// default width for showTime
|
||||
const pickerStyle = {} as any;
|
||||
if (props.showTime) {
|
||||
pickerStyle.width = (style && style.width) || 350;
|
||||
}
|
||||
|
||||
const clearIcon = (!props.disabled && props.allowClear && value && (value[0] || value[1])) ? (
|
||||
<Icon
|
||||
type="cross-circle"
|
||||
className={`${prefixCls}-picker-clear`}
|
||||
onClick={this.clearSelection}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
const input = ({ value: inputValue }: { value: any }) => {
|
||||
const start = inputValue[0];
|
||||
const end = inputValue[1];
|
||||
return (
|
||||
<span className={props.pickerInputClass}>
|
||||
<input
|
||||
disabled={props.disabled}
|
||||
readOnly
|
||||
value={(start && start.format(props.format)) || ''}
|
||||
placeholder={startPlaceholder}
|
||||
className={`${prefixCls}-range-picker-input`}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
<span className={`${prefixCls}-range-picker-separator`}> ~ </span>
|
||||
<input
|
||||
disabled={props.disabled}
|
||||
readOnly
|
||||
value={(end && end.format(props.format)) || ''}
|
||||
placeholder={endPlaceholder}
|
||||
className={`${prefixCls}-range-picker-input`}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
{clearIcon}
|
||||
<span className={`${prefixCls}-picker-icon`} />
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<span
|
||||
ref={this.savePicker}
|
||||
id={props.id}
|
||||
className={classNames(props.className, props.pickerClass)}
|
||||
style={{ ...style, ...pickerStyle }}
|
||||
tabIndex={props.disabled ? -1 : 0}
|
||||
onFocus={props.onFocus}
|
||||
onBlur={props.onBlur}
|
||||
>
|
||||
<RcDatePicker
|
||||
{...props}
|
||||
{...pickerChangeHandler}
|
||||
calendar={calendar}
|
||||
value={value}
|
||||
open={open}
|
||||
onOpenChange={this.handleOpenChange}
|
||||
prefixCls={`${prefixCls}-picker-container`}
|
||||
style={popupStyle}
|
||||
>
|
||||
{input}
|
||||
</RcDatePicker>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,365 @@
|
|||
<script>
|
||||
import * as moment from 'moment'
|
||||
import RangeCalendar from '../vc-calendar/src/RangeCalendar'
|
||||
import VcDatePicker from '../vc-calendar/src/Picker'
|
||||
import classNames from 'classnames'
|
||||
import Icon from '../icon'
|
||||
import callMoment from '../_util/callMoment'
|
||||
import { RangePickerProps } from './interface'
|
||||
import { hasProp, getOptionProps, initDefaultProps, mergeProps } from '../_util/props-util'
|
||||
import BaseMixin from '../_util/BaseMixin'
|
||||
function noop () {}
|
||||
function getShowDateFromValue (value) {
|
||||
const [start, end] = value
|
||||
// value could be an empty array, then we should not reset showDate
|
||||
if (!start && !end) {
|
||||
return
|
||||
}
|
||||
const newEnd = end && end.isSame(start, 'month') ? end.clone().add(1, 'month') : end
|
||||
return [start, newEnd]
|
||||
}
|
||||
|
||||
function formatValue (value, format) {
|
||||
return (value && value.format(format)) || ''
|
||||
}
|
||||
|
||||
function pickerValueAdapter (value) {
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
}
|
||||
return [value, value.clone().add(1, 'month')]
|
||||
}
|
||||
|
||||
function isEmptyArray (arr) {
|
||||
if (Array.isArray(arr)) {
|
||||
return arr.length === 0 || arr.every(i => !i)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function fixLocale (value, localeCode) {
|
||||
if (!localeCode) {
|
||||
return
|
||||
}
|
||||
if (!value || value.length === 0) {
|
||||
return
|
||||
}
|
||||
if (value[0]) {
|
||||
value[0].locale(localeCode)
|
||||
}
|
||||
if (value[1]) {
|
||||
value[1].locale(localeCode)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
mixins: [BaseMixin],
|
||||
name: 'RangePicker',
|
||||
props: initDefaultProps(RangePickerProps(), {
|
||||
prefixCls: 'ant-calendar',
|
||||
allowClear: true,
|
||||
showToday: false,
|
||||
}),
|
||||
|
||||
data () {
|
||||
const value = this.value || this.defaultValue || []
|
||||
if (
|
||||
value[0] && !moment.isMoment(value[0]) ||
|
||||
value[1] && !moment.isMoment(value[1])
|
||||
) {
|
||||
throw new Error(
|
||||
'The value/defaultValue of RangePicker must be a moment object array after `antd@2.0`, ' +
|
||||
'see: https://u.ant.design/date-picker-value',
|
||||
)
|
||||
}
|
||||
const pickerValue = !value || isEmptyArray(value) ? this.defaultPickerValue : value
|
||||
return {
|
||||
sValue: value,
|
||||
sShowDate: pickerValueAdapter(pickerValue || callMoment(moment)),
|
||||
sOpen: this.open,
|
||||
sHoverValue: [],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value (val) {
|
||||
const value = val || []
|
||||
this.setState({
|
||||
sValue: value,
|
||||
sShowDate: getShowDateFromValue(value) || this.sShowDate,
|
||||
})
|
||||
},
|
||||
open (val) {
|
||||
this.setState({
|
||||
sOpen: val,
|
||||
})
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
clearSelection (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
this.setState({ sValue: [] })
|
||||
this.handleChange([])
|
||||
},
|
||||
|
||||
clearHoverValue () {
|
||||
this.setState({ sHoverValue: [] })
|
||||
},
|
||||
|
||||
handleChange (value) {
|
||||
if (!hasProp(this, 'value')) {
|
||||
this.setState(({ sShowDate }) => ({
|
||||
sValue: value,
|
||||
sShowDate: getShowDateFromValue(value) || sShowDate,
|
||||
}))
|
||||
}
|
||||
this.$emit('change', value, [
|
||||
formatValue(value[0], this.format),
|
||||
formatValue(value[1], this.format),
|
||||
])
|
||||
},
|
||||
|
||||
handleOpenChange (open) {
|
||||
if (!hasProp(this, 'open')) {
|
||||
this.setState({ sOpen: open })
|
||||
}
|
||||
|
||||
if (open === false) {
|
||||
this.clearHoverValue()
|
||||
}
|
||||
this.$emit('openChange', open)
|
||||
},
|
||||
|
||||
handleShowDateChange (showDate) {
|
||||
this.setState({ sShowDate: showDate })
|
||||
},
|
||||
|
||||
handleHoverChange (hoverValue) {
|
||||
this.setState({ sHoverValue: hoverValue })
|
||||
},
|
||||
|
||||
handleRangeMouseLeave () {
|
||||
if (this.sOpen) {
|
||||
this.clearHoverValue()
|
||||
}
|
||||
},
|
||||
|
||||
handleCalendarInputSelect (value) {
|
||||
if (!value[0]) {
|
||||
return
|
||||
}
|
||||
this.setState(({ sShowDate }) => ({
|
||||
sValue: value,
|
||||
sShowDate: getShowDateFromValue(value) || sShowDate,
|
||||
}))
|
||||
},
|
||||
|
||||
handleRangeClick (value) {
|
||||
if (typeof value === 'function') {
|
||||
value = value()
|
||||
}
|
||||
|
||||
this.setValue(value, true)
|
||||
this.$emit('ok', value)
|
||||
},
|
||||
|
||||
setValue (value, hidePanel) {
|
||||
this.handleChange(value)
|
||||
if ((hidePanel || !this.showTime) && !hasProp(this, 'open')) {
|
||||
this.setState({ sOpen: false })
|
||||
}
|
||||
},
|
||||
|
||||
focus () {
|
||||
this.$refs.picker.focus()
|
||||
},
|
||||
|
||||
blur () {
|
||||
this.$refs.picker.blur()
|
||||
},
|
||||
|
||||
renderFooter (...args) {
|
||||
const { prefixCls, ranges, renderExtraFooter } = this
|
||||
if (!ranges && !renderExtraFooter) {
|
||||
return null
|
||||
}
|
||||
const customFooter = renderExtraFooter ? (
|
||||
<div class={`${prefixCls}-footer-extra`} key='extra'>
|
||||
{renderExtraFooter(...args)}
|
||||
</div>
|
||||
) : null
|
||||
const operations = Object.keys(ranges || {}).map((range) => {
|
||||
const value = ranges[range]
|
||||
return (
|
||||
<a
|
||||
key={range}
|
||||
onClick={() => this.handleRangeClick(value)}
|
||||
onMouseenter={() => this.setState({ sHoverValue: value })}
|
||||
onMouseleave={this.handleRangeMouseLeave}
|
||||
>
|
||||
{range}
|
||||
</a>
|
||||
)
|
||||
})
|
||||
const rangeNode = (
|
||||
<div class={`${prefixCls}-footer-extra ${prefixCls}-range-quick-selector`} key='range'>
|
||||
{operations}
|
||||
</div>
|
||||
)
|
||||
return [rangeNode, customFooter]
|
||||
},
|
||||
},
|
||||
|
||||
render () {
|
||||
const props = getOptionProps(this)
|
||||
const { sValue: value, sShowDate: showDate, sHoverValue: hoverValue, sOpen: open, $listeners, $scopedSlots } = this
|
||||
const { calendarChange = noop, ok = noop, focus = noop, blur = noop, panelChange = noop } = $listeners
|
||||
const {
|
||||
prefixCls, popupStyle,
|
||||
disabledDate, disabledTime,
|
||||
showTime, showToday,
|
||||
ranges, locale, localeCode, format,
|
||||
} = props
|
||||
const dateRender = props.dateRender || $scopedSlots.dateRender
|
||||
fixLocale(value, localeCode)
|
||||
fixLocale(showDate, localeCode)
|
||||
|
||||
const calendarClassName = classNames({
|
||||
[`${prefixCls}-time`]: showTime,
|
||||
[`${prefixCls}-range-with-ranges`]: ranges,
|
||||
})
|
||||
|
||||
// 需要选择时间时,点击 ok 时才触发 onChange
|
||||
const pickerChangeHandler = {
|
||||
on: {
|
||||
change: this.handleChange,
|
||||
},
|
||||
}
|
||||
let calendarProps = {
|
||||
on: {
|
||||
ok: this.handleChange,
|
||||
}, props: {},
|
||||
}
|
||||
if (props.timePicker) {
|
||||
pickerChangeHandler.on.change = changedValue => this.handleChange(changedValue)
|
||||
} else {
|
||||
calendarProps = { on: {}, props: {}}
|
||||
}
|
||||
if ('mode' in props) {
|
||||
calendarProps.props.mode = props.mode
|
||||
}
|
||||
|
||||
const startPlaceholder = ('placeholder' in props)
|
||||
? props.placeholder[0] : locale.lang.rangePlaceholder[0]
|
||||
const endPlaceholder = ('placeholder' in props)
|
||||
? props.placeholder[1] : locale.lang.rangePlaceholder[1]
|
||||
const rangeCalendarProps = mergeProps(calendarProps, {
|
||||
props: {
|
||||
format: format,
|
||||
prefixCls: prefixCls,
|
||||
renderFooter: this.renderFooter,
|
||||
timePicker: props.timePicker,
|
||||
disabledDate: disabledDate,
|
||||
disabledTime: disabledTime,
|
||||
dateInputPlaceholder: [startPlaceholder, endPlaceholder],
|
||||
locale: locale.lang,
|
||||
dateRender: dateRender,
|
||||
value: showDate,
|
||||
hoverValue: hoverValue,
|
||||
showToday: showToday,
|
||||
},
|
||||
on: {
|
||||
change: calendarChange,
|
||||
ok: ok,
|
||||
valueChange: this.handleShowDateChange,
|
||||
hoverChange: this.handleHoverChange,
|
||||
panelChange: panelChange,
|
||||
inputSelect: this.handleCalendarInputSelect,
|
||||
},
|
||||
class: calendarClassName,
|
||||
scopedSlots: $scopedSlots,
|
||||
})
|
||||
const calendar = (
|
||||
<RangeCalendar
|
||||
{...rangeCalendarProps}
|
||||
/>
|
||||
)
|
||||
|
||||
// default width for showTime
|
||||
const pickerStyle = {}
|
||||
if (props.showTime) {
|
||||
pickerStyle.width = '350px'
|
||||
}
|
||||
|
||||
const clearIcon = (!props.disabled && props.allowClear && value && (value[0] || value[1])) ? (
|
||||
<Icon
|
||||
type='cross-circle'
|
||||
class={`${prefixCls}-picker-clear`}
|
||||
onClick={this.clearSelection}
|
||||
/>
|
||||
) : null
|
||||
|
||||
const input = ({ value: inputValue }) => {
|
||||
const start = inputValue[0]
|
||||
const end = inputValue[1]
|
||||
return (
|
||||
<span class={props.pickerInputClass}>
|
||||
<input
|
||||
disabled={props.disabled}
|
||||
readOnly
|
||||
value={(start && start.format(props.format)) || ''}
|
||||
placeholder={startPlaceholder}
|
||||
class={`${prefixCls}-range-picker-input`}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
<span class={`${prefixCls}-range-picker-separator`}> ~ </span>
|
||||
<input
|
||||
disabled={props.disabled}
|
||||
readOnly
|
||||
value={(end && end.format(props.format)) || ''}
|
||||
placeholder={endPlaceholder}
|
||||
class={`${prefixCls}-range-picker-input`}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
{clearIcon}
|
||||
<span class={`${prefixCls}-picker-icon`} />
|
||||
</span>
|
||||
)
|
||||
}
|
||||
const vcDatePickerProps = mergeProps({
|
||||
props,
|
||||
on: $listeners,
|
||||
}, pickerChangeHandler, {
|
||||
props: {
|
||||
calendar: calendar,
|
||||
value: value,
|
||||
open: open,
|
||||
prefixCls: `${prefixCls}-picker-container`,
|
||||
},
|
||||
on: {
|
||||
openChange: this.handleOpenChange,
|
||||
},
|
||||
style: popupStyle,
|
||||
})
|
||||
return (
|
||||
<span
|
||||
ref='picker'
|
||||
class={props.pickerClass}
|
||||
style={pickerStyle}
|
||||
tabIndex={props.disabled ? -1 : 0}
|
||||
onFocus={focus}
|
||||
onBlur={blur}
|
||||
>
|
||||
<VcDatePicker
|
||||
{...vcDatePickerProps}
|
||||
>
|
||||
{input}
|
||||
</VcDatePicker>
|
||||
</span>
|
||||
)
|
||||
},
|
||||
}
|
||||
</script>
|
|
@ -3,8 +3,9 @@ import * as moment from 'moment'
|
|||
import Calendar from '../vc-calendar'
|
||||
import VcDatePicker from '../vc-calendar/src/Picker'
|
||||
import Icon from '../icon'
|
||||
import { hasProp, getOptionProps } from '../_util/props-util'
|
||||
import { hasProp, getOptionProps, initDefaultProps } from '../_util/props-util'
|
||||
import BaseMixin from '../_util/BaseMixin'
|
||||
import { WeexPickerProps } from './interface'
|
||||
|
||||
function formatValue (value, format) {
|
||||
return (value && value.format(format)) || ''
|
||||
|
@ -18,6 +19,10 @@ export default {
|
|||
// };
|
||||
|
||||
// private input: any;
|
||||
props: initDefaultProps(WeexPickerProps(), {
|
||||
format: 'YYYY-wo',
|
||||
allowClear: true,
|
||||
}),
|
||||
name: 'WeekPicker',
|
||||
mixins: [BaseMixin],
|
||||
data () {
|
||||
|
@ -85,7 +90,7 @@ export default {
|
|||
const {
|
||||
prefixCls, disabled, pickerClass, popupStyle,
|
||||
pickerInputClass, format, allowClear, locale, localeCode, disabledDate,
|
||||
sValue: pickerValue, $listeners,
|
||||
sValue: pickerValue, $listeners, $scopedSlots,
|
||||
} = this
|
||||
const { focus = noop, blur = noop } = $listeners
|
||||
|
||||
|
@ -94,11 +99,11 @@ export default {
|
|||
}
|
||||
|
||||
const placeholder = hasProp(this, 'placeholder') ? this.placeholder : locale.lang.placeholder
|
||||
|
||||
const weekDateRender = this.dateRender || $scopedSlots.dateRender || this.weekDateRender
|
||||
const calendar = (
|
||||
<Calendar
|
||||
showWeekNumber
|
||||
dateRender={this.weekDateRender}
|
||||
dateRender={weekDateRender}
|
||||
prefixCls={prefixCls}
|
||||
format={format}
|
||||
locale={locale.lang}
|
||||
|
|
|
@ -6,14 +6,14 @@ import classNames from 'classnames'
|
|||
import Icon from '../icon'
|
||||
import callMoment from '../_util/callMoment'
|
||||
import BaseMixin from '../_util/BaseMixin'
|
||||
import { hasProp, getOptionProps } from '../_util/props-util'
|
||||
import { hasProp, getOptionProps, initDefaultProps, mergeProps } from '../_util/props-util'
|
||||
|
||||
// export const PickerProps = {
|
||||
// value?: moment.Moment;
|
||||
// prefixCls: string;
|
||||
// }
|
||||
function noop () {}
|
||||
export default function createPicker (TheCalendar) {
|
||||
export default function createPicker (TheCalendar, props) {
|
||||
return {
|
||||
// static defaultProps = {
|
||||
// prefixCls: 'ant-calendar',
|
||||
|
@ -22,6 +22,11 @@ export default function createPicker (TheCalendar) {
|
|||
// };
|
||||
|
||||
// private input: any;
|
||||
props: initDefaultProps(props, {
|
||||
prefixCls: 'ant-calendar',
|
||||
allowClear: true,
|
||||
showToday: true,
|
||||
}),
|
||||
mixins: [BaseMixin],
|
||||
data () {
|
||||
const value = this.value || this.defaultValue
|
||||
|
@ -84,11 +89,11 @@ export default function createPicker (TheCalendar) {
|
|||
},
|
||||
|
||||
render () {
|
||||
const { sValue: value, showDate, $listeners } = this
|
||||
const { sValue: value, showDate, $listeners, $scopedSlots } = this
|
||||
const { panelChange = noop, focus = noop, blur = noop, ok = noop } = $listeners
|
||||
const props = getOptionProps(this)
|
||||
const { prefixCls, locale, localeCode } = props
|
||||
|
||||
const dateRender = props.dateRender || $scopedSlots.dateRender
|
||||
const placeholder = ('placeholder' in props)
|
||||
? props.placeholder : locale.lang.placeholder
|
||||
|
||||
|
@ -114,27 +119,33 @@ export default function createPicker (TheCalendar) {
|
|||
if ('mode' in props) {
|
||||
calendarProps.props.mode = props.mode
|
||||
}
|
||||
|
||||
const theCalendarProps = mergeProps(calendarProps, {
|
||||
props: {
|
||||
disabledDate: props.disabledDate,
|
||||
disabledTime,
|
||||
locale: locale.lang,
|
||||
timePicker: props.timePicker,
|
||||
defaultValue: props.defaultPickerValue || callMoment(moment),
|
||||
dateInputPlaceholder: placeholder,
|
||||
prefixCls,
|
||||
dateRender,
|
||||
format: props.format,
|
||||
showToday: props.showToday,
|
||||
monthCellContentRender: props.monthCellContentRender,
|
||||
renderFooter: this.renderFooter,
|
||||
value: showDate,
|
||||
},
|
||||
on: {
|
||||
ok: ok,
|
||||
panelChange: panelChange,
|
||||
change: this.handleCalendarChange,
|
||||
},
|
||||
class: calendarClassName,
|
||||
scopedSlots: $scopedSlots,
|
||||
})
|
||||
const calendar = (
|
||||
<TheCalendar
|
||||
{...calendarProps}
|
||||
disabledDate={props.disabledDate}
|
||||
disabledTime={disabledTime}
|
||||
locale={locale.lang}
|
||||
timePicker={props.timePicker}
|
||||
defaultValue={props.defaultPickerValue || callMoment(moment)}
|
||||
dateInputPlaceholder={placeholder}
|
||||
prefixCls={prefixCls}
|
||||
class={calendarClassName}
|
||||
onOk={ok}
|
||||
dateRender={props.dateRender}
|
||||
format={props.format}
|
||||
showToday={props.showToday}
|
||||
monthCellContentRender={props.monthCellContentRender}
|
||||
renderFooter={this.renderFooter}
|
||||
onPanelChange={panelChange}
|
||||
onChange={this.handleCalendarChange}
|
||||
value={showDate}
|
||||
{...theCalendarProps}
|
||||
/>
|
||||
)
|
||||
|
||||
|
@ -155,8 +166,6 @@ export default function createPicker (TheCalendar) {
|
|||
value={(inputValue && inputValue.format(props.format)) || ''}
|
||||
placeholder={placeholder}
|
||||
class={props.pickerInputClass}
|
||||
onFocus={focus}
|
||||
onBlur={blur}
|
||||
/>
|
||||
{clearIcon}
|
||||
<span class={`${prefixCls}-picker-icon`} />
|
||||
|
@ -179,8 +188,8 @@ export default function createPicker (TheCalendar) {
|
|||
return (
|
||||
<span
|
||||
class={props.pickerClass}
|
||||
// onFocus={focus}
|
||||
// onBlur={blur}
|
||||
onFocus={focus}
|
||||
onBlur={blur}
|
||||
>
|
||||
<VcDatePicker
|
||||
{...vcDatePickerProps}
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
---
|
||||
order: 0
|
||||
title:
|
||||
zh-CN: 基本
|
||||
en-US: Basic
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
<cn>
|
||||
#### 基本
|
||||
最简单的用法,在浮层中可以选择或者输入日期。
|
||||
</cn>
|
||||
|
||||
## en-US
|
||||
|
||||
<us>
|
||||
#### Basic
|
||||
Basic use case. Users can select or input a date in panel.
|
||||
</us>
|
||||
|
||||
````jsx
|
||||
import { DatePicker } from 'antd';
|
||||
const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
|
||||
|
||||
function onChange(date, dateString) {
|
||||
console.log(date, dateString);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
```html
|
||||
<template>
|
||||
<div>
|
||||
<DatePicker onChange={onChange} />
|
||||
<a-date-picker @change="onChange" />
|
||||
<br />
|
||||
<MonthPicker onChange={onChange} placeholder="Select month" />
|
||||
<a-month-picker @change="onChange" placeholder="Select month" />
|
||||
<br />
|
||||
<RangePicker onChange={onChange} />
|
||||
<a-range-picker @change="onChange" />
|
||||
<br />
|
||||
<WeekPicker onChange={onChange} placeholder="Select week" />
|
||||
<a-week-picker @change="onChange" placeholder="Select week" />
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
onChange(date, dateString) {
|
||||
console.log(date, dateString);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
|
|
|
@ -1,52 +1,52 @@
|
|||
---
|
||||
order: 12
|
||||
title:
|
||||
zh-CN: 定制日期单元格
|
||||
en-US: Customized Date Rendering
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
<cn>
|
||||
#### 定制日期单元格
|
||||
使用 `dateRender` 可以自定义日期单元格的内容和样式。
|
||||
</cn>
|
||||
|
||||
## en-US
|
||||
|
||||
<us>
|
||||
#### Customized Date Rendering
|
||||
We can customize the rendering of date cells in the calendar by providing a `dateRender` function to `DatePicker`.
|
||||
</us>
|
||||
|
||||
````jsx
|
||||
import { DatePicker } from 'antd';
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
ReactDOM.render(
|
||||
```html
|
||||
<template>
|
||||
<div>
|
||||
<DatePicker
|
||||
dateRender={(current) => {
|
||||
const style = {};
|
||||
if (current.date() === 1) {
|
||||
style.border = '1px solid #1890ff';
|
||||
style.borderRadius = '50%';
|
||||
}
|
||||
return (
|
||||
<div className="ant-calendar-date" style={style}>
|
||||
{current.date()}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<RangePicker
|
||||
dateRender={(current) => {
|
||||
const style = {};
|
||||
if (current.date() === 1) {
|
||||
style.border = '1px solid #1890ff';
|
||||
style.borderRadius = '50%';
|
||||
}
|
||||
return (
|
||||
<div className="ant-calendar-date" style={style}>
|
||||
{current.date()}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<a-date-picker>
|
||||
<template slot="dateRender" slot-scope="current, today">
|
||||
<div class="ant-calendar-date" :style="getCurrentStyle(current, today)">
|
||||
{{current.date()}}
|
||||
</div>
|
||||
</tempalte>
|
||||
</a-date-picker>
|
||||
<a-range-picker>
|
||||
<template slot="dateRender" slot-scope="current">
|
||||
<div class="ant-calendar-date" :style="getCurrentStyle(current)">
|
||||
{{current.date()}}
|
||||
</div>
|
||||
</tempalte>
|
||||
</a-range-picker>
|
||||
<a-week-picker>
|
||||
<template slot="dateRender" slot-scope="current">
|
||||
<div class="ant-calendar-date" :style="getCurrentStyle(current)">
|
||||
{{current.date()}}
|
||||
</div>
|
||||
</tempalte>
|
||||
</a-week-picker>
|
||||
</div>
|
||||
, mountNode);
|
||||
````
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
getCurrentStyle(current, today) {
|
||||
const style = {};
|
||||
if (current.date() === 1) {
|
||||
style.border = '1px solid #1890ff';
|
||||
style.borderRadius = '50%';
|
||||
}
|
||||
return style
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
|
|
@ -1,80 +1,78 @@
|
|||
---
|
||||
order: 6
|
||||
title:
|
||||
zh-CN: 不可选择日期和时间
|
||||
en-US: Disabled Date & Time
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
<cn>
|
||||
#### 不可选择日期和时间
|
||||
可用 `disabledDate` 和 `disabledTime` 分别禁止选择部分日期和时间,其中 `disabledTime` 需要和 `showTime` 一起使用。
|
||||
</cn>
|
||||
|
||||
## en-US
|
||||
|
||||
<us>
|
||||
#### Disabled Date & Time
|
||||
Disabled part of dates and time by `disabledDate` and `disabledTime` respectively, and `disabledTime` only works with `showTime`.
|
||||
</us>
|
||||
|
||||
````jsx
|
||||
import moment from 'moment';
|
||||
import { DatePicker } from 'antd';
|
||||
const { MonthPicker, RangePicker } = DatePicker;
|
||||
|
||||
function range(start, end) {
|
||||
const result = [];
|
||||
for (let i = start; i < end; i++) {
|
||||
result.push(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function disabledDate(current) {
|
||||
// Can not select days before today and today
|
||||
return current && current < moment().endOf('day');
|
||||
}
|
||||
|
||||
function disabledDateTime() {
|
||||
return {
|
||||
disabledHours: () => range(0, 24).splice(4, 20),
|
||||
disabledMinutes: () => range(30, 60),
|
||||
disabledSeconds: () => [55, 56],
|
||||
};
|
||||
}
|
||||
|
||||
function disabledRangeTime(_, type) {
|
||||
if (type === 'start') {
|
||||
return {
|
||||
disabledHours: () => range(0, 60).splice(4, 20),
|
||||
disabledMinutes: () => range(30, 60),
|
||||
disabledSeconds: () => [55, 56],
|
||||
};
|
||||
}
|
||||
return {
|
||||
disabledHours: () => range(0, 60).splice(20, 4),
|
||||
disabledMinutes: () => range(0, 31),
|
||||
disabledSeconds: () => [55, 56],
|
||||
};
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
```html
|
||||
<template>
|
||||
<div>
|
||||
<DatePicker
|
||||
<a-date-picker
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
disabledDate={disabledDate}
|
||||
disabledTime={disabledDateTime}
|
||||
showTime={{ defaultValue: moment('00:00:00', 'HH:mm:ss') }}
|
||||
:disabledDate="disabledDate"
|
||||
:disabledTime="disabledDateTime"
|
||||
:showTime="{ defaultValue: moment('00:00:00', 'HH:mm:ss') }"
|
||||
/>
|
||||
<br />
|
||||
<MonthPicker disabledDate={disabledDate} placeholder="Select month" />
|
||||
<a-month-picker :disabledDate="disabledDate" placeholder="Select month" />
|
||||
<br />
|
||||
<RangePicker
|
||||
disabledDate={disabledDate}
|
||||
disabledTime={disabledRangeTime}
|
||||
showTime={{
|
||||
hideDisabledOptions: true,
|
||||
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('11:59:59', 'HH:mm:ss')],
|
||||
}}
|
||||
<a-range-picker
|
||||
:disabledDate="disabledDate"
|
||||
:disabledTime="disabledRangeTime"
|
||||
:showTime="{
|
||||
hideDisabledOptions: true,
|
||||
defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('11:59:59', 'HH:mm:ss')]
|
||||
}"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</div>,
|
||||
mountNode
|
||||
);
|
||||
````
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
export default {
|
||||
methods: {
|
||||
moment,
|
||||
range(start, end) {
|
||||
const result = [];
|
||||
for (let i = start; i < end; i++) {
|
||||
result.push(i);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
disabledDate(current) {
|
||||
// Can not select days before today and today
|
||||
return current && current < moment().endOf('day');
|
||||
},
|
||||
|
||||
disabledDateTime() {
|
||||
return {
|
||||
disabledHours: () => this.range(0, 24).splice(4, 20),
|
||||
disabledMinutes: () => this.range(30, 60),
|
||||
disabledSeconds: () => [55, 56],
|
||||
};
|
||||
},
|
||||
|
||||
disabledRangeTime(_, type) {
|
||||
if (type === 'start') {
|
||||
return {
|
||||
disabledHours: () => this.range(0, 60).splice(4, 20),
|
||||
disabledMinutes: () => this.range(30, 60),
|
||||
disabledSeconds: () => [55, 56],
|
||||
};
|
||||
}
|
||||
return {
|
||||
disabledHours: () => this.range(0, 60).splice(20, 4),
|
||||
disabledMinutes: () => this.range(0, 31),
|
||||
disabledSeconds: () => [55, 56],
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
|
|
@ -6,9 +6,9 @@ import RangePicker from './RangePicker'
|
|||
import WeekPicker from './WeekPicker'
|
||||
import { DatePickerProps, MonthPickerProps, WeexPickerProps, RangePickerProps } from './interface'
|
||||
|
||||
const DatePicker = wrapPicker(createPicker(VcCalendar), DatePickerProps())
|
||||
const DatePicker = wrapPicker(createPicker(VcCalendar, DatePickerProps()), DatePickerProps())
|
||||
|
||||
const MonthPicker = wrapPicker(createPicker(MonthCalendar), MonthPickerProps(), 'YYYY-MM')
|
||||
const MonthPicker = wrapPicker(createPicker(MonthCalendar, MonthPickerProps()), MonthPickerProps(), 'YYYY-MM')
|
||||
|
||||
Object.assign(DatePicker, {
|
||||
RangePicker: wrapPicker(RangePicker, RangePickerProps()),
|
||||
|
|
|
@ -5,25 +5,31 @@ import PropTypes from '../_util/vue-types'
|
|||
export const MomentType = {
|
||||
type: Object,
|
||||
validator: function (value) {
|
||||
return moment.isMoment(value)
|
||||
return value === undefined || moment.isMoment(value)
|
||||
},
|
||||
}
|
||||
|
||||
export const PickerProps = () => ({
|
||||
transitionName: PropTypes.string,
|
||||
prefixCls: PropTypes.string,
|
||||
inputPrefixCls: PropTypes.string,
|
||||
format: PropTypes.string,
|
||||
disabled: PropTypes.boolean,
|
||||
allowClear: PropTypes.boolean,
|
||||
disabled: PropTypes.bool,
|
||||
allowClear: PropTypes.bool,
|
||||
popupStyle: PropTypes.object,
|
||||
locale: PropTypes.any,
|
||||
localeCode: PropTypes.string,
|
||||
size: PropTypes.oneOf(['large', 'small', 'default']),
|
||||
getCalendarContainer: PropTypes.func,
|
||||
open: PropTypes.boolean,
|
||||
// onOpenChange: PropTypes.(status: boolean) => void,
|
||||
open: PropTypes.bool,
|
||||
// onOpenChange: PropTypes.(status: bool) => void,
|
||||
disabledDate: PropTypes.func,
|
||||
renderExtraFooter: PropTypes.any,
|
||||
showToday: PropTypes.bool,
|
||||
dateRender: PropTypes.any, // (current: moment.Moment, today: moment.Moment) => React.ReactNode,
|
||||
pickerClass: PropTypes.string,
|
||||
pickerInputClass: PropTypes.string,
|
||||
timePicker: PropTypes.any,
|
||||
})
|
||||
|
||||
export const SinglePickerProps = () => ({
|
||||
|
@ -36,10 +42,9 @@ export const SinglePickerProps = () => ({
|
|||
export const DatePickerProps = () => ({
|
||||
...PickerProps(), ...SinglePickerProps(),
|
||||
showTime: PropTypes.oneOfType([PropTypes.shape(TimePickerProps()).loose, PropTypes.bool]),
|
||||
showToday: PropTypes.bool,
|
||||
open: PropTypes.bool,
|
||||
disabledTime: PropTypes.func,
|
||||
// onOpenChange?: (status: boolean) => void;
|
||||
// onOpenChange?: (status: bool) => void;
|
||||
// onOk?: (selectedTime: moment.Moment) => void;
|
||||
placeholder: PropTypes.string,
|
||||
})
|
||||
|
@ -47,9 +52,10 @@ export const DatePickerProps = () => ({
|
|||
export const MonthPickerProps = () => ({
|
||||
...PickerProps(), ...SinglePickerProps(),
|
||||
placeholder: PropTypes.string,
|
||||
monthCellContentRender: PropTypes.func,
|
||||
})
|
||||
|
||||
export const RangePickerValue = PropTypes.arrayOf(PropTypes.oneOfType([undefined, MomentType]))
|
||||
export const RangePickerValue = PropTypes.arrayOf(MomentType)
|
||||
export const RangePickerPresetRange = PropTypes.oneOfType([RangePickerValue, PropTypes.func])
|
||||
|
||||
export const RangePickerProps = () => ({
|
||||
|
@ -62,9 +68,10 @@ export const RangePickerProps = () => ({
|
|||
// onOk?: (selectedTime: moment.Moment) => void;
|
||||
showTime: PropTypes.oneOfType([PropTypes.shape(TimePickerProps()).loose, PropTypes.bool]),
|
||||
ranges: PropTypes.objectOf(String),
|
||||
placeholder: PropTypes.oneOfType(String),
|
||||
mode: PropTypes.oneOfType([PropTypes.string, PropTypes.oneOfType(String)]),
|
||||
placeholder: PropTypes.arrayOf(String),
|
||||
mode: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(String)]),
|
||||
disabledTime: PropTypes.func,
|
||||
showToday: PropTypes.bool,
|
||||
// onPanelChange?: (value?: RangePickerValue, mode?: string | string[]) => void;
|
||||
})
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
import TimePickerPanel from '../vc-time-picker/src/Panel'
|
||||
import TimePickerPanel from '../vc-time-picker/Panel'
|
||||
import classNames from 'classnames'
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver'
|
||||
import { generateShowHourMinuteSecond } from '../time-picker'
|
||||
import enUS from './locale/en_US'
|
||||
import { getOptionProps } from '../_util/props-util'
|
||||
import { getOptionProps, initDefaultProps } from '../_util/props-util'
|
||||
|
||||
function getColumns ({ showHour, showMinute, showSecond, use12Hours }) {
|
||||
let column = 0
|
||||
|
@ -25,23 +25,14 @@ function getColumns ({ showHour, showMinute, showSecond, use12Hours }) {
|
|||
|
||||
export default function wrapPicker (Picker, props, defaultFormat) {
|
||||
return {
|
||||
props: {
|
||||
|
||||
},
|
||||
// static defaultProps = {
|
||||
// format: defaultFormat || 'YYYY-MM-DD',
|
||||
// transitionName: 'slide-up',
|
||||
// popupStyle: {},
|
||||
// onChange() {
|
||||
// },
|
||||
// onOk() {
|
||||
// },
|
||||
// onOpenChange() {
|
||||
// },
|
||||
// locale: {},
|
||||
// prefixCls: 'ant-calendar',
|
||||
// inputPrefixCls: 'ant-input',
|
||||
// };
|
||||
props: initDefaultProps(props, {
|
||||
format: defaultFormat || 'YYYY-MM-DD',
|
||||
transitionName: 'slide-up',
|
||||
popupStyle: {},
|
||||
locale: {},
|
||||
prefixCls: 'ant-calendar',
|
||||
inputPrefixCls: 'ant-input',
|
||||
}),
|
||||
|
||||
mounted () {
|
||||
const { autoFocus, disabled } = this
|
||||
|
@ -135,7 +126,7 @@ export default function wrapPicker (Picker, props, defaultFormat) {
|
|||
blur: this.handleBlur,
|
||||
},
|
||||
ref: 'picker',
|
||||
|
||||
scopedSlots: this.$scopedSlots || {},
|
||||
}
|
||||
return (
|
||||
<Picker
|
||||
|
|
|
@ -104,3 +104,7 @@ const { Step } = Steps
|
|||
export { Steps, Step }
|
||||
|
||||
export { default as Calendar } from './calendar'
|
||||
|
||||
import DatePicker from './date-picker'
|
||||
const { MonthPicker, RangePicker, WeekPicker } = DatePicker
|
||||
export { DatePicker, MonthPicker, RangePicker, WeekPicker }
|
||||
|
|
|
@ -33,3 +33,4 @@ import './time-picker/style'
|
|||
import './steps/style'
|
||||
import './breadcrumb/style'
|
||||
import './calendar/style'
|
||||
import './date-picker/style'
|
||||
|
|
|
@ -19,11 +19,18 @@ export function generateShowHourMinuteSecond (format) {
|
|||
showSecond: format.indexOf('s') > -1,
|
||||
}
|
||||
}
|
||||
|
||||
function isMoment (value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.length === 0 || !!value.find((val) => val === undefined || moment.isMoment(val))
|
||||
} else {
|
||||
return value === undefined || moment.isMoment(value)
|
||||
}
|
||||
}
|
||||
const MomentType = PropTypes.custom(isMoment)
|
||||
export const TimePickerProps = () => ({
|
||||
size: PropTypes.oneOf(['large', 'default', 'small']),
|
||||
value: PropTypes.object,
|
||||
defaultValue: PropTypes.object,
|
||||
value: MomentType,
|
||||
defaultValue: MomentType,
|
||||
open: PropTypes.bool,
|
||||
format: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
|
|
|
@ -4,6 +4,7 @@ import BaseMixin from '@/components/_util/BaseMixin'
|
|||
import { getOptionProps, hasProp } from '@/components/_util/props-util'
|
||||
import { cloneElement } from '@/components/_util/vnode'
|
||||
import KeyCode from '@/components/_util/KeyCode'
|
||||
import * as moment from 'moment'
|
||||
import DateTable from './date/DateTable'
|
||||
import CalendarHeader from './calendar/CalendarHeader'
|
||||
import CalendarFooter from './calendar/CalendarFooter'
|
||||
|
@ -46,15 +47,24 @@ function goDay (direction) {
|
|||
return goTime.call(this, direction, 'days')
|
||||
}
|
||||
|
||||
function isMoment (value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.length === 0 || !!value.find((val) => val === undefined || moment.isMoment(val))
|
||||
} else {
|
||||
return value === undefined || moment.isMoment(value)
|
||||
}
|
||||
}
|
||||
const MomentType = PropTypes.custom(isMoment)
|
||||
const Calendar = {
|
||||
props: {
|
||||
locale: PropTypes.object.def(enUs),
|
||||
format: PropTypes.string,
|
||||
visible: PropTypes.bool.def(true),
|
||||
prefixCls: PropTypes.string.def('rc-calendar'),
|
||||
// prefixCls: PropTypes.string,
|
||||
defaultValue: PropTypes.object,
|
||||
value: PropTypes.object,
|
||||
selectedValue: PropTypes.object,
|
||||
defaultValue: MomentType,
|
||||
value: MomentType,
|
||||
selectedValue: MomentType,
|
||||
mode: PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade']),
|
||||
// locale: PropTypes.object,
|
||||
showDateInput: PropTypes.bool.def(true),
|
||||
|
@ -73,6 +83,7 @@ const Calendar = {
|
|||
disabledTime: PropTypes.any,
|
||||
renderFooter: PropTypes.func.def(() => null),
|
||||
renderSidebar: PropTypes.func.def(() => null),
|
||||
dateRender: PropTypes.func,
|
||||
},
|
||||
|
||||
mixins: [BaseMixin, CommonMixin, CalendarMixin],
|
||||
|
@ -219,7 +230,6 @@ const Calendar = {
|
|||
let timePickerEle = null
|
||||
|
||||
if (timePicker && showTimePicker) {
|
||||
console.log(timePicker)
|
||||
const timePickerOriginProps = getOptionProps(timePicker)
|
||||
const timePickerProps = {
|
||||
props: {
|
||||
|
@ -239,7 +249,6 @@ const Calendar = {
|
|||
if (timePickerOriginProps.defaultValue !== undefined) {
|
||||
timePickerProps.props.defaultOpenValue = timePickerOriginProps.defaultValue
|
||||
}
|
||||
console.log(timePickerProps)
|
||||
timePickerEle = cloneElement(timePicker, timePickerProps)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import enUs from './locale/en_US'
|
|||
const FullCalendar = {
|
||||
props: {
|
||||
locale: PropTypes.object.def(enUs),
|
||||
format: PropTypes.string,
|
||||
visible: PropTypes.bool.def(true),
|
||||
prefixCls: PropTypes.string.def('rc-calendar'),
|
||||
defaultType: PropTypes.string.def('date'),
|
||||
|
|
|
@ -10,6 +10,7 @@ import enUs from './locale/en_US'
|
|||
const MonthCalendar = {
|
||||
props: {
|
||||
locale: PropTypes.object.def(enUs),
|
||||
format: PropTypes.string,
|
||||
visible: PropTypes.bool.def(true),
|
||||
prefixCls: PropTypes.string.def('rc-calendar'),
|
||||
monthCellRender: PropTypes.func,
|
||||
|
@ -80,8 +81,11 @@ const MonthCalendar = {
|
|||
},
|
||||
|
||||
render () {
|
||||
const { mode, sValue: value, $props: props } = this
|
||||
const { prefixCls, locale, disabledDate, monthCellRender, monthCellContentRender, renderFooter } = props
|
||||
const { mode, sValue: value, $props: props, $scopedSlots } = this
|
||||
const { prefixCls, locale, disabledDate } = props
|
||||
const monthCellRender = this.monthCellRender || $scopedSlots.monthCellRender
|
||||
const monthCellContentRender = this.monthCellContentRender || $scopedSlots.monthCellContentRender
|
||||
const renderFooter = this.renderFooter || $scopedSlots.renderFooter
|
||||
const children = (
|
||||
<div class={`${prefixCls}-month-calendar-content`}>
|
||||
<div class={`${prefixCls}-month-header-wrap`}>
|
||||
|
|
|
@ -7,12 +7,22 @@ import createChainedFunction from '@/components/_util/createChainedFunction'
|
|||
import KeyCode from '@/components/_util/KeyCode'
|
||||
import placements from './picker/placements'
|
||||
import Trigger from '@/components/trigger'
|
||||
|
||||
import moment from 'moment'
|
||||
import { setTimeout } from 'timers'
|
||||
function isMoment (value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.length === 0 || !!value.find((val) => val === undefined || moment.isMoment(val))
|
||||
} else {
|
||||
return value === undefined || moment.isMoment(value)
|
||||
}
|
||||
}
|
||||
const MomentType = PropTypes.custom(isMoment)
|
||||
const Picker = {
|
||||
props: {
|
||||
animation: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
|
||||
disabled: PropTypes.bool,
|
||||
transitionName: PropTypes.string,
|
||||
format: PropTypes.string,
|
||||
// onChange: PropTypes.func,
|
||||
// onOpenChange: PropTypes.func,
|
||||
children: PropTypes.func,
|
||||
|
@ -23,12 +33,12 @@ const Picker = {
|
|||
prefixCls: PropTypes.string.def('rc-calendar-picker'),
|
||||
placement: PropTypes.any.def('bottomLeft'),
|
||||
value: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.array,
|
||||
MomentType,
|
||||
PropTypes.arrayOf(MomentType),
|
||||
]),
|
||||
defaultValue: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.array,
|
||||
MomentType,
|
||||
PropTypes.arrayOf(MomentType),
|
||||
]),
|
||||
align: PropTypes.object.def({}),
|
||||
},
|
||||
|
@ -136,7 +146,6 @@ const Picker = {
|
|||
select: createChainedFunction(calendarEvents.select, this.onCalendarSelect),
|
||||
clear: createChainedFunction(calendarEvents.clear, this.onCalendarClear),
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
return cloneElement(props.calendar, extraProps)
|
||||
|
@ -168,8 +177,8 @@ const Picker = {
|
|||
},
|
||||
|
||||
focusCalendar () {
|
||||
if (this.sOpen && !!this.$refs.calendarInstance) {
|
||||
this.$refs.calendarInstance.focus()
|
||||
if (this.sOpen && this.calendarInstance && this.calendarInstance.context) {
|
||||
this.calendarInstance.context.focus()
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -191,6 +200,10 @@ const Picker = {
|
|||
value: sValue,
|
||||
open: sOpen,
|
||||
}
|
||||
if (this.sOpen || !this.calendarInstance) {
|
||||
this.calendarInstance = this.getCalendarElement()
|
||||
}
|
||||
|
||||
return (<Trigger
|
||||
popupAlign={align}
|
||||
builtinPlacements={placements}
|
||||
|
@ -207,7 +220,7 @@ const Picker = {
|
|||
popupClassName={dropdownClassName}
|
||||
>
|
||||
<template slot='popup'>
|
||||
{this.getCalendarElement()}
|
||||
{this.calendarInstance}
|
||||
</template>
|
||||
{cloneElement(children(childrenState, props), { on: { keydown: this.onKeyDown }})}
|
||||
</Trigger>)
|
||||
|
|
|
@ -102,6 +102,7 @@ const RangeCalendar = {
|
|||
disabledTime: PropTypes.func.def(noop),
|
||||
renderFooter: PropTypes.func.def(() => null),
|
||||
renderSidebar: PropTypes.func.def(() => null),
|
||||
dateRender: PropTypes.func,
|
||||
},
|
||||
|
||||
mixins: [BaseMixin, CommonMixin],
|
||||
|
@ -123,7 +124,7 @@ const RangeCalendar = {
|
|||
watch: {
|
||||
value (val) {
|
||||
const newState = {}
|
||||
newState.sValue = normalizeAnchor(val, 0)
|
||||
newState.sValue = normalizeAnchor(this.$props, 0)
|
||||
this.setState(newState)
|
||||
},
|
||||
hoverValue (val) {
|
||||
|
@ -258,25 +259,25 @@ const RangeCalendar = {
|
|||
onStartPanelChange (value, mode) {
|
||||
const { sMode, sValue } = this
|
||||
const newMode = [mode, sMode[1]]
|
||||
const newValue = [value || sValue[0], sValue[1]]
|
||||
this.__emit('panelChange', newValue, newMode)
|
||||
if (!hasProp(this, 'mode')) {
|
||||
this.setState({
|
||||
sMode: newMode,
|
||||
})
|
||||
}
|
||||
const newValue = [value || sValue[0], sValue[1]]
|
||||
this.__emit('panelChange', newValue, newMode)
|
||||
},
|
||||
|
||||
onEndPanelChange (value, mode) {
|
||||
const { sMode, sValue } = this
|
||||
const newMode = [sMode[0], mode]
|
||||
const newValue = [sValue[0], value || sValue[1]]
|
||||
this.__emit('panelChange', newValue, newMode)
|
||||
if (!hasProp(this, 'mode')) {
|
||||
this.setState({
|
||||
sMode: newMode,
|
||||
})
|
||||
}
|
||||
const newValue = [sValue[0], value || sValue[1]]
|
||||
this.__emit('panelChange', newValue, newMode)
|
||||
},
|
||||
|
||||
getStartValue () {
|
||||
|
@ -378,20 +379,13 @@ const RangeCalendar = {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasProp(this, 'selectedValue')) {
|
||||
this.setState({
|
||||
sSelectedValue: selectedValue,
|
||||
})
|
||||
}
|
||||
|
||||
// 尚未选择过时间,直接输入的话
|
||||
if (!this.sSelectedValue[0] || !this.sSelectedValue[1]) {
|
||||
const startValue = selectedValue[0] || moment()
|
||||
const endValue = selectedValue[1] || startValue.clone().add(1, 'months')
|
||||
this.setState({
|
||||
sSelectedValue: selectedValue,
|
||||
sValue: getValueFromSelectedValue([startValue, endValue]),
|
||||
sValue: selectedValue && selectedValue.length === 2 ? getValueFromSelectedValue([startValue, endValue]) : this.sValue,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -408,6 +402,11 @@ const RangeCalendar = {
|
|||
this.fireHoverValueChange([])
|
||||
this.__emit('select', selectedValue)
|
||||
}
|
||||
if (!hasProp(this, 'selectedValue')) {
|
||||
this.setState({
|
||||
sSelectedValue: selectedValue,
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
fireValueChange (value) {
|
||||
|
@ -606,7 +605,7 @@ const RangeCalendar = {
|
|||
|
||||
return (
|
||||
<div
|
||||
ref={this.saveRoot}
|
||||
ref='rootInstance'
|
||||
class={className}
|
||||
tabIndex='0'
|
||||
>
|
||||
|
|
|
@ -35,6 +35,8 @@ const CalendarHeader = {
|
|||
enableNext: PropTypes.any.def(1),
|
||||
disabledMonth: PropTypes.func,
|
||||
mode: PropTypes.any,
|
||||
monthCellRender: PropTypes.func,
|
||||
monthCellContentRender: PropTypes.func,
|
||||
},
|
||||
data () {
|
||||
this.nextMonth = goMonth.bind(this, 1)
|
||||
|
|
|
@ -17,13 +17,19 @@ function getNowByCurrentStateValue (value) {
|
|||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
function isMoment (value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.length === 0 || !!value.find((val) => val === undefined || moment.isMoment(val))
|
||||
} else {
|
||||
return value === undefined || moment.isMoment(value)
|
||||
}
|
||||
}
|
||||
const MomentType = PropTypes.custom(isMoment)
|
||||
const CalendarMixin = {
|
||||
mixins: [BaseMixin],
|
||||
props: {
|
||||
value: PropTypes.object,
|
||||
defaultValue: PropTypes.object,
|
||||
// onKeyDown: PropTypes.func,
|
||||
value: MomentType,
|
||||
defaultValue: MomentType,
|
||||
},
|
||||
|
||||
data () {
|
||||
|
@ -65,7 +71,6 @@ const CalendarMixin = {
|
|||
// [props.className]: !!props.className,
|
||||
[newProps.class]: !!newProps.class,
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref='rootInstance'
|
||||
|
|
|
@ -25,10 +25,12 @@ const CalendarPart = {
|
|||
disabledDate: PropTypes.any,
|
||||
timePicker: PropTypes.any,
|
||||
disabledTime: PropTypes.any,
|
||||
mode: PropTypes.any,
|
||||
// onInputSelect: PropTypes.func,
|
||||
timePickerDisabledTime: PropTypes.object,
|
||||
enableNext: PropTypes.any,
|
||||
enablePrev: PropTypes.any,
|
||||
dateRender: PropTypes.func,
|
||||
},
|
||||
render () {
|
||||
const { $props: props, $listeners = {}} = this
|
||||
|
@ -62,9 +64,10 @@ const CalendarPart = {
|
|||
showTimePicker,
|
||||
}
|
||||
const index = direction === 'left' ? 0 : 1
|
||||
const timePickerProps = getOptionProps(timePicker)
|
||||
const timePickerEle = shouldShowTimePicker &&
|
||||
cloneElement(timePicker, {
|
||||
let timePickerEle = null
|
||||
if (shouldShowTimePicker) {
|
||||
const timePickerProps = getOptionProps(timePicker)
|
||||
timePickerEle = cloneElement(timePicker, {
|
||||
props: {
|
||||
showHour: true,
|
||||
showMinute: true,
|
||||
|
@ -80,6 +83,7 @@ const CalendarPart = {
|
|||
},
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
const dateInputElement = showDateInput &&
|
||||
<DateInput
|
||||
|
|
|
@ -28,8 +28,8 @@ const Panel = {
|
|||
return moment()
|
||||
},
|
||||
},
|
||||
value: PropTypes.object,
|
||||
defaultValue: PropTypes.object,
|
||||
value: PropTypes.any,
|
||||
defaultValue: PropTypes.any,
|
||||
placeholder: PropTypes.string,
|
||||
format: PropTypes.string,
|
||||
inputReadOnly: PropTypes.bool.def(false),
|
||||
|
|
|
@ -3,7 +3,7 @@ const AsyncComp = () => {
|
|||
const hashs = window.location.hash.split('/')
|
||||
const d = hashs[hashs.length - 1]
|
||||
return {
|
||||
component: import(`../components/calendar/demo/${d}`),
|
||||
component: import(`../components/date-picker/demo/${d}`),
|
||||
}
|
||||
}
|
||||
export default [
|
||||
|
|
Loading…
Reference in New Issue