diff --git a/src/TimePicker/src/main.vue b/src/TimePicker/src/main.vue index ae08a2fc9..68bf18f3c 100644 --- a/src/TimePicker/src/main.vue +++ b/src/TimePicker/src/main.vue @@ -10,14 +10,17 @@ ref="activator" v-model="displayTimeString" class="n-time-picker-input" + passively-activated :force-focus="active" :placeholder="localizedPlaceholder" - lazy-focus + :clearable="clearable" @focus="handleTimeInputFocus" + @blur="handleTimeInputBlur" + @activate="handleTimeInputActivate" + @deactivate="handleTimeInputDeactivate" @click="handleActivatorClick" @input="handleTimeInput" - @wrapper-blur-to-outside="handleTimeInputWrapperBlur" - @blur="handleTimeInputBlur" + @clear="handleTimeInputClear" />
+
@@ -175,8 +182,9 @@ import getMinutes from 'date-fns/getMinutes' import getHours from 'date-fns/getHours' import getSeconds from 'date-fns/getSeconds' import { strictParse } from '../../_utils/component/datePicker' -import zhCN from 'date-fns/locale/zh-CN' -import enUS from 'date-fns/locale/en-US' +import keyboardDelegate from '../../_utils/delegate/keyboardDelegate' +import { KEY_CODE } from '../../_utils/event/keyCode' +import NBaseFocusDetector from '../../_base/FocusDetector' const DEFAULT_FORMAT = 'HH:mm:ss' @@ -192,7 +200,8 @@ export default { name: 'NTimePicker', components: { NInput, - NScrollbar + NScrollbar, + NBaseFocusDetector }, directives: { clickoutside @@ -244,6 +253,10 @@ export default { default: () => { return false } + }, + clearable: { + type: Boolean, + default: false } }, data () { @@ -271,12 +284,6 @@ export default { localizedPositiveText () { return this.localeNamespace.positiveText }, - dateFnsLocale () { - return ({ - 'zh-CN': zhCN, - 'en-US': enUS - })[this.locale] - }, dateFnsOptions () { return { locale: this.dateFnsLocale @@ -352,21 +359,43 @@ export default { } }, methods: { + handleTimeInputClear (e) { + e.stopPropagation() + this.$emit('change', null) + this.refreshTimeString(null) + }, + handleFocusDectorFocus () { + this.closeTimeSelector({ + returnFocus: true, + emitBlur: false + }) + }, + handleMenuKeyDown (e) { + switch (e.keyCode) { + case KEY_CODE.ESC: + this.closeTimeSelector({ + returnFocus: true, + emitBlur: false + }) + break + case KEY_CODE.TAB: + const shiftPressed = keyboardDelegate.getKeyboardStatus().shiftPressed + if (shiftPressed && e.target === this.$refs.panel) { + e.preventDefault() + this.closeTimeSelector({ + returnFocus: true, + emitBlur: false + }) + } + break + } + }, disableTransitionOneTick (unit) { this[unit + 'TransitionDisabled'] = true this.$nextTick().then(() => { this[unit + 'TransitionDisabled'] = false }) }, - afterBlur (e) { - if (this.active) { - this.$nextTick().then(() => { - if (!(this.$refs.panel && this.$refs.panel.contains(document.activeElement))) { - this.closeTimeSelector() - } - }) - } - }, justifyValueAfterChangeDisplayTimeString () { const time = strictParse(this.displayTimeString, this.format, new Date(), this.dateFnsOptions) if (isValid(time)) { @@ -426,14 +455,36 @@ export default { } }, handleTimeInputFocus () { + this.$emit('focus') + }, + handleTimeInputBlur (e) { + if (this.active) { + const panel = this.$refs.panel + if (!( + panel && + panel.contains(e.relatedTarget) + )) { + this.$emit('blur') + this.closeTimeSelector({ + returnFocus: false, + emitBlur: false + }) + } + } + }, + handleTimeInputActivate () { if (this.disabled) return if (!this.active) { this.openTimeSelector() } }, - handleTimeInputBlur () { + handleTimeInputDeactivate (e) { + if (this.disabled) return this.refreshTimeString() - this.afterBlur() + this.closeTimeSelector({ + returnFocus: false, + emitBlur: false + }) }, scrollTimer () { if (this.$refs.hours && this.$refs.hours.$el) { @@ -466,14 +517,25 @@ export default { } }, handleClickOutside (e) { - if (!this.$refs.activator.$el.contains(e.target)) { - this.closeTimeSelector() + if (this.active && !this.$refs.activator.$el.contains(e.target)) { + this.closeTimeSelector({ + returnFocus: false, + emitBlur: true + }) } }, - closeTimeSelector (returnFocus = false) { - this.active = false - if (!returnFocus) { - this.$emit('blur', this.value) + closeTimeSelector ({ + returnFocus, + emitBlur + }) { + if (this.active) { + this.active = false + if (returnFocus) { + this.$refs.activator.focus() + } + if (emitBlur) { + this.$emit('blur') + } } }, handleTimeInput () { @@ -485,7 +547,7 @@ export default { }, handleNowClick () { const now = new Date() - if (!this.value) this.$emit('change', now.valueOf()) + if (!this.value) this.$emit('change', getTime(now)) else { const newValue = setSeconds( setMinutes( @@ -497,7 +559,7 @@ export default { ), getSeconds(now) ) - this.$emit('change', newValue) + this.$emit('change', getTime(newValue)) } }, handleConfirmClick () { @@ -505,7 +567,10 @@ export default { return } this.refreshTimeString() - this.closeTimeSelector() + this.closeTimeSelector({ + returnFocus: true, + emitBlur: false + }) } } } diff --git a/src/_utils/delegate/keyboardDelegate.js b/src/_utils/delegate/keyboardDelegate.js new file mode 100644 index 000000000..6adf54d64 --- /dev/null +++ b/src/_utils/delegate/keyboardDelegate.js @@ -0,0 +1,44 @@ +import { KEY_CODE } from '../event/keyCode' + +class KeyboardDelegate { + constructor () { + this.shiftPressed = false + this.ctrlPressed = false + this.commandPressed = false + window.addEventListener('keydown', e => { + switch (e.keyCode) { + case KEY_CODE.SHIFT: + this.shiftPressed = true + break + case KEY_CODE.CTRL: + this.ctrlPressed = true + break + case KEY_CODE.COMMAND: + this.commandPressed = true + break + } + }) + window.addEventListener('keyup', e => { + switch (e.keyCode) { + case KEY_CODE.SHIFT: + this.shiftPressed = false + break + case KEY_CODE.CTRL: + this.ctrlPressed = false + break + case KEY_CODE.ALT: + this.commandPressed = false + break + } + }) + } + getKeyboardStatus () { + return { + shiftPressed: this.shiftPressed, + ctrlPressed: this.ctrlPressed, + commandPressed: this.commandPressed + } + } +} + +export default new KeyboardDelegate() diff --git a/src/_utils/event/keyCode.js b/src/_utils/event/keyCode.js index f49caef1e..25796b9b2 100644 --- a/src/_utils/event/keyCode.js +++ b/src/_utils/event/keyCode.js @@ -3,7 +3,12 @@ const KEY_CODE = { LEFT: 37, UP: 38, RIGHT: 39, - DOWN: 40 + DOWN: 40, + SHIFT: 16, + CTRL: 17, + TAB: 9, + COMMAND: 18, + ESC: 27 } export {