Skip to content
Lenso UI

Calendar

Calendar 从 HeroUI v2 到 v3 的迁移指南。

完整的 API 参考、样式指南与高级示例请参阅 v3 Calendar 文档。本指南只关注从 HeroUI v2 的迁移。

结构变化

在 v2 中,Calendar 是一个完全通过 props 配置的单一组件:

import { Calendar } from "@lenso/ui";
export default function App() {  return <Calendar aria-label="Date" />;}

在 v3 中,Calendar 改用带显式子组件的复合组件模式:

import { Calendar } from "@lenso/ui";
export default function App() {  return (    <Calendar aria-label="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>  );}

主要变化

1. 组件结构

v2: 单一 Calendar 组件,所有布局都在内部处理
v3: 复合组件:Calendar.Header、Calendar.Heading、Calendar.NavButton、Calendar.Grid、Calendar.GridHeader、Calendar.GridBody、Calendar.HeaderCell、Calendar.Cell、Calendar.CellIndicator

2. 年份选择器

v2: 通过 showMonthAndYearPickers prop 提供内置月份 / 年份选择器
v3: 使用专用复合组件:Calendar.YearPickerTrigger、Calendar.YearPickerGrid、Calendar.YearPickerGridBody、Calendar.YearPickerCell

3. Prop 变更

v2 propv3 等效项说明
valuevalue保持一致
defaultValuedefaultValue保持一致
onChangeonChange保持一致
focusedValuefocusedValue保持一致
onFocusChangeonFocusChange保持一致
minValueminValue保持一致
maxValuemaxValue保持一致
isDateUnavailableisDateUnavailable保持一致
isDisabledisDisabled保持一致
isReadOnlyisReadOnly保持一致
isInvalidisInvalid保持一致
visibleMonthsvisibleDuration改为 {months: number} 对象
showMonthAndYearPickers-使用 Calendar.YearPickerTrigger 和 Calendar.YearPickerGrid
onHeaderExpandedChangeonYearPickerOpenChange已重命名
color-已移除(请改用 Tailwind CSS)
calendarWidth-已移除(请改用 className 或 Tailwind CSS)
weekdayStyle-已移除
pageBehaviorpageBehavior保持一致
firstDayOfWeek-改用 I18nProvider 的 locale
hideDisabledDates-已移除
disableAnimation-已移除
topContent-将自定义内容作为 Calendar children 放在 Calendar.Grid 之前
bottomContent-将自定义内容作为 Calendar children 放在 Calendar.Grid 之后
classNames-在各个复合组件上使用 className
errorMessage-已移除(请在外部处理校验)

4. color prop 已移除

v2: color prop 支持 default、primary、secondary、success、warning、danger
v3: 不再提供 color prop,请使用 Tailwind CSS 类设置单元格样式,或通过自定义 calendar.css 覆盖

迁移示例

基本日历

import { Calendar } from "@lenso/ui";import { today, getLocalTimeZone } from "@internationalized/date";
<Calendar  aria-label="Date"  defaultValue={today(getLocalTimeZone())}/>

受控状态

import { useState } from "react";import { Calendar } from "@lenso/ui";import { parseDate } from "@internationalized/date";
const [value, setValue] = useState(parseDate("2024-03-07"));
<Calendar  aria-label="Date"  value={value}  onChange={setValue}/>

月份和年份选择器

<Calendar  aria-label="Date"  showMonthAndYearPickers/>

多个月份

<Calendar  aria-label="Date"  visibleMonths={2}/>

不可用日期

import { isWeekend } from "@internationalized/date";import { useLocale } from "@react-aria/i18n";
const { locale } = useLocale();
<Calendar  aria-label="Date"  isDateUnavailable={(date) => isWeekend(date, locale)}/>

顶部与底部内容

<Calendar  aria-label="Date"  topContent={<p>Select a date</p>}  bottomContent={    <button onClick={() => setValue(today(getLocalTimeZone()))}>      Today    </button>  }/>

单元格指示器

{/* v2 did not have a built-in cell indicator API */}

样式变化

v2:classNames prop

<Calendar  classNames={{    base: "custom-base",    prevButton: "custom-prev",    nextButton: "custom-next",    title: "custom-title",    cell: "custom-cell",    cellButton: "custom-cell-button",  }}/>

v3:直接使用 className prop

<Calendar className="custom-base">  <Calendar.Header>    <Calendar.Heading className="custom-title" />    <Calendar.NavButton slot="previous" className="custom-prev" />    <Calendar.NavButton slot="next" className="custom-next" />  </Calendar.Header>  <Calendar.Grid>    <Calendar.GridHeader>      {(day) => <Calendar.HeaderCell>{day}</Calendar.HeaderCell>}    </Calendar.GridHeader>    <Calendar.GridBody>      {(date) => <Calendar.Cell date={date} className="custom-cell" />}    </Calendar.GridBody>  </Calendar.Grid></Calendar>

组件结构

v3 Calendar 遵循以下结构:

Calendar (Root)  ├── [Custom top content]  ├── Calendar.Header  │   ├── Calendar.Heading (or Calendar.YearPickerTrigger)  │   ├── Calendar.NavButton slot="previous"  │   └── Calendar.NavButton slot="next"  ├── Calendar.Grid (one per visible month)  │   ├── Calendar.GridHeader  │   │   └── Calendar.HeaderCell (render prop)  │   └── Calendar.GridBody  │       └── Calendar.Cell (render prop)  │           └── Calendar.CellIndicator (optional)  ├── Calendar.YearPickerGrid (optional)  │   └── Calendar.YearPickerGridBody  │       └── Calendar.YearPickerCell  └── [Custom bottom content]

总结

  1. 组件结构:单一组件 → 带显式布局控制的复合组件
  2. 年份选择器:showMonthAndYearPickers prop → 专用的 Calendar.YearPickerTrigger 和 Calendar.YearPickerGrid 组件
  3. 多个月份:visibleMonths={n} → visibleDuration={{months: n}},并使用多个带 offset 的 Calendar.Grid 组件
  4. color 已移除:请改用 Tailwind CSS 类
  5. 顶部 / 底部内容:prop 已移除 → 直接将内容作为 children 放在 Calendar 内
  6. 单元格自定义:新增 Calendar.CellIndicator,且 Calendar.Cell 支持渲染 prop
  7. 样式:classNames prop → 各个复合组件上的 className
  8. 已移除 prop:calendarWidth、weekdayStyle、hideDisabledDates、disableAnimation —— 请使用 Tailwind CSS 或省略