diff --git a/packages/devui-vue/devui/time-picker/__tests__/time-picker.spec.ts b/packages/devui-vue/devui/time-picker/__tests__/time-picker.spec.ts index 26f607222f33c227a8688a7b17638a415812c7d0..865b5c9d457cc1ced0481fa41b81c1120e2450e2 100644 --- a/packages/devui-vue/devui/time-picker/__tests__/time-picker.spec.ts +++ b/packages/devui-vue/devui/time-picker/__tests__/time-picker.spec.ts @@ -1,8 +1,204 @@ import { mount } from '@vue/test-utils'; -import { TimePicker } from '../index'; +import DTimePicker from '../src/time-picker'; +import { nextTick, ref } from 'vue'; describe('time-picker test', () => { it('time-picker init render', async () => { - // todo + + const wrapper = mount({ + components: { DTimePicker }, + template: ``, + + setup() { + return + } + }); + + const container = wrapper.find('.devui-time-picker'); + const timeUl = wrapper.findAll('.time-ul') + await nextTick() + expect(timeUl[0].element.childElementCount).toBe(24) + expect(timeUl[1].element.childElementCount).toBe(60) + expect(timeUl[2].element.childElementCount).toBe(60) + expect(container.classes()).toContain('devui-time-picker') + }) + + it('time-picker default open work', async () => { + + const wrapper = mount({ + components: { DTimePicker }, + template: ``, + setup() { + + const vModelValue = ref('12:30:40') + const autoOpen = ref(true) + + return { + vModelValue, + autoOpen + } + } + }); + + const timeInput = wrapper.find('.time-input') + const tiemPopup = wrapper.find('.devui-time-popup') + + await nextTick() + expect(timeInput.element.value).toBe('12:30:40') + expect(tiemPopup.classes()).toContain('devui-show-time-popup') + expect(tiemPopup.attributes('style')).toMatch('width: 300px'); + + }); + + it('time-picker disabled work', async () => { + const wrapper = mount(DTimePicker, { + props: { + disabled: true, + }, + }); + + expect(wrapper.find('.devui-time-picker').classes()).toContain('picker-disabled') + expect(wrapper.find('.time-input').element.disabled).toBe(true) + }) + + it('time-picker min-time work', async () => { + const wrapper = mount({ + components: { DTimePicker }, + template: ``, + setup() { + const vModelValue = ref('01:03:00') + return { + vModelValue + } + } + }) + + const timeInput = wrapper.find('.time-input') + await nextTick() + // 如果 v-mode 的时间超出 限制范围,将返回最小时间值 + expect(timeInput.element.value).toBe('01:04:30') + }) + + it('time-picker max-time work', async () => { + const wrapper = mount({ + components: { DTimePicker }, + template: ``, + setup() { + const vModelValue = ref('23:30:00') + return { + vModelValue + } + } + }) + + const timeInput = wrapper.find('.time-input') + await nextTick() + expect(timeInput.element.value).toBe('22:46:20') + }) + + it('time-picker format mm:HH:ss work', async () => { + const wrapper = mount({ + components: { DTimePicker }, + template: ``, + setup() { + const vModelValue = ref('23:30:00') + return { + vModelValue + } + } + }) + + const timeInput = wrapper.find('.time-input') + await nextTick() + expect(timeInput.element.value).toBe('30:23:00') + }) + + it('time-picker format mm:ss work', async () => { + const wrapper = mount({ + components: { DTimePicker }, + template: ``, + setup() { + const vModelValue = ref('23:30:00') + return { + vModelValue + } + } + }) + + const timeInput = wrapper.find('.time-input') + await nextTick() + expect(timeInput.element.value).toBe('30:00') + }) + + it('time-picker format hh:mm work', async () => { + const wrapper = mount({ + components: { DTimePicker }, + template: ``, + setup() { + const vModelValue = ref('23:30:00') + return { + vModelValue + } + } + }) + + const timeInput = wrapper.find('.time-input') + await nextTick() + expect(timeInput.element.value).toBe('23:30') + }) + + it('time-picker slot customViewTemplate work', async () => { + + const slotDemo = ref() + + const chooseTime = () => { + const timeObj = { + time: '21', + type: 'mm' + } + slotDemo.value.chooseTime(timeObj) + } + // 插槽内方法 -- 选择当前时间 + const chooseNowFun = () => { + const date = new Date() + const hour = date.getHours() > 9 ? date.getHours() : '0' + date.getHours() + const minute = date.getMinutes() > 9 ? date.getMinutes() : '0' + date.getMinutes() + const second = date.getSeconds() > 9 ? date.getSeconds() : '0' + date.getSeconds() + const timeObj = { + time: hour + ':' + minute + ':' + second + } + slotDemo.value.chooseTime(timeObj) + + return timeObj.time + } + + const wrapper = mount({ + components: { DTimePicker }, + template: ` + + + `, + setup() { + return { + chooseNowFun, + chooseTime, + slotDemo + } + } + }) + + const timeInput = wrapper.find('.time-input') + const slotBottomNow = wrapper.find('.slot-bottom-now') + const slotBottomOne = wrapper.find('.slot-bottom-one') + await slotBottomNow.trigger('click') + expect(timeInput.element.value).toBe(chooseNowFun()) + + await slotBottomOne.trigger('click') + expect(timeInput.element.value).toMatch(/21/) }) }) diff --git a/packages/devui-vue/devui/time-picker/index.ts b/packages/devui-vue/devui/time-picker/index.ts index 7535762542f21f511e69c6dcd2f056a6c5ba224f..85c682ab4d4724704f772c4c0ab14652024dd2c9 100644 --- a/packages/devui-vue/devui/time-picker/index.ts +++ b/packages/devui-vue/devui/time-picker/index.ts @@ -10,7 +10,7 @@ export { TimePicker } export default { title: 'TimePicker 时间选择器', category: '数据录入', - status: '80%', // TODO: 组件若开发完成则填入"已完成",并删除该注释 + status: '90%', // TODO: 组件若开发完成则填入"已完成",并删除该注释 install(app: App): void { app.use(TimePicker as any) } diff --git a/packages/devui-vue/devui/time-picker/src/composables/use-time-picker.ts b/packages/devui-vue/devui/time-picker/src/composables/use-time-picker.ts index f80fdedb43b5463499f00facb82bcce7e2a01c1d..9b2f58b9dfcb0998870e73930f57ee2ec1a6e027 100644 --- a/packages/devui-vue/devui/time-picker/src/composables/use-time-picker.ts +++ b/packages/devui-vue/devui/time-picker/src/composables/use-time-picker.ts @@ -3,7 +3,7 @@ import { TimeObj } from '../types' import { getPositionFun } from '../utils' export default function useTimePicker( - hh:Ref,mm:Ref,ss:Ref,minTime:string,format:string, + hh:Ref,mm:Ref,ss:Ref,minTime:string,maxTime:string,format:string, autoOpen:boolean,disabled:boolean,value:string ):any{ const isActive = ref(false) @@ -37,19 +37,42 @@ export default function useTimePicker( const mouseInIputFun = ()=>{ if(firsthandActiveTime.value == '00:00:00'){ + const vModelValueArr = vModeValue.value.split(':') + const minTimeValueArr = minTime.split(':') + vModeValue.value == '' ? vModeValue.value = '00:00:00' : '' - - vModeValue.value > minTime - ? firsthandActiveTime.value = vModeValue.value - : firsthandActiveTime.value = minTime + + if( vModeValue.value > minTime ){ + firsthandActiveTime.value = vModeValue.value + setInputValue(vModelValueArr[0],vModelValueArr[1],vModelValueArr[2]) + }else{ + firsthandActiveTime.value = minTime + setInputValue(minTimeValueArr[0],minTimeValueArr[1],minTimeValueArr[2]) + } } - setInputValue() + isActive.value = true showPopup.value = true } + /** + * 判断v-model 绑定的时间是否超出 最大值 最小值 范围 + * 如果带有格式化 , 将执行格式化 + * */ + const vModelIsBeyond = ()=>{ + if(vModeValue.value != '' && vModeValue.value < minTime){ + vModeValue.value = minTime + }else if( vModeValue.value != '' && vModeValue.value > maxTime ){ + vModeValue.value = maxTime + } + + const vModelValueArr = vModeValue.value.split(':') + vModeValue.value && setInputValue(vModelValueArr[0],vModelValueArr[1],vModelValueArr[2]) + } + + const getTimeValue = (e:MouseEvent)=>{ e.stopPropagation() if(showPopup.value){ @@ -57,19 +80,19 @@ export default function useTimePicker( mm.value = timePopupDom.value.changTimeData().activeMinute.value ss.value = timePopupDom.value.changTimeData().activeSecond.value firsthandActiveTime.value = `${hh.value}:${mm.value}:${ss.value}` - setInputValue() + setInputValue(hh.value,mm.value,ss.value) } } - const setInputValue = ()=> { + const setInputValue = (hh:string,mm:string,ss:string)=> { if(format == 'hh:mm:ss'){ - vModeValue.value = `${hh.value}:${mm.value}:${ss.value}` + vModeValue.value = `${hh}:${mm}:${ss}` }else if(format == 'mm:hh:ss'){ - vModeValue.value = `${mm.value}:${hh.value}:${ss.value}` + vModeValue.value = `${mm}:${hh}:${ss}` }else if(format == 'hh:mm'){ - vModeValue.value = `${hh.value}:${mm.value}` + vModeValue.value = `${hh}:${mm}` }else if(format == 'mm:ss'){ - vModeValue.value = `${mm.value}:${ss.value}` + vModeValue.value = `${mm}:${ss}` } } @@ -88,7 +111,7 @@ export default function useTimePicker( ss.value = '00' } firsthandActiveTime.value = `${hh.value}:${mm.value}:${ss.value}` - setInputValue() + setInputValue(hh.value,mm.value,ss.value) } const isOutOpen =()=>{ @@ -100,7 +123,9 @@ export default function useTimePicker( ss.value = timeArr[2] firsthandActiveTime.value = vModeValue.value - setInputValue() + + setInputValue(hh.value,mm.value,ss.value) + isActive.value = true showPopup.value = autoOpen } @@ -117,14 +142,14 @@ export default function useTimePicker( ss.value = slotTime.time } firsthandActiveTime.value = `${hh.value}:${mm.value}:${ss.value}` - setInputValue() + setInputValue(hh.value,mm.value,ss.value) } else { const timeArr = slotTime.time.split(':') hh.value = timeArr[0] mm.value = timeArr[1] ss.value = timeArr[2] firsthandActiveTime.value = `${hh.value}:${mm.value}:${ss.value}` - setInputValue() + setInputValue(hh.value,mm.value,ss.value) } } @@ -140,10 +165,10 @@ export default function useTimePicker( firsthandActiveTime, vModeValue, getPopupPosition, - setInputValue, getTimeValue, clickVerifyFun, isOutOpen, + vModelIsBeyond, clearAll, chooseTime } diff --git a/packages/devui-vue/devui/time-picker/src/time-picker.tsx b/packages/devui-vue/devui/time-picker/src/time-picker.tsx index 857ca20e7f249e538172abdd084ee66a0c146c95..15be03e08c1ec8b8f58aff5dd79aabb5a4f48158 100644 --- a/packages/devui-vue/devui/time-picker/src/time-picker.tsx +++ b/packages/devui-vue/devui/time-picker/src/time-picker.tsx @@ -30,11 +30,12 @@ export default defineComponent({ getTimeValue, clickVerifyFun, isOutOpen, + vModelIsBeyond, clearAll, timePopupDom, vModeValue, getPopupPosition - } = useTimePicker(activeHour,activeMinute,activeSecond,props.minTime,format,props.autoOpen,props.disabled,props.modelValue) + } = useTimePicker(activeHour,activeMinute,activeSecond,props.minTime,props.maxTime,format,props.autoOpen,props.disabled,props.modelValue) const selectedTimeChage = (e:MouseEvent) => { @@ -46,6 +47,7 @@ export default defineComponent({ onMounted(() => { getPopupPosition() isOutOpen() + vModelIsBeyond() document.addEventListener('click', clickVerifyFun) document.addEventListener('click',getTimeValue) document.addEventListener('scroll',getPopupPosition) @@ -60,7 +62,7 @@ export default defineComponent({ watch(vModeValue,(newValue:string)=>{ ctx.emit('update:modelValue',vModeValue.value) - if(newValue != props.minTime){ + if(newValue != props.minTime && newValue != '00:00'){ showClearIcon.value = true }else{ showClearIcon.value = false diff --git a/packages/devui-vue/docs/components/time-picker/index.md b/packages/devui-vue/docs/components/time-picker/index.md index dc3f1f37e8f7fb7248c52dbb36ad9d26521d3dd0..858f7c11c6e1702936dd27c100bf5a8c6a2d39e5 100644 --- a/packages/devui-vue/docs/components/time-picker/index.md +++ b/packages/devui-vue/docs/components/time-picker/index.md @@ -48,18 +48,31 @@ + + ``` ::: @@ -73,17 +86,33 @@

mm:HH:ss

- +

hh:mm

- +

MM:ss

- +
+ ``` ::: @@ -111,11 +140,6 @@ export default defineComponent({ setup(props,ctx){ let slotDemo = ref(null) - // 返回选中的时间 - const selectedTimeChage =(timeValue)=>{ - console.log(timeValue) - } - const chooseTime = ()=>{ let timeObj ={ time:'23',