import { ref, type Ref, computed, type ComputedRef, nextTick, } from 'vue' import moment, { type Moment } from 'moment' // import 'moment/locale/ru' type UseCalendarOptions = { disablePastDates?: boolean } export type CalendarDay = { date: Moment faded: boolean disabled: boolean } export type Calendar = { date: Ref days: ComputedRef prevMonth: () => void nextMonth: () => void prevYear: () => void nextYear: () => void } export function useCalendar(currentDate?: Moment, options: UseCalendarOptions = {}) { const date = ref(currentDate ? moment(currentDate) : moment()) const disablePastDates = options.disablePastDates !== undefined ? options.disablePastDates : false // date.value.locale('ru') // Глобальная установка локализации работает только с moment@2.8.0 const days = computed(() => { const start = moment(date.value).startOf('month').startOf('isoWeek') const end = moment(date.value).endOf('month').endOf('isoWeek') const day = moment(start) const days: CalendarDay[] = [] while (day.isSameOrBefore(end)) { days.push({ date: moment(day), faded: !day.isSame(date.value, 'month'), disabled: disablePastDates && day.isBefore(moment(), 'day'), }) day.add(1, 'day') } return days }) const prevMonth = () => { date.value = moment(date.value.add(-1, 'month')) } const nextMonth = () => { date.value = moment(date.value.add(1, 'month')) } const prevYear = () => { date.value = moment(date.value.add(-1, 'year')) } const nextYear = () => { date.value = moment(date.value.add(1, 'year')) } return { date, days, prevMonth, prevYear, nextMonth, nextYear, } } export function useCalendarTemplate(calendar: Calendar, days: JSX.Element[]) { const arrowClickHandler = (e: MouseEvent, callback: () => unknown) => { e.stopPropagation() callback() } const mouseWheelHandler = (e: WheelEvent) => { e.preventDefault() if (e.deltaY > 0) calendar.nextMonth() else calendar.prevMonth() } return (
arrowClickHandler(e, calendar.prevMonth)}>
{ calendar.date.value.toDate().toLocaleString('ru', { month: 'long' }) }
arrowClickHandler(e, calendar.nextMonth)}>
arrowClickHandler(e, calendar.prevYear)}>
{ calendar.date.value.format('YYYY') }
arrowClickHandler(e, calendar.nextYear)}>
Пн
Вт
Ср
Чт
Пт
Сб
Вс
{ days }
) }