first commit
This commit is contained in:
commit
eb2f504652
32490 changed files with 5731109 additions and 0 deletions
296
node_modules/@vuepic/vue-datepicker/src/VueDatePicker/components/Calendar.vue
generated
vendored
Normal file
296
node_modules/@vuepic/vue-datepicker/src/VueDatePicker/components/Calendar.vue
generated
vendored
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
<template>
|
||||
<div :class="calendarParentClass">
|
||||
<div :style="contentWrapStyle">
|
||||
<div
|
||||
ref="calendarWrapRef"
|
||||
v-if="!specificMode"
|
||||
:class="calendarWrapClass"
|
||||
role="grid"
|
||||
:aria-label="defaults.ariaLabels?.calendarWrap"
|
||||
>
|
||||
<div class="dp__calendar_header" role="row">
|
||||
<div class="dp__calendar_header_item" role="gridcell" v-if="weekNumbers">
|
||||
{{ weekNumName }}
|
||||
</div>
|
||||
<div
|
||||
class="dp__calendar_header_item"
|
||||
role="gridcell"
|
||||
v-for="(dayVal, i) in weekDays"
|
||||
:key="i"
|
||||
data-test="calendar-header"
|
||||
>
|
||||
<slot v-if="$slots['calendar-header']" name="calendar-header" :day="dayVal" :index="i" />
|
||||
<template v-if="!$slots['calendar-header']">
|
||||
{{ dayVal }}
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dp__calendar_header_separator"></div>
|
||||
<transition :name="transitionName" :css="!!transitions">
|
||||
<div
|
||||
class="dp__calendar"
|
||||
role="grid"
|
||||
:aria-label="defaults.ariaLabels?.calendarDays"
|
||||
v-if="showCalendar"
|
||||
>
|
||||
<div class="dp__calendar_row" role="row" v-for="(week, weekInd) in mappedDates" :key="weekInd">
|
||||
<div role="gridcell" v-if="weekNumbers" class="dp__calendar_item dp__week_num">
|
||||
<div class="dp__cell_inner">
|
||||
{{ getWeekNum(week.days) }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-for="(dayVal, dayInd) in week.days"
|
||||
role="gridcell"
|
||||
class="dp__calendar_item"
|
||||
:ref="(el) => assignDayRef(el, weekInd, dayInd)"
|
||||
:key="dayInd + weekInd"
|
||||
:aria-selected="
|
||||
dayVal.classData.dp__active_date ||
|
||||
dayVal.classData.dp__range_start ||
|
||||
dayVal.classData.dp__range_start
|
||||
"
|
||||
:aria-disabled="dayVal.classData.dp__cell_disabled"
|
||||
:aria-label="defaults.ariaLabels?.day?.(dayVal)"
|
||||
tabindex="0"
|
||||
:data-test="dayVal.value"
|
||||
@click.stop.prevent="$emit('select-date', dayVal)"
|
||||
@keydown.enter="$emit('select-date', dayVal)"
|
||||
@keydown.space="$emit('handle-space', dayVal)"
|
||||
@mouseenter="onMouseOver(dayVal, weekInd, dayInd)"
|
||||
@mouseleave="onMouseLeave(dayVal)"
|
||||
>
|
||||
<div class="dp__cell_inner" :class="dayVal.classData">
|
||||
<slot
|
||||
name="day"
|
||||
v-if="$slots.day && showDay(dayVal)"
|
||||
:day="+dayVal.text"
|
||||
:date="dayVal.value"
|
||||
></slot>
|
||||
<template v-if="!$slots.day"> {{ dayVal.text }} </template>
|
||||
<div
|
||||
v-if="dayVal.marker && showDay(dayVal)"
|
||||
:class="markerClass(dayVal.marker)"
|
||||
:style="dayVal.marker.color ? { backgroundColor: dayVal.marker.color } : {}"
|
||||
></div>
|
||||
<div
|
||||
class="dp__marker_tooltip"
|
||||
v-if="dateMatch(dayVal.value)"
|
||||
:style="markerTooltipStyle"
|
||||
>
|
||||
<div class="dp__tooltip_content" @click.stop v-if="dayVal.marker?.tooltip">
|
||||
<div
|
||||
v-for="(tooltip, i) in dayVal.marker.tooltip"
|
||||
:key="i"
|
||||
class="dp__tooltip_text"
|
||||
>
|
||||
<slot
|
||||
name="marker-tooltip"
|
||||
v-if="$slots['marker-tooltip']"
|
||||
:tooltip="tooltip"
|
||||
:day="dayVal.value"
|
||||
></slot>
|
||||
<template v-if="!$slots['marker-tooltip']">
|
||||
<div
|
||||
class="dp__tooltip_mark"
|
||||
:style="tooltip.color ? { backgroundColor: tooltip.color } : {}"
|
||||
></div>
|
||||
<div>{{ tooltip.text }}</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="dp__arrow_bottom_tp"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, nextTick, onMounted, ref } from 'vue';
|
||||
|
||||
import { getDayNames, getDefaultMarker, unrefElement } from '@/utils/util';
|
||||
import { useArrowNavigation, useUtils } from '@/components/composables';
|
||||
import { AllProps } from '@/utils/props';
|
||||
import { getDate, isDateAfter, isDateEqual, resetDateTime } from '@/utils/date-utils';
|
||||
|
||||
import type { PropType, UnwrapRef } from 'vue';
|
||||
import type { DynamicClass, ICalendarDate, ICalendarDay, IMarker } from '@/interfaces';
|
||||
|
||||
const emit = defineEmits([
|
||||
'select-date',
|
||||
'set-hover-date',
|
||||
'handle-scroll',
|
||||
'mount',
|
||||
'handle-swipe',
|
||||
'handle-space',
|
||||
'tooltip-open',
|
||||
'tooltip-close',
|
||||
]);
|
||||
|
||||
const props = defineProps({
|
||||
mappedDates: { type: Array as PropType<ICalendarDate[]>, default: () => [] },
|
||||
getWeekNum: {
|
||||
type: Function as PropType<(dates: UnwrapRef<ICalendarDay[]>) => string | number>,
|
||||
default: () => '',
|
||||
},
|
||||
specificMode: { type: Boolean as PropType<boolean>, default: false },
|
||||
instance: { type: Number as PropType<number>, default: 0 },
|
||||
month: { type: Number as PropType<number>, default: 0 },
|
||||
year: { type: Number as PropType<number>, default: 0 },
|
||||
...AllProps,
|
||||
});
|
||||
|
||||
const { buildMultiLevelMatrix } = useArrowNavigation();
|
||||
const { setDateMonthOrYear, defaults } = useUtils(props);
|
||||
|
||||
const showMakerTooltip = ref<Date | null>(null);
|
||||
const markerTooltipStyle = ref({ bottom: '', left: '', transform: '' });
|
||||
const dayRefs = ref<HTMLElement[][]>([]);
|
||||
const calendarWrapRef = ref<HTMLElement | null>(null);
|
||||
const showCalendar = ref(true);
|
||||
const transitionName = ref('');
|
||||
const touch = ref({ startX: 0, endX: 0, startY: 0, endY: 0 });
|
||||
|
||||
const weekDays = computed(() => {
|
||||
if (props.dayNames) {
|
||||
return Array.isArray(props.dayNames) ? props.dayNames : props.dayNames(props.locale, +props.weekStart);
|
||||
}
|
||||
return getDayNames(props.locale, +props.weekStart);
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
emit('mount', { cmp: 'calendar', refs: dayRefs });
|
||||
if (!props.noSwipe) {
|
||||
if (calendarWrapRef.value) {
|
||||
calendarWrapRef.value.addEventListener('touchstart', onTouchStart, { passive: false });
|
||||
calendarWrapRef.value.addEventListener('touchend', onTouchEnd, { passive: false });
|
||||
calendarWrapRef.value.addEventListener('touchmove', onTouchMove, { passive: false });
|
||||
}
|
||||
}
|
||||
if (props.monthChangeOnScroll && calendarWrapRef.value) {
|
||||
calendarWrapRef.value.addEventListener('wheel', onScroll, { passive: false });
|
||||
}
|
||||
});
|
||||
|
||||
const getTransitionName = (isNext: boolean) => {
|
||||
if (isNext) return props.vertical ? 'vNext' : 'next';
|
||||
return props.vertical ? 'vPrevious' : 'previous';
|
||||
};
|
||||
|
||||
const triggerTransition = (month: number, year: number): void => {
|
||||
if (props.transitions) {
|
||||
const newDate = resetDateTime(setDateMonthOrYear(getDate(), props.month, props.year));
|
||||
transitionName.value = isDateAfter(resetDateTime(setDateMonthOrYear(getDate(), month, year)), newDate)
|
||||
? defaults.value.transitions[getTransitionName(true)]
|
||||
: defaults.value.transitions[getTransitionName(false)];
|
||||
showCalendar.value = false;
|
||||
nextTick(() => {
|
||||
showCalendar.value = true;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Class object for calendar wrapper
|
||||
const calendarWrapClass = computed(
|
||||
(): DynamicClass => ({
|
||||
dp__calendar_wrap: true,
|
||||
[props.calendarClassName]: !!props.calendarClassName,
|
||||
}),
|
||||
);
|
||||
|
||||
const markerClass = computed((): ((marker: IMarker) => DynamicClass) => (marker) => {
|
||||
const defaultMarker = getDefaultMarker(marker);
|
||||
return {
|
||||
dp__marker_dot: defaultMarker.type === 'dot',
|
||||
dp__marker_line: defaultMarker.type === 'line',
|
||||
};
|
||||
});
|
||||
|
||||
const dateMatch = computed((): ((day: Date) => boolean) => (day) => isDateEqual(day, showMakerTooltip.value));
|
||||
|
||||
const calendarParentClass = computed(() => ({
|
||||
dp__calendar: true,
|
||||
dp__calendar_next: defaults.value.multiCalendars > 0 && props.instance !== 0,
|
||||
}));
|
||||
|
||||
const showDay = computed(() => (day: ICalendarDay) => props.hideOffsetDates ? day.current : true);
|
||||
|
||||
const contentWrapStyle = computed(() => (props.specificMode ? { height: `${props.modeHeight}px` } : undefined));
|
||||
|
||||
const onMouseOver = (day: UnwrapRef<ICalendarDay>, weekInd: number, dayInd: number): void => {
|
||||
emit('set-hover-date', day);
|
||||
if (day.marker?.tooltip?.length) {
|
||||
const el = unrefElement(dayRefs.value[weekInd][dayInd]);
|
||||
if (el) {
|
||||
const { width, height } = el.getBoundingClientRect();
|
||||
|
||||
markerTooltipStyle.value = {
|
||||
bottom: `${height}px`,
|
||||
left: `${width / 2}px`,
|
||||
transform: `translateX(-50%)`,
|
||||
};
|
||||
showMakerTooltip.value = day.value;
|
||||
emit('tooltip-open', day.value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseLeave = (day: UnwrapRef<ICalendarDay>): void => {
|
||||
if (showMakerTooltip.value) {
|
||||
showMakerTooltip.value = null;
|
||||
emit('tooltip-close', day.value);
|
||||
}
|
||||
};
|
||||
|
||||
const onTouchStart = (ev: TouchEvent): void => {
|
||||
touch.value.startX = ev.changedTouches[0].screenX;
|
||||
touch.value.startY = ev.changedTouches[0].screenY;
|
||||
};
|
||||
|
||||
const onTouchEnd = (ev: TouchEvent): void => {
|
||||
touch.value.endX = ev.changedTouches[0].screenX;
|
||||
touch.value.endY = ev.changedTouches[0].screenY;
|
||||
handleTouch();
|
||||
};
|
||||
|
||||
const onTouchMove = (ev: TouchEvent): void => {
|
||||
if (props.vertical && !props.inline) {
|
||||
ev.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
const handleTouch = () => {
|
||||
const property = props.vertical ? 'Y' : 'X';
|
||||
if (Math.abs(touch.value[`start${property}`] - touch.value[`end${property}`]) > 10) {
|
||||
emit('handle-swipe', touch.value[`start${property}`] > touch.value[`end${property}`] ? 'right' : 'left');
|
||||
}
|
||||
};
|
||||
|
||||
const assignDayRef = (el: any, weekInd: number, dayInd: number) => {
|
||||
if (el) {
|
||||
if (Array.isArray(dayRefs.value[weekInd])) {
|
||||
dayRefs.value[weekInd][dayInd] = el;
|
||||
} else {
|
||||
dayRefs.value[weekInd] = [el];
|
||||
}
|
||||
}
|
||||
if (props.arrowNavigation) {
|
||||
buildMultiLevelMatrix(dayRefs.value, 'calendar');
|
||||
}
|
||||
};
|
||||
|
||||
const onScroll = (ev: WheelEvent) => {
|
||||
if (props.monthChangeOnScroll) {
|
||||
ev.preventDefault();
|
||||
emit('handle-scroll', ev);
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({ triggerTransition });
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue