UNPKG

hongluan-ui

Version:
1 lines 26.5 kB
{"version":3,"file":"picker.mjs","sources":["../../../../../../../packages/components/time-picker/src/common/picker.vue"],"sourcesContent":["<template>\n <hl-tooltip\n ref=\"refPopper\"\n :visible=\"pickerVisible\"\n trigger=\"click\"\n v-bind=\"$attrs\"\n role=\"dialog\"\n :popper-class=\"`${namespace}-datepicker-popper ${popperClass}`\"\n :offset=\"popperOffset\"\n :popper-options=\"hlPopperOptions\"\n :fallback-placements=\"['bottom', 'top', 'right', 'left']\"\n transition=\"dropdown\"\n :show-arrow=\"false\"\n :gpu-acceleration=\"false\"\n :stop-popper-mouse-event=\"false\"\n :hide-after=\"0\"\n :teleported=\"teleported\"\n persistent\n @before-show=\"onBeforeShow\"\n @show=\"onShow\"\n @hide=\"onHide\"\n >\n <template #default>\n <hl-input\n v-if=\"!isRangeInput\"\n :id=\"id\"\n ref=\"inputRef\"\n container-role=\"combobox\"\n :model-value=\"displayValue\"\n :name=\"name\"\n :size=\"size\"\n :disabled=\"pickerDisabled\"\n :placeholder=\"placeholder\"\n :fill=\"fill\"\n :thin=\"thin\"\n :class=\"[\n namespace + '-date-input',\n $attrs.class,\n type,\n {\n 'block': block,\n }\n ]\"\n :style=\"$attrs.style\"\n :readonly=\"!editable || readonly || isDatesPicker || isMonthsPicker || isYearsPicker || type === 'week'\"\n :aria-label=\"label || ariaLabel\"\n :tabindex=\"tabindex\"\n :validate-event=\"false\"\n @input=\"onUserInput\"\n @focus=\"handleFocusInput\"\n @blur=\"handleBlurInput\"\n @keydown=\"handleKeydownInput\"\n @change=\"handleChange\"\n @mousedown=\"onMouseDownInput\"\n @mouseenter=\"onMouseEnter\"\n @mouseleave=\"onMouseLeave\"\n @touchstart.passive=\"onTouchStartInput\"\n @click.stop\n >\n <template #prefix>\n <span @mousedown.prevent=\"onMouseDownInput\" @touchstart.passive=\"onTouchStartInput\">\n <slot name=\"icon\">\n <hl-icon>\n <system-clock v-if=\"triggerName === 'clock'\" />\n <system-calendar v-if=\"triggerName === 'calendar'\" />\n </hl-icon>\n </slot>\n </span>\n </template>\n <template #suffix>\n <hl-icon v-if=\"showClose\" class=\"input-close\" @mousedown.stop @click.stop=\"onClearIconClick\">\n <system-close />\n </hl-icon>\n </template>\n </hl-input>\n <div\n v-else\n ref=\"inputRef\"\n :class=\"[\n namespace + '-input',\n 'date-' + type,\n pickerDisabled ? 'is-disabled' : '',\n pickerVisible ? 'is-focus' : '',\n namespace + '-date-input',\n size,\n $attrs.class,\n {\n 'block': block,\n 'fill': fill,\n 'thin': thin,\n }\n ]\"\n :style=\"$attrs.style\"\n @click.stop=\"handleFocusInput\"\n @mouseenter=\"onMouseEnter\"\n @mouseleave=\"onMouseLeave\"\n @touchstart.passive=\"onTouchStartInput\"\n @keydown=\"handleKeydownInput\"\n >\n <div :class=\"'range-input'\">\n <input\n :id=\"id && id[0]\"\n autocomplete=\"off\"\n :name=\"name && name[0]\"\n :placeholder=\"startPlaceholder\"\n :value=\"displayValue && displayValue[0]\"\n :disabled=\"pickerDisabled\"\n :readonly=\"!editable || readonly\"\n @mousedown=\"onMouseDownInput\"\n @input=\"handleStartInput\"\n @change=\"handleStartChange\"\n @focus=\"handleFocusInput\"\n @blur=\"handleBlurInput\"\n >\n <slot name=\"range-separator\">\n <span class=\"range-separator\">{{ rangeSeparator }}</span>\n </slot>\n <input\n :id=\"id && id[1]\"\n autocomplete=\"off\"\n :name=\"name && name[1]\"\n :placeholder=\"endPlaceholder\"\n :value=\"displayValue && displayValue[1]\"\n :disabled=\"pickerDisabled\"\n :readonly=\"!editable || readonly\"\n @mousedown=\"onMouseDownInput\"\n @focus=\"handleFocusInput\"\n @blur=\"handleBlurInput\"\n @input=\"handleEndInput\"\n @change=\"handleEndChange\"\n >\n </div>\n <span class=\"input-affixe prefix\" @mousedown.prevent=\"onMouseDownInput\" @touchstart.passive=\"onTouchStartInput\">\n <slot name=\"icon\">\n <hl-icon>\n <system-clock v-if=\"triggerName === 'clock'\" />\n <system-calendar v-if=\"triggerName === 'calendar'\" />\n </hl-icon>\n </slot>\n </span>\n <span class=\"input-affixe suffix\">\n <hl-icon v-if=\"showClose\" class=\"input-close\" @mousedown.stop @click.stop=\"onClearIconClick\">\n <system-close />\n </hl-icon>\n </span>\n </div>\n </template>\n <template #content>\n <slot\n :visible=\"pickerVisible\"\n :actual-visible=\"pickerActualVisible\"\n :parsed-value=\"parsedValue\"\n :format=\"format\"\n :date-format=\"dateFormat\"\n :time-format=\"timeFormat\"\n :unlink-panels=\"unlinkPanels\"\n :type=\"type\"\n :default-value=\"defaultValue\"\n @pick=\"onPick\"\n @select-range=\"setSelectionRange\"\n @set-picker-option=\"onSetPickerOption\"\n @calendar-change=\"onCalendarChange\"\n @panel-change=\"onPanelChange\"\n @keydown=\"onKeydownPopperContent\"\n @mousedown.stop\n ></slot>\n </template>\n </hl-tooltip>\n</template>\n<script lang=\"ts\" setup>\nimport { computed, inject, nextTick, provide, ref, unref, watch, onBeforeUnmount } from 'vue'\nimport { isEqual } from 'lodash-unified'\nimport { onClickOutside } from '@vueuse/core'\nimport { useEmptyValues, useFormItem, useLocale, useNamespace } from '@hongluan-ui/hooks'\nimport { FormItemEvents } from '@hongluan-ui/tokens'\nimport HlInput from '@hongluan-ui/components/input'\nimport HlTooltip from '@hongluan-ui/components/tooltip'\nimport HlIcon from '@hongluan-ui/components/icon'\nimport { SystemClock, SystemCalendar, SystemClose } from '@hongluan-ui/components/system-icon'\nimport { debugWarn, isArray } from '@hongluan-ui/utils'\nimport { EVENT_CODE } from '@hongluan-ui/constants'\nimport { formatter, parseDate, valueEquals } from '../utils'\nimport { timePickerDefaultProps } from './props'\n\nimport type { Dayjs } from 'dayjs'\nimport type { ComponentPublicInstance } from 'vue'\nimport type { Options } from '@popperjs/core'\nimport type {\n DateModelType,\n DateOrDates,\n DayOrDays,\n PickerOptions,\n SingleOrRange,\n TimePickerDefaultProps,\n UserInput,\n} from './props'\nimport type { TooltipInstance } from '@hongluan-ui/components/tooltip'\n\n// Date object and string\n\ndefineOptions({\n name: 'Picker',\n})\n\nconst props = defineProps(timePickerDefaultProps)\nconst emit = defineEmits([\n 'update:modelValue',\n 'change',\n 'focus',\n 'blur',\n 'clear',\n 'calendar-change',\n 'panel-change',\n 'visible-change',\n 'keydown',\n])\n\nconst { lang } = useLocale()\n\nconst { namespace } = useNamespace()\n\nconst { form, formItem } = useFormItem()\n\nconst hlPopperOptions = inject('PopperOptions', {} as Options)\nconst { valueOnClear } = useEmptyValues(props, null)\n\nconst refPopper = ref<TooltipInstance>()\nconst inputRef = ref<HTMLElement | ComponentPublicInstance>()\nconst pickerVisible = ref(false)\nconst pickerActualVisible = ref(false)\nconst valueOnOpen = ref<TimePickerDefaultProps['modelValue'] | null>(null)\n\nlet hasJustTabExitedInput = false\nlet ignoreFocusEvent = false\n\nwatch(pickerVisible, val => {\n if (!val) {\n userInput.value = null\n nextTick(() => {\n emitChange(props.modelValue)\n })\n } else {\n nextTick(() => {\n if (val) {\n valueOnOpen.value = props.modelValue\n }\n })\n }\n})\nconst emitChange = (\n val: TimePickerDefaultProps['modelValue'] | null,\n isClear?: boolean,\n) => {\n // determine user real change only\n if (isClear || !valueEquals(val, valueOnOpen.value)) {\n emit('change', val)\n props.validateEvent &&\n formItem?.validate?.(FormItemEvents.change).catch(err => debugWarn(err))\n }\n}\nconst emitInput = (input: SingleOrRange<DateModelType | Dayjs> | null) => {\n if (!valueEquals(props.modelValue, input)) {\n let formatted\n if (isArray(input)) {\n formatted = input.map(item =>\n formatter(item, props.valueFormat, lang.value),\n )\n } else if (input) {\n formatted = formatter(input, props.valueFormat, lang.value)\n }\n emit('update:modelValue', input ? formatted : input, lang.value)\n }\n}\nconst emitKeydown = (e: KeyboardEvent) => {\n emit('keydown', e)\n}\n\nconst refInput = computed<HTMLInputElement[]>(() => {\n if (inputRef.value) {\n const _r = isRangeInput.value\n ? inputRef.value\n : (inputRef.value as any as ComponentPublicInstance).$el\n return Array.from<HTMLInputElement>(_r.querySelectorAll('input'))\n }\n return []\n})\n\nconst setSelectionRange = (start: number, end: number, pos?: 'min' | 'max') => {\n const _inputs = refInput.value\n if (!_inputs.length) return\n if (!pos || pos === 'min') {\n _inputs[0].setSelectionRange(start, end)\n _inputs[0].focus()\n } else if (pos === 'max') {\n _inputs[1].setSelectionRange(start, end)\n _inputs[1].focus()\n }\n}\nconst focusOnInputBox = () => {\n focus(true, true)\n nextTick(() => {\n ignoreFocusEvent = false\n })\n}\n\nconst onPick = (date: any = '', visible = false) => {\n if (!visible) {\n ignoreFocusEvent = true\n }\n pickerVisible.value = visible\n let result\n if (isArray(date)) {\n result = date.map(_ => _.toDate())\n } else {\n // clear btn emit null\n result = date ? date.toDate() : date\n }\n userInput.value = null\n emitInput(result)\n}\n\nconst onBeforeShow = () => {\n pickerActualVisible.value = true\n}\n\nconst onShow = () => {\n emit('visible-change', true)\n}\n\nconst onKeydownPopperContent = (event: KeyboardEvent) => {\n if ((event as KeyboardEvent)?.key === EVENT_CODE.esc) {\n focus(true, true)\n }\n}\n\nconst onHide = () => {\n pickerActualVisible.value = false\n pickerVisible.value = false\n ignoreFocusEvent = false\n emit('visible-change', false)\n}\n\nconst handleOpen = () => {\n pickerVisible.value = true\n}\n\nconst handleClose = () => {\n pickerVisible.value = false\n}\n\nconst focus = (focusStartInput = true, isIgnoreFocusEvent = false) => {\n ignoreFocusEvent = isIgnoreFocusEvent\n const [leftInput, rightInput] = unref(refInput)\n let input = leftInput\n if (!focusStartInput && isRangeInput.value) {\n input = rightInput\n }\n if (input) {\n input.focus()\n }\n}\n\nconst handleFocusInput = (e?: FocusEvent) => {\n if (\n props.readonly ||\n pickerDisabled.value ||\n pickerVisible.value ||\n ignoreFocusEvent\n ) {\n return\n }\n pickerVisible.value = true\n emit('focus', e)\n}\n\nlet currentHandleBlurDeferCallback:\n| (() => Promise<void> | undefined)\n| undefined = undefined\n\n// Check if document.activeElement is inside popper or any input before popper close\nconst handleBlurInput = (e?: FocusEvent) => {\n const handleBlurDefer = async () => {\n setTimeout(() => {\n if (currentHandleBlurDeferCallback === handleBlurDefer) {\n if (\n !(\n refPopper.value?.isFocusInsideContent() && !hasJustTabExitedInput\n ) &&\n refInput.value.filter(input => {\n return input.contains(document.activeElement)\n }).length === 0\n ) {\n handleChange()\n pickerVisible.value = false\n emit('blur', e)\n props.validateEvent &&\n formItem?.validate?.(FormItemEvents.blur).catch(err => debugWarn(err))\n }\n hasJustTabExitedInput = false\n }\n }, 0)\n }\n currentHandleBlurDeferCallback = handleBlurDefer\n handleBlurDefer()\n}\n\nconst pickerDisabled = computed(() => {\n return props.disabled || form?.disabled\n})\n\nconst parsedValue = computed(() => {\n let dayOrDays: DayOrDays\n if (valueIsEmpty.value) {\n if (pickerOptions.value.getDefaultValue) {\n dayOrDays = pickerOptions.value.getDefaultValue()\n }\n } else {\n if (isArray(props.modelValue)) {\n dayOrDays = props.modelValue.map(d =>\n parseDate(d, props.valueFormat, lang.value),\n ) as [Dayjs, Dayjs]\n } else {\n dayOrDays = parseDate(props.modelValue, props.valueFormat, lang.value)!\n }\n }\n\n if (pickerOptions.value.getRangeAvailableTime) {\n const availableResult = pickerOptions.value.getRangeAvailableTime(\n dayOrDays!,\n )\n if (!isEqual(availableResult, dayOrDays!)) {\n dayOrDays = availableResult\n emitInput(\n (isArray(dayOrDays)\n ? dayOrDays.map(_ => _.toDate())\n : dayOrDays.toDate()) as SingleOrRange<Date>,\n )\n }\n }\n if (isArray(dayOrDays!) && dayOrDays.some(day => !day)) {\n dayOrDays = [] as unknown as DayOrDays\n }\n return dayOrDays!\n})\n\nconst displayValue = computed<UserInput>(() => {\n if (!pickerOptions.value.panelReady) return ''\n const formattedValue = formatDayjsToString(parsedValue.value)\n if (isArray(userInput.value)) {\n return [\n userInput.value[0] || (formattedValue && formattedValue[0]) || '',\n userInput.value[1] || (formattedValue && formattedValue[1]) || '',\n ]\n } else if (userInput.value !== null) {\n return userInput.value\n }\n if (!isTimePicker.value && valueIsEmpty.value) return ''\n if (!pickerVisible.value && valueIsEmpty.value) return ''\n if (formattedValue) {\n return isDatesPicker.value || isMonthsPicker.value || isYearsPicker.value\n ? (formattedValue as Array<string>).join(', ')\n : formattedValue\n }\n return ''\n})\n\nconst isTimeLikePicker = computed(() => props.type.includes('time'))\n\nconst isTimePicker = computed(() => props.type.startsWith('time'))\n\nconst isDatesPicker = computed(() => props.type === 'dates')\n\nconst isMonthsPicker = computed(() => props.type === 'months')\n\nconst isYearsPicker = computed(() => props.type === 'years')\n\nconst triggerName = computed(() => isTimeLikePicker.value ? 'clock' : 'calendar')\n\nconst showClose = ref(false)\n\nconst onClearIconClick = (event: MouseEvent) => {\n if (props.readonly || pickerDisabled.value) return\n if (showClose.value) {\n event.stopPropagation()\n focusOnInputBox()\n // When the handleClear Function was provided, emit null will be executed inside it\n // There is no need for us to execute emit null twice. #14752\n if (pickerOptions.value.handleClear) {\n pickerOptions.value.handleClear()\n } else {\n emitInput(valueOnClear.value)\n }\n emitChange(valueOnClear.value, true)\n showClose.value = false\n pickerVisible.value = false\n }\n emit('clear')\n}\n\nconst valueIsEmpty = computed(() => {\n const { modelValue } = props\n return (\n !modelValue || (isArray(modelValue) && !modelValue.filter(Boolean).length)\n )\n})\n\nconst onMouseDownInput = async (event: MouseEvent) => {\n if (props.readonly || pickerDisabled.value) return\n if (\n (event.target as HTMLElement)?.tagName !== 'INPUT' ||\n refInput.value.includes(document.activeElement as HTMLInputElement)\n ) {\n pickerVisible.value = true\n }\n}\nconst onMouseEnter = () => {\n if (props.readonly || pickerDisabled.value) return\n if (!valueIsEmpty.value && props.clearable) {\n showClose.value = true\n }\n}\nconst onMouseLeave = () => {\n showClose.value = false\n}\nconst onTouchStartInput = (event: TouchEvent) => {\n if (props.readonly || pickerDisabled.value) return\n if (\n (event.touches[0].target as HTMLElement)?.tagName !== 'INPUT' ||\n refInput.value.includes(document.activeElement as HTMLInputElement)\n ) {\n pickerVisible.value = true\n }\n}\nconst isRangeInput = computed(() => {\n return props.type.includes('range')\n})\n\nconst popperEl = computed(() => unref(refPopper)?.popperRef?.contentRef)\nconst popperPaneRef = computed(() => {\n return refPopper.value?.popperRef?.contentRef\n})\n\nconst actualInputRef = computed(() => {\n if (unref(isRangeInput)) {\n return unref(inputRef)\n }\n\n return (unref(inputRef) as ComponentPublicInstance)?.$el\n})\n\nconst stophandle = onClickOutside(actualInputRef, (e: PointerEvent) => {\n if (!pickerVisible.value || props.readonly || pickerDisabled.value) return\n\n const unrefedPopperEl = unref(popperEl)\n const inputEl = unref(actualInputRef)\n if (\n (unrefedPopperEl &&\n (e.target === unrefedPopperEl ||\n e.composedPath().includes(unrefedPopperEl))) ||\n e.target === inputEl ||\n e.composedPath().includes(inputEl)\n )\n return\n\n ignoreFocusEvent = true\n pickerVisible.value = false\n})\n\nonBeforeUnmount(() => {\n stophandle?.()\n})\n\nconst userInput = ref<UserInput>(null)\n\nconst handleChange = () => {\n if (userInput.value) {\n const value = parseUserInputToDayjs(displayValue.value)\n if (value) {\n if (isValidValue(value)) {\n emitInput(\n (isArray(value)\n ? value.map(_ => _.toDate())\n : value.toDate()) as DateOrDates,\n )\n userInput.value = null\n }\n }\n }\n if (userInput.value === '') {\n emitInput(valueOnClear.value)\n emitChange(valueOnClear.value)\n userInput.value = null\n }\n}\n\nconst parseUserInputToDayjs = (value: UserInput) => {\n if (!value) return null\n return pickerOptions.value.parseUserInput!(value)\n}\n\nconst formatDayjsToString = (value: DayOrDays) => {\n if (!value) return null\n return pickerOptions.value.formatToString!(value)\n}\n\nconst isValidValue = (value: DayOrDays) => {\n return pickerOptions.value.isValidValue!(value)\n}\n\nconst handleKeydownInput = async (event: KeyboardEvent) => {\n if (props.readonly || pickerDisabled.value) return\n\n const { code } = event\n emitKeydown(event)\n if (code === EVENT_CODE.esc) {\n if (pickerVisible.value === true) {\n pickerVisible.value = false\n event.preventDefault()\n event.stopPropagation()\n }\n return\n }\n\n if (code === EVENT_CODE.down) {\n if (pickerOptions.value.handleFocusPicker) {\n event.preventDefault()\n event.stopPropagation()\n }\n if (pickerVisible.value === false) {\n pickerVisible.value = true\n await nextTick()\n }\n if (pickerOptions.value.handleFocusPicker) {\n pickerOptions.value.handleFocusPicker()\n return\n }\n }\n\n if (code === EVENT_CODE.tab) {\n hasJustTabExitedInput = true\n return\n }\n\n if (code === EVENT_CODE.enter || code === EVENT_CODE.numpadEnter) {\n if (\n userInput.value === null ||\n userInput.value === '' ||\n isValidValue(parseUserInputToDayjs(displayValue.value) as DayOrDays)\n ) {\n handleChange()\n pickerVisible.value = false\n }\n event.stopPropagation()\n return\n }\n\n // if user is typing, do not let picker handle key input\n if (userInput.value) {\n event.stopPropagation()\n return\n }\n if (pickerOptions.value.handleKeydownInput) {\n pickerOptions.value.handleKeydownInput(event)\n }\n}\nconst onUserInput = (e: string) => {\n userInput.value = e\n // Temporary fix when the picker is dismissed and the input box\n // is focused, just mimic the behavior of antdesign.\n if (!pickerVisible.value) {\n pickerVisible.value = true\n }\n}\n\nconst handleStartInput = (event: Event) => {\n const target = event.target as HTMLInputElement\n if (userInput.value) {\n userInput.value = [target.value, userInput.value[1]]\n } else {\n userInput.value = [target.value, null]\n }\n}\n\nconst handleEndInput = (event: Event) => {\n const target = event.target as HTMLInputElement\n if (userInput.value) {\n userInput.value = [userInput.value[0], target.value]\n } else {\n userInput.value = [null, target.value]\n }\n}\n\nconst handleStartChange = () => {\n const values = userInput.value as string[]\n const value = parseUserInputToDayjs(values && values[0]) as Dayjs\n const parsedVal = unref(parsedValue) as [Dayjs, Dayjs]\n if (value && value.isValid()) {\n userInput.value = [\n formatDayjsToString(value) as string,\n displayValue.value?.[1] || null,\n ]\n const newValue = [value, parsedVal && (parsedVal[1] || null)] as DayOrDays\n if (isValidValue(newValue)) {\n emitInput(newValue)\n userInput.value = null\n }\n }\n}\n\nconst handleEndChange = () => {\n const values = unref(userInput) as string[]\n const value = parseUserInputToDayjs(values && values[1]) as Dayjs\n const parsedVal = unref(parsedValue) as [Dayjs, Dayjs]\n if (value && value.isValid()) {\n userInput.value = [\n unref(displayValue)?.[0] || null,\n formatDayjsToString(value) as string,\n ]\n const newValue = [parsedVal && parsedVal[0], value] as DayOrDays\n if (isValidValue(newValue)) {\n emitInput(newValue)\n userInput.value = null\n }\n }\n}\n\nconst pickerOptions = ref<Partial<PickerOptions>>({})\nconst onSetPickerOption = <T extends keyof PickerOptions>(\n e: [T, PickerOptions[T]],\n) => {\n pickerOptions.value[e[0]] = e[1]\n pickerOptions.value.panelReady = true\n}\n\nconst onCalendarChange = (e: [Date, null | Date]) => {\n emit('calendar-change', e)\n}\n\nconst onPanelChange = (\n value: [Dayjs, Dayjs],\n mode: 'month' | 'year',\n view: unknown,\n) => {\n emit('panel-change', value, mode, view)\n}\n\nprovide('EP_PICKER_BASE', {\n props,\n})\n\ndefineExpose({\n popperPaneRef,\n /**\n * @description focus input box.\n */\n focus,\n /**\n * @description opens picker\n */\n handleOpen,\n /**\n * @description closes picker\n */\n handleClose,\n /**\n * @description emit focus event\n */\n handleFocusInput,\n /**\n * @description emit blur event\n */\n handleBlurInput,\n /**\n * @description pick item manually\n */\n onPick,\n})\n</script>\n"],"names":[],"mappings":"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"}