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)可在月份切换时保持网格高度稳定。在非公历 locale 中请谨慎使用,类似 firstDayOfWeek

周视图

设置 visibleDuration={{ weeks: n }} 可一次显示一周或多周。导航按可见周范围前进。显示多周时使用 pageBehavior="single" 可每次移动一周。

日视图

设置 visibleDuration={{ days: n }} 可显示连续日期的滚动窗口。导航按可见日范围前进。显示多天时使用 pageBehavior="single" 可每次移动一天。

多选

设置 selectionMode="multiple" 允许选择多个日期。valuedefaultValueonChange 使用日期数组。

聚焦值

使用 focusedValueonFocusChange 以编程方式控制聚焦日期。

单元格标记

可自定义 Calendar.Cell 子节点,并使用 Calendar.CellIndicator 显示事件等元数据。

自定义导航图标

Calendar.NavButton 传入子节点以替换默认 chevron 图标。

多月份展示

使用 visibleDurationoffset 渲染多个月份网格,适用于预订与规划场景。

典型场景

国际化日历

默认情况下,Calendar 使用用户 locale 的历法系统显示日期。可用 I18nProvider 包裹 Calendar 并设置 Unicode 历法 locale 扩展 来覆盖。

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

Note: onChange 事件始终返回与 valuedefaultValue 相同历法系统的日期(未提供 value 时为公历),无论显示 locale 如何。这确保应用逻辑在单一历法系统下一致运行,同时仍以用户偏好的格式显示日期。

自定义样式

Tailwind CSS

全局 CSS

@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;
  }
}

样式参考

HeroUI 遵循 BEM 方法论,确保组件变体与状态可复用且易于自定义。

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 属性:

  • Selected[data-selected="true"]
  • Today[data-today="true"]
  • Unavailable[data-unavailable="true"]
  • Outside month[data-outside-month="true"]
  • Hovered:hover[data-hovered="true"]
  • Pressed:active[data-pressed="true"]
  • Focus visible:focus-visible[data-focus-visible="true"]
  • Disabled:disabled[data-disabled="true"]

API 参考

Calendar

Calendar 继承 React Aria Calendar 的所有属性。

Prop类型默认值描述
selectionMode'single' | 'multiple''single'是否可选择单个或多个日期
valueDateValue | nullDateValue[] | null-受控选中日期。selectionModemultiple 时使用数组
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-月份中的周数,覆盖 locale 默认值
isDateUnavailable(date: DateValue) => boolean-标记日期为不可用
firstDayOfWeek'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'-覆盖 locale 默认的一周起始日
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-年份选择器打开状态变化时调用

Composition Parts

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

Year Picker Parts

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

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

Calendar.Cell Render

Calendar.Cell 子节点为函数时,可使用 React Aria render props:

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

有关支持的历法系统及其标识符的完整列表,请参阅:

  • @internationalized/date — 所有日期组件使用的日期类型(CalendarDateCalendarDateTimeZonedDateTime)与工具
  • I18nProvider — 覆盖子树的 locale
  • useLocale — 读取当前 locale 与布局方向

相关组件

本页目录