import { computed, defineComponent } from 'vue'; // Utils import { createNamespace, HAPTICS_FEEDBACK, makeStringProp } from '../utils'; import { t, bem, compareMonth, getPrevMonth, getPrevYear, getNextMonth, getNextYear, } from './utils'; // Components import { Icon } from '../icon'; // Types import type { CalendarSwitchMode } from './types'; const [name] = createNamespace('calendar-header'); export default defineComponent({ name, props: { date: Date, minDate: Date, maxDate: Date, title: String, subtitle: String, showTitle: Boolean, showSubtitle: Boolean, firstDayOfWeek: Number, switchMode: makeStringProp('none'), }, emits: ['clickSubtitle', 'panelChange'], setup(props, { slots, emit }) { const prevMonthDisabled = computed(() => { const prevMonth = getPrevMonth(props.date!); return props.minDate && compareMonth(prevMonth, props.minDate) < 0; }); const prevYearDisabled = computed(() => { const prevYear = getPrevYear(props.date!); return props.minDate && compareMonth(prevYear, props.minDate) < 0; }); const nextMonthDisabled = computed(() => { const nextMonth = getNextMonth(props.date!); return props.maxDate && compareMonth(nextMonth, props.maxDate) > 0; }); const nextYearDisabled = computed(() => { const nextYear = getNextYear(props.date!); return props.maxDate && compareMonth(nextYear, props.maxDate) > 0; }); const renderTitle = () => { if (props.showTitle) { const text = props.title || t('title'); const title = slots.title ? slots.title() : text; return
{title}
; } }; const onClickSubtitle = (event: MouseEvent) => emit('clickSubtitle', event); const onPanelChange = (date: Date) => emit('panelChange', date); const renderAction = (isNext?: boolean) => { const showYearAction = props.switchMode === 'year-month'; const monthSlot = slots[isNext ? 'next-month' : 'prev-month']; const yearSlot = slots[isNext ? 'next-year' : 'prev-year']; const monthDisabled = isNext ? nextMonthDisabled.value : prevMonthDisabled.value; const yearDisabled = isNext ? nextYearDisabled.value : prevYearDisabled.value; const monthIconName = isNext ? 'arrow' : 'arrow-left'; const yearIconName = isNext ? 'arrow-double-right' : 'arrow-double-left'; const onMonthChange = () => onPanelChange((isNext ? getNextMonth : getPrevMonth)(props.date!)); const onYearChange = () => onPanelChange((isNext ? getNextYear : getPrevYear)(props.date!)); const MonthAction = ( {monthSlot ? ( monthSlot({ disabled: monthDisabled }) ) : ( )} ); const YearAction = showYearAction && ( {yearSlot ? ( yearSlot({ disabled: yearDisabled }) ) : ( )} ); return isNext ? [MonthAction, YearAction] : [YearAction, MonthAction]; }; const renderSubtitle = () => { if (props.showSubtitle) { const title = slots.subtitle ? slots.subtitle({ date: props.date, text: props.subtitle, }) : props.subtitle; const canSwitch = props.switchMode !== 'none'; return (
{canSwitch ? [ renderAction(),
{title}
, renderAction(true), ] : title}
); } }; const renderWeekDays = () => { const { firstDayOfWeek } = props; const weekdays = t('weekdays'); const renderWeekDays = [ ...weekdays.slice(firstDayOfWeek, 7), ...weekdays.slice(0, firstDayOfWeek), ]; return (
{renderWeekDays.map((text) => ( {text} ))}
); }; return () => (
{renderTitle()} {renderSubtitle()} {renderWeekDays()}
); }, });