Skip to content

Calendar Component ​

This component is used for selecting a single date, a date range, and more. The calendar is wrapped in a container that pops up from the bottom.

Note

This component overlaps to some extent with the date selection mode of the Picker. The difference is that this component is designed for more professional date selection scenarios, supporting date range selection, etc. In addition, the Picker component's date mode can be configured with more parameters, such as hours, minutes, and seconds, so you can choose between them based on different use cases.

📌 Platform Compatibility ​

APP(vue)H5WeChat Mini ProgramAlipay Mini Program
✔✔✔✔

⚠️ Notes ​

1. Display Control ​

Use v-model:show to control the visibility of the calendar popup:

html
<hy-calendar v-model:show="show" @confirm="onConfirm"></hy-calendar>

2. Default Date Format ​

defaultDate supports multiple formats:

html
<!-- Single date -->
<hy-calendar defaultDate="2025-05-01"></hy-calendar>
<hy-calendar :defaultDate="new Date()"></hy-calendar>

<!-- Multiple dates (mode=multiple or range) -->
<hy-calendar mode="multiple" :defaultDate="['2025-05-01', '2025-05-05']"></hy-calendar>
<hy-calendar mode="range" :defaultDate="['2025-05-01', '2025-05-05']"></hy-calendar>

3. formatter Formatting Function ​

The formatter function is used to customize date display, such as adding marker dots, bottom info, etc.:

ts
const formatter = (day: any) => {
    // The day object contains properties such as: date, day, week, disabled, dot, bottomInfo
    if (day.day === 15) {
        day.dot = true; // Show marker dot
        day.bottomInfo = 'Payday'; // Bottom info text
    }
    return day;
};

Note: For WeChat Mini Program compatibility, you need to set it via the setFormatter method:

ts
onReady(() => {
    (this.$refs.calendar as any).setFormatter(formatter);
});

4. forbidDays Disabled Dates ​

forbidDays is used to specify dates that cannot be selected (only applicable to mode=single or mode=multiple):

html
<hy-calendar
    mode="single"
    :forbidDays="['2025-05-01', '2025-05-02']"
    forbidDaysToast="This date is not selectable"
></hy-calendar>

5. Date Range Restrictions ​

You can set both minDate and maxDate to restrict the selectable date range:

html
<hy-calendar minDate="2025-01-01" maxDate="2025-12-31"></hy-calendar>

🏯 Basic Usage Example ​

html
<template>
    <!-- Single date selection -->
    <hy-calendar v-model:show="show" @confirm="onConfirm"></hy-calendar>
</template>

<script setup>
    import { ref } from 'vue'

    const show = ref(false)

    const onConfirm = (dates: string[]) => {
        uni.showToast({
            title: `Selected: ${dates[0]}`,
            icon: 'none'
        })
    }
</script>

Calendar Modes ​

html
<template>
    <!-- Single mode (default) -->
    <hy-calendar v-model:show="show1" mode="single" @confirm="onConfirm"></hy-calendar>

    <!-- Multiple mode -->
    <hy-calendar v-model:show="show2" mode="multiple" @confirm="onConfirm"></hy-calendar>

    <!-- Range mode -->
    <hy-calendar v-model:show="show3" mode="range" @confirm="onConfirm"></hy-calendar>
</template>

<script setup>
    import { ref } from 'vue'

    const show1 = ref(false)
    const show2 = ref(false)
    const show3 = ref(false)

    const onConfirm = (dates: string[]) => {
        console.log('Selected dates:', dates)
    }
</script>

Custom Theme Color ​

html
<template>
    <hy-calendar v-model:show="show" color="#f56c6c" @confirm="onConfirm"></hy-calendar>
</template>

Custom Text ​

html
<template>
    <hy-calendar
        v-model:show="show"
        mode="range"
        startText="Check-in"
        endText="Check-out"
        confirmDisabledText="Please select a check-out date"
        :formatter="formatter"
        @confirm="onConfirm"
    ></hy-calendar>
</template>

<script setup>
    import { ref } from 'vue'

    const show = ref(false)

    const formatter = (day: any) => {
        const today = new Date()
        const month = today.getMonth() + 1
        const date = today.getDate()

        // Show a discount mark on the 3rd day after today
        if (day.month === month && day.day === date + 3) {
            day.bottomInfo = 'Discount'
            day.dot = true
        }
        return day
    }

    const onConfirm = (dates: string[]) => {
        uni.showToast({
            title: `${dates[0]} ~ ${dates[dates.length - 1]}`,
            icon: 'none'
        })
    }
</script>

Date Range Restrictions ​

html
<template>
    <!-- Set maximum date -->
    <hy-calendar v-model:show="show1" maxDate="2025-05-05" @confirm="onConfirm"></hy-calendar>

    <!-- Set minimum and maximum dates -->
    <hy-calendar
        v-model:show="show2"
        minDate="2025-01-01"
        maxDate="2025-12-31"
        @confirm="onConfirm"
    ></hy-calendar>
</template>

Show Lunar Calendar ​

html
<template>
    <hy-calendar v-model:show="show" showLunar @confirm="onConfirm"></hy-calendar>
</template>

Default Date ​

html
<template>
    <!-- Single date -->
    <hy-calendar v-model:show="show1" defaultDate="2025-05-01" @confirm="onConfirm"></hy-calendar>

    <!-- Multiple dates (multiple mode) -->
    <hy-calendar
        v-model:show="show2"
        mode="multiple"
        :defaultDate="['2025-04-25', '2025-04-30']"
        @confirm="onConfirm"
    ></hy-calendar>

    <!-- Date range (range mode) -->
    <hy-calendar
        v-model:show="show3"
        mode="range"
        :defaultDate="['2025-05-01', '2025-05-05']"
        @confirm="onConfirm"
    ></hy-calendar>
</template>

Range Selection Restrictions ​

html
<template>
    <hy-calendar
        v-model:show="show"
        mode="range"
        :maxRange="7"
        rangePrompt="You can select up to 7 days"
        allowSameDay
        @confirm="onConfirm"
    ></hy-calendar>
</template>

Disabled Dates ​

html
<template>
    <hy-calendar
        v-model:show="show"
        mode="single"
        :forbidDays="forbidDays"
        forbidDaysToast="This date has already been booked"
        @confirm="onConfirm"
    ></hy-calendar>
</template>

<script setup>
    import { ref } from 'vue';

    const show = ref(false);
    const forbidDays = ref(['2025-05-01', '2025-05-02', '2025-05-03']);
</script>

Read-only Mode ​

html
<template>
    <hy-calendar v-model:show="show" readonly defaultDate="2025-05-01"></hy-calendar>
</template>

API ​

Calendar Props ​

ParameterDescriptionTypeDefault Value
showWhether to show the calendar popupbooleanfalse
titleTitle contentstringSelect Date
showTitleWhether to show the titlebooleantrue
showSubtitleWhether to show the subtitlebooleantrue
modeDate selection typesingle|multiple|rangesingle
startTextWhen mode=range, the hint text at the bottom of the first datestringStart
endTextWhen mode=range, the hint text at the bottom of the last datestringEnd
customListCustom listarray[]
colorTheme color, effective for the bottom button and selected datesstring-
minDateMinimum selectable datenumber | string0
maxDateMaximum selectable datenumber | string0
defaultDateDefault selected date; must be in array format when mode is multiple or rangestring|string[]|Date|nullnull
maxCountWhen mode=multiple, the maximum number of selectable datesnumberNumber.MAX_SAFE_INTEGER
rowHeightDate row height; numeric values default to pxnumber56
formatterDate formatting function (for WeChat Mini Program compatibility, it can only be set via the setFormatter method)Function | nullnull
showLunarWhether to show the lunar calendarbooleanfalse
showMarkWhether to show the month background markbooleantrue
showConfirmWhether to show the confirm buttonbooleantrue
confirmTextText of the confirm buttonstringConfirm
confirmDisabledTextText of the confirm button when in disabled statestringConfirm
closeOnClickOverlayWhether to allow closing the calendar by clicking the overlay (Note: the close event must be handled by yourself; the close callback is only triggered when clicking the overlay after enabling closeOnClickOverlay)booleanfalse
readonlyWhether it is in read-only state; date selection is disabled in read-only statebooleanfalse
maxRangeMaximum number of selectable days in a date range, unlimited by default, effective when mode = rangenumberNumber.MAX_SAFE_INTEGER
rangePromptPrompt text shown when the range selection exceeds the maximum number of selectable days, effective when mode = rangestring | nullCannot select more than xx days
showRangePromptWhether to show the prompt text when the range selection exceeds the maximum number of selectable days, effective when mode = rangebooleantrue
allowSameDayWhether to allow the start and end of the date range to be the same day, effective when mode = rangebooleanfalse
roundBorder radius value, no rounding by defaultstring | number0
monthNumMaximum number of months to displaynumber3
weekTextWeekday texts, useful for multi-language support.string[]['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
forbidDaysList of dates that cannot be selected in single and multiple modes, effective when mode != range.Date[][]
forbidDaysToastPrompt shown when selecting a forbidden date in single or multiple modestringThis date is disabled

Methods ​

Method NameDescription
setFormatterInternal method exposed for WeChat Mini Program compatibility, used to set the date formatting function

Events ​

Event NameDescriptionCallback Parameters
confirmTriggered when date selection is complete; if show-confirm is true, it is triggered when the confirm button is clickedSelected dates array string[]
closeTriggered when the calendar is closed-

Typings ​

Type Definitions
ts
// Date item
export interface DateItem {
    date: string | number | Date;
    day: number | string;
    week: number;
    disabled?: boolean;
    dot?: boolean;
    bottomInfo?: string;
    [key: string]: any;
}

// Month data
export interface MonthData {
    year: number | string;
    month: number | string;
    date: DateItem[];
}

// Month component props
export interface IMonthProps {
    showMark?: boolean;
    color?: string;
    months?: MonthData[];
    mode?: 'single' | 'multiple' | 'range';
    rowHeight?: string | number;
    maxCount?: number;
    startText?: string;
    endText?: string;
    defaultDate?: string | string[] | Date | null;
    minDate?: string | number;
    maxDate?: string | number;
    maxMonth?: number;
    readonly?: boolean;
    maxRange?: number;
    rangePrompt?: string;
    showRangePrompt?: boolean;
    allowSameDay?: boolean;
    forbidDays?: string[];
    forbidDaysToast?: string;
}

CSS Variables ​

VariableDescriptionDefault Value
--hy-calendar-confirm-paddingConfirm button padding7px 18px
--hy-calendar-title-font-sizeTitle font size16px
--hy-calendar-title-heightTitle height (including line height)42px
--hy-calendar-subtitle-font-sizeSubtitle font size14px
--hy-calendar-subtitle-heightSubtitle height (including line height)40px
--hy-calendar-weekday-font-sizeWeekday font size13px
--hy-calendar-weekday-line-heightWeekday line height30px
--hy-calendar-month-title-font-sizeMonth title font size14px
--hy-calendar-month-title-heightMonth title height (including line height)42px
--hy-calendar-month-mark-font-sizeMonth watermark text size155px
--hy-calendar-day-selected-radiusSelected date border radius3px
--hy-calendar-day-dot-sizeDate dot size7px
--hy-calendar-day-info-font-sizeDate number font size16px
--hy-calendar-day-bottom-info-font-sizeDate bottom info font size10px
--hy-calendar-subtitle-colorSubtitle colorFollows --hy-text-color--2
--hy-calendar-weekday-colorWeekday colorFollows --hy-text-color--grey
--hy-calendar-month-title-colorMonth title colorFollows --hy-text-color--2
--hy-calendar-month-mark-colorMonth watermark colorFollows --hy-text-color--4
--hy-calendar-day-selected-colorSelected date text color#ffffff
--hy-calendar-day-disabled-colorDisabled date text colorFollows --hy-text-color--disabled
--hy-calendar-day-bottom-info-colorDate bottom info colorFollows --hy-text-color--2
12:33
battery