@extclp/vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
1 lines • 15.5 kB
Source Map (JSON)
{"version":3,"file":"calendar-panel.vue2.mjs","sources":["../../../components/calendar/calendar-panel.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { Renderer } from '@/components/renderer'\n\nimport { computed, ref, toRef, watch } from 'vue'\n\nimport CalendarCell from './calendar-cell.vue'\nimport { emitEvent, useLocale, useNameHelper, useProps } from '@vexip-ui/config'\nimport { useHover } from '@vexip-ui/hooks'\nimport {\n debounceMinor,\n differenceDays,\n endOfDay,\n rangeDate,\n startOfDay,\n startOfWeek,\n toFalse\n} from '@vexip-ui/utils'\nimport { calendarPanelProps } from './props'\n\nimport type { Dateable } from '@vexip-ui/utils'\nimport type { CalendarPanelSlots, WeekIndex } from './symbol'\n\ndefineOptions({ name: 'CalendarPanel' })\n\nconst _props = defineProps(calendarPanelProps)\nconst props = useProps('calendarBase', _props, {\n locale: null,\n value: {\n default: null,\n static: true\n },\n year: () => new Date().getFullYear(),\n month: {\n default: () => new Date().getMonth() + 1,\n validator: value => value > 0 && value <= 12\n },\n weekDays: {\n default: null,\n validator: value => !value || value.length === 0 || value.length === 7\n },\n weekStart: {\n default: 0,\n validator: value => value >= 0 && value < 7\n },\n today: {\n default: () => new Date(),\n validator: value => !Number.isNaN(+new Date(value))\n },\n disabledDate: {\n default: toFalse,\n isFunc: true\n },\n valueType: {\n default: 'start',\n validator: value => value === 'start' || value === 'end'\n },\n min: null,\n max: null,\n range: null,\n slots: () => ({})\n})\n\nconst emit = defineEmits(['update:value'])\n\ndefineSlots<CalendarPanelSlots>()\n\nconst nh = useNameHelper('calendar')\n\nconst startValue = ref<Date | null>(null)\nconst endValue = ref<Date | null>(null)\nconst dateRange = ref<Date[]>([])\nconst hoveredDate = ref<Date | null>(null)\n\nconst { wrapper, isHover } = useHover()\nconst locale = useLocale('calendar', toRef(props, 'locale'))\n\nconst min = computed(() => (props.min ? +startOfDay(props.min) : -Infinity))\nconst max = computed(() => (props.max ? +endOfDay(props.max) : Infinity))\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})\n\nconst updateDateRange = debounceMinor(setDateRange)\n\nparseValue(props.value)\nsetDateRange()\n\nwatch(() => props.value, parseValue)\nwatch([() => props.year, () => props.month, () => props.weekStart], updateDateRange)\nwatch(isHover, value => {\n if (!value) {\n hoveredDate.value = null\n }\n})\nwatch(hoveredDate, value => {\n emitEvent(props.onHover, value)\n})\n\ndefineExpose({\n startValue,\n endValue,\n body: wrapper,\n isSelected,\n isHovered,\n isPrevMonth,\n isNextMonth,\n isDisabled,\n isToday,\n isInRange\n})\n\nfunction getWeekLabel(index: number) {\n return props.weekDays?.[index] || locale.value[`week${(index || 7) as WeekIndex}`]\n}\n\nfunction setDateRange() {\n dateRange.value = rangeDate(\n startOfWeek(new Date(props.year, props.month - 1, 1), props.weekStart),\n 42\n )\n}\n\nfunction parseValue(value: Dateable | Dateable[]) {\n if (!Array.isArray(value)) {\n value = [value, value]\n }\n\n for (let i = 0; i < 2; ++i) {\n const date = new Date(value[i] ?? '')\n\n if (i === 0) {\n startValue.value = Number.isNaN(+date) ? null : date\n } else {\n endValue.value = Number.isNaN(+date) ? null : date\n }\n\n if (!props.range) break\n }\n}\n\nfunction isSelected(date: Date) {\n if (!date || (!startValue.value && !endValue.value)) {\n return false\n }\n\n return !!(\n (startValue.value && !differenceDays(date, startValue.value)) ||\n (endValue.value && !differenceDays(date, endValue.value))\n )\n}\n\nfunction isDisabled(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 isHovered(date: Date) {\n if (!date || !hoveredDate.value) {\n return false\n }\n\n return !differenceDays(date, hoveredDate.value)\n}\n\nfunction isPrevMonth(date: Date) {\n const { year, month } = props\n const dateYear = date.getFullYear()\n const dateMonth = date.getMonth()\n\n return dateYear < year || (dateYear === year && dateMonth < month - 1)\n}\n\nfunction isNextMonth(date: Date) {\n const { year, month } = props\n const dateYear = date.getFullYear()\n const dateMonth = date.getMonth()\n\n return dateYear > year || (dateYear === year && dateMonth > month - 1)\n}\n\nfunction isToday(date: Date) {\n return differenceDays(date, props.today) === 0\n}\n\nfunction handleSelect(date: Date) {\n if (isDisabled(date)) {\n return\n }\n\n if (props.valueType === 'start') {\n startValue.value = date\n } else {\n endValue.value = date\n }\n\n emitEvent(props.onSelect, date)\n emit('update:value', date)\n}\n\nfunction handleHover(date: Date) {\n hoveredDate.value = isDisabled(date) ? null : date\n}\n\nfunction isInRange(date: Date) {\n if (!hoveredDate.value && !startValue.value && !endValue.value) {\n return false\n }\n\n let min: number\n let max: number\n\n if (startValue.value && endValue.value) {\n const startTime = startValue.value.getTime()\n const endTime = endValue.value.getTime()\n\n min = Math.min(startTime, endTime)\n max = Math.max(startTime, endTime)\n } else if (hoveredDate.value) {\n if (!startValue.value && !endValue.value) return false\n\n const hoveredTime = hoveredDate.value.getTime()\n\n if (!startValue.value || !endValue.value) {\n const selectedTime = (startValue.value ?? endValue.value)!.getTime()\n\n min = Math.min(hoveredTime, selectedTime)\n max = Math.max(hoveredTime, selectedTime)\n } else {\n const startTime = startValue.value.getTime()\n const endTime = endValue.value.getTime()\n const minTime = Math.min(startTime, endTime)\n const maxTime = Math.max(startTime, endTime)\n\n min = Math.min(hoveredTime, minTime)\n max = Math.max(hoveredTime, maxTime)\n }\n } else {\n return false\n }\n\n return date.getTime() >= min && date.getTime() <= max\n}\n</script>\n\n<template>\n <div\n :class=\"[nh.be('panel'), nh.bs('vars'), props.inherit && nh.bem('panel', 'inherit')]\"\n role=\"grid\"\n >\n <slot name=\"header\">\n <Renderer :renderer=\"props.slots.header\"></Renderer>\n </slot>\n <div :class=\"[nh.be('row'), nh.bem('row', 'week')]\" aria-hidden>\n <div v-for=\"week in 7\" :key=\"week\" :class=\"[nh.be('cell'), nh.be('cell-week')]\">\n <slot\n name=\"week\"\n :label=\"getWeekLabel((week - 1 + props.weekStart) % 7)\"\n :index=\"week - 1\"\n :week=\"(week - 1 + props.weekStart) % 7\"\n >\n <Renderer\n :renderer=\"props.slots.week\"\n :data=\"{\n label: getWeekLabel((week - 1 + props.weekStart) % 7),\n index: week - 1,\n week: (week - 1 + props.weekStart) % 7\n }\"\n >\n <div :class=\"nh.be('index')\">\n {{ getWeekLabel((week - 1 + props.weekStart) % 7) }}\n </div>\n </Renderer>\n </slot>\n </div>\n </div>\n <div ref=\"body\" :class=\"nh.be('body')\">\n <div v-for=\"row in 6\" :key=\"row\" :class=\"nh.be('row')\">\n <CalendarCell\n v-for=\"cell in 7\"\n :key=\"(row - 1) * 7 + cell\"\n :date=\"dateRange[(row - 1) * 7 + cell - 1]\"\n :locale=\"locale\"\n :selected=\"isSelected(dateRange[(row - 1) * 7 + cell - 1])\"\n :hovered=\"isHovered(dateRange[(row - 1) * 7 + cell - 1])\"\n :is-prev=\"isPrevMonth(dateRange[(row - 1) * 7 + cell - 1])\"\n :is-next=\"isNextMonth(dateRange[(row - 1) * 7 + cell - 1])\"\n :is-today=\"isToday(dateRange[(row - 1) * 7 + cell - 1])\"\n :disabled=\"isDisabled(dateRange[(row - 1) * 7 + cell - 1])\"\n :in-range=\"props.range && isInRange(dateRange[(row - 1) * 7 + cell - 1])\"\n @hover=\"handleHover\"\n @select=\"handleSelect\"\n >\n <template\n v-if=\"$slots.item || props.slots.item\"\n #item=\"{\n date,\n label,\n selected,\n hovered,\n isPrev,\n isNext,\n isToday: matchedToday,\n disabled,\n inRange\n }\"\n >\n <slot\n name=\"item\"\n :date=\"date\"\n :label=\"label\"\n :selected=\"selected\"\n :hovered=\"hovered\"\n :is-prev=\"isPrev\"\n :is-next=\"isNext\"\n :is-today=\"matchedToday\"\n :disabled=\"disabled\"\n :in-range=\"inRange\"\n >\n <Renderer\n :renderer=\"props.slots.item\"\n :data=\"{\n date,\n label,\n selected,\n hovered,\n isPrev,\n isNext,\n isToday: matchedToday,\n disabled,\n inRange\n }\"\n ></Renderer>\n </slot>\n </template>\n <template v-if=\"$slots.itemContent || props.slots.itemContent\" #default=\"cellParams\">\n <slot name=\"itemContent\" v-bind=\"cellParams\">\n <Renderer :renderer=\"props.slots.itemContent\" :data=\"cellParams\"></Renderer>\n </slot>\n </template>\n </CalendarCell>\n </div>\n </div>\n <slot name=\"footer\">\n <Renderer :renderer=\"props.slots.footer\"></Renderer>\n </slot>\n </div>\n</template>\n"],"names":["props","useProps","__props","value","toFalse","emit","__emit","nh","useNameHelper","startValue","ref","endValue","dateRange","hoveredDate","wrapper","isHover","useHover","locale","useLocale","toRef","min","computed","startOfDay","max","endOfDay","reversed","updateDateRange","debounceMinor","setDateRange","parseValue","watch","emitEvent","__expose","isSelected","isHovered","isPrevMonth","isNextMonth","isDisabled","isToday","isInRange","getWeekLabel","index","_a","rangeDate","startOfWeek","i","date","differenceDays","time","year","month","dateYear","dateMonth","handleSelect","handleHover","startTime","endTime","hoveredTime","selectedTime","minTime","maxTime"],"mappings":"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"}