feat: update date-picker

pull/2682/head
tanjinzhou 2020-07-22 17:47:08 +08:00
parent 88d3fc18c6
commit a3a53613c5
14 changed files with 256 additions and 308 deletions

View File

@ -1,20 +1,22 @@
import CalendarOutlined from '@ant-design/icons-vue/CalendarOutlined'; import CalendarOutlined from '@ant-design/icons-vue/CalendarOutlined';
import { isValidElement } from '../_util/props-util'; import { isValidElement } from '../_util/props-util';
import { cloneElement } from '../_util/vnode'; import { cloneElement } from '../_util/vnode';
import classNames from 'classnames';
export default { const InputIcon = (_, { attrs }) => {
functional: true, const { suffixIcon, prefixCls } = attrs;
render(h, context) { return (
const { props } = context; (suffixIcon && isValidElement(suffixIcon) ? (
const { suffixIcon, prefixCls } = props; cloneElement(suffixIcon, {
return ( class: classNames({
(suffixIcon && isValidElement(suffixIcon) ? ( [suffixIcon.props?.class]: suffixIcon.props.class,
cloneElement(suffixIcon, { [`${prefixCls}-picker-icon`]: true,
class: `${prefixCls}-picker-icon`, }),
}) })
) : ( ) : (
<span class={`${prefixCls}-picker-icon`}>{suffixIcon}</span> <span class={`${prefixCls}-picker-icon`}>{suffixIcon}</span>
)) || <CalendarOutlined class={`${prefixCls}-picker-icon`} /> )) || <CalendarOutlined class={`${prefixCls}-picker-icon`} />
); );
},
}; };
InputIcon.inheritAttrs = false;
export default InputIcon;

View File

@ -1,3 +1,4 @@
import { inject } from 'vue';
import * as moment from 'moment'; import * as moment from 'moment';
import RangeCalendar from '../vc-calendar/src/RangeCalendar'; import RangeCalendar from '../vc-calendar/src/RangeCalendar';
import VcDatePicker from '../vc-calendar/src/Picker'; import VcDatePicker from '../vc-calendar/src/Picker';
@ -8,19 +9,11 @@ import Tag from '../tag';
import { ConfigConsumerProps } from '../config-provider'; import { ConfigConsumerProps } from '../config-provider';
import interopDefault from '../_util/interopDefault'; import interopDefault from '../_util/interopDefault';
import { RangePickerProps } from './interface'; import { RangePickerProps } from './interface';
import { import { hasProp, getOptionProps, initDefaultProps, getComponent } from '../_util/props-util';
hasProp,
getOptionProps,
initDefaultProps,
mergeProps,
getComponent,
getListeners,
} from '../_util/props-util';
import BaseMixin from '../_util/BaseMixin'; import BaseMixin from '../_util/BaseMixin';
import { formatDate } from './utils'; import { formatDate } from './utils';
import InputIcon from './InputIcon'; import InputIcon from './InputIcon';
function noop() {}
function getShowDateFromValue(value, mode) { function getShowDateFromValue(value, mode) {
const [start, end] = value; const [start, end] = value;
// value could be an empty array, then we should not reset showDate // value could be an empty array, then we should not reset showDate
@ -70,17 +63,16 @@ function fixLocale(value, localeCode) {
export default { export default {
name: 'ARangePicker', name: 'ARangePicker',
mixins: [BaseMixin], mixins: [BaseMixin],
model: { inheritAttrs: false,
prop: 'value',
event: 'change',
},
props: initDefaultProps(RangePickerProps(), { props: initDefaultProps(RangePickerProps(), {
allowClear: true, allowClear: true,
showToday: false, showToday: false,
separator: '~', separator: '~',
}), }),
inject: { setup() {
configProvider: { default: () => ConfigConsumerProps }, return {
configProvider: inject('configProvider', ConfigConsumerProps),
};
}, },
data() { data() {
const value = this.value || this.defaultValue || []; const value = this.value || this.defaultValue || [];
@ -133,6 +125,10 @@ export default {
this.setState({ sOpen: false }); this.setState({ sOpen: false });
} }
}, },
savePicker(node) {
this.picker = node;
},
clearSelection(e) { clearSelection(e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@ -212,18 +208,17 @@ export default {
}, },
focus() { focus() {
this.$refs.picker.focus(); this.picker.focus();
}, },
blur() { blur() {
this.$refs.picker.blur(); this.picker.blur();
}, },
renderFooter() { renderFooter() {
const { ranges, $scopedSlots, $slots } = this; const { ranges, $slots } = this;
const { _prefixCls: prefixCls, _tagPrefixCls: tagPrefixCls } = this; const { _prefixCls: prefixCls, _tagPrefixCls: tagPrefixCls } = this;
const renderExtraFooter = const renderExtraFooter = this.renderExtraFooter || $slots.renderExtraFooter;
this.renderExtraFooter || $scopedSlots.renderExtraFooter || $slots.renderExtraFooter;
if (!ranges && !renderExtraFooter) { if (!ranges && !renderExtraFooter) {
return null; return null;
} }
@ -261,7 +256,7 @@ export default {
}, },
render() { render() {
const props = getOptionProps(this); const props = { ...getOptionProps(this), ...this.$attrs };
let suffixIcon = getComponent(this, 'suffixIcon'); let suffixIcon = getComponent(this, 'suffixIcon');
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon; suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
const { const {
@ -269,16 +264,8 @@ export default {
sShowDate: showDate, sShowDate: showDate,
sHoverValue: hoverValue, sHoverValue: hoverValue,
sOpen: open, sOpen: open,
$scopedSlots, $slots,
} = this; } = this;
const listeners = getListeners(this);
const {
calendarChange = noop,
ok = noop,
focus = noop,
blur = noop,
panelChange = noop,
} = listeners;
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
tagPrefixCls: customizeTagPrefixCls, tagPrefixCls: customizeTagPrefixCls,
@ -293,6 +280,12 @@ export default {
format, format,
separator, separator,
inputReadOnly, inputReadOnly,
style,
onCalendarChange,
onOk,
onBlur,
onFocus,
onPanelChange,
} = props; } = props;
const getPrefixCls = this.configProvider.getPrefixCls; const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('calendar', customizePrefixCls); const prefixCls = getPrefixCls('calendar', customizePrefixCls);
@ -300,7 +293,7 @@ export default {
this._prefixCls = prefixCls; this._prefixCls = prefixCls;
this._tagPrefixCls = tagPrefixCls; this._tagPrefixCls = tagPrefixCls;
const dateRender = props.dateRender || $scopedSlots.dateRender; const dateRender = props.dateRender || $slots.dateRender;
fixLocale(value, localeCode); fixLocale(value, localeCode);
fixLocale(showDate, localeCode); fixLocale(showDate, localeCode);
@ -311,23 +304,18 @@ export default {
// ok onChange // ok onChange
const pickerChangeHandler = { const pickerChangeHandler = {
on: { onChange: this.handleChange,
change: this.handleChange,
},
}; };
let calendarProps = { let calendarProps = {
on: { onOk: this.handleChange,
ok: this.handleChange,
},
props: {},
}; };
if (props.timePicker) { if (props.timePicker) {
pickerChangeHandler.on.change = changedValue => this.handleChange(changedValue); pickerChangeHandler.onChange = changedValue => this.handleChange(changedValue);
} else { } else {
calendarProps = { on: {}, props: {} }; calendarProps = {};
} }
if ('mode' in props) { if ('mode' in props) {
calendarProps.props.mode = props.mode; calendarProps.mode = props.mode;
} }
const startPlaceholder = Array.isArray(props.placeholder) const startPlaceholder = Array.isArray(props.placeholder)
@ -337,35 +325,31 @@ export default {
? props.placeholder[1] ? props.placeholder[1]
: locale.lang.rangePlaceholder[1]; : locale.lang.rangePlaceholder[1];
const rangeCalendarProps = mergeProps(calendarProps, { const rangeCalendarProps = {
props: { ...calendarProps,
separator, separator,
format, format,
prefixCls, prefixCls,
renderFooter: this.renderFooter, renderFooter: this.renderFooter,
timePicker: props.timePicker, timePicker: props.timePicker,
disabledDate, disabledDate,
disabledTime, disabledTime,
dateInputPlaceholder: [startPlaceholder, endPlaceholder], dateInputPlaceholder: [startPlaceholder, endPlaceholder],
locale: locale.lang, locale: locale.lang,
dateRender, dateRender,
value: showDate, value: showDate,
hoverValue, hoverValue,
showToday, showToday,
inputReadOnly, inputReadOnly,
}, onChange: onCalendarChange,
on: { onOk,
change: calendarChange, onValueChange: this.handleShowDateChange,
ok, onHoverChange: this.handleHoverChange,
valueChange: this.handleShowDateChange, onPanelChange,
hoverChange: this.handleHoverChange, onInputSelect: this.handleCalendarInputSelect,
panelChange,
inputSelect: this.handleCalendarInputSelect,
},
class: calendarClassName, class: calendarClassName,
scopedSlots: $scopedSlots, };
}); const calendar = <RangeCalendar {...rangeCalendarProps} vSlots={$slots} />;
const calendar = <RangeCalendar {...rangeCalendarProps} />;
// default width for showTime // default width for showTime
const pickerStyle = {}; const pickerStyle = {};
@ -406,38 +390,31 @@ export default {
</span> </span>
); );
}; };
const vcDatePickerProps = mergeProps( const vcDatePickerProps = {
{ ...props,
props, ...pickerChangeHandler,
on: listeners, calendar,
}, value,
pickerChangeHandler, open,
{ prefixCls: `${prefixCls}-picker-container`,
props: { onOpenChange: this.handleOpenChange,
calendar, style: popupStyle,
value, };
open,
prefixCls: `${prefixCls}-picker-container`,
},
on: {
openChange: this.handleOpenChange,
},
style: popupStyle,
scopedSlots: { default: input, ...$scopedSlots },
},
);
return ( return (
<span <span
ref="picker" ref={this.savePicker}
id={props.id}
class={classNames(props.class, props.pickerClass)}
style={{ ...style, ...pickerStyle }}
class={props.pickerClass} class={props.pickerClass}
style={pickerStyle} style={pickerStyle}
tabindex={props.disabled ? -1 : 0} tabindex={props.disabled ? -1 : 0}
onFocus={focus} onFocus={onFocus}
onBlur={blur} onBlur={onBlur}
onMouseenter={this.onMouseEnter} onMouseenter={this.onMouseEnter}
onMouseleave={this.onMouseLeave} onMouseleave={this.onMouseLeave}
> >
<VcDatePicker {...vcDatePickerProps} /> <VcDatePicker {...vcDatePickerProps} vSlots={$slots} children={input}></VcDatePicker>
</span> </span>
); );
}, },

View File

@ -1,15 +1,11 @@
import { inject } from 'vue';
import * as moment from 'moment'; import * as moment from 'moment';
import Calendar from '../vc-calendar'; import Calendar from '../vc-calendar';
import VcDatePicker from '../vc-calendar/src/Picker'; import VcDatePicker from '../vc-calendar/src/Picker';
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
import { ConfigConsumerProps } from '../config-provider'; import { ConfigConsumerProps } from '../config-provider';
import { import { hasProp, getOptionProps, initDefaultProps, getComponent } from '../_util/props-util';
hasProp, import classNames from 'classnames';
getOptionProps,
initDefaultProps,
getComponent,
getListeners,
} from '../_util/props-util';
import BaseMixin from '../_util/BaseMixin'; import BaseMixin from '../_util/BaseMixin';
import { WeekPickerProps } from './interface'; import { WeekPickerProps } from './interface';
import interopDefault from '../_util/interopDefault'; import interopDefault from '../_util/interopDefault';
@ -21,24 +17,17 @@ function formatValue(value, format) {
function noop() {} function noop() {}
export default { export default {
// static defaultProps = {
// format: 'YYYY-wo',
// allowClear: true,
// };
// private input: any;
name: 'AWeekPicker', name: 'AWeekPicker',
mixins: [BaseMixin], mixins: [BaseMixin],
model: { inheritAttrs: false,
prop: 'value',
event: 'change',
},
props: initDefaultProps(WeekPickerProps(), { props: initDefaultProps(WeekPickerProps(), {
format: 'gggg-wo', format: 'gggg-wo',
allowClear: true, allowClear: true,
}), }),
inject: { setup() {
configProvider: { default: () => ConfigConsumerProps }, return {
configProvider: inject('configProvider', ConfigConsumerProps),
};
}, },
data() { data() {
const value = this.value || this.defaultValue; const value = this.value || this.defaultValue;
@ -82,10 +71,13 @@ export default {
}); });
}, },
methods: { methods: {
saveInput(node) {
this.input = node;
},
weekDateRender(current) { weekDateRender(current) {
const selectedValue = this.$data._value; const selectedValue = this.$data._value;
const { _prefixCls: prefixCls, $scopedSlots } = this; const { _prefixCls: prefixCls, $slots } = this;
const dateRender = this.dateRender || $scopedSlots.dateRender; const dateRender = this.dateRender || $slots.dateRender;
const dateNode = dateRender ? dateRender(current) : current.date(); const dateNode = dateRender ? dateRender(current) : current.date();
if ( if (
selectedValue && selectedValue &&
@ -118,15 +110,15 @@ export default {
this.handleChange(null); this.handleChange(null);
}, },
focus() { focus() {
this.$refs.input.focus(); this.input.focus();
}, },
blur() { blur() {
this.$refs.input.blur(); this.input.blur();
}, },
renderFooter(...args) { renderFooter(...args) {
const { _prefixCls: prefixCls, $scopedSlots } = this; const { _prefixCls: prefixCls, $slots } = this;
const renderExtraFooter = this.renderExtraFooter || $scopedSlots.renderExtraFooter; const renderExtraFooter = this.renderExtraFooter || $slots.renderExtraFooter;
return renderExtraFooter ? ( return renderExtraFooter ? (
<div class={`${prefixCls}-footer-extra`}>{renderExtraFooter(...args)}</div> <div class={`${prefixCls}-footer-extra`}>{renderExtraFooter(...args)}</div>
) : null; ) : null;
@ -134,7 +126,7 @@ export default {
}, },
render() { render() {
const props = getOptionProps(this); const props = { ...getOptionProps(this), ...this.$attrs };
let suffixIcon = getComponent(this, 'suffixIcon'); let suffixIcon = getComponent(this, 'suffixIcon');
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon; suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
const { const {
@ -150,22 +142,21 @@ export default {
disabledDate, disabledDate,
defaultPickerValue, defaultPickerValue,
$data, $data,
$scopedSlots, $slots,
} = this; } = this;
const listeners = getListeners(this);
const getPrefixCls = this.configProvider.getPrefixCls; const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('calendar', customizePrefixCls); const prefixCls = getPrefixCls('calendar', customizePrefixCls);
this._prefixCls = prefixCls; this._prefixCls = prefixCls;
const { _value: pickerValue, _open: open } = $data; const { _value: pickerValue, _open: open } = $data;
const { focus = noop, blur = noop } = listeners; const { class: className, style, id, onFocus = noop, onBlur = noop } = props;
if (pickerValue && localeCode) { if (pickerValue && localeCode) {
pickerValue.locale(localeCode); pickerValue.locale(localeCode);
} }
const placeholder = hasProp(this, 'placeholder') ? this.placeholder : locale.lang.placeholder; const placeholder = hasProp(this, 'placeholder') ? this.placeholder : locale.lang.placeholder;
const weekDateRender = this.dateRender || $scopedSlots.dateRender || this.weekDateRender; const weekDateRender = this.dateRender || $slots.dateRender || this.weekDateRender;
const calendar = ( const calendar = (
<Calendar <Calendar
showWeekNumber showWeekNumber
@ -191,14 +182,14 @@ export default {
return ( return (
<span style={{ display: 'inline-block', width: '100%' }}> <span style={{ display: 'inline-block', width: '100%' }}>
<input <input
ref="input" ref={this.saveInput}
disabled={disabled} disabled={disabled}
readonly readonly
value={(value && value.format(format)) || ''} value={(value && value.format(format)) || ''}
placeholder={placeholder} placeholder={placeholder}
class={pickerInputClass} class={pickerInputClass}
onFocus={focus} onFocus={onFocus}
onBlur={blur} onBlur={onBlur}
/> />
{clearIcon} {clearIcon}
{inputIcon} {inputIcon}
@ -206,24 +197,18 @@ export default {
); );
}; };
const vcDatePickerProps = { const vcDatePickerProps = {
props: { ...props,
...props, calendar,
calendar, prefixCls: `${prefixCls}-picker-container`,
prefixCls: `${prefixCls}-picker-container`, value: pickerValue,
value: pickerValue, open,
open, onChange: this.handleChange,
}, onOpenChange: this.handleOpenChange,
on: {
...listeners,
change: this.handleChange,
openChange: this.handleOpenChange,
},
style: popupStyle, style: popupStyle,
scopedSlots: { default: input, ...$scopedSlots },
}; };
return ( return (
<span class={pickerClass}> <span class={classNames(className, pickerClass)} style={style} id={id}>
<VcDatePicker {...vcDatePickerProps} /> <VcDatePicker {...vcDatePickerProps} vSlots={$slots} children={input}></VcDatePicker>
</span> </span>
); );
}, },

View File

@ -1,3 +1,4 @@
import { inject } from 'vue';
import * as moment from 'moment'; import * as moment from 'moment';
import omit from 'lodash/omit'; import omit from 'lodash/omit';
import MonthCalendar from '../vc-calendar/src/MonthCalendar'; import MonthCalendar from '../vc-calendar/src/MonthCalendar';
@ -12,10 +13,8 @@ import {
hasProp, hasProp,
getOptionProps, getOptionProps,
initDefaultProps, initDefaultProps,
mergeProps,
getComponent, getComponent,
isValidElement, isValidElement,
getListeners,
} from '../_util/props-util'; } from '../_util/props-util';
import { cloneElement } from '../_util/vnode'; import { cloneElement } from '../_util/vnode';
import { formatDate } from './utils'; import { formatDate } from './utils';
@ -24,20 +23,18 @@ import { formatDate } from './utils';
// value?: moment.Moment; // value?: moment.Moment;
// prefixCls: string; // prefixCls: string;
// } // }
function noop() {}
export default function createPicker(TheCalendar, props) { export default function createPicker(TheCalendar, props) {
return { return {
inheritAttrs: false,
props: initDefaultProps(props, { props: initDefaultProps(props, {
allowClear: true, allowClear: true,
showToday: true, showToday: true,
}), }),
mixins: [BaseMixin], mixins: [BaseMixin],
model: { setup() {
prop: 'value', return {
event: 'change', configProvider: inject('configProvider', ConfigConsumerProps),
}, };
inject: {
configProvider: { default: () => ConfigConsumerProps },
}, },
data() { data() {
const value = this.value || this.defaultValue; const value = this.value || this.defaultValue;
@ -79,6 +76,9 @@ export default function createPicker(TheCalendar, props) {
}, },
}, },
methods: { methods: {
saveInput(node) {
this.input = node;
},
clearSelection(e) { clearSelection(e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@ -106,16 +106,15 @@ export default function createPicker(TheCalendar, props) {
this.$emit('openChange', open); this.$emit('openChange', open);
}, },
focus() { focus() {
this.$refs.input.focus(); this.input.focus();
}, },
blur() { blur() {
this.$refs.input.blur(); this.input.blur();
}, },
renderFooter(...args) { renderFooter(...args) {
const { $scopedSlots, $slots, _prefixCls: prefixCls } = this; const { $slots, _prefixCls: prefixCls } = this;
const renderExtraFooter = const renderExtraFooter = this.renderExtraFooter || $slots.renderExtraFooter;
this.renderExtraFooter || $scopedSlots.renderExtraFooter || $slots.renderExtraFooter;
return renderExtraFooter ? ( return renderExtraFooter ? (
<div class={`${prefixCls}-footer-extra`}> <div class={`${prefixCls}-footer-extra`}>
{typeof renderExtraFooter === 'function' {typeof renderExtraFooter === 'function'
@ -133,22 +132,19 @@ export default function createPicker(TheCalendar, props) {
}, },
render() { render() {
const { $scopedSlots } = this; const { $slots } = this;
const { sValue: value, showDate, _open: open } = this.$data; const { sValue: value, showDate, _open: open } = this.$data;
let suffixIcon = getComponent(this, 'suffixIcon'); let suffixIcon = getComponent(this, 'suffixIcon');
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon; suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
const listeners = getListeners(this); const props = omit({ ...getOptionProps(this), ...this.$attrs }, ['onChange']);
const { panelChange = noop, focus = noop, blur = noop, ok = noop } = listeners;
const props = getOptionProps(this);
const { prefixCls: customizePrefixCls, locale, localeCode, inputReadOnly } = props; const { prefixCls: customizePrefixCls, locale, localeCode, inputReadOnly } = props;
const getPrefixCls = this.configProvider.getPrefixCls; const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('calendar', customizePrefixCls); const prefixCls = getPrefixCls('calendar', customizePrefixCls);
this._prefixCls = prefixCls; this._prefixCls = prefixCls;
const dateRender = props.dateRender || $scopedSlots.dateRender; const dateRender = props.dateRender || $slots.dateRender;
const monthCellContentRender = const monthCellContentRender = props.monthCellContentRender || $slots.monthCellContentRender;
props.monthCellContentRender || $scopedSlots.monthCellContentRender;
const placeholder = 'placeholder' in props ? props.placeholder : locale.lang.placeholder; const placeholder = 'placeholder' in props ? props.placeholder : locale.lang.placeholder;
const disabledTime = props.showTime ? props.disabledTime : null; const disabledTime = props.showTime ? props.disabledTime : null;
@ -162,45 +158,41 @@ export default function createPicker(TheCalendar, props) {
value.locale(localeCode); value.locale(localeCode);
} }
const pickerProps = { props: {}, on: {} }; const pickerProps = {};
const calendarProps = { props: {}, on: {} }; const calendarProps = {};
const pickerStyle = {}; const pickerStyle = {};
if (props.showTime) { if (props.showTime) {
// fix https://github.com/ant-design/ant-design/issues/1902 // fix https://github.com/ant-design/ant-design/issues/1902
calendarProps.on.select = this.handleChange; calendarProps.onSelect = this.handleChange;
pickerStyle.minWidth = '195px'; pickerStyle.minWidth = '195px';
} else { } else {
pickerProps.on.change = this.handleChange; pickerProps.onChange = this.handleChange;
} }
if ('mode' in props) { if ('mode' in props) {
calendarProps.props.mode = props.mode; calendarProps.mode = props.mode;
} }
const theCalendarProps = mergeProps(calendarProps, { const theCalendarProps = {
props: { ...calendarProps,
disabledDate: props.disabledDate, disabledDate: props.disabledDate,
disabledTime, disabledTime,
locale: locale.lang, locale: locale.lang,
timePicker: props.timePicker, timePicker: props.timePicker,
defaultValue: props.defaultPickerValue || interopDefault(moment)(), defaultValue: props.defaultPickerValue || interopDefault(moment)(),
dateInputPlaceholder: placeholder, dateInputPlaceholder: placeholder,
prefixCls, prefixCls,
dateRender, dateRender,
format: props.format, format: props.format,
showToday: props.showToday, showToday: props.showToday,
monthCellContentRender, monthCellContentRender,
renderFooter: this.renderFooter, renderFooter: this.renderFooter,
value: showDate, value: showDate,
inputReadOnly, inputReadOnly,
}, onOk: props.onOk,
on: { onPanelChange: props.onPanelChange,
ok, onChange: this.handleCalendarChange,
panelChange,
change: this.handleCalendarChange,
},
class: calendarClassName, class: calendarClassName,
scopedSlots: $scopedSlots, };
}); const calendar = <TheCalendar {...theCalendarProps} vSlots={$slots} />;
const calendar = <TheCalendar {...theCalendarProps} />;
const clearIcon = const clearIcon =
!props.disabled && props.allowClear && value ? ( !props.disabled && props.allowClear && value ? (
@ -219,10 +211,10 @@ export default function createPicker(TheCalendar, props) {
const input = ({ value: inputValue }) => ( const input = ({ value: inputValue }) => (
<div> <div>
<input <input
ref="input" ref={this.saveInput}
disabled={props.disabled} disabled={props.disabled}
onFocus={focus} onFocus={props.onFocus}
onBlur={blur} onBlur={props.onBlur}
readonly readonly
value={formatDate(inputValue, this.format)} value={formatDate(inputValue, this.format)}
placeholder={placeholder} placeholder={placeholder}
@ -235,33 +227,28 @@ export default function createPicker(TheCalendar, props) {
</div> </div>
); );
const vcDatePickerProps = { const vcDatePickerProps = {
props: { ...props,
...props, ...pickerProps,
...pickerProps.props, calendar,
calendar, value,
value, prefixCls: `${prefixCls}-picker-container`,
prefixCls: `${prefixCls}-picker-container`, open,
}, onOpenChange: this.handleOpenChange,
on: {
...omit(listeners, 'change'),
...pickerProps.on,
open,
onOpenChange: this.handleOpenChange,
},
style: props.popupStyle, style: props.popupStyle,
scopedSlots: { default: input, ...$scopedSlots }, children: input,
}; };
return ( return (
<span <span
class={props.pickerClass} id={props.id}
style={pickerStyle} class={classNames(props.class, props.pickerClass)}
style={{ ...pickerStyle, ...props.style }}
// tabindex={props.disabled ? -1 : 0} // tabindex={props.disabled ? -1 : 0}
// onFocus={focus} // onFocus={focus}
// onBlur={blur} // onBlur={blur}
onMouseenter={this.onMouseEnter} onMouseenter={this.onMouseEnter}
onMouseleave={this.onMouseLeave} onMouseleave={this.onMouseLeave}
> >
<VcDatePicker {...vcDatePickerProps} /> <VcDatePicker {...vcDatePickerProps} vSlots={omit($slots, ['default'])}></VcDatePicker>
</span> </span>
); );
}, },

View File

@ -5,7 +5,6 @@ import wrapPicker from './wrapPicker';
import RangePicker from './RangePicker'; import RangePicker from './RangePicker';
import WeekPicker from './WeekPicker'; import WeekPicker from './WeekPicker';
import { DatePickerProps, MonthPickerProps, WeekPickerProps, RangePickerProps } from './interface'; import { DatePickerProps, MonthPickerProps, WeekPickerProps, RangePickerProps } from './interface';
import Base from '../base';
const DatePicker = wrapPicker( const DatePicker = wrapPicker(
{ ...createPicker(VcCalendar, DatePickerProps()), name: 'ADatePicker' }, { ...createPicker(VcCalendar, DatePickerProps()), name: 'ADatePicker' },
@ -26,12 +25,11 @@ Object.assign(DatePicker, {
}); });
/* istanbul ignore next */ /* istanbul ignore next */
DatePicker.install = function(Vue) { DatePicker.install = function(app) {
Vue.use(Base); app.component(DatePicker.name, DatePicker);
Vue.component(DatePicker.name, DatePicker); app.component(DatePicker.RangePicker.name, DatePicker.RangePicker);
Vue.component(DatePicker.RangePicker.name, DatePicker.RangePicker); app.component(DatePicker.MonthPicker.name, DatePicker.MonthPicker);
Vue.component(DatePicker.MonthPicker.name, DatePicker.MonthPicker); app.component(DatePicker.WeekPicker.name, DatePicker.WeekPicker);
Vue.component(DatePicker.WeekPicker.name, DatePicker.WeekPicker);
}; };
export default DatePicker; export default DatePicker;

View File

@ -18,7 +18,6 @@ export const PickerProps = () => ({
size: PropTypes.oneOf(['large', 'small', 'default']), size: PropTypes.oneOf(['large', 'small', 'default']),
getCalendarContainer: PropTypes.func, getCalendarContainer: PropTypes.func,
open: PropTypes.bool, open: PropTypes.bool,
// onOpenChange: PropTypes.(status: bool) => void,
disabledDate: PropTypes.func, disabledDate: PropTypes.func,
showToday: PropTypes.bool, showToday: PropTypes.bool,
dateRender: PropTypes.any, // (current: moment.Moment, today: moment.Moment) => React.ReactNode, dateRender: PropTypes.any, // (current: moment.Moment, today: moment.Moment) => React.ReactNode,
@ -31,6 +30,12 @@ export const PickerProps = () => ({
align: PropTypes.object.def(() => ({})), align: PropTypes.object.def(() => ({})),
inputReadOnly: PropTypes.bool, inputReadOnly: PropTypes.bool,
valueFormat: PropTypes.string, valueFormat: PropTypes.string,
onOpenChange: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
'onUpdate:value': PropTypes.func,
onMouseenter: PropTypes.func,
onMouseleave: PropTypes.func,
}); });
export const SinglePickerProps = () => ({ export const SinglePickerProps = () => ({
@ -39,7 +44,7 @@ export const SinglePickerProps = () => ({
defaultPickerValue: TimeType, defaultPickerValue: TimeType,
renderExtraFooter: PropTypes.any, renderExtraFooter: PropTypes.any,
placeholder: PropTypes.string, placeholder: PropTypes.string,
// onChange?: (date: moment.Moment, dateString: string) => void; onChange: PropTypes.func,
}); });
export const DatePickerProps = () => ({ export const DatePickerProps = () => ({
@ -48,9 +53,10 @@ export const DatePickerProps = () => ({
showTime: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]), showTime: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
open: PropTypes.bool, open: PropTypes.bool,
disabledTime: PropTypes.func, disabledTime: PropTypes.func,
// onOpenChange?: (status: bool) => void;
// onOk?: (selectedTime: moment.Moment) => void;
mode: PropTypes.oneOf(['time', 'date', 'month', 'year']), mode: PropTypes.oneOf(['time', 'date', 'month', 'year']),
onOpenChange: PropTypes.func,
onPanelChange: PropTypes.func,
onOk: PropTypes.func,
}); });
export const MonthPickerProps = () => ({ export const MonthPickerProps = () => ({
@ -68,9 +74,6 @@ export const RangePickerProps = () => ({
defaultValue: TimesType, defaultValue: TimesType,
defaultPickerValue: TimesType, defaultPickerValue: TimesType,
timePicker: PropTypes.any, timePicker: PropTypes.any,
// onChange?: (dates: TimesType, dateStrings: [string, string]) => void;
// onCalendarChange?: (dates: TimesType, dateStrings: [string, string]) => void;
// onOk?: (selectedTime: moment.Moment) => void;
showTime: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]), showTime: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
ranges: PropTypes.object, ranges: PropTypes.object,
placeholder: PropTypes.arrayOf(String), placeholder: PropTypes.arrayOf(String),
@ -79,7 +82,12 @@ export const RangePickerProps = () => ({
disabledTime: PropTypes.func, disabledTime: PropTypes.func,
showToday: PropTypes.bool, showToday: PropTypes.bool,
renderExtraFooter: PropTypes.any, renderExtraFooter: PropTypes.any,
// onPanelChange?: (value?: TimesType, mode?: string | string[]) => void; onChange: PropTypes.func,
onCalendarChange: PropTypes.func,
onOk: PropTypes.func,
onPanelChange: PropTypes.func,
onMouseenter: PropTypes.func,
onMouseleave: PropTypes.func,
}); });
export const WeekPickerProps = () => ({ export const WeekPickerProps = () => ({

View File

@ -1,9 +1,10 @@
import { provide, inject } from 'vue';
import TimePickerPanel from '../vc-time-picker/Panel'; import TimePickerPanel from '../vc-time-picker/Panel';
import classNames from 'classnames'; import classNames from 'classnames';
import LocaleReceiver from '../locale-provider/LocaleReceiver'; import LocaleReceiver from '../locale-provider/LocaleReceiver';
import { generateShowHourMinuteSecond } from '../time-picker'; import { generateShowHourMinuteSecond } from '../time-picker';
import enUS from './locale/en_US'; import enUS from './locale/en_US';
import { getOptionProps, initDefaultProps, getListeners } from '../_util/props-util'; import { getOptionProps, initDefaultProps } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider'; import { ConfigConsumerProps } from '../config-provider';
import { checkValidate, stringToMoment, momentToString } from '../_util/moment-util'; import { checkValidate, stringToMoment, momentToString } from '../_util/moment-util';
@ -41,23 +42,24 @@ function getColumns({ showHour, showMinute, showSecond, use12Hours }) {
export default function wrapPicker(Picker, props, pickerType) { export default function wrapPicker(Picker, props, pickerType) {
return { return {
name: Picker.name, name: Picker.name,
inheritAttrs: false,
props: initDefaultProps(props, { props: initDefaultProps(props, {
transitionName: 'slide-up', transitionName: 'slide-up',
popupStyle: {}, popupStyle: {},
locale: {}, locale: {},
}), }),
model: { // model: {
prop: 'value', // prop: 'value',
event: 'change', // event: 'change',
}, // },
inject: { setup() {
configProvider: { default: () => ConfigConsumerProps },
},
provide() {
return { return {
savePopupRef: this.savePopupRef, configProvider: inject('configProvider', ConfigConsumerProps),
}; };
}, },
created() {
provide('savePopupRef', this.savePopupRef);
},
mounted() { mounted() {
const { autofocus, disabled, value, defaultValue, valueFormat } = this; const { autofocus, disabled, value, defaultValue, valueFormat } = this;
checkValidate('DatePicker', defaultValue, 'defaultValue', valueFormat); checkValidate('DatePicker', defaultValue, 'defaultValue', valueFormat);
@ -74,6 +76,9 @@ export default function wrapPicker(Picker, props, pickerType) {
}, },
}, },
methods: { methods: {
savePicker(node) {
this.picker = node;
},
getDefaultLocale() { getDefaultLocale() {
const result = { const result = {
...enUS, ...enUS,
@ -109,11 +114,9 @@ export default function wrapPicker(Picker, props, pickerType) {
this.$emit('mouseleave', e); this.$emit('mouseleave', e);
}, },
handleChange(date, dateString) { handleChange(date, dateString) {
this.$emit( const value = this.valueFormat ? momentToString(date, this.valueFormat) : date;
'change', this.$emit('update:value', value);
this.valueFormat ? momentToString(date, this.valueFormat) : date, this.$emit('change', value, dateString);
dateString,
);
}, },
handleOk(val) { handleOk(val) {
this.$emit('ok', this.valueFormat ? momentToString(val, this.valueFormat) : val); this.$emit('ok', this.valueFormat ? momentToString(val, this.valueFormat) : val);
@ -126,11 +129,11 @@ export default function wrapPicker(Picker, props, pickerType) {
); );
}, },
focus() { focus() {
this.$refs.picker.focus(); this.picker.focus();
}, },
blur() { blur() {
this.$refs.picker.blur(); this.picker.blur();
}, },
transformValue(props) { transformValue(props) {
@ -146,7 +149,7 @@ export default function wrapPicker(Picker, props, pickerType) {
}, },
renderPicker(locale, localeCode) { renderPicker(locale, localeCode) {
const props = getOptionProps(this); const props = { ...getOptionProps(this), ...this.$attrs };
this.transformValue(props); this.transformValue(props);
const { const {
prefixCls: customizePrefixCls, prefixCls: customizePrefixCls,
@ -186,54 +189,35 @@ export default function wrapPicker(Picker, props, pickerType) {
const columns = getColumns(vcTimePickerProps); const columns = getColumns(vcTimePickerProps);
const timePickerCls = `${prefixCls}-time-picker-column-${columns}`; const timePickerCls = `${prefixCls}-time-picker-column-${columns}`;
const timePickerPanelProps = { const timePickerPanelProps = {
props: { ...vcTimePickerProps,
...vcTimePickerProps, ...showTime,
...showTime, prefixCls: `${prefixCls}-time-picker`,
prefixCls: `${prefixCls}-time-picker`, placeholder: locale.timePickerLocale.placeholder,
placeholder: locale.timePickerLocale.placeholder, transitionName: 'slide-up',
transitionName: 'slide-up',
},
class: timePickerCls, class: timePickerCls,
on: { onEsc: () => {},
esc: () => {},
},
}; };
const timePicker = showTime ? <TimePickerPanel {...timePickerPanelProps} /> : null; const timePicker = showTime ? <TimePickerPanel {...timePickerPanelProps} /> : null;
const pickerProps = { const pickerProps = {
props: { ...props,
...props, getCalendarContainer: getPopupContainer,
getCalendarContainer: getPopupContainer, format: mergedFormat,
format: mergedFormat, pickerClass,
pickerClass, pickerInputClass,
pickerInputClass, locale,
locale, localeCode,
localeCode, timePicker,
timePicker, onOpenChange: this.handleOpenChange,
}, onFocus: this.handleFocus,
on: { onBlur: this.handleBlur,
...getListeners(this), onMouseenter: this.handleMouseEnter,
openChange: this.handleOpenChange, onMouseleave: this.handleMouseLeave,
focus: this.handleFocus, onChange: this.handleChange,
blur: this.handleBlur, onOk: this.handleOk,
mouseenter: this.handleMouseEnter, onCalendarChange: this.handleCalendarChange,
mouseleave: this.handleMouseLeave, ref: this.savePicker,
change: this.handleChange,
ok: this.handleOk,
calendarChange: this.handleCalendarChange,
},
ref: 'picker',
scopedSlots: this.$scopedSlots || {},
}; };
return ( return <Picker {...pickerProps} vSlots={this.$slots} />;
<Picker {...pickerProps}>
{this.$slots &&
Object.keys(this.$slots).map(key => (
<template slot={key} key={key}>
{this.$slots[key]}
</template>
))}
</Picker>
);
}, },
}, },
@ -242,7 +226,7 @@ export default function wrapPicker(Picker, props, pickerType) {
<LocaleReceiver <LocaleReceiver
componentName="DatePicker" componentName="DatePicker"
defaultLocale={this.getDefaultLocale} defaultLocale={this.getDefaultLocale}
scopedSlots={{ default: this.renderPicker }} children={this.renderPicker}
/> />
); );
}, },

View File

@ -61,6 +61,8 @@ const Calendar = {
focusablePanel: PropTypes.bool.def(true), focusablePanel: PropTypes.bool.def(true),
inputMode: PropTypes.string, inputMode: PropTypes.string,
inputReadOnly: PropTypes.bool, inputReadOnly: PropTypes.bool,
monthCellRender: PropTypes.func,
monthCellContentRender: PropTypes.func,
}, },
mixins: [BaseMixin, CommonMixin, CalendarMixin], mixins: [BaseMixin, CommonMixin, CalendarMixin],

View File

@ -52,6 +52,7 @@ const Picker = {
data() { data() {
const props = this.$props; const props = this.$props;
this.calendarElement = null;
this.saveCalendarRef = refFn.bind(this, 'calendarInstance'); this.saveCalendarRef = refFn.bind(this, 'calendarInstance');
let open; let open;
if (hasProp(this, 'open')) { if (hasProp(this, 'open')) {

View File

@ -52,7 +52,7 @@ const CalendarFooter = {
if (showToday) { if (showToday) {
nowEl = <TodayButton key="todayButton" {...btnProps} />; nowEl = <TodayButton key="todayButton" {...btnProps} />;
} }
delete btnProps.props.value; delete btnProps.value;
let okBtn = null; let okBtn = null;
if (showOk === true || (showOk !== false && !!timePicker)) { if (showOk === true || (showOk !== false && !!timePicker)) {
okBtn = <OkButton key="okButton" {...btnProps} />; okBtn = <OkButton key="okButton" {...btnProps} />;

View File

@ -33,6 +33,8 @@ const DateInput = {
clearIcon: PropTypes.any, clearIcon: PropTypes.any,
inputMode: PropTypes.string, inputMode: PropTypes.string,
inputReadOnly: PropTypes.bool, inputReadOnly: PropTypes.bool,
disabled: PropTypes.bool,
showClear: PropTypes.bool,
}, },
data() { data() {

View File

@ -1,6 +1,6 @@
import PropTypes from '../../../_util/vue-types'; import PropTypes from '../../../_util/vue-types';
import BaseMixin from '../../../_util/BaseMixin'; import BaseMixin from '../../../_util/BaseMixin';
import { hasProp, getListeners } from '../../../_util/props-util'; import { hasProp } from '../../../_util/props-util';
import MonthTable from './MonthTable'; import MonthTable from './MonthTable';
function goYear(direction) { function goYear(direction) {
@ -86,7 +86,7 @@ const MonthPanel = {
<a <a
class={`${prefixCls}-year-select`} class={`${prefixCls}-year-select`}
role="button" role="button"
onClick={getListeners(this).yearPanelShow || noop} onClick={this.$attrs.onYearPanelShow || noop}
title={locale.yearSelect} title={locale.yearSelect}
> >
<span class={`${prefixCls}-year-select-content`}>{year}</span> <span class={`${prefixCls}-year-select-content`}>{year}</span>

View File

@ -4,7 +4,7 @@
</div> </div>
</template> </template>
<script> <script>
import demo from '../antdv-demo/docs/calendar/demo/basic'; import demo from '../antdv-demo/docs/date-picker/demo/basic';
export default { export default {
components: { components: {

View File

@ -35,6 +35,7 @@ import {
Carousel, Carousel,
TimePicker, TimePicker,
Calendar, Calendar,
DatePicker,
notification, notification,
message, message,
} from 'ant-design-vue'; } from 'ant-design-vue';
@ -87,4 +88,5 @@ app
.use(Carousel) .use(Carousel)
.use(TimePicker) .use(TimePicker)
.use(Calendar) .use(Calendar)
.use(DatePicker)
.mount('#app'); .mount('#app');