From ad76b5736ec735b25bdaa0a10a83a6582902d422 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Wed, 30 Oct 2019 16:22:17 +0800 Subject: [PATCH] feat(date-picker): change & blur events & some keyboard bindings --- .../components/datePicker/enUS/events.md | 76 +++++++++++++ .../components/datePicker/enUS/index.md | 1 + packages/common/DatePicker/src/main.vue | 101 ++++++++++-------- .../src/panel/commonCalendarMixin.js | 7 ++ packages/common/DatePicker/src/panel/date.vue | 2 + .../common/DatePicker/src/panel/daterange.vue | 2 + .../common/DatePicker/src/panel/datetime.vue | 2 + .../DatePicker/src/panel/datetimerange.vue | 2 + .../DatePicker/src/panel/focusDetector.vue | 21 ++++ styles/DatePicker.scss | 30 +++--- styles/themes/dark/components/DatePicker.scss | 2 +- .../themes/light/components/DatePicker.scss | 2 +- 12 files changed, 187 insertions(+), 61 deletions(-) create mode 100644 demo/documentation/components/datePicker/enUS/events.md create mode 100644 packages/common/DatePicker/src/panel/focusDetector.vue diff --git a/demo/documentation/components/datePicker/enUS/events.md b/demo/documentation/components/datePicker/enUS/events.md new file mode 100644 index 000000000..fd9ab25da --- /dev/null +++ b/demo/documentation/components/datePicker/enUS/events.md @@ -0,0 +1,76 @@ +# Events +```html + + + + + +``` +```js +export default { + data() { + return { + datetime: 891360258000, + date: null, + datetimerange: [324910284, 910391323], + daterange: [324910284, 910391323], + disabled: false + }; + }, + methods: { + onBlur1 (v) { + this.$NMessage.info('Blur1 ' + v) + }, + onChange1 (v) { + this.$NMessage.info('Change1 ' + v) + }, + onBlur2 (v) { + this.$NMessage.error('Blur2 ' + v) + }, + onChange2 (v) { + this.$NMessage.error('Change2 ' + v) + }, + onBlur3 (v) { + this.$NMessage.warning('Blur3 ' + v) + }, + onChange3 (v) { + this.$NMessage.warning('Change3 ' + v) + }, + onBlur4 (v) { + this.$NMessage.success('Blur4 ' + v) + }, + onChange4 (v) { + this.$NMessage.success('Change4 ' + v) + } + } +}; +``` +```css +.n-date-picker { + margin: 0 12px 8px 0; +} +``` \ No newline at end of file diff --git a/demo/documentation/components/datePicker/enUS/index.md b/demo/documentation/components/datePicker/enUS/index.md index 4e42992da..3e268eb95 100644 --- a/demo/documentation/components/datePicker/enUS/index.md +++ b/demo/documentation/components/datePicker/enUS/index.md @@ -6,4 +6,5 @@ daterange datetimerange disabled actions +events ``` \ No newline at end of file diff --git a/packages/common/DatePicker/src/main.vue b/packages/common/DatePicker/src/main.vue index 770d8814b..7a16dfc53 100644 --- a/packages/common/DatePicker/src/main.vue +++ b/packages/common/DatePicker/src/main.vue @@ -10,12 +10,15 @@ > @@ -71,6 +78,7 @@ :actions="actions" :theme="synthesizedTheme" @input="handlePanelInput" + @blur="handlePanelBlur" @close="closeCalendar" /> @@ -190,7 +200,7 @@ export default { }, default: 'date' }, - splitor: { + seperator: { type: String, default: 'to' }, @@ -220,8 +230,7 @@ export default { displayTime: '', displayStartTime: '', displayEndTime: '', - active: false, - isFocus: false + active: false } }, computed: { @@ -261,15 +270,32 @@ export default { * If new value is valid, set calendarTime and refresh display strings. * If new value is invalid, do nothing. */ - value (newValue) { - console.log(newValue) + value (newValue, oldValue) { this.refresh(newValue) + if (this.isRange) { + if (!( + Array.isArray(newValue) && + Array.isArray(oldValue) && + newValue.length === 2 && + newValue.length === oldValue.length && + newValue[0] === oldValue[0] && + newValue[1] === oldValue[1] + )) { + this.$emit('change', newValue) + } + } else { this.$emit('change', newValue) } } }, created () { this.refresh(this.value) }, methods: { + /** + * this blur is not really blur event, its key tab out of panel + */ + handlePanelBlur () { + this.closeCalendar(true) + }, handleClickOutside (e) { if (this.active && !this.$refs.activator.contains(e.target)) { this.closeCalendar() @@ -315,19 +341,26 @@ export default { /** * Blur */ - handleTimeInputBlur () { + afterBlur (e) { + if (this.active) { + window.setTimeout(() => { + if (!(this.$refs.panel && this.$refs.panel.$el.contains(document.activeElement))) { + this.closeCalendar() + } + }, 0) + } + }, + handleTimeInputBlur (e) { if (this.disabled) return const newSelectedDateTime = strictParse(this.displayTime, this.computedFormat, new Date()) - console.log('handle blur', this.displayTime, this.computedFormat, new Date()) - console.log('handle blur new time', typeof newSelectedDateTime) if (isValid(newSelectedDateTime)) { this.$emit('input', getTime(newSelectedDateTime)) } else { this.refreshDisplayTime(this.value) } - this.isFocus = false + this.afterBlur(e) }, - handleRangeInputBlur () { + handleRangeInputBlur (e) { if (this.disabled) return const startDateTime = strictParse(this.displayStartTime, this.computedFormat, new Date()) const endDateTime = strictParse(this.displayEndTime, this.computedFormat, new Date()) @@ -336,28 +369,8 @@ export default { } else { this.changeStartEndTime(startDateTime, endDateTime) } - this.isFocus = false + this.afterBlur(e) }, - // handleStartTimeInputBlur () { - // if (this.disabled) return - // const startMoment = strictParse(this.displayStartTime, this.computedFormat, null) - // if (startMoment !== null) { - // this.changeStartDateTime(startMoment) - // } else { - // this.refresh(this.value) - // } - // this.isFocus = false - // }, - // handleEndTimeInputBlur () { - // if (this.disabled) return - // const endMoment = strictParse(this.displayStartTime, this.computedFormat, null) - // if (endMoment !== null) { - // this.changeStartDateTime(endMoment) - // } else { - // this.refresh(this.value) - // } - // this.isFocus = false - // }, /** * Input */ @@ -386,13 +399,6 @@ export default { this.displayEndTime = endTime // console.log('handleRangeInput', v, newStartTime, newEndTime) }, - // handleEndTimeInput (e) { - // const v = e.target.value - // const newEndTime = moment(v, this.computedFormat, true) - // if (newEndTime.isValid()) { - // this.changeEndDateTime(newEndTime) - // } - // }, /** * Click */ @@ -411,7 +417,7 @@ export default { */ handleFocus () { if (this.disabled) return - this.isFocus = true + if (!this.active) this.openCalendar() }, /** * Calendar @@ -419,11 +425,18 @@ export default { openCalendar (e) { if (this.disabled || this.active) return this.active = true - // console.log('into open calendar') this.$nextTick().then(this.updatePosition) }, - closeCalendar () { - this.active = false + closeCalendar (returnFocus = false) { + if (this.active) { + this.active = false + this.$emit('blur', this.value) + if (returnFocus) { + if (this.$refs.input && this.$refs.input.$el) { + this.$refs.input.$el.focus() + } + } + } }, toggleCalendar () { diff --git a/packages/common/DatePicker/src/panel/commonCalendarMixin.js b/packages/common/DatePicker/src/panel/commonCalendarMixin.js index d2f9343c9..692329e89 100644 --- a/packages/common/DatePicker/src/panel/commonCalendarMixin.js +++ b/packages/common/DatePicker/src/panel/commonCalendarMixin.js @@ -1,4 +1,5 @@ import clickoutside from '../../../../directives/clickoutside' +import focusDetector from './focusDetector' const TIME_CONST = { weekdays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], @@ -11,6 +12,9 @@ export default { directives: { clickoutside }, + components: { + focusDetector + }, data () { return { noTransition: false, @@ -21,6 +25,9 @@ export default { clearValue () { this.$emit('input', null) }, + handleBlur (e) { + this.$emit('blur', e) + }, banTransitionOneTick () { if (this.active) { this.noTransition = true diff --git a/packages/common/DatePicker/src/panel/date.vue b/packages/common/DatePicker/src/panel/date.vue index 15278fa99..64366265f 100644 --- a/packages/common/DatePicker/src/panel/date.vue +++ b/packages/common/DatePicker/src/panel/date.vue @@ -3,6 +3,7 @@
diff --git a/packages/common/DatePicker/src/panel/daterange.vue b/packages/common/DatePicker/src/panel/daterange.vue index 2c9ec73b1..52fe92581 100644 --- a/packages/common/DatePicker/src/panel/daterange.vue +++ b/packages/common/DatePicker/src/panel/daterange.vue @@ -3,6 +3,7 @@
diff --git a/packages/common/DatePicker/src/panel/datetime.vue b/packages/common/DatePicker/src/panel/datetime.vue index 336228121..1d24ff8ab 100644 --- a/packages/common/DatePicker/src/panel/datetime.vue +++ b/packages/common/DatePicker/src/panel/datetime.vue @@ -3,6 +3,7 @@
diff --git a/packages/common/DatePicker/src/panel/datetimerange.vue b/packages/common/DatePicker/src/panel/datetimerange.vue index 2d9c90014..7ec9d3549 100644 --- a/packages/common/DatePicker/src/panel/datetimerange.vue +++ b/packages/common/DatePicker/src/panel/datetimerange.vue @@ -3,6 +3,7 @@
+
diff --git a/packages/common/DatePicker/src/panel/focusDetector.vue b/packages/common/DatePicker/src/panel/focusDetector.vue new file mode 100644 index 000000000..11bbabc9b --- /dev/null +++ b/packages/common/DatePicker/src/panel/focusDetector.vue @@ -0,0 +1,21 @@ + + + diff --git a/styles/DatePicker.scss b/styles/DatePicker.scss index cfcacaf3d..4ccd93a11 100644 --- a/styles/DatePicker.scss +++ b/styles/DatePicker.scss @@ -14,6 +14,7 @@ @include b(date-picker-panel) { @include once { + outline: none; @include fade-in-scale-up-transition(date-picker-panel); margin-top: 4px; margin-bottom: 4px; @@ -165,7 +166,9 @@ } } - + &:hover { + background-color: map-get($--date-picker-item-background-color, 'hover'); + } @include not-m(in-display-month) { color: map-get($--date-picker-item-text-color, 'inactive'); } @@ -202,21 +205,18 @@ } } } - @include m(selected) { - @include once { - border-radius: 3px; - width: 24px; - margin: 8px 11px; - } - color: map-get($--date-picker-item-text-color, 'active'); - background-color: map-get($--date-picker-item-background-color, 'active'); - &::after { - background-color: map-get($--date-picker-item-sup-color, 'active'); - } - } } - &:hover { - background-color: map-get($--date-picker-item-background-color, 'hover'); + @include m(selected) { + @include once { + border-radius: 3px; + width: 24px; + margin: 8px 11px; + } + color: map-get($--date-picker-item-text-color, 'active'); + background-color: map-get($--date-picker-item-background-color, 'active'); + &::after { + background-color: map-get($--date-picker-item-sup-color, 'active'); + } } } } diff --git a/styles/themes/dark/components/DatePicker.scss b/styles/themes/dark/components/DatePicker.scss index 70e849dfa..20ea6f354 100644 --- a/styles/themes/dark/components/DatePicker.scss +++ b/styles/themes/dark/components/DatePicker.scss @@ -18,5 +18,5 @@ 'active': $--primary-6 ) !global; $--date-picker-divider-color: rgba(255, 255, 255, .08) !global; - $--date-picker-box-shadow: 0px 2px 8px 0px rgba(0,0,0,0.12) !global; + $--date-picker-box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.18) !global; } \ No newline at end of file diff --git a/styles/themes/light/components/DatePicker.scss b/styles/themes/light/components/DatePicker.scss index a0e18afda..31c2edefe 100644 --- a/styles/themes/light/components/DatePicker.scss +++ b/styles/themes/light/components/DatePicker.scss @@ -18,5 +18,5 @@ 'active': $--primary-6 ) !global; $--date-picker-divider-color: $--n-divider-color !global; - $--date-picker-box-shadow: 0px 2px 8px 0px rgba(0,0,0,0.12) !global; + $--date-picker-box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.18) !global; } \ No newline at end of file