Calendar 日历

手写 React 日历组件,支持月份切换、日期选择、禁用日期和受控模式。

基础用法

2026年5月
import { Calendar } from '@enterprise-ui/react19';

<Calendar defaultValue={new Date()} />

受控选择

当前选择:5/21/2026

2026年5月
const [selectedDate, setSelectedDate] = useState<Date | undefined>(new Date());

<Calendar value={selectedDate} onChange={setSelectedDate} />

范围选择

当前范围:5/21/2026 - 5/27/2026

2026年5月
const [selectedRange, setSelectedRange] = useState<CalendarRange>({
  start: new Date(),
  end: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate() + 6),
});

<Calendar
  mode="range"
  rangeValue={selectedRange}
  onRangeChange={setSelectedRange}
/>

禁用日期

可以通过 minDate、maxDate 和 disabledDate 组合限制可选范围。

2026年5月
<Calendar
  defaultValue={new Date()}
  minDate={new Date()}
  disabledDate={(date) => date.getDay() === 0 || date.getDay() === 6}
/>

核心实现思路

  • 先拿到当前面板月份的 1 号。
  • 根据一周起始日计算需要补齐多少个上月日期。
  • 从补齐后的第一天开始生成 42 个日期,固定 6 行 7 列。
  • 点击日期时区分受控和非受控模式,最后统一触发 onChange。

API

Calendar Props

参数说明类型默认值
value受控选中日期Date-
mode选择模式,支持单选和范围选择'single' | 'range''single'
defaultValue非受控默认选中日期Date-
rangeValue受控范围值{ start?: Date; end?: Date }-
defaultRangeValue非受控默认范围值{ start?: Date; end?: Date }-
onRangeChange范围选择回调(range: CalendarRange) => void-
defaultMonth初始展示月份Datenew Date()
onChange日期选择回调(date: Date) => void-
disabledDate自定义禁用日期规则(date: Date) => boolean-
minDate最小可选日期Date-
maxDate最大可选日期Date-
weekStartsOn一周从周日或周一开始0 | 11
showOutsideDays是否展示非本月补齐日期booleantrue
renderDay自定义日期格子内容(date, meta) => React.ReactNode-