diff --git a/packages/components/time-picker/__tests__/time-picker.test.ts b/packages/components/time-picker/__tests__/time-picker.test.ts index d856bbe391..236b7c70af 100644 --- a/packages/components/time-picker/__tests__/time-picker.test.ts +++ b/packages/components/time-picker/__tests__/time-picker.test.ts @@ -6,6 +6,7 @@ import dayjs from 'dayjs' import triggerEvent from '@element-plus/test-utils/trigger-event' import { rAF } from '@element-plus/test-utils/tick' import { ElFormItem } from '@element-plus/components/form' +import sleep from '@element-plus/test-utils/sleep' import TimePicker from '../src/time-picker' import Picker from '../src/common/picker.vue' @@ -468,6 +469,63 @@ describe('TimePicker', () => { false ) }) + + it('can auto skip when disabled', async () => { + const disabledHoursArr = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 23, + ] + const wrapper = _mount( + ``, + () => ({ value: new Date(2016, 9, 20, 18, 30) }), + { + methods: { + disabledHours() { + return disabledHoursArr + }, + }, + } + ) + const input = wrapper.find('input') + input.trigger('focus') + await nextTick() + + const list = document.querySelectorAll('.el-time-spinner__list') + const hoursEl = list[0] + let activeHours = getSpinnerTextAsArray(hoursEl, '.is-active')[0] + + expect(activeHours).toEqual(20) + const hoursElWrapperList = document.querySelectorAll( + '.el-time-spinner__wrapper' + ) + const hoursElWrapper = hoursElWrapperList[0] + const hoursElArrowDown: Element | null = + hoursElWrapper.querySelector('.arrow-down') + expect(hoursElArrowDown).toBeTruthy() + + const mousedownEvt = new MouseEvent('mousedown') + const mouseupEvt = new MouseEvent('mouseup') + + const testTime = 130 + hoursElArrowDown.dispatchEvent(mousedownEvt) + hoursElArrowDown.dispatchEvent(mouseupEvt) + await sleep(testTime) + activeHours = getSpinnerTextAsArray(hoursEl, '.is-active')[0] + expect(activeHours).toEqual(21) + hoursElArrowDown.dispatchEvent(mousedownEvt) + hoursElArrowDown.dispatchEvent(mouseupEvt) + await sleep(testTime) + activeHours = getSpinnerTextAsArray(hoursEl, '.is-active')[0] + expect(activeHours).toEqual(22) + hoursElArrowDown.dispatchEvent(new MouseEvent('mousedown')) + hoursElArrowDown.dispatchEvent(new MouseEvent('mouseup')) + await sleep(testTime) + activeHours = getSpinnerTextAsArray(hoursEl, '.is-active')[0] + expect(activeHours).toEqual(20) + }) }) describe('TimePicker(range)', () => { diff --git a/packages/components/time-picker/src/time-picker-com/basic-time-spinner.vue b/packages/components/time-picker/src/time-picker-com/basic-time-spinner.vue index 806ecc2f15..538b4954e0 100644 --- a/packages/components/time-picker/src/time-picker-com/basic-time-spinner.vue +++ b/packages/components/time-picker/src/time-picker-com/basic-time-spinner.vue @@ -229,15 +229,29 @@ const scrollDown = (step: number) => { } const label = currentScrollbar.value! - let now = unref(timePartials)[label] + const now = unref(timePartials)[label] const total = currentScrollbar.value === 'hours' ? 24 : 60 - now = (now + step + total) % total + const next = findNextUnDisabled(label, now, step, total) - modifyDateField(label, now) - adjustSpinner(label, now) + modifyDateField(label, next) + adjustSpinner(label, next) nextTick(() => emitSelectRange(label)) } +const findNextUnDisabled = ( + type: TimeUnit, + now: number, + step: number, + total: number +) => { + let next = (now + step + total) % total + const list = unref(timeList)[type] + while (list[next] && next !== now) { + next = (next + step + total) % total + } + return next +} + const modifyDateField = (type: TimeUnit, value: number) => { const list = unref(timeList)[type] const isDisabled = list[value]