Browse Source

feat: update date-picker

pull/802/head
wangxueliang 6 years ago
parent
commit
300fc9a2bc
  1. 39
      components/date-picker/RangePicker.jsx
  2. 51
      components/date-picker/WeekPicker.jsx
  3. 37
      components/date-picker/createPicker.js
  4. 5
      components/date-picker/demo/mode.md
  5. 1
      components/date-picker/demo/time.md
  6. 8
      components/date-picker/index.en-US.md
  7. 7
      components/date-picker/index.js
  8. 8
      components/date-picker/index.zh-CN.md
  9. 1
      components/date-picker/interface.js
  10. 6
      components/date-picker/locale/example.json
  11. 44
      components/date-picker/wrapPicker.js
  12. 2
      components/modal/demo/confirm-router.md

39
components/date-picker/RangePicker.jsx

@ -5,6 +5,7 @@ import classNames from 'classnames';
import shallowequal from 'shallowequal';
import Icon from '../icon';
import Tag from '../tag';
import { ConfigConsumerProps } from '../config-provider';
import interopDefault from '../_util/interopDefault';
import { RangePickerProps } from './interface';
import {
@ -73,11 +74,12 @@ export default {
event: 'change',
},
props: initDefaultProps(RangePickerProps(), {
prefixCls: 'ant-calendar',
tagPrefixCls: 'ant-tag',
allowClear: true,
showToday: false,
}),
inject: {
configProvider: { default: () => ({}) },
},
data() {
const value = this.value || this.defaultValue || [];
const [start, end] = value;
@ -109,13 +111,24 @@ export default {
};
}
this.setState(state);
this.prevState = {...this.$data, ...state};
},
open(val) {
this.setState({
sOpen: val,
});
const state = { sOpen: val};
this.setState(state);
this.prevState = {...this.$data, ...state};
},
},
mounted() {
this.prevState = {...this.$data};
},
updated() {
this.$nextTick(() => {
if(!hasProp(this, 'open') && this.prevState.sOpen && !this.sOpen) {
this.focus();
}
});
},
methods: {
clearSelection(e) {
e.preventDefault();
@ -148,10 +161,6 @@ export default {
this.clearHoverValue();
}
this.$emit('openChange', open);
if (!open) {
this.focus();
}
},
handleShowDateChange(showDate) {
@ -212,7 +221,8 @@ export default {
},
renderFooter(...args) {
const { prefixCls, ranges, $scopedSlots, $slots, tagPrefixCls } = this;
const { ranges, $scopedSlots, $slots } = this;
const { _prefixCls: prefixCls, _tagPrefixCls: tagPrefixCls } = this;
const renderExtraFooter =
this.renderExtraFooter || $scopedSlots.renderExtraFooter || $slots.renderExtraFooter;
if (!ranges && !renderExtraFooter) {
@ -268,7 +278,8 @@ export default {
panelChange = noop,
} = $listeners;
const {
prefixCls,
prefixCls: customizePrefixCls,
tagPrefixCls: customizeTagPrefixCls,
popupStyle,
disabledDate,
disabledTime,
@ -279,6 +290,12 @@ export default {
localeCode,
format,
} = props;
const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls;
const prefixCls = getPrefixCls('calendar', customizePrefixCls);
const tagPrefixCls = getPrefixCls('tag', customizeTagPrefixCls);
this._prefixCls = prefixCls;
this._tagPrefixCls = tagPrefixCls;
const dateRender = props.dateRender || $scopedSlots.dateRender;
fixLocale(value, localeCode);
fixLocale(showDate, localeCode);

51
components/date-picker/WeekPicker.jsx

@ -2,6 +2,7 @@ import * as moment from 'moment';
import Calendar from '../vc-calendar';
import VcDatePicker from '../vc-calendar/src/Picker';
import Icon from '../icon';
import { ConfigConsumerProps } from '../config-provider';
import {
hasProp,
getOptionProps,
@ -36,6 +37,9 @@ export default {
format: 'gggg-wo',
allowClear: true,
}),
inject: {
configProvider: { default: () => ({}) },
},
data() {
const value = this.value || this.defaultValue;
if (value && !interopDefault(moment).isMoment(value)) {
@ -50,17 +54,32 @@ export default {
},
watch: {
value(val) {
this.setState({ _value: val });
const state = { _value: val };
this.setState(state);
this.prevState = {...this.$data, ...state};
},
open(val) {
this.setState({ _open: val });
const state = { _open: val };
this.setState(state);
this.prevState = {...this.$data, ...state};
},
},
mounted() {
this.prevState = {...this.$data};
},
updated() {
this.$nextTick(() => {
if(!hasProp(this, 'open') && this.prevState._open && !this._open) {
this.focus();
}
});
},
methods: {
weekDateRender(current) {
const selectedValue = this.$data._value;
const { prefixCls } = this;
const { _prefixCls: prefixCls, $scopedSlots } = this;
const dateRender = this.dateRender || $scopedSlots.dateRender;
const dateNode = dateRender ? dateRender(current) : current.date();
if (
selectedValue &&
current.year() === selectedValue.year() &&
@ -68,11 +87,11 @@ export default {
) {
return (
<div class={`${prefixCls}-selected-day`}>
<div class={`${prefixCls}-date`}>{current.date()}</div>
<div class={`${prefixCls}-date`}>{dateNode}</div>
</div>
);
}
return <div class={`${prefixCls}-date`}>{current.date()}</div>;
return <div class={`${prefixCls}-date`}>{dateNode}</div>;
},
handleChange(value) {
if (!hasProp(this, 'value')) {
@ -85,17 +104,19 @@ export default {
this.setState({ _open: open });
}
this.$emit('openChange', open);
if (!open) {
this.focus();
}
},
clearSelection(e) {
e.preventDefault();
e.stopPropagation();
this.handleChange(null);
},
renderFooter(...args) {
const {_prefixCls: prefixCls, $scopedSlots} = this;
const renderExtraFooter = this.renderExtraFooter || $scopedSlots.renderExtraFooter;
return renderExtraFooter ? (
<div class={`${prefixCls}-footer-extra`}>{renderExtraFooter(...args)}</div>
) : null;
},
focus() {
this.$refs.input.focus();
},
@ -110,7 +131,7 @@ export default {
let suffixIcon = getComponentFromProp(this, 'suffixIcon');
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
const {
prefixCls,
prefixCls: customizePrefixCls,
disabled,
pickerClass,
popupStyle,
@ -124,6 +145,11 @@ export default {
$listeners,
$scopedSlots,
} = this;
const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls;
const prefixCls = getPrefixCls('calendar', customizePrefixCls);
this._prefixCls = prefixCls;
const { _value: pickerValue, _open: open } = $data;
const { focus = noop, blur = noop } = $listeners;
@ -143,6 +169,7 @@ export default {
showDateInput={false}
showToday={false}
disabledDate={disabledDate}
renderFooter={this.renderFooter}
/>
);
const clearIcon =

37
components/date-picker/createPicker.js

@ -4,6 +4,7 @@ import MonthCalendar from '../vc-calendar/src/MonthCalendar';
import VcDatePicker from '../vc-calendar/src/Picker';
import classNames from 'classnames';
import Icon from '../icon';
import { ConfigConsumerProps } from '../config-provider';
import interopDefault from '../_util/interopDefault';
import BaseMixin from '../_util/BaseMixin';
import {
@ -23,15 +24,7 @@ import { cloneElement } from '../_util/vnode';
function noop() {}
export default function createPicker(TheCalendar, props) {
return {
// static defaultProps = {
// prefixCls: 'ant-calendar',
// allowClear: true,
// showToday: true,
// };
// private input: any;
props: initDefaultProps(props, {
prefixCls: 'ant-calendar',
allowClear: true,
showToday: true,
}),
@ -40,6 +33,9 @@ export default function createPicker(TheCalendar, props) {
prop: 'value',
event: 'change',
},
inject: {
configProvider: { default: () => ({}) },
},
data() {
const value = this.value || this.defaultValue;
if (value && !interopDefault(moment).isMoment(value)) {
@ -62,6 +58,7 @@ export default function createPicker(TheCalendar, props) {
state.showDate = props.value;
}
this.setState(state);
this.prevState = {...this.$data, ...state};
},
value(val) {
const state = {};
@ -70,11 +67,23 @@ export default function createPicker(TheCalendar, props) {
state.showDate = val;
}
this.setState(state);
this.prevState = {...this.$data, ...state};
},
},
mounted() {
this.prevState = {...this.$data};
},
updated() {
this.$nextTick(() => {
if(!hasProp(this, 'open') && this.prevState._open && !this._open) {
this.focus();
}
});
},
methods: {
renderFooter(...args) {
const { prefixCls, $scopedSlots, $slots } = this;
const { $scopedSlots, $slots } = this;
const { _prefixCls: prefixCls } = this;
const renderExtraFooter =
this.renderExtraFooter || $scopedSlots.renderExtraFooter || $slots.renderExtraFooter;
return renderExtraFooter ? (
@ -111,9 +120,6 @@ export default function createPicker(TheCalendar, props) {
this.setState({ _open: open });
}
this.$emit('openChange', open);
if (!open) {
this.focus();
}
},
focus() {
this.$refs.input.focus();
@ -137,7 +143,12 @@ export default function createPicker(TheCalendar, props) {
suffixIcon = Array.isArray(suffixIcon) ? suffixIcon[0] : suffixIcon;
const { panelChange = noop, focus = noop, blur = noop, ok = noop } = $listeners;
const props = getOptionProps(this);
const { prefixCls, locale, localeCode } = props;
const { prefixCls: customizePrefixCls, locale, localeCode } = props;
const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls;
const prefixCls = getPrefixCls('calendar', customizePrefixCls);
this._prefixCls = prefixCls;
const dateRender = props.dateRender || $scopedSlots.dateRender;
const monthCellContentRender =
props.monthCellContentRender || $scopedSlots.monthCellContentRender;

5
components/date-picker/demo/mode.md

@ -25,6 +25,7 @@ Determing which panel to show with `mode` and `onPanelChange`.
:value="value"
:mode="mode2"
@panelChange="handlePanelChange2"
@change="handleChange"
/>
</div>
</template>
@ -43,7 +44,9 @@ export default {
this.mode1 = 'time'
}
},
handleChange(value){
this.value = value
},
handlePanelChange1(value, mode) {
this.mode1 = mode
},

1
components/date-picker/demo/time.md

@ -14,7 +14,6 @@ This property provide an additional time selection. When `showTime` is an Object
<div>
<a-date-picker
showTime
format="YYYY-MM-DD HH:mm:ss"
placeholder="Select Time"
@change="onChange"
@ok="onOk"

8
components/date-picker/index.en-US.md

@ -32,6 +32,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
| disabledDate | specify the date that cannot be selected | (currentDate: moment) => boolean | - |
| getCalendarContainer | to set the container of the floating layer, while the default is to create a `div` element in `body` | function(trigger) | - |
| locale | localization configuration | object | [default](https://github.com/vueComponent/ant-design-vue/blob/master/components/date-picker/locale/example.json) |
| mode | picker panel mode | `time|date|month|year` | 'date' |
| open | open state of picker | boolean | - |
| placeholder | placeholder of date input | string\|RangePicker\[] | - |
| popupStyle | to customize the style of the popup calendar | object | {} |
@ -61,7 +62,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
| defaultPickerValue | to set default picker date | [moment](http://momentjs.com/) | - |
| disabledTime | to specify the time that cannot be selected | function(date) | - |
| format | to set the date format, refer to [moment.js](http://momentjs.com/) | string | "YYYY-MM-DD" |
| renderExtraFooter | render extra footer in panel by setting a scoped slot | slot="renderExtraFooter" | - |
| renderExtraFooter | render extra footer in panel by setting a scoped slot | slot="renderExtraFooter" slot-scope="mode" | - |
| showTime | to provide an additional time selection | object\|boolean | [TimePicker Options](/components/time-picker/#API) |
| showTime.defaultValue | to set default time of selected date | [moment](http://momentjs.com/) | moment() |
| showToday | whether to show "Today" button | boolean | true |
@ -82,7 +83,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
| defaultPickerValue | to set default picker date | [moment](http://momentjs.com/) | - |
| format | to set the date format. When an array is provided, all values are used for parsing and first value for display. refer to [moment.js](http://momentjs.com/) | string \| string[] | "YYYY-MM" |
| monthCellContentRender | Custom month cell content render method by setting a scoped slot | slot="monthCellContentRender" slot-scope="date, locale" | - |
| renderExtraFooter | render extra footer in panel by setting a scoped slot | slot="renderExtraFooter" | - |
| renderExtraFooter | render extra footer in panel by setting a scoped slot | slot="renderExtraFooter" slot-scope="mode" | - |
| value(v-model) | to set date | [moment](http://momentjs.com/) | - |
### MonthPicker Events
@ -98,6 +99,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
| defaultPickerValue | to set default picker date | [moment](http://momentjs.com/) | - |
| format | to set the date format, refer to [moment.js](http://momentjs.com/) | string | "YYYY-wo" |
| value(v-model) | to set date | [moment](http://momentjs.com/) | - |
| renderExtraFooter | render extra footer in panel by setting a scoped slot | slot="renderExtraFooter" slot-scope="mode" | - |
### WeekPicker Events
| Events Name | Description | Arguments |
@ -113,7 +115,7 @@ The following APIs are shared by DatePicker, MonthPicker, RangePicker, WeekPicke
| disabledTime | to specify the time that cannot be selected | function(dates: \[moment, moment\], partial: `'start'|'end'`) | - |
| format | to set the date format | string | "YYYY-MM-DD HH:mm:ss" |
| ranges | preseted ranges for quick selection | { \[range: string]: [moment](http://momentjs.com/)\[] } \| { \[range: string]: () => [moment](http://momentjs.com/)\[] } | - |
| renderExtraFooter | render extra footer in panel by setting a scoped slot| slot="renderExtraFooter" | - |
| renderExtraFooter | render extra footer in panel by setting a scoped slot| slot="renderExtraFooter" slot-scope="mode" | - |
| showTime | to provide an additional time selection | object\|boolean | [TimePicker Options](/components/time-picker/#API) |
| showTime.defaultValue | to set default time of selected date, [demo](https://ant.design/components/date-picker/#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | \[moment(), moment()] |
| value(v-model) | to set date | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | - |

7
components/date-picker/index.js

@ -9,18 +9,19 @@ import { DatePickerProps, MonthPickerProps, WeekPickerProps, RangePickerProps }
const DatePicker = wrapPicker(
{ ...createPicker(VcCalendar, DatePickerProps()), name: 'ADatePicker' },
DatePickerProps(),
'date'
);
const MonthPicker = wrapPicker(
{ ...createPicker(MonthCalendar, MonthPickerProps()), name: 'AMonthPicker' },
MonthPickerProps(),
'YYYY-MM',
'month',
);
Object.assign(DatePicker, {
RangePicker: wrapPicker(RangePicker, RangePickerProps()),
RangePicker: wrapPicker(RangePicker, RangePickerProps(), 'date'),
MonthPicker,
WeekPicker: wrapPicker(WeekPicker, WeekPickerProps(), 'gggg-wo'),
WeekPicker: wrapPicker(WeekPicker, WeekPickerProps(), 'week'),
});
/* istanbul ignore next */

8
components/date-picker/index.zh-CN.md

@ -61,7 +61,8 @@ moment.locale('zh-cn');
| defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | 无 |
| disabledTime | 不可选择的时间 | function(date) | 无 |
| format | 设置日期格式,为数组时支持多格式匹配,展示以第一个为准。配置参考 [moment.js](http://momentjs.com/) | string \| string[] | "YYYY-MM-DD" |
| renderExtraFooter | 在面板中添加额外的页脚 | slot="renderExtraFooter" | - |
| mode | 日期面板的状态 | `time|date|month|year` | 'date' |
| renderExtraFooter | 在面板中添加额外的页脚 | slot="renderExtraFooter" slot-scope="mode" | - |
| showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/components/time-picker-cn/#API) |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒 | [moment](http://momentjs.com/) | moment() |
| showToday | 是否展示“今天”按钮 | boolean | true |
@ -82,7 +83,7 @@ moment.locale('zh-cn');
| defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | 无 |
| format | 展示的日期格式,配置参考 [moment.js](http://momentjs.com/) | string | "YYYY-MM" |
| monthCellContentRender | 自定义的月份内容渲染方法 | slot="monthCellContentRender" slot-scope="date, locale" | - |
| renderExtraFooter | 在面板中添加额外的页脚 | slot="renderExtraFooter" | - |
| renderExtraFooter | 在面板中添加额外的页脚 | slot="renderExtraFooter" slot-scope="mode" | - |
| value(v-model) | 日期 | [moment](http://momentjs.com/) | 无 |
### MonthPicker事件
@ -99,6 +100,7 @@ moment.locale('zh-cn');
| defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | 无 |
| format | 展示的日期格式,配置参考 [moment.js](http://momentjs.com/) | string | "YYYY-wo" |
| value(v-model) | 日期 | [moment](http://momentjs.com/) | - |
| renderExtraFooter | 在面板中添加额外的页脚 | slot="renderExtraFooter" slot-scope="mode" | - |
### WeekPicker事件
@ -115,7 +117,7 @@ moment.locale('zh-cn');
| disabledTime | 不可选择的时间 | function(dates: \[moment, moment\], partial: `'start'|'end'`) | 无 |
| format | 展示的日期格式 | string | "YYYY-MM-DD HH:mm:ss" |
| ranges       | 预设时间范围快捷选择 | { \[range: string]: [moment](http://momentjs.com/)\[] } \| { \[range: string]: () => [moment](http://momentjs.com/)\[] } | 无 |
| renderExtraFooter | 在面板中添加额外的页脚 | slot="renderExtraFooter" | - |
| renderExtraFooter | 在面板中添加额外的页脚 | slot="renderExtraFooter" slot-scope="mode" | - |
| showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/components/time-picker-cn/#API) |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒 | [moment](http://momentjs.com/)\[] | \[moment(), moment()] |
| value(v-model) | 日期 | [moment](http://momentjs.com/)\[] | 无 |

1
components/date-picker/interface.js

@ -53,6 +53,7 @@ export const DatePickerProps = () => ({
// onOpenChange?: (status: bool) => void;
// onOk?: (selectedTime: moment.Moment) => void;
placeholder: PropTypes.string,
mode: PropTypes.oneOf(['time', 'date', 'month', 'year']),
});
export const MonthPickerProps = () => ({

6
components/date-picker/locale/example.json

@ -31,9 +31,5 @@
},
"timePickerLocale": {
"placeholder": "Select time"
},
"dateFormat": "YYYY-MM-DD",
"dateTimeFormat": "YYYY-MM-DD HH:mm:ss",
"weekFormat": "YYYY-wo",
"monthFormat": "YYYY-MM"
}
}

44
components/date-picker/wrapPicker.js

@ -4,6 +4,21 @@ import LocaleReceiver from '../locale-provider/LocaleReceiver';
import { generateShowHourMinuteSecond } from '../time-picker';
import enUS from './locale/en_US';
import { getOptionProps, initDefaultProps } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider';
const DEFAULT_FORMAT = {
date: 'YYYY-MM-DD',
dateTime: 'YYYY-MM-DD HH:mm:ss',
week: 'gggg-wo',
month: 'YYYY-MM',
};
const LOCALE_FORMAT_MAPPING = {
date: 'dateFormat',
dateTime: 'dateTimeFormat',
week: 'weekFormat',
month: 'monthFormat',
};
function getColumns({ showHour, showMinute, showSecond, use12Hours }) {
let column = 0;
@ -22,22 +37,21 @@ function getColumns({ showHour, showMinute, showSecond, use12Hours }) {
return column;
}
export default function wrapPicker(Picker, props, defaultFormat) {
export default function wrapPicker(Picker, props, pickerType) {
return {
name: Picker.name,
props: initDefaultProps(props, {
format: defaultFormat || 'YYYY-MM-DD',
transitionName: 'slide-up',
popupStyle: {},
locale: {},
prefixCls: 'ant-calendar',
inputPrefixCls: 'ant-input',
}),
model: {
prop: 'value',
event: 'change',
},
inject: {
configProvider: { default: () => ({}) },
},
mounted() {
const { autoFocus, disabled } = this;
if (autoFocus && !disabled) {
@ -89,7 +103,24 @@ export default function wrapPicker(Picker, props, defaultFormat) {
renderPicker(locale, localeCode) {
const props = getOptionProps(this);
const { prefixCls, inputPrefixCls, size, showTime, disabled } = props;
const {
prefixCls: customizePrefixCls,
inputPrefixCls: customizeInputPrefixCls,
size,
showTime,
disabled,
format,
} = props;
const mergedPickerType = showTime ? `${pickerType}Time` : pickerType;
const mergedFormat =
format ||
locale[LOCALE_FORMAT_MAPPING[mergedPickerType]] ||
DEFAULT_FORMAT[mergedPickerType];
const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls;
const prefixCls = getPrefixCls('calendar', customizePrefixCls);
const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls);
const pickerClass = classNames(`${prefixCls}-picker`, {
[`${prefixCls}-picker-${size}`]: !!size,
});
@ -121,6 +152,7 @@ export default function wrapPicker(Picker, props, defaultFormat) {
const pickerProps = {
props: {
...props,
format: mergedFormat,
pickerClass,
pickerInputClass,
locale,

2
components/modal/demo/confirm-router.md

@ -23,7 +23,7 @@ export default {
for (let i = 0; i < 3; i += 1) {
setTimeout(() => {
this.$confirm({
content: ( // JSX support
content: (
<Button onClick={this.destroyAll}>
Click to destroy all
</Button>

Loading…
Cancel
Save