From f93798446e623418a6d36697a09fd7017a3b84fa Mon Sep 17 00:00:00 2001 From: Jiewei Qian Date: Tue, 10 Oct 2017 20:49:41 +1100 Subject: [PATCH] *-picker: refactor (#7367) * Revert "Picker only emit user change (#6214)" This reverts commit 1912c473ef0fed4fe4ac9cb68f73d6995604131a. * picker/util: add helper methods range: n => Array modify{Date, Time}: Date => Date clear{Time, Milliseconds}: Date => Date limitTimeRange: Date => Date timeWithinRange: Date, [Date] => Boolean * time-spinner: refactory * time-panel: refactory * picker refactory * date-panel, *-table: refactory * time-select: refactory * test: update time-picker * test: update date-picker * time-range: refactory * date-range: refactory * test: update time-select * test: update form date-picker/time-picker * docs: update date-picker --- examples/docs/en-US/date-picker.md | 109 +++- examples/docs/en-US/datetime-picker.md | 6 +- examples/docs/en-US/time-picker.md | 8 +- examples/docs/zh-CN/date-picker.md | 107 +++- examples/docs/zh-CN/datetime-picker.md | 4 +- examples/docs/zh-CN/time-picker.md | 4 +- packages/date-picker/src/basic/date-table.vue | 46 +- .../date-picker/src/basic/month-table.vue | 54 +- .../date-picker/src/basic/time-spinner.vue | 149 +++--- packages/date-picker/src/basic/year-table.vue | 59 +-- packages/date-picker/src/panel/date-range.vue | 286 ++++++----- packages/date-picker/src/panel/date.vue | 336 ++++++------ packages/date-picker/src/panel/time-range.vue | 205 ++++---- .../date-picker/src/panel/time-select.vue | 51 +- packages/date-picker/src/panel/time.vue | 127 ++--- packages/date-picker/src/picker.vue | 329 ++++++++---- .../date-picker/src/picker/date-picker.js | 30 -- .../date-picker/src/picker/time-picker.js | 44 -- .../date-picker/src/picker/time-select.js | 30 -- packages/date-picker/src/util/index.js | 153 +++--- test/unit/specs/date-picker.spec.js | 479 +++++++++++++++--- test/unit/specs/form.spec.js | 78 +-- test/unit/specs/time-picker.spec.js | 192 ++++--- test/unit/specs/time-select.spec.js | 12 +- 24 files changed, 1767 insertions(+), 1131 deletions(-) diff --git a/examples/docs/en-US/date-picker.md b/examples/docs/en-US/date-picker.md index d930911cd..37ef89a6b 100644 --- a/examples/docs/en-US/date-picker.md +++ b/examples/docs/en-US/date-picker.md @@ -57,7 +57,11 @@ value4: '', value5: '', value6: '', - value7: '' + value7: '', + value8: '', + value9: '', + value10: '', + value11: '' }; } }; @@ -275,25 +279,116 @@ Picking a date range is supported. ::: +### Default Value + +If user hasn't picked a date, shows today's calendar by default. You can use `default-value` to set another date. Its value should be parsable by `new Date()`. + +If type is `daterange`, `default-value` sets the left side calendar. + +:::demo +```html + + + +``` +::: + +### Formatted Value + +By default, DatePicker emits `Date` object. You can use `value-format` to designate the format of emitted value, it accepts the same format string of `format` attribute. + +:::warning +This feature is at alpha stage. Feedback welcome. +::: + +:::demo +```html + + + +``` +::: + ### Attributes | Attribute | Description | Type | Accepted Values | Default | |---------- |-------------- |---------- |-------------------------------- |-------- | | readonly | whether DatePicker is read only | boolean | — | false | | disabled | whether DatePicker is disabled | boolean | — | false | -|size | size of Input | string | large/small/mini | — | +| size | size of Input | string | large/small/mini | — | | editable | whether the input is editable | boolean | — | true | | clearable | Whether to show clear button | boolean | — | true | | placeholder | placeholder in non-range mode | string | — | — | | start-placeholder | placeholder for the start date in range mode | string | — | — | | end-placeholder | placeholder for the end date in range mode | string | — | — | | type | type of the picker | string | year/month/date/datetime/ week/datetimerange/daterange | date | -| format | format of the picker | string | year `yyyy` month `MM` day `dd`, hour `HH`, minute `mm`, second `ss` | yyyy-MM-dd | +| format | format of the input box | string | year `yyyy`, month `MM`, day `dd`, hour `HH`, minute `mm`, second `ss` | yyyy-MM-dd | | align | alignment | left/center/right | left | | popper-class | custom class name for DatePicker's dropdown | string | — | — | | picker-options | additional options, check the table below | object | — | {} | -| range-separator | range separator | string | - | '-' | -| default-value | optional default time of the picker | Date | anything accepted by `new Date()` | - | -|name | same as `name` in native input | string | — | — | +| range-separator | range separator | string | — | '-' | +| default-value | optional, default date of the calendar | Date | anything accepted by `new Date()` | — | +| value-format | optional, format of bounded value | string | year `yyyy`, month `MM`, day `dd`, hour `HH`, minute `mm`, second `ss` | — | +| name | same as `name` in native input | string | — | — | ### Picker Options | Attribute | Description | Type | Accepted Values | Default | @@ -313,7 +408,7 @@ Picking a date range is supported. ### Events | Event Name | Description | Parameters | |---------|--------|---------| -| change | triggers when input value changes | formatted value | +| change | triggers when user confirms the value | component's bounded value | | blur | triggers when Input blurs | (event: Event) | | focus | triggers when Input focuses | (event: Event) | diff --git a/examples/docs/en-US/datetime-picker.md b/examples/docs/en-US/datetime-picker.md index 71f726546..1014b10d1 100644 --- a/examples/docs/en-US/datetime-picker.md +++ b/examples/docs/en-US/datetime-picker.md @@ -251,7 +251,9 @@ DateTimePicker is derived from DatePicker and TimePicker. For a more detailed ex | popper-class | custom class name for DateTimePicker's dropdown | string | — | — | | picker-options | additional options, check the table below | object | — | {} | | range-separator | range separator | string | - | '-' | -|name | same as `name` in native input | string | — | — | +| default-value | optional, default date of the calendar | Date | anything accepted by `new Date()` | — | +| value-format | optional, format of bounded value | string | year `yyyy`, month `MM`, day `dd`, hour `HH`, minute `mm`, second `ss` | — | +| name | same as `name` in native input | string | — | — | ### Picker Options | Attribute | Description | Type | Accepted Values | Default | @@ -269,7 +271,7 @@ DateTimePicker is derived from DatePicker and TimePicker. For a more detailed ex ### Events | Event Name | Description | Parameters | |---------|--------|---------| -| change | triggers when input value changes | formatted value | +| change | triggers when user confirms the value | component's bounded value | | blur | triggers when Input blurs | (event: Event) | | focus | triggers when Input focuses | (event: Event) | diff --git a/examples/docs/en-US/time-picker.md b/examples/docs/en-US/time-picker.md index e9aaab6cb..303a834d3 100644 --- a/examples/docs/en-US/time-picker.md +++ b/examples/docs/en-US/time-picker.md @@ -161,12 +161,14 @@ Can pick an arbitrary time range. | placeholder | placeholder in non-range mode | string | — | — | | start-placeholder | placeholder for the start time in range mode | string | — | — | | end-placeholder | placeholder for the end time in range mode | string | — | — | -| value | value of the picker | date for Time Picker, and string for Time Select | hour `HH`, minute `mm`, second `ss` | HH:mm:ss | +| value | value of the picker | Date for Time Picker, and string for Time Select | hour `HH`, minute `mm`, second `ss` | HH:mm:ss | | align | alignment | left / center / right | left | | popper-class | custom class name for TimePicker's dropdown | string | — | — | | picker-options | additional options, check the table below | object | — | {} | | range-separator | range separator | string | - | '-' | -|name | same as `name` in native input | string | — | — | +| default-value | optional, default date of the calendar | Date for TimePicker, string for TimeSelect | anything accepted by `new Date()` for TimePicker, selectable value for TimeSelect | — | +| value-format | optional, only for TimePicker, format of bounded value | string | hour `HH`, minute `mm`, second `ss` | — | +| name | same as `name` in native input | string | — | — | ### Time Select Options | Attribute | Description | Type | Accepted Values | Default | @@ -187,6 +189,6 @@ Can pick an arbitrary time range. ### Events | Event Name | Description | Parameters | |---------|--------|---------| -| change | triggers when input value changes | formatted value | +| change | triggers when user confirms the value | component's bounded value | | blur | triggers when Input blurs | (event: Event) | | focus | triggers when Input focuses | (event: Event) | diff --git a/examples/docs/zh-CN/date-picker.md b/examples/docs/zh-CN/date-picker.md index cccd98e09..b83150a86 100644 --- a/examples/docs/zh-CN/date-picker.md +++ b/examples/docs/zh-CN/date-picker.md @@ -65,7 +65,11 @@ value4: '', value5: '', value6: '', - value7: '' + value7: '', + value8: '', + value9: '', + value10: '', + value11: '' }; } }; @@ -285,6 +289,96 @@ ``` ::: +### 默认显示日期 + +未选择日期时,默认显示今天的日历。使用`default-value`可以指定其他日期,该值需要能够被`new Date()`解析。 +类型为`daterange`时,指定左侧日历的日期。 + +:::demo +```html + + + +``` +::: + +### 返回值格式 + +默认情况下,组件接受并返回`Date`对象。 +使用`value-format`指定返回值的格式,支持的格式与`format`相同。 + +:::warning +该功能处于测试阶段,欢迎提供反馈。 +::: + +:::demo +```html + + + +``` +::: + ### Attributes | 参数 | 说明 | 类型 | 可选值 | 默认值 | |---------- |-------------- |---------- |-------------------------------- |-------- | @@ -297,12 +391,13 @@ | start-placeholder | 范围选择时开始日期的占位内容 | string | — | — | | end-placeholder | 范围选择时结束日期的占位内容 | string | — | — | | type | 显示类型 | string | year/month/date/week/ datetime/datetimerange/daterange | date | -| format | 时间日期格式化 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss` | yyyy-MM-dd | +| format | 输入框的时间日期格式 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss` | yyyy-MM-dd | | align | 对齐方式 | string | left, center, right | left | | popper-class | DatePicker 下拉框的类名 | string | — | — | -|picker-options | 当前时间日期选择器特有的选项参考下表 | object | — | {} | -| range-separator | 选择范围时的分隔符 | string | - | '-' | -| default-value | 可选,DatePicker打开时默认显示的时间 | Date | 可被new Date()解析 | - | +| picker-options | 当前时间日期选择器特有的选项参考下表 | object | — | {} | +| range-separator | 选择范围时的分隔符 | string | — | '-' | +| default-value | 可选,选择器打开时默认显示的时间 | Date | 可被`new Date()`解析 | — | +| value-format | 可选,绑定值的格式 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss` | — | | name | 原生属性 | string | — | — | ### Picker Options @@ -322,7 +417,7 @@ ### Events | 事件名称 | 说明 | 回调参数 | |---------|--------|---------| -| change | 当 input 的值改变时触发,返回值和文本框一致 | 格式化后的值 | +| change | 用户确认选定的值时触发 | 组件绑定值 | | blur | 当 input 失去焦点时触发 | (event: Event) | | focus | 当 input 获得焦点时触发 | (event: Event) | diff --git a/examples/docs/zh-CN/datetime-picker.md b/examples/docs/zh-CN/datetime-picker.md index dd4bdb50c..ccdf2409b 100644 --- a/examples/docs/zh-CN/datetime-picker.md +++ b/examples/docs/zh-CN/datetime-picker.md @@ -250,6 +250,8 @@ DateTimePicker 由 DatePicker 和 TimePicker 派生,`Picker Options` 或者其 | popper-class | DateTimePicker 下拉框的类名 | string | — | — | | picker-options | 当前时间日期选择器特有的选项参考下表 | object | — | {} | | range-separator | 选择范围时的分隔符 | string | - | '-' | +| default-value | 可选,选择器打开时默认显示的时间 | Date | 可被`new Date()`解析 | — | +| value-format | 可选,绑定值的格式 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss` | — | | name | 原生属性 | string | — | — | ### Picker Options @@ -268,7 +270,7 @@ DateTimePicker 由 DatePicker 和 TimePicker 派生,`Picker Options` 或者其 ### Events | Event Name | Description | Parameters | |---------|--------|---------| -| change | 当 input 的值改变时触发,返回值和文本框一致 | formatted value | +| change | 用户确认选定的值时触发 | 组件绑定值 | | blur | 当 input 失去焦点时触发 | (event: Event) | | focus | 当 input 获得焦点时触发 | (event: Event) | diff --git a/examples/docs/zh-CN/time-picker.md b/examples/docs/zh-CN/time-picker.md index 6b4dc2eb1..8349557af 100644 --- a/examples/docs/zh-CN/time-picker.md +++ b/examples/docs/zh-CN/time-picker.md @@ -166,6 +166,8 @@ | popper-class | TimePicker 下拉框的类名 | string | — | — | | picker-options | 当前时间日期选择器特有的选项参考下表 | object | — | {} | | range-separator | 选择范围时的分隔符 | string | - | '-' | +| value-format | 可选,仅TimePicker时可用,绑定值的格式,同DatePicker | string | 小时 `HH`,分 `mm`,秒 `ss` | — | +| default-value | 可选,选择器打开时默认显示的时间 | Date(TimePicker) / string(TimeSelect) | 可被`new Date()`解析(TimePicker) / 可选值(TimeSelect) | — | | name | 原生属性 | string | — | — | ### Time Select Options @@ -186,7 +188,7 @@ ### Events | 事件名 | 说明 | 参数 | |---------|--------|---------| -| change | 当 input 的值改变时触发,返回值和文本框一致 | formatted value | +| change | 用户确认选定的值时触发 | 组件绑定值 | | blur | 当 input 失去焦点时触发 | (event: Event) | | focus | 当 input 获得焦点时触发 | (event: Event) | diff --git a/packages/date-picker/src/basic/date-table.vue b/packages/date-picker/src/basic/date-table.vue index 3752148ca..e9ab4d2cd 100644 --- a/packages/date-picker/src/basic/date-table.vue +++ b/packages/date-picker/src/basic/date-table.vue @@ -30,7 +30,7 @@ diff --git a/packages/date-picker/src/panel/time-select.vue b/packages/date-picker/src/panel/time-select.vue index a51ede5ae..1fcdabd55 100644 --- a/packages/date-picker/src/panel/time-select.vue +++ b/packages/date-picker/src/panel/time-select.vue @@ -9,7 +9,7 @@
{{ item.value }}
@@ -78,11 +78,6 @@ watch: { value(val) { if (!val) return; - if (this.minTime && compareTime(val, this.minTime) < 0) { - this.$emit('pick', '', false, false); - } else if (this.maxTime && compareTime(val, this.maxTime) > 0) { - this.$emit('pick', '', false, false); - } this.$nextTick(() => this.scrollToOption()); } }, @@ -95,34 +90,47 @@ }, handleClear() { - this.$emit('pick', '', false, false); + this.$emit('pick'); }, - scrollToOption(className = 'selected') { + scrollToOption(selector = '.selected') { const menu = this.$refs.popper.querySelector('.el-picker-panel__content'); - scrollIntoView(menu, menu.getElementsByClassName(className)[0]); + scrollIntoView(menu, menu.querySelector(selector)); }, handleMenuEnter() { - this.$nextTick(() => this.scrollToOption()); + const selected = this.items.map(item => item.value).indexOf(this.value) !== -1; + const hasDefault = this.items.map(item => item.value).indexOf(this.defaultValue) !== -1; + const option = (selected && '.selected') || (hasDefault && '.default') || '.time-select-item:not(.disabled)'; + this.$nextTick(() => this.scrollToOption(option)); }, scrollDown(step) { const items = this.items; + const length = items.length; + let total = items.length; let index = items.map(item => item.value).indexOf(this.value); - let length = items.length; - let total = Math.abs(step); - step = step > 0 ? 1 : -1; - while (length-- && total) { - index = (index + step + items.length) % items.length; - const item = items[index]; - if (!item.disabled) { - total--; + while (total--) { + index = (index + step + length) % length; + if (!items[index].disabled) { + this.$emit('pick', items[index].value, true); + return; } } - if (!items[index].disabled) { - this.value = items[index].value; - this.$emit('pick', this.value, true); + }, + + isValidValue(date) { + return this.items.filter(item => !item.disabled).map(item => item.value).indexOf(date) !== -1; + }, + + handleKeydown(event) { + const keyCode = event.keyCode; + if (keyCode === 38 || keyCode === 40) { + const mapping = { 40: 1, 38: -1 }; + const offset = mapping[keyCode.toString()]; + this.scrollDown(offset); + event.stopPropagation(); + return; } } }, @@ -134,6 +142,7 @@ end: '18:00', step: '00:30', value: '', + defaultValue: '', visible: false, minTime: '', maxTime: '', diff --git a/packages/date-picker/src/panel/time.vue b/packages/date-picker/src/panel/time.vue index 447cfcad4..cb0bf68dd 100644 --- a/packages/date-picker/src/panel/time.vue +++ b/packages/date-picker/src/panel/time.vue @@ -1,7 +1,7 @@