UNPKG

@extclp/vexip-ui

Version:

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

1 lines 14.4 kB
{"version":3,"file":"date-control.vue2.mjs","sources":["../../../components/date-picker/date-control.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\n\nimport { useNameHelper } from '@vexip-ui/config'\nimport { doubleDigits, getLastDayOfMonth } from '@vexip-ui/utils'\nimport { handleKeyEnter } from './helper'\n\nimport type { PropType } from 'vue'\nimport type { LocaleConfig } from '@vexip-ui/config'\nimport type { DateTimeType, DateType } from './symbol'\n\ndefineOptions({ name: 'DateControl' })\n\nconst props = defineProps({\n unitType: {\n type: String as PropType<DateTimeType | ''>,\n default: ''\n },\n enabled: {\n type: Object as PropType<Record<DateTimeType, boolean>>,\n default: () => ({})\n },\n activated: {\n type: Object as PropType<Record<DateTimeType, boolean>>,\n default: () => ({})\n },\n dateValue: {\n type: Object as PropType<Record<DateTimeType, number>>,\n default: () => ({})\n },\n dateSeparator: {\n type: String,\n default: '/'\n },\n timeSeparator: {\n type: String,\n default: ':'\n },\n visible: {\n type: Boolean,\n default: false\n },\n focused: {\n type: Boolean,\n default: false\n },\n filler: {\n type: String,\n default: '-',\n validator: (value: string) => {\n return value.length === 1\n }\n },\n steps: {\n type: Array as PropType<number[]>,\n default: () => [1, 1, 1]\n },\n ctrlSteps: {\n type: Array as PropType<number[]>,\n default: () => [5, 5, 5]\n },\n labels: {\n type: Object as PropType<Partial<Record<DateTimeType, string>>>,\n default: () => ({})\n },\n hasError: {\n type: Boolean,\n default: false\n },\n placeholder: {\n type: String,\n default: ''\n },\n readonly: {\n type: Boolean,\n default: false\n },\n labeledBy: {\n type: String,\n default: undefined\n },\n locale: {\n type: Object as PropType<LocaleConfig['calendar'] & LocaleConfig['datePicker']>,\n default: () => ({})\n },\n dateUnitOrder: {\n type: Array as PropType<DateType[]>,\n default: () => ['year', 'month', 'date']\n }\n})\n\nconst emit = defineEmits([\n 'input',\n 'plus',\n 'minus',\n 'enter',\n 'cancel',\n 'unit-focus',\n 'prev-unit',\n 'next-unit',\n 'blur'\n])\n\nconst nh = useNameHelper('date-picker')\n\nconst wrapper = ref<HTMLElement>()\n\nconst label = computed(() => props.locale.ariaLabel ?? {})\nconst isActivated = computed(() => {\n return (Object.keys(props.enabled) as DateTimeType[]).every(type => {\n return !props.enabled[type] || props.activated[type]\n })\n})\nconst className = computed(() => {\n return {\n [nh.be('input')]: true,\n [nh.bem('input', 'activated')]: isActivated.value,\n [nh.bem('input', 'error')]: props.hasError\n }\n})\nconst showTimeUnits = computed(() => {\n return props.enabled.hour || props.enabled.minute || props.enabled.second\n})\nconst formattedYear = computed(() => {\n return formatValue('year')\n})\nconst formattedMonth = computed(() => {\n return formatValue('month')\n})\nconst formattedDate = computed(() => {\n return formatValue('date')\n})\nconst formattedHour = computed(() => {\n return formatValue('hour')\n})\nconst formattedMinute = computed(() => {\n return formatValue('minute')\n})\nconst formattedSecond = computed(() => {\n return formatValue('second')\n})\nconst maxDateCount = computed(() => {\n return getLastDayOfMonth(props.dateValue.year, props.dateValue.month)\n})\nconst dateUnitOrder = computed(() => {\n const [one, two, three] = props.dateUnitOrder\n\n return {\n [one]: -4,\n [two]: -2,\n [three]: 0\n }\n})\n\ndefineExpose({\n isActivated,\n wrapper,\n focus: () => {\n wrapper.value?.focus()\n },\n blur: () => {\n wrapper.value?.blur()\n }\n})\n\nfunction formatValue(type: DateTimeType) {\n const isYear = type === 'year'\n const filler = props.filler\n\n return props.activated[type]\n ? isYear\n ? props.dateValue.year.toString().padStart(4, '0')\n : doubleDigits(props.dateValue[type])\n : `${isYear ? `${filler}${filler}` : ''}${filler}${filler}`\n}\n\nfunction getUnitFocusClass(type: DateTimeType) {\n return props.visible && props.unitType === type ? nh.bem('unit', 'focused') : null\n}\n\nfunction handleInputFocus(type: DateTimeType) {\n if (props.readonly) return\n\n emit('unit-focus', type)\n}\n\nfunction handleInput(event: KeyboardEvent) {\n if (!props.visible) return\n\n const type = handleKeyEnter(event)\n\n if (props.readonly) {\n switch (type) {\n case 'ok': {\n emit('enter')\n break\n }\n case 'esc': {\n emit('cancel')\n break\n }\n }\n\n return\n }\n\n switch (type) {\n case 'next': {\n emit('next-unit')\n break\n }\n case 'prev': {\n emit('prev-unit')\n break\n }\n case 'up': {\n emit('minus', event.ctrlKey)\n break\n }\n case 'down': {\n emit('plus', event.ctrlKey)\n break\n }\n case 'ok': {\n emit('enter')\n break\n }\n case 'esc': {\n emit('cancel')\n break\n }\n default: {\n if (typeof type === 'number') {\n emit('input', type)\n }\n }\n }\n}\n\nfunction handleBlur() {\n emit('blur')\n}\n</script>\n\n<template>\n <div\n ref=\"wrapper\"\n :class=\"className\"\n role=\"none\"\n tabindex=\"-1\"\n @keydown=\"handleInput\"\n @blur=\"handleBlur\"\n >\n <div v-if=\"!focused && !isActivated\" :class=\"nh.be('placeholder')\">\n {{ placeholder }}\n </div>\n <template v-else>\n <div\n v-if=\"enabled.year\"\n :class=\"[nh.be('unit'), getUnitFocusClass('year')]\"\n role=\"spinbutton\"\n :aria-label=\"label.year\"\n :aria-valuenow=\"props.dateValue.year\"\n :aria-valuetext=\"formattedYear\"\n :aria-valuemin=\"1\"\n :aria-valuemax=\"9999\"\n :aria-labelledby=\"labeledBy\"\n :style=\"{ order: dateUnitOrder['year'] }\"\n @click=\"handleInputFocus('year')\"\n >\n {{ formattedYear }}\n </div>\n <div\n v-if=\"labels.year\"\n :class=\"nh.be('label')\"\n aria-hidden\n :style=\"{ order: dateUnitOrder['year'] }\"\n @click=\"handleInputFocus('year')\"\n >\n {{ labels.year }}\n </div>\n <template v-if=\"enabled.month\">\n <div\n v-if=\"enabled.year\"\n :class=\"nh.be('separator')\"\n aria-hidden\n style=\"order: -3\"\n >\n {{ dateSeparator }}\n </div>\n <div\n :class=\"[nh.be('unit'), getUnitFocusClass('month')]\"\n role=\"spinbutton\"\n :aria-label=\"label.month\"\n :aria-valuenow=\"props.dateValue.month\"\n :aria-valuetext=\"formattedMonth\"\n :aria-valuemin=\"1\"\n :aria-valuemax=\"12\"\n :aria-labelledby=\"labeledBy\"\n :style=\"{ order: dateUnitOrder['month'] }\"\n @click=\"handleInputFocus('month')\"\n >\n {{ formattedMonth }}\n </div>\n <div\n v-if=\"labels.month\"\n :class=\"nh.be('label')\"\n aria-hidden\n :style=\"{ order: dateUnitOrder['month'] }\"\n @click=\"handleInputFocus('month')\"\n >\n {{ labels.month }}\n </div>\n </template>\n <template v-if=\"enabled.date\">\n <div\n v-if=\"enabled.month || enabled.year\"\n :class=\"nh.be('separator')\"\n aria-hidden\n style=\"order: -1\"\n >\n {{ dateSeparator }}\n </div>\n <div\n :class=\"[nh.be('unit'), getUnitFocusClass('date')]\"\n role=\"spinbutton\"\n :aria-label=\"label.date\"\n :aria-valuenow=\"props.dateValue.date\"\n :aria-valuetext=\"formattedDate\"\n :aria-valuemin=\"1\"\n :aria-valuemax=\"maxDateCount || 31\"\n :aria-labelledby=\"labeledBy\"\n :style=\"{ order: dateUnitOrder['date'] }\"\n @click=\"handleInputFocus('date')\"\n >\n {{ formattedDate }}\n </div>\n <div\n v-if=\"labels.date\"\n :class=\"nh.be('label')\"\n aria-hidden\n :style=\"{ order: dateUnitOrder['date'] }\"\n @click=\"handleInputFocus('date')\"\n >\n {{ labels.date }}\n </div>\n </template>\n\n <template v-if=\"showTimeUnits\">\n <div :class=\"nh.be('pad')\"></div>\n <div\n v-if=\"enabled.hour\"\n :class=\"[nh.be('unit'), getUnitFocusClass('hour')]\"\n role=\"spinbutton\"\n :aria-label=\"label.hour\"\n :aria-valuenow=\"props.dateValue.hour\"\n :aria-valuetext=\"formattedHour\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"23\"\n :aria-labelledby=\"labeledBy\"\n @click=\"handleInputFocus('hour')\"\n >\n {{ formattedHour }}\n </div>\n <div\n v-if=\"labels.hour\"\n :class=\"nh.be('label')\"\n aria-hidden\n @click=\"handleInputFocus('hour')\"\n >\n {{ labels.hour }}\n </div>\n <template v-if=\"enabled.minute\">\n <div v-if=\"enabled.hour\" :class=\"nh.be('separator')\" aria-hidden>\n {{ timeSeparator }}\n </div>\n <div\n :class=\"[nh.be('unit'), getUnitFocusClass('minute')]\"\n role=\"spinbutton\"\n :aria-label=\"label.minute\"\n :aria-valuenow=\"props.dateValue.minute\"\n :aria-valuetext=\"formattedMinute\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"59\"\n :aria-labelledby=\"labeledBy\"\n @click=\"handleInputFocus('minute')\"\n >\n {{ formattedMinute }}\n </div>\n <div\n v-if=\"labels.minute\"\n :class=\"nh.be('label')\"\n aria-hidden\n @click=\"handleInputFocus('minute')\"\n >\n {{ labels.minute }}\n </div>\n </template>\n <template v-if=\"enabled.second\">\n <div v-if=\"enabled.minute || enabled.hour\" :class=\"nh.be('separator')\" aria-hidden>\n {{ timeSeparator }}\n </div>\n <div\n :class=\"[nh.be('unit'), getUnitFocusClass('second')]\"\n role=\"spinbutton\"\n :aria-label=\"label.second\"\n :aria-valuenow=\"props.dateValue.second\"\n :aria-valuetext=\"formattedSecond\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"59\"\n :aria-labelledby=\"labeledBy\"\n @click=\"handleInputFocus('second')\"\n >\n {{ formattedSecond }}\n </div>\n <div\n v-if=\"labels.second\"\n :class=\"nh.be('label')\"\n aria-hidden\n @click=\"handleInputFocus('second')\"\n >\n {{ labels.second }}\n </div>\n </template>\n </template>\n </template>\n </div>\n</template>\n"],"names":["props","__props","emit","__emit","nh","useNameHelper","wrapper","ref","label","computed","isActivated","type","className","showTimeUnits","formattedYear","formatValue","formattedMonth","formattedDate","formattedHour","formattedMinute","formattedSecond","maxDateCount","getLastDayOfMonth","dateUnitOrder","one","two","three","__expose","_a","isYear","filler","doubleDigits","getUnitFocusClass","handleInputFocus","handleInput","event","handleKeyEnter","handleBlur"],"mappings":"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"}