UNPKG

@extclp/vexip-ui

Version:

A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good

1 lines 64.9 kB
{"version":3,"file":"date-picker.vue2.mjs","sources":["../../../components/date-picker/date-picker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { Icon } from '@/components/icon'\nimport { Popper } from '@/components/popper'\nimport { Renderer } from '@/components/renderer'\nimport { useFieldStore } from '@/components/form'\n\nimport { computed, nextTick, reactive, ref, toRef, watch } from 'vue'\n\nimport DateControl from './date-control.vue'\nimport DatePanel from './date-panel.vue'\nimport {\n createIconProp,\n createSizeProp,\n createStateProp,\n emitEvent,\n makeSentence,\n useIcons,\n useLocale,\n useNameHelper,\n useProps,\n useWordSpace\n} from '@vexip-ui/config'\nimport {\n placementWhileList,\n useClickOutside,\n useHover,\n usePopper,\n useSetTimeout\n} from '@vexip-ui/hooks'\nimport {\n boundRange,\n differenceDays,\n doubleDigits,\n format,\n getTime,\n isLeapYear,\n isObject,\n mergeObjects,\n startOfMonth,\n toAttrValue,\n toDate,\n toFalse\n} from '@vexip-ui/utils'\nimport { datePickerProps } from './props'\nimport { useColumn, useTimeBound } from './helper'\nimport { datePickerTypes, invalidDate } from './symbol'\n\nimport type { PopperExposed } from '@/components/popper'\nimport type { Dateable } from '@vexip-ui/utils'\nimport type {\n DatePickerChangeEvent,\n DatePickerFormatFn,\n DatePickerSlots,\n DateTimeType,\n DateType,\n TimeType\n} from './symbol'\n\ndefineOptions({ name: 'DatePicker' })\n\nconst {\n idFor,\n labelId,\n state,\n disabled,\n loading,\n size,\n validateField,\n clearField,\n getFieldValue,\n setFieldValue\n} = useFieldStore<Dateable | Dateable[]>(() => reference.value?.focus())\n\nconst nh = useNameHelper('date-picker')\n\nconst _props = defineProps(datePickerProps)\nconst props = useProps('datePicker', _props, {\n size: createSizeProp(size),\n state: createStateProp(state),\n locale: null,\n type: {\n default: 'date',\n validator: value => datePickerTypes.includes(value)\n },\n visible: false,\n placement: {\n default: 'bottom-start',\n validator: value => placementWhileList.includes(value)\n },\n transfer: false,\n value: {\n default: () => getFieldValue(),\n static: true\n },\n format: 'yMd Hms',\n valueFormat: null,\n filler: {\n default: '-',\n validator: value => value.length === 1\n },\n clearable: false,\n noAction: false,\n labels: () => ({}),\n dateSeparator: '/',\n timeSeparator: ':',\n shortcuts: () => [],\n disabledDate: {\n default: toFalse,\n isFunc: true\n },\n steps: () => [1, 1, 1],\n ctrlSteps: () => [5, 5, 5],\n prefix: createIconProp(),\n prefixColor: '',\n suffix: createIconProp(),\n suffixColor: '',\n noSuffix: false,\n disabled: () => disabled.value,\n transitionName: () => nh.ns('drop'),\n confirmText: null,\n cancelText: null,\n today: {\n default: () => new Date(),\n validator: value => !Number.isNaN(new Date(value))\n },\n range: null,\n loading: () => loading.value,\n loadingIcon: createIconProp(),\n loadingLock: false,\n loadingEffect: null,\n min: null,\n max: null,\n outsideClose: true,\n outsideCancel: false,\n placeholder: null,\n unitReadonly: false,\n weekStart: null,\n popperAlive: null,\n shortcutsPlacement: 'left',\n slots: () => ({})\n})\n\nconst emit = defineEmits(['update:value', 'update:formatted-value', 'update:visible'])\n\nconst slots = defineSlots<DatePickerSlots>()\n\nconst calendarLocale = useLocale('calendar')\nconst datePickerLocale = useLocale('datePicker')\nconst icons = useIcons()\nconst wordSpace = useWordSpace()\n\nconst placement = toRef(props, 'placement')\nconst transfer = toRef(props, 'transfer')\nconst currentVisible = ref(props.visible)\nconst focused = ref(false)\nconst startState = createDateState()\nconst endState = createDateState()\nconst currentState = ref<'start' | 'end'>('start')\nconst lastValue = ref('')\nconst firstSelected = ref<number[] | undefined>()\nconst hoveredDate = ref(new Date())\nconst staticWheel = ref(false)\nconst dateUnitOrder = ref<DateType[]>([])\n\nconst { timer } = useSetTimeout()\n\nconst wrapper = useClickOutside(handleClickOutside)\nconst popper = ref<PopperExposed>()\nconst { reference, transferTo, updatePopper } = usePopper({\n placement,\n transfer,\n wrapper,\n popper: computed(() => popper.value?.wrapper),\n isDrop: true\n})\nconst { isHover } = useHover(reference)\n\nconst startInput = ref<InstanceType<typeof DateControl>>()\nconst endInput = ref<InstanceType<typeof DateControl>>()\nconst datePanel = ref<InstanceType<typeof DatePanel>>()\n\nconst mergedLocale = computed(() => {\n const locale = mergeObjects(calendarLocale.value, datePickerLocale.value, true)\n\n return isObject(props.locale) ? mergeObjects(locale, props.locale) : locale\n})\nconst startPlaceholder = computed(() => {\n if (props.placeholder) {\n return Array.isArray(props.placeholder) ? props.placeholder[0] : props.placeholder\n }\n\n const { select, start, [props.type]: type } = mergedLocale.value.placeholder\n\n return makeSentence(props.range ? `${start} ${type}` : `${select} ${type}`, wordSpace.value)\n})\nconst endPlaceholder = computed(() => {\n if (props.placeholder) {\n return Array.isArray(props.placeholder)\n ? props.placeholder[1] || props.placeholder[0]\n : props.placeholder\n }\n\n const { end, [props.type]: type } = mergedLocale.value.placeholder\n\n return makeSentence(`${end} ${type}`, wordSpace.value)\n})\nconst className = computed(() => {\n return [\n nh.b(),\n nh.ns('input-vars'),\n nh.bs('vars'),\n nh.bm(props.type),\n {\n [nh.bm('inherit')]: props.inherit,\n [nh.bm('disabled')]: props.disabled,\n [nh.bm(props.size)]: props.size !== 'default',\n [nh.bm('no-hour')]: !startState.enabled.hour,\n [nh.bm('no-minute')]: !startState.enabled.minute,\n [nh.bm('no-second')]: !startState.enabled.second,\n [nh.bm('visible')]: currentVisible.value,\n [nh.bm(props.state)]: props.state !== 'default',\n [nh.bm('is-range')]: props.range\n }\n ]\n})\nconst readonly = computed(() => props.loading && props.loadingLock)\nconst selectorClass = computed(() => {\n const baseCls = nh.be('selector')\n\n return {\n [baseCls]: true,\n [`${baseCls}--disabled`]: props.disabled,\n [`${baseCls}--readonly`]: readonly.value,\n [`${baseCls}--loading`]: props.loading,\n [`${baseCls}--${props.size}`]: props.size !== 'default',\n [`${baseCls}--focused`]: focused.value,\n [`${baseCls}--${props.state}`]: props.state !== 'default'\n }\n})\nconst hasPrefix = computed(() => {\n return !!(slots.prefix || props.prefix)\n})\nconst currentValue = computed(() => {\n const values = [startState, endState].map(state => {\n const values = Object.values(state.dateValue).map(doubleDigits)\n\n return `${values.slice(0, 3).join('-')} ${values.slice(3).join(':')}`\n })\n\n return props.range ? values : values[0]\n})\nconst hoveredLarge = computed(() => {\n if (!firstSelected.value) return false\n\n const [year, month, date] = firstSelected.value\n const firstTime = new Date(`${year}-${month}-${date}`).getTime()\n const hoverTime = hoveredDate.value.getTime()\n\n return firstTime < hoverTime\n})\nconst showClear = computed(() => {\n return !props.disabled && !readonly.value && props.clearable && isHover.value && !!lastValue.value\n})\nconst min = computed(() => {\n if (props.min) {\n const date = rawValueToDate(props.min, invalidDate)\n\n if (Number.isNaN(+date)) return -Infinity\n\n date.setHours(0, 0, 0, 0)\n\n return date.getTime()\n }\n\n return -Infinity\n})\nconst max = computed(() => {\n if (props.max) {\n let date = rawValueToDate(props.max, invalidDate)\n\n if (Number.isNaN(+date)) return Infinity\n\n if (props.type !== 'datetime') {\n date.setHours(23, 59, 59, 999)\n\n if (props.type === 'year') {\n date.setMonth(11)\n date.setDate(31)\n } else if (props.type === 'month') {\n date.setMonth(date.getMonth() + 1)\n date = startOfMonth(date)\n date.setDate(date.getDate() - 1)\n }\n }\n\n return date.getTime()\n }\n\n return Infinity\n})\nconst reversed = computed(() => {\n if (Number.isNaN(min.value) || Number.isNaN(max.value)) {\n return false\n }\n\n return min.value > max.value\n})\nconst startMinTime = computed(() => {\n if (props.type === 'datetime' && props.min && !differenceDays(props.min, startState.getDate())) {\n return getTime(props.min)\n }\n\n return ''\n})\nconst startMaxTime = computed(() => {\n if (props.type === 'datetime' && props.max && !differenceDays(props.max, startState.getDate())) {\n return getTime(props.max)\n }\n\n return ''\n})\nconst endMinTime = computed(() => {\n if (\n props.type === 'datetime' &&\n props.range &&\n props.min &&\n !differenceDays(props.min, startState.getDate())\n ) {\n return getTime(props.min)\n }\n\n return ''\n})\nconst endMaxTime = computed(() => {\n if (\n props.type === 'datetime' &&\n props.range &&\n props.max &&\n !differenceDays(props.max, startState.getDate())\n ) {\n return getTime(props.max)\n }\n\n return ''\n})\nconst startReversed = computed(() => {\n if (!props.range) return false\n\n const startValue = startState.dateValue\n const endValue = endState.dateValue\n\n let types: DateTimeType[]\n\n if (props.type === 'year') {\n types = ['year']\n } else if (props.type === 'month') {\n types = ['year', 'month']\n } else if (props.type === 'date') {\n types = ['year', 'month', 'date']\n } else {\n types = ['year', 'month', 'date', 'hour', 'minute', 'second']\n }\n\n for (const type of types) {\n if (startValue[type] < endValue[type]) return false\n if (startValue[type] > endValue[type]) return true\n }\n\n return false\n})\n\nconst startTimeBound = useTimeBound(startMinTime, startMaxTime)\nconst endTimeBound = useTimeBound(endMinTime, endMaxTime)\n\nconst isTimeDisabled = computed(() => {\n return currentState.value === 'start'\n ? startTimeBound.isTimeDisabled\n : endTimeBound.isTimeDisabled\n})\nconst startError = computed(() => {\n const { hour, minute, second } = startState.dateValue\n const { isTimeDisabled } = startTimeBound\n\n return (\n startReversed.value ||\n isDateDisabled(startState.getDate()) ||\n isTimeDisabled.hour(hour) ||\n isTimeDisabled.minute(hour, minute) ||\n isTimeDisabled.second(hour, minute, second)\n )\n})\nconst endError = computed(() => {\n if (!props.range) return false\n\n const { hour, minute, second } = endState.dateValue\n const { isTimeDisabled } = endTimeBound\n\n return (\n startReversed.value ||\n isDateDisabled(endState.getDate()) ||\n isTimeDisabled.hour(hour) ||\n isTimeDisabled.minute(hour, minute) ||\n isTimeDisabled.second(hour, minute, second)\n )\n})\nconst noActionMode = computed(() => props.type !== 'datetime' && props.noAction)\n\nwatch(() => props.type, parseFormat)\nwatch(\n () => props.value,\n value => {\n parseValue(value)\n\n lastValue.value = (Array.isArray(value) ? value[0] || value[1] : value) ? getStringValue() : ''\n },\n { immediate: true }\n)\nwatch(\n () => props.type,\n value => {\n const hasMonth = value !== 'year'\n const hasDate = hasMonth && value !== 'month'\n\n startState.enabled.year = true\n endState.enabled.year = true\n startState.enabled.month = hasMonth\n endState.enabled.month = hasMonth\n startState.enabled.date = hasDate\n endState.enabled.date = hasDate\n },\n { immediate: true }\n)\nwatch(() => props.format, parseFormat, { immediate: true })\nwatch(\n () => props.visible,\n value => {\n currentVisible.value = value\n }\n)\nwatch(currentVisible, value => {\n if (value) {\n updatePopper()\n }\n})\nwatch(focused, value => {\n if (value) {\n emitEvent(props.onFocus)\n } else {\n emitEvent(props.onBlur)\n }\n})\nwatch(currentState, value => {\n if (!props.unitReadonly && currentVisible.value) {\n emitEvent(props.onChangeCol, getCurrentState().column, value)\n }\n})\nwatch(\n () => startState.column,\n value => {\n if (!props.unitReadonly && currentVisible.value && currentState.value === 'start') {\n emitEvent(props.onChangeCol, value, 'start')\n }\n }\n)\nwatch(\n () => endState.column,\n value => {\n if (!props.unitReadonly && currentVisible.value && currentState.value === 'end') {\n emitEvent(props.onChangeCol, value, 'end')\n }\n }\n)\nwatch(\n () => props.disabled,\n value => {\n if (value) {\n setVisible(false)\n handleBlur()\n }\n }\n)\nwatch(readonly, value => {\n if (value) {\n setVisible(false)\n }\n})\n\ndefineExpose({\n idFor,\n currentVisible,\n focused,\n isHover,\n startState,\n endState,\n currentState,\n startError,\n endError,\n wrapper,\n reference,\n popper,\n start: startInput,\n end: endInput,\n panel: datePanel,\n updatePopper,\n focus: (options?: FocusOptions) => reference.value?.focus(options),\n blur: () => reference.value?.blur()\n})\n\nfunction createDateState() {\n // const noFiller = props.noFiller\n const { currentColumn, enabled, resetColumn, enterColumn } = useColumn([\n 'year',\n 'month',\n 'date',\n 'hour',\n 'minute',\n 'second'\n ] as DateTimeType[])\n\n const dateValue = reactive({\n year: 1970,\n month: 1, // 1 ~ 12\n date: 1,\n hour: 0,\n minute: 0,\n second: 0\n })\n const activated = reactive({\n year: false,\n month: false,\n date: false,\n hour: false,\n minute: false,\n second: false\n })\n\n let valueRecord = { ...dateValue }\n let activatedRecord = { ...activated }\n\n return reactive({\n column: currentColumn,\n enabled,\n activated,\n dateValue,\n resetColumn,\n enterColumn,\n setDate: (date: Date, withTime = true) => {\n dateValue.year = date.getFullYear()\n dateValue.month = date.getMonth() + 1\n dateValue.date = date.getDate()\n\n if (withTime) {\n dateValue.hour = date.getHours()\n dateValue.minute = date.getMinutes()\n dateValue.second = date.getSeconds()\n }\n },\n getDate: () => {\n return new Date(\n dateValue.year,\n dateValue.month - 1,\n dateValue.date,\n dateValue.hour,\n dateValue.minute,\n dateValue.second\n )\n },\n record() {\n valueRecord = { ...dateValue }\n activatedRecord = { ...activated }\n },\n restore() {\n Object.assign(dateValue, valueRecord)\n Object.assign(activated, activatedRecord)\n }\n })\n}\n\nfunction getCurrentState() {\n return currentState.value === 'start' ? startState : endState\n}\n\nfunction rawValueToDate(value: Dateable, defaultValue = new Date(props.today)) {\n let date = toDate(value)\n\n if (Number.isNaN(date.getTime())) {\n date = defaultValue\n }\n\n return date\n}\n\nfunction parseValue<T extends Dateable | null>(value: T | T[]) {\n if (!Array.isArray(value)) {\n value = [value, value]\n }\n\n for (let i = 0; i < 2; ++i) {\n const date = rawValueToDate(value[i] ?? '')\n const state = i === 0 ? startState : endState\n\n state.setDate(date)\n toggleActivated(!!value[i], i === 0 ? 'start' : 'end')\n\n if (!props.range) break\n }\n}\n\nfunction parseDateUnitOrder() {\n const orderSet = new Set<DateType>()\n\n // to ignore 'xxx'\n let inQuotation = false\n\n for (let i = 0, len = props.format.length; i < len; ++i) {\n const char = props.format.charAt(i)\n\n if (char === \"'\") {\n inQuotation = !inQuotation\n } else if (!inQuotation) {\n switch (char) {\n case 'y':\n orderSet.add('year')\n break\n case 'M':\n orderSet.add('month')\n break\n case 'd':\n orderSet.add('date')\n break\n }\n }\n }\n\n dateUnitOrder.value = [...orderSet]\n}\n\nfunction parseTimeUnitEnabled() {\n const isDatetime = props.type === 'datetime'\n\n ;[startState, endState].forEach(state => {\n state.enabled.hour = false\n state.enabled.minute = false\n state.enabled.second = false\n\n if (isDatetime && props.format) {\n // to ignore 'H', 'm' and 's'\n let inQuotation = false\n\n for (let i = 0, len = props.format.length; i < len; ++i) {\n const char = props.format.charAt(i)\n\n if (char === \"'\") {\n inQuotation = !inQuotation\n } else if (!inQuotation) {\n switch (char) {\n case 'H':\n state.enabled.hour = true\n break\n case 'm':\n state.enabled.minute = true\n break\n case 's':\n state.enabled.second = true\n break\n }\n }\n }\n }\n })\n}\n\nfunction parseFormat() {\n parseDateUnitOrder()\n parseTimeUnitEnabled()\n}\n\nfunction toggleActivated(value: boolean, valueType?: 'start' | 'end') {\n const states = valueType\n ? valueType === 'start'\n ? [startState]\n : [endState]\n : [startState, endState]\n\n states.forEach(state => {\n ;(Object.keys(state.activated) as DateTimeType[]).forEach(type => {\n state.activated[type] = value\n })\n })\n}\n\nfunction getStringValue() {\n return Array.isArray(currentValue.value) ? currentValue.value.join('|') : currentValue.value\n}\n\nfunction isDateDisabled(date: Date) {\n if (typeof props.disabledDate === 'function') {\n if (props.disabledDate(date)) {\n return true\n }\n }\n\n const time = date.getTime()\n\n if (reversed.value) {\n if (time > max.value && time < min.value) {\n return true\n }\n } else {\n if (time < min.value || time > max.value) {\n return true\n }\n }\n\n return false\n}\n\nfunction verifyDate() {\n if (startError.value || (props.range && endError.value)) {\n parseValue(props.value)\n }\n}\n\nfunction setVisible(visible: boolean) {\n if (currentVisible.value === visible) return\n\n currentVisible.value = visible\n\n emit('update:visible', visible)\n emitEvent(props.onToggle, visible)\n}\n\nfunction emitChange() {\n verifyDate()\n\n if (lastValue.value !== getStringValue()) {\n lastValue.value = getStringValue()\n\n const values = Array.isArray(currentValue.value) ? currentValue.value : [currentValue.value]\n const emitValues: number[] = []\n const formattedValues: unknown[] = []\n\n const valueFormat = props.valueFormat\n const formatValue: DatePickerFormatFn =\n typeof valueFormat === 'function'\n ? valueFormat\n : valueFormat\n ? (timestamp, type) =>\n format(\n timestamp,\n !Array.isArray(valueFormat)\n ? valueFormat\n : type === 'start'\n ? valueFormat[0]\n : valueFormat[1]\n )\n : timestamp => timestamp\n\n for (let i = 0; i < 2; ++i) {\n if (props.type === 'year') {\n emitValues[i] = new Date(\n i === 0 ? startState.dateValue.year : endState.dateValue.year,\n 0\n ).getTime()\n } else if (props.type !== 'datetime') {\n emitValues[i] = new Date(values[i].split(' ')[0] + ' 00:00:00').getTime()\n } else {\n emitValues[i] = new Date(values[i]).getTime()\n }\n\n formattedValues[i] = formatValue(emitValues[i], i === 0 ? 'start' : 'end')\n\n if (!props.range) break\n }\n\n const emitValue = props.range ? emitValues : emitValues[0]\n const formattedValue = props.range ? formattedValues : formattedValues[0]\n\n toggleActivated(true)\n emit('update:value', emitValue)\n emit('update:formatted-value', formattedValue)\n setFieldValue(emitValue)\n emitEvent(props.onChange as DatePickerChangeEvent, emitValue)\n validateField()\n }\n}\n\nfunction finishInput(shouldChange = true) {\n setVisible(false)\n\n shouldChange && emitChange()\n startState.resetColumn()\n endState.resetColumn()\n}\n\nfunction verifyValue(type: DateTimeType) {\n const dateValue = getCurrentState().dateValue\n\n switch (type) {\n case 'year': {\n dateValue.year = boundRange(dateValue.year, 1970, 9999)\n break\n }\n case 'month': {\n dateValue.month = boundRange(dateValue.month, 1, 12)\n break\n }\n case 'date': {\n const month = dateValue.month\n\n let lastDay\n\n if (month < 7) {\n if (month !== 2) {\n lastDay = 30 + (month % 2)\n } else {\n if (isLeapYear(dateValue.year)) {\n lastDay = 29\n } else {\n lastDay = 28\n }\n }\n } else {\n lastDay = 31 - (month % 2)\n }\n\n dateValue.date = boundRange(dateValue.date, 1, lastDay)\n break\n }\n case 'hour':\n case 'minute':\n case 'second': {\n dateValue[type] = boundRange(dateValue[type], 0, type === 'hour' ? 23 : 59)\n dateValue[type] = Math.round(dateValue[type] / getStep(type)) * getStep(type)\n }\n }\n}\n\nfunction handleFocused() {\n if (props.disabled) return\n\n focused.value = true\n\n timer.focus = setTimeout(() => {\n if (focused.value) {\n if (currentState.value === 'start') {\n startInput.value?.focus()\n } else {\n endInput.value?.focus()\n }\n }\n }, 120)\n}\n\nfunction handleBlur() {\n clearTimeout(timer.focus)\n\n focused.value = false\n startInput.value?.blur()\n endInput.value?.blur()\n}\n\nfunction showPanel(event: Event) {\n if (props.disabled || readonly.value) return\n\n const target = event.target as Node\n\n setVisible(true)\n\n if (wrapper.value && target) {\n const units = Array.from(wrapper.value.querySelectorAll(`.${nh.be('unit')}`))\n const index = units.findIndex(unit => unit === target || unit.contains(target))\n\n if (!~index) {\n startState.column = null\n endState.column = null\n }\n\n if (props.range && index >= units.length / 2) {\n toggleCurrentState('end')\n } else {\n toggleCurrentState('start')\n }\n }\n\n handleFocused()\n}\n\nfunction handleInput(value: number) {\n const state = getCurrentState()\n const type = state.column\n\n if (!type) return\n\n handleInputNumber(type, value)\n\n if (type === 'year' ? state.dateValue.year >= 1000 : state.dateValue[type] >= 10) {\n state.enterColumn('next', false)\n }\n}\n\nfunction handleInputNumber(type: DateTimeType, number: number) {\n const state = getCurrentState()\n const prev = state.dateValue[type]\n\n if (state.activated[type] && prev > 0 && prev < (type === 'year' ? 1000 : 10)) {\n state.dateValue[type] = prev * 10 + number\n } else {\n state.dateValue[type] = number\n setActivatedTrue(type)\n }\n\n type !== 'year' && verifyValue(type)\n emitEvent(props.onInput, type, state.dateValue[type])\n}\n\nfunction setActivatedTrue(type: DateTimeType) {\n const activated = getCurrentState().activated\n\n if (type === 'date') {\n activated.year = true\n activated.month = true\n } else if (type === 'month') {\n activated.year = true\n } else if (type === 'minute') {\n activated.hour = true\n } else if (type === 'second') {\n activated.hour = true\n activated.minute = true\n }\n\n activated[type] = true\n}\n\nfunction handleInputFocus(type: DateTimeType) {\n getCurrentState().column = type\n}\n\nfunction isTimeType(type: DateTimeType): type is TimeType {\n return ['hour', 'minute', 'second'].includes(type)\n}\n\nfunction handleAdjust(adjustType: 'plus' | 'minus', ctrlKey: boolean) {\n const isPlus = adjustType === 'plus'\n const sign = isPlus ? 1 : -1\n const state = getCurrentState()\n const type = state.column\n\n if (!type) return\n\n if (state.enabled[type]) {\n if (isTimeType(type)) {\n state.dateValue[type] += sign * (ctrlKey ? getCtrlStep(type) : getStep(type))\n } else {\n if (ctrlKey) {\n if (type === 'year') {\n state.dateValue.year += sign * 10\n } else {\n state.dateValue[type === 'date' ? 'month' : 'year'] += sign\n }\n } else {\n state.dateValue[type] += sign\n }\n\n computeDate()\n updateDateActivated(type)\n }\n\n verifyValue(type)\n emitEvent(props[isPlus ? 'onPlus' : 'onMinus'], type, state.dateValue[type])\n datePanel.value?.refreshCalendar(currentState.value)\n }\n}\n\nfunction handlePlus(ctrlKey: boolean) {\n handleAdjust('plus', ctrlKey)\n}\n\nfunction handleMinus(ctrlKey: boolean) {\n handleAdjust('minus', ctrlKey)\n}\n\nfunction computeDate() {\n const dateValue = getCurrentState().dateValue\n const date = new Date(dateValue.year, dateValue.month - 1, dateValue.date)\n\n dateValue.year = date.getFullYear()\n dateValue.month = date.getMonth() + 1\n dateValue.date = date.getDate()\n}\n\nfunction fallbackFocus() {\n requestAnimationFrame(() => {\n handleBlur()\n reference.value?.focus()\n })\n}\n\nfunction handleEnter() {\n fallbackFocus()\n finishInput()\n emitEvent(props.onEnter)\n}\n\nfunction handleCancel() {\n fallbackFocus()\n parseValue(lastValue.value.split('|'))\n finishInput(false)\n emitEvent(props.onCancel)\n}\n\nfunction handleClear(finish = true) {\n if (props.disabled || readonly.value) return\n\n if (props.clearable) {\n nextTick(() => {\n const emitValue = props.range ? ([] as number[]) : null\n\n parseValue(null)\n finish && finishInput(false)\n emit('update:value', emitValue)\n emit('update:formatted-value', props.range ? [] : null)\n emitEvent(props.onChange as DatePickerChangeEvent, emitValue)\n emitEvent(props.onClear)\n clearField(emitValue!)\n finish && handleBlur()\n\n lastValue.value = ''\n\n nextTick(() => {\n toggleActivated(false)\n })\n })\n }\n}\n\nfunction handleShortcut(name: string, value: Dateable | Dateable[]) {\n fallbackFocus()\n parseValue(value)\n emitEvent(props.onShortcut as (name: string, value: Dateable | Dateable[]) => void, name, value)\n finishInput()\n}\n\n// 只有时分秒\nfunction getStep(type: TimeType) {\n return props.steps[type === 'hour' ? 0 : type === 'minute' ? 1 : 2] || 1\n}\n\n// 只有时分秒\nfunction getCtrlStep(type: TimeType) {\n return props.ctrlSteps[type === 'hour' ? 0 : type === 'minute' ? 1 : 2] || 1\n}\n\nfunction handleDateHover(hoverDate: Date | null) {\n if (props.range && hoverDate) {\n hoveredDate.value = hoverDate\n\n if (firstSelected.value) {\n const hoverValues = [hoverDate.getFullYear(), hoverDate.getMonth() + 1, hoverDate.getDate()]\n const start = hoveredLarge.value ? firstSelected.value : hoverValues\n const end = hoveredLarge.value ? hoverValues : firstSelected.value\n\n let types: DateTimeType[]\n\n if (props.type === 'year') {\n types = ['year']\n } else if (props.type === 'month') {\n types = ['year', 'month']\n } else {\n types = ['year', 'month', 'date']\n }\n\n for (let i = 0, len = types.length; i < len; ++i) {\n startState.dateValue[types[i]] = start[i]\n endState.dateValue[types[i]] = end[i]\n }\n }\n }\n}\n\nfunction handlePanelChange(values: number[]) {\n let types: DateTimeType[]\n\n if (props.type === 'year') {\n types = ['year']\n } else if (props.type === 'month') {\n types = ['year', 'month']\n } else {\n types = ['year', 'month', 'date']\n }\n\n if (!props.range) {\n for (let i = 0, len = types.length; i < len; ++i) {\n startState.dateValue[types[i]] = values[i]\n updateDateActivated(types[i], 'start')\n }\n\n if (noActionMode.value) handleEnter()\n\n return\n }\n\n if (!firstSelected.value) {\n firstSelected.value = values\n\n for (let i = 0, len = types.length; i < len; ++i) {\n startState.dateValue[types[i]] = values[i]\n endState.dateValue[types[i]] = values[i]\n updateDateActivated(types[i], 'start')\n updateDateActivated(types[i], 'end')\n }\n } else {\n const [year, month, date] = firstSelected.value\n const firstTime = new Date(`${year}-${month}-${date}`).getTime()\n const secondTime = new Date(`${values[0]}-${values[1]}-${values[2]}`).getTime()\n const start = firstTime < secondTime ? firstSelected.value : values\n const end = firstTime < secondTime ? values : firstSelected.value\n\n for (let i = 0, len = types.length; i < len; ++i) {\n startState.dateValue[types[i]] = start[i]\n endState.dateValue[types[i]] = end[i]\n updateDateActivated(types[i], 'start')\n updateDateActivated(types[i], 'end')\n }\n\n verifyRangeValue()\n firstSelected.value = undefined\n\n if (noActionMode.value) handleEnter()\n }\n}\n\nfunction handleTimeChange(valueType: 'start' | 'end', type: TimeType, time: number) {\n const state = valueType === 'start' ? startState : endState\n\n state.dateValue[type] = time\n updateDateActivated('hour', valueType)\n updateDateActivated('minute', valueType)\n updateDateActivated('second', valueType)\n}\n\nfunction updateDateActivated(type: DateTimeType, valueType?: 'start' | 'end') {\n const state = valueType ? (valueType === 'start' ? startState : endState) : getCurrentState()\n\n if (type === 'month') {\n state.activated.year = true\n } else if (type === 'date') {\n state.activated.year = true\n state.activated.month = true\n }\n\n state.activated[type] = true\n}\n\nfunction verifyRangeValue() {\n if (!props.range) return\n\n const startDate = startState.getDate()\n const endDate = endState.getDate()\n\n if (startDate.getTime() > endDate.getTime()) {\n startState.setDate(endDate)\n endState.setDate(startDate)\n }\n}\n\nfunction toggleCurrentState(type: 'start' | 'end') {\n currentState.value = type\n}\n\nfunction enterColumn(type: 'prev' | 'next') {\n if (props.range) {\n if (type === 'prev' && currentState.value === 'start' && !startState.column) {\n toggleCurrentState('end')\n }\n\n const state = getCurrentState()\n const currentColumn = state.column\n\n state.enterColumn(type, !currentColumn)\n\n if (currentColumn === state.column) {\n const isStart = currentState.value === 'start'\n const otherState = isStart ? endState : startState\n\n otherState.resetColumn(type === 'prev' ? 'second' : 'year', type === 'prev')\n toggleCurrentState(isStart ? 'end' : 'start')\n }\n } else {\n startState.enterColumn(type)\n }\n}\n\nfunction handleStartInput(type: DateTimeType) {\n toggleCurrentState('start')\n handleInputFocus(type)\n\n nextTick(() => {\n datePanel.value?.refreshCalendar('start')\n })\n}\n\nfunction handleEndInput(type: DateTimeType) {\n toggleCurrentState('end')\n handleInputFocus(type)\n\n nextTick(() => {\n datePanel.value?.refreshCalendar('end')\n })\n}\n\nfunction handleClickOutside() {\n emitEvent(props.onClickOutside)\n\n if (props.outsideClose && currentVisible.value) {\n finishInput(!noActionMode.value && !props.outsideCancel)\n handleBlur()\n emitEvent(props.onOutsideClose)\n }\n}\n</script>\n\n<template>\n <div\n :id=\"idFor\"\n ref=\"wrapper\"\n :class=\"className\"\n role=\"group\"\n :aria-disabled=\"toAttrValue(props.disabled)\"\n :aria-expanded=\"toAttrValue(currentVisible)\"\n aria-haspopup=\"dialog\"\n :aria-labelledby=\"labelId\"\n @click=\"showPanel\"\n >\n <div\n ref=\"reference\"\n :class=\"selectorClass\"\n tabindex=\"0\"\n @keydown.space.prevent=\"showPanel\"\n @keydown.backspace.prevent=\"handleClear(false)\"\n >\n <div\n v-if=\"hasPrefix\"\n :class=\"[nh.be('icon'), nh.be('prefix')]\"\n :style=\"{ color: props.prefixColor }\"\n >\n <slot name=\"prefix\">\n <Renderer :renderer=\"props.slots.prefix\">\n <Icon :icon=\"props.prefix\"></Icon>\n </Renderer>\n </slot>\n </div>\n <div :class=\"nh.be('control')\">\n <DateControl\n ref=\"start\"\n :unit-type=\"currentState === 'start' ? startState.column! : ''\"\n :enabled=\"startState.enabled\"\n :activated=\"startState.activated\"\n :date-value=\"startState.dateValue\"\n :steps=\"props.steps\"\n :ctrl-steps=\"props.ctrlSteps\"\n :focused=\"focused\"\n :visible=\"currentVisible\"\n :date-separator=\"props.dateSeparator\"\n :time-separator=\"props.timeSeparator\"\n :filler=\"props.filler\"\n :labels=\"props.labels\"\n :has-error=\"startError\"\n :placeholder=\"startPlaceholder\"\n :readonly=\"props.unitReadonly\"\n :labeled-by=\"labelId\"\n :date-unit-order=\"dateUnitOrder\"\n @input=\"handleInput\"\n @plus=\"handlePlus\"\n @minus=\"handleMinus\"\n @enter=\"handleEnter\"\n @cancel=\"handleCancel\"\n @unit-focus=\"handleStartInput\"\n @prev-unit=\"enterColumn('prev')\"\n @next-unit=\"enterColumn('next')\"\n @blur=\"startState.column = null\"\n ></DateControl>\n <template v-if=\"props.range\">\n <div :class=\"nh.be('exchange')\">\n <slot name=\"exchange\">\n <Renderer :renderer=\"props.slots.exchange\">\n <Icon v-bind=\"icons.exchange\" style=\"padding-top: 1px\"></Icon>\n </Renderer>\n </slot>\n </div>\n <DateControl\n ref=\"end\"\n :unit-type=\"currentState === 'end' ? endState.column! : ''\"\n :enabled=\"endState.enabled\"\n :activated=\"endState.activated\"\n :date-value=\"endState.dateValue\"\n :steps=\"props.steps\"\n :ctrl-steps=\"props.ctrlSteps\"\n :focused=\"focused\"\n :visible=\"currentVisible\"\n :date-separator=\"props.dateSeparator\"\n :time-separator=\"props.timeSeparator\"\n :filler=\"props.filler\"\n :labels=\"props.labels\"\n :has-error=\"endError\"\n :placeholder=\"endPlaceholder\"\n :readonly=\"props.unitReadonly\"\n :labeled-by=\"labelId\"\n :date-unit-order=\"dateUnitOrder\"\n @input=\"handleInput\"\n @plus=\"handlePlus\"\n @minus=\"handleMinus\"\n @enter=\"handleEnter\"\n @cancel=\"handleCancel\"\n @unit-focus=\"handleEndInput\"\n @prev-unit=\"enterColumn('prev')\"\n @next-unit=\"enterColumn('next')\"\n @blur=\"endState.column = null\"\n ></DateControl>\n </template>\n </div>\n <div\n v-if=\"!props.noSuffix\"\n :class=\"[nh.be('icon'), nh.be('suffix')]\"\n :style=\"{\n color: props.suffixColor,\n opacity: showClear || props.loading ? '0%' : ''\n }\"\n >\n <slot name=\"suffix\">\n <Renderer :renderer=\"props.slots.suffix\">\n <Icon v-bind=\"icons.calendar\" :icon=\"props.suffix || icons.calendar.icon\"></Icon>\n </Renderer>\n </slot>\n </div>\n <div\n v-else-if=\"props.clearable || props.loading\"\n :class=\"[nh.be('icon'), nh.bem('icon', 'placeholder'), nh.be('suffix')]\"\n ></div>\n <Transition :name=\"nh.ns('fade')\" appear>\n <button\n v-if=\"showClear\"\n :class=\"[nh.be('icon'), nh.be('clear')]\"\n type=\"button\"\n tabindex=\"-1\"\n :aria-label=\"mergedLocale.ariaLabel.clear\"\n @click.stop=\"handleClear()\"\n >\n <Icon v-bind=\"icons.clear\" label=\"clear\"></Icon>\n </button>\n <div v-else-if=\"props.loading\" :class=\"[nh.be('icon'), nh.be('loading')]\">\n <Icon\n v-bind=\"icons.loading\"\n :effect=\"props.loadingEffect || icons.loading.effect\"\n :icon=\"props.loadingIcon || icons.loading.icon\"\n label=\"loading\"\n ></Icon>\n </div>\n </Transition>\n </div>\n <Popper\n ref=\"popper\"\n :class=\"[nh.be('popper'), nh.ns('calendar-vars'), nh.ns('time-picker-vars'), nh.bs('vars')]\"\n :visible=\"currentVisible\"\n :to=\"transferTo\"\n :transition=\"props.transitionName\"\n :alive=\"props.popperAlive ?? !transferTo\"\n @click.stop=\"handleFocused\"\n @before-enter=\"staticWheel = true\"\n @before-leave=\"staticWheel = true\"\n @after-enter=\"staticWheel = false\"\n @after-leave=\"staticWheel = false\"\n >\n <DatePanel\n ref=\"panel\"\n :type=\"props.type\"\n :start-value=\"startState.dateValue\"\n :end-value=\"endState.dateValue\"\n :start-activated=\"startState.activated\"\n :end-activated=\"endState.activated\"\n :value-type=\"currentState\"\n :shortcuts=\"props.shortcuts\"\n :confirm-text=\"props.confirmText\"\n :cancel-text=\"props.cancelText\"\n :today=\"props.today\"\n :no-action=\"props.noAction\"\n :steps=\"props.steps\"\n :range=\"props.range\"\n :min=\"props.min\"\n :max=\"props.max\"\n :disabled-date=\"isDateDisabled\"\n :disabled-time=\"isTimeDisabled\"\n :has-error=\"startError || endError\"\n :selecting-type=\"hoveredLarge ? 'end' : 'start'\"\n :locale=\"mergedLocale\"\n :week-start=\"props.weekStart\"\n :static-wheel=\"staticWheel\"\n :shortcuts-placement=\"props.shortcutsPlacement\"\n :labeled-by=\"labelId\"\n @shortcut=\"handleShortcut\"\n @change=\"handlePanelChange\"\n @confirm=\"handleEnter\"\n @cancel=\"handleCancel\"\n @hover=\"handleDateHover\"\n @time-change=\"handleTimeChange\"\n >\n <template v-if=\"$slots.panelTitle || props.slots.panelTitle\" #title=\"titleParams\">\n <slot name=\"panelTitle\" v-bind=\"titleParams\">\n <Renderer :renderer=\"props.slots.panelTitle\" :data=\"titleParams\"></Renderer>\n </slot>\n </template>\n <template v-if=\"$slots.panelYear || props.slots.panelYear\" #year=\"yearParams\">\n <slot name=\"panelYear\" v-bind=\"yearParams\">\n <Renderer :renderer=\"props.slots.panelYear\" :data=\"yearParams\"></Renderer>\n </slot>\n </template>\n <template v-if=\"$slots.panelMonth || props.slots.panelMonth\" #month=\"monthParams\">\n <slot name=\"panelMonth\" v-bind=\"monthParams\">\n <Renderer :renderer=\"props.slots.panelMonth\" :data=\"monthParams\"></Renderer>\n </slot>\n </template>\n <template v-if=\"$slots.panelWeek || props.slots.panelWeek\" #week=\"weekParams\">\n <slot name=\"panelWeek\" v-bind=\"weekParams\">\n <Renderer :renderer=\"props.slots.panelWeek\" :data=\"weekParams\"></Renderer>\n </slot>\n </template>\n <template v-if=\"$slots.panelDate || props.slots.panelDate\" #date=\"dateParams\">\n <slot name=\"panelDate\" v-bind=\"dateParams\">\n <Renderer :renderer=\"props.slots.panelDate\" :data=\"dateParams\"></Renderer>\n </slot>\n </template>\n </DatePanel>\n </Popper>\n </div>\n</template>\n"],"names":["idFor","labelId","state","disabled","loading","size","validateField","clearField","getFieldValue","setFieldValue","useFieldStore","_a","reference","nh","useNameHelper","props","useProps","__props","createSizeProp","createStateProp","value","datePickerTypes","placementWhileList","toFalse","createIconProp","emit","__emit","slots","_useSlots","calendarLocale","useLocale","datePickerLocale","icons","useIcons","wordSpace","useWordSpace","placement","toRef","transfer","currentVisible","ref","focused","startState","createDateState","endState","currentState","lastValue","firstSelected","hoveredDate","staticWheel","dateUnitOrder","timer","useSetTimeout","wrapper","useClickOutside","handleClickOutside","popper","transferTo","updatePopper","usePopper","computed","isHover","useHover","startInput","endInput","datePanel","mergedLocale","locale","mergeObjects","isObject","startPlaceholder","select","start","type","makeSentence","endPlaceholder","end","className","readonly","selectorClass","baseCls","hasPrefix","currentValue","values","doubleDigits","hoveredLarge","year","month","date","firstTime","hoverTime","showClear","min","rawValueToDate","invalidDate","max","startOfMonth","reversed","startMinTime","differenceDays","getTime","startMaxTime","endMinTime","endMaxTime","startReversed","startValue","endValue","types","startTimeBound","useTimeBound","endTimeBound","isTimeDisabled","startError","hour","minute","second","isDateDisabled","endError","noActionMode","watch","parseFormat","parseValue","getStringValue","hasMonth","hasDate","emitEvent","getCurrentState","setVisible","handleBlur","__expose","options","currentColumn","enabled","resetColumn","enterColumn","useColumn","dateValue","reactive","activated","valueRecord","activatedRecord","withTime","defaultValue","toDate","i","toggleActivated","parseDateUnitOrder","orderSet","inQuotation","len","char","parseTimeUnitEnabled","isDatetime","valueType","time","verifyDate","visible","emitChange","emitValues","formattedValues","valueFormat","formatValue","timestamp","format","emitValue","formattedValue","finishInput","shouldChange","verifyValue","boundRange","lastDay","isLeapYear","getStep","handleFocused","_b","showPanel","event","target","units","index","unit","toggleCurrentState","handleInput","handleInputNumber","number","prev","setActivatedTrue","handleInputFocus","isTimeType","handleAdjust","adjustType","ctrlKey","isPlus","sign","getCtrlStep","computeDate","updateDateActivated","handlePlus","handleMinus","fallbackFocus","handleEnter","handleCancel","handleClear","finish","nextTick","handleShortcut","name","handleDateHover","hoverDate","hoverValues","handlePanelChange","secondTime","verifyRangeValue","handleTimeChange","startDate","endDate","isStart","handleStartInput","handleEndInput"],"mappings":"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