ProComponents, templates & AI tooling
HeroUI
27.7k

Calendar 日历更新

基于 React Aria Calendar 的可组合日期选择器,包含月份网格、导航与年份选择器支持。

引入

import { Calendar } from '@heroui/react';

用法

组件结构

import {Calendar} from '@heroui/react';

export default () => (
  <Calendar aria-label="Event date">
    <Calendar.Header>
      <Calendar.Heading />
      <Calendar.NavButton slot="previous" />
      <Calendar.NavButton slot="next" />
    </Calendar.Header>
    <Calendar.Grid>
      <Calendar.GridHeader>
        {(day) => <Calendar.HeaderCell>{day}</Calendar.HeaderCell>}
      </Calendar.GridHeader>
      <Calendar.GridBody>
        {(date) => <Calendar.Cell date={date} />}
      </Calendar.GridBody>
    </Calendar.Grid>
  </Calendar>
)

年份选择器

Calendar.YearPickerTriggerCalendar.YearPickerGrid 以及对应的 body/cell 子组件提供一体化的年份导航模式。

默认值

受控

使用受控的 valuefocusedValue 与外部状态协同,并支持自定义快捷键。

最小与最大日期

不可用日期

使用 isDateUnavailable 禁用周末、节假日或已被预订等日期。

固定周数

weeksInMonth 设为固定值(例如 6),可在月份切换时保持网格高度稳定。在非公历场景中请谨慎使用,与 firstDayOfWeek 类似。

周视图

设置 visibleDuration={{ weeks: n }} 可一次显示一个或多个周。翻页会按可见周范围前进。显示多周时可配合 pageBehavior="single" 每次仅移动一周。

日视图

设置 visibleDuration={{ days: n }} 可显示连续多天的滚动窗口。翻页会按可见天数范围前进。显示多天时配合 pageBehavior="single" 可每次仅移动一天。

多选

设置 selectionMode="multiple" 以选择多个日期。此时 valuedefaultValueonChange 使用日期数组。

禁用

只读

焦点值

使用 focusedValueonFocusChange 以编程方式控制焦点落在哪一天。

单元格指示器

你可以自定义 Calendar.Cell 的子节点,并使用 Calendar.CellIndicator 展示活动等元数据。

多个月份

使用 visibleDurationoffset 渲染多个月份网格,适用于预订与规划场景。在各列头部为 Calendar.Heading 设置 offset(例如 offset={{ months: 1 }})以显示对应月份标题。

国际化日历

默认情况下,Calendar 使用用户语言环境对应的历法系统显示日期。你可以使用 I18nProvider 包裹 Calendar,并通过 Unicode 历法语言扩展 覆盖。

下方示例展示印度历法系统:

提示: onChange 事件始终返回与 valuedefaultValue 相同历法系统中的日期(若未提供值则为公历),与界面展示的语言环境无关。这样应用逻辑可以始终使用单一历法系统,同时仍可按用户偏好的格式展示日期。

自定义导航图标

Calendar.NavButton 传入子节点即可替换默认的箭头图标。

真实场景示例

自定义样式

样式

传入 Tailwind CSS 类

import {Calendar} from '@heroui/react';

function CustomCalendar() {
  return (
    <Calendar aria-label="Custom calendar" className="w-72 rounded-2xl border border-border bg-surface p-3 shadow-sm">
      <Calendar.Header className="pb-3">
        <Calendar.Heading className="text-default" />
        <Calendar.NavButton slot="previous" className="text-default" />
        <Calendar.NavButton slot="next" className="text-default" />
      </Calendar.Header>
      <Calendar.Grid>
        <Calendar.GridHeader>
          {(day) => <Calendar.HeaderCell>{day}</Calendar.HeaderCell>}
        </Calendar.GridHeader>
        <Calendar.GridBody>
          {(date) => <Calendar.Cell date={date} />}
        </Calendar.GridBody>
      </Calendar.Grid>
    </Calendar>
  );
}

自定义组件类

@layer components {
  .calendar {
    @apply w-72 rounded-2xl border border-border bg-surface p-3 shadow-sm;
  }

  .calendar__heading {
    @apply text-sm font-semibold text-default-700;
  }

  .calendar__cell[data-selected="true"] {
    @apply bg-accent text-accent-foreground;
  }
}

CSS 类

Calendar 在 packages/styles/components/calendar.csspackages/styles/components/calendar-year-picker.css 中使用以下类:

  • .calendar - 根容器。
  • .calendar__header - 包含导航按钮与标题的头部行。
  • .calendar__heading - 当前月份标签。
  • .calendar__nav-button - 上一月/下一月导航控件。
  • .calendar__grid - 主体日期网格。
  • .calendar__grid-header - 星期标题行容器。
  • .calendar__grid-body - 日期行容器。
  • .calendar__header-cell - 星期标题单元格。
  • .calendar__cell - 可交互的日期单元格。
  • .calendar__cell-indicator - 日期单元格内的点状指示器。
  • .calendar-year-picker__trigger - 年份选择器切换按钮。
  • .calendar-year-picker__trigger-heading - 年份选择触发器内的标题文本。
  • .calendar-year-picker__trigger-indicator - 年份选择触发器内的指示图标。
  • .calendar-year-picker__year-grid - 可选年份的覆盖网格。
  • .calendar-year-picker__year-cell - 单个年份选项。

交互状态

Calendar 同时支持伪类与 React Aria 的 data 属性:

  • 已选中[data-selected="true"]
  • 今天[data-today="true"]
  • 不可用[data-unavailable="true"]
  • 跨月[data-outside-month="true"]
  • 悬停:hover[data-hovered="true"]
  • 按下:active[data-pressed="true"]
  • 可见焦点:focus-visible[data-focus-visible="true"]
  • 禁用:disabled[data-disabled="true"]

API 参考

Calendar Props

Calendar 继承 React Aria Calendar 的全部 props。

Prop类型默认值描述
selectionMode'single' | 'multiple''single'单选或多选日期。
valueDateValue | nullDateValue[] | null-受控的选中日期。selectionMode="multiple" 时使用数组。
defaultValueDateValue | nullDateValue[] | null-初始选中日期(非受控)。
onChange(value: DateValue | null)(value: DateValue[] | null) => void-选中变化时调用。
focusedValueDateValue-受控的焦点日期。
onFocusChange(value: DateValue) => void-焦点移动到其它日期时调用。
minValueDateValue历法感知的 1900-01-01最早可选日期。
maxValueDateValue历法感知的 2099-12-31最晚可选日期。
weeksInMonthnumber-一个月的周数。该值会覆盖区域设置的默认值。
isDateUnavailable(date: DateValue) => boolean-将日期标记为不可用。
firstDayOfWeek'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'-覆盖区域设置的一周起始日。
pageBehavior'visible' | 'single''visible'翻页按可见范围或单步前进。
selectionAlignment'start' | 'center' | 'end''center'初始渲染时按选中项对齐可见范围。
isDisabledbooleanfalse禁用交互与选择。
isReadOnlybooleanfalse内容只读,无法更改选中。
isInvalidbooleanfalse将日历标记为无效以配合校验 UI。
visibleDuration{months?: number; weeks?: number; days?: number}{months: 1}可见时间范围。使用 { months: n } 为月视图,{ weeks: n } 为周视图,{ days: n } 为日视图。
defaultYearPickerOpenbooleanfalse内置年份选择器的初始展开状态。
isYearPickerOpenboolean-受控的年份选择器展开状态。
onYearPickerOpenChange(isOpen: boolean) => void-年份选择器展开状态变化时调用。

组合部件

Component描述
Calendar.Header导航与标题的头部容器。
Calendar.Heading可见范围的格式化标题。支持 offset(多月份布局)与 format(月/年/日格式选项)。
Calendar.NavButton上一月/下一月导航控件(slot="previous"slot="next")。
Calendar.Grid单个月的日期网格(多月份布局支持 offset)。
Calendar.GridHeader星期标题容器。
Calendar.GridBody日期单元格主体容器。
Calendar.HeaderCell星期标签单元格。
Calendar.Cell单个日期单元格。
Calendar.CellIndicator用于自定义元数据的可选指示元素。
Calendar.YearPickerTrigger切换年份选择模式的触发器。
Calendar.YearPickerTriggerHeading年份选择触发器内的本地化标题内容。
Calendar.YearPickerTriggerIndicator年份选择触发器内的切换图标。
Calendar.YearPickerGrid年份选择覆盖网格容器。
Calendar.YearPickerGridBody年份网格单元格的 body 渲染器。
Calendar.YearPickerCell单个年份选项单元格。

年份选择器子组件

年份选择器子组件继承 React Aria useCalendarHeadinguseCalendarYearPicker 的格式化属性。

组件属性类型默认值描述
Calendar.YearPickerTriggerHeadingformatDateFormatterOptions-自定义月/年标题(如 {month: 'short'})。
Calendar.YearPickerTriggerHeadingoffset{months?: number}-相对聚焦日期偏移标题(多月布局)。
Calendar.YearPickerGridformatDateFormatterOptions{year: 'numeric'}自定义年份单元格标签(纪元、历法系统等)。
Calendar.YearPickerGridvisibleYearsnumbermin–max 跨度或 20滑动窗口中显示的年份数量。当同时设置 minValuemaxValue 时,默认为二者之间的完整范围。

Calendar.Cell Render Props

Calendar.Cellchildren 为函数时,可使用 React Aria 的渲染参数:

Prop类型描述
formattedDatestring单元格日期的本地化标签。
isSelectedboolean该日期是否被选中。
isUnavailableboolean该日期是否不可用。
isDisabledboolean单元格是否禁用。
isOutsideMonthboolean是否属于相邻月份。

支持的历法系统及其标识符完整列表见:

  • @internationalized/date — 各日期组件共用的日期类型(CalendarDateCalendarDateTimeZonedDateTime)与工具函数
  • I18nProvider — 为子树覆盖语言环境
  • useLocale — 读取当前语言环境与书写方向

本页目录