- UI组件
- 前端
【免费下载链接】react-day-picker
DayPicker is a customizable date picker component for React. Add date pickers, calendars, and date inputs to your web applications.
DayPicker 用Modifier(修饰器)来表示日历中一个日期的不同样式或状态。这个类型别名在 src/types/Modifiers.ts 中定义为string。本文将从这一看似简单的定义出发,拆解 DayPicker 修饰器系统的完整设计:内部修饰器(如selected、disabled、today)、自定义修饰器(modifiersprop)、修饰器的匹配与传播,以及如何在样式和可访问性中使用它们。
注意:本文内容基于仓库中 version-8.10.2 版本的 API 文档。版本 9 及更高版本对修饰器 API 做了一些调整(例如
modifiersClassNames被重构),本文的代码示例均以 8.10.2 为准。
Modifier的定义
Modifier:string
一个modifier(修饰器)代表日历中显示的一个日期的不同样式或状态。它本身就是一个字符串,用作修饰器名称(modifier name),这些字符串是修饰器映射(modifier map)中的键(key),控制 DayPicker 如何表现和显示日期。
源码中它的定义位于 src/types/Modifiers.ts:9:
// 逻辑定义:type Modifier = string虽然类型简单,但它支撑起整个修饰器系统——多个复合类型都以它为键:
| 类型别名 | 定义 | 说明 |
|---|---|---|
| DayModifiers | Record<Modifier, Matcher \| Matcher[]> | 通过modifiersprop 传入的自定义修饰器 |
| CustomModifiers | Record<Modifier, Matcher[]> | 自定义修饰器的映射,值只能是Matcher数组 |
| ActiveModifiers | Record<Modifier, true> & Partial<Record<InternalModifier, true>> | 与某个日期匹配的修饰器集合 |
这些类型都围绕同一个概念:修饰器名称(Modifier字符串)→ 匹配规则(Matcher)或匹配结果(true)。
内部修饰器
DayPicker 内置了一组内部修饰器,其名称由 InternalModifier 枚举 定义:
| 枚举成员 | 值 | 说明 |
|---|---|---|
Disabled | "disabled" | 通过disabledprop 应用到被禁用日期的修饰器 |
Hidden | "hidden" | 通过hiddenprop 应用到被隐藏日期的修饰器 |
Outside | "outside" | 应用于当前显示月份之外的日期(外部日期) |
RangeEnd | "range_end" | 范围选择模式下,应用于所选范围的结束日 |
RangeMiddle | "range_middle" | 范围选择模式下,应用于所选范围的中间日 |
RangeStart | "range_start" | 范围选择模式下,应用于所选范围的开始日 |
Selected | "selected" | 通过selectedprop 应用到被选中日期的修饰器 |
Today | "today" | 通过todayprop 应用到指定日期的修饰器 |
这些内部修饰器在 DayPickerBase 接口中通过对应 props 配置:
disabled?: Matcher | Matcher[]:将disabled修饰器应用到匹配的日期。hidden?: Matcher | Matcher[]:将hidden修饰器应用到匹配的日期,并将其从日历中隐藏。selected?: Matcher | Matcher[]:将selected修饰器应用到匹配的日期。today?: Date:设置“今天”的日期(默认是当前日期),该日期会获得today修饰器。
例如,选中 2024 年 10 月 1 日,并禁用 2024 年 10 月 15 日:
<DayPicker selected={new Date(2024, 9, 1)} disabled={new Date(2024, 9, 15)} />匹配逻辑(isMatch)
修饰器名称是如何被应用到具体日期上的?关键在于 isMatch 函数,其源码位于 src/contexts/Modifiers/utils/isMatch.ts。它接受一个日期和一个Matcher数组,返回该日期是否匹配任何一个匹配器。
匹配器(Matcher)可以是一个日期、一个日期范围({from, to})、一个星期几({dayOfWeek})、一个布尔函数,或任意组合。这也是 DayPicker 能支持 禁用日期、范围选择 等功能的基础。
自定义修饰器(modifiers prop)
除了内部修饰器,DayPicker 还允许通过modifiersprop 定义自定义修饰器。modifiers的类型是 DayModifiers(Record<Modifier, Matcher | Matcher[]>),也就是一个从修饰器名称映射到匹配规则的记录。
import { DayPicker } from "react-day-picker"; export function App() { return ( <DayPicker modifiers={{ weekend: { dayOfWeek: [0, 6] }, // 匹配周六和周日 holiday: new Date(2024, 9, 1), // 匹配特定日期 past: { before: new Date() }, // 匹配所有过去的日期 }} /> ); }自定义修饰器也可以与内置修饰器组合使用,例如先禁用一部分日期、再对它们应用自定义样式:
<DayPicker disabled={{ before: new Date() }} modifiersClassNames={{ disabled: "my-disabled-day", holiday: "my-holiday-day", }} />CustomModifiers 与DayModifiers的区别在于:它只接受Matcher数组(Record<Modifier, Matcher[]>)。
修饰器的匹配结果:ActiveModifiers
当 DayPicker 渲染每个日期时,会计算出该日期匹配的所有修饰器,生成一个ActiveModifiers对象(src/types/Modifiers.ts):
const activeModifiers: ActiveModifiers = { selected: true, customModifier: true };这是一个Record<Modifier, true>与Partial<Record<InternalModifier, true>>的交叉类型。它的键就是匹配上的修饰器名称(Modifier),值固定为true。
在自定义DayContent或DayButton中,你可以通过 useActiveModifiers hook 获取某个日期的活动修饰器:
import { useActiveModifiers } from "react-day-picker"; function MyDayContent({ date, displayMonth }) { const activeModifiers = useActiveModifiers(date, displayMonth); // activeModifiers.selected === true 表示该日期被选中 return <div>{date.getDate()}</div>; }修饰器驱动的样式与类名
修饰器最主要的用途之一是驱动样式。DayPicker 8.x 提供两种方式:
- modifiersClassNames(
Record<string, string>):为匹配某修饰器的日期元素指定 CSS 类名。 - modifiersStyles(
Record<string, CSSProperties>):为匹配某修饰器的日期元素指定内联样式。
<DayPicker modifiers={{ weekend: { dayOfWeek: [0, 6] } }} modifiersClassNames={{ weekend: "weekend-day" }} modifiersStyles={{ weekend: { color: "red" } }} />在底层,getStyleForModifiers 等辅助函数负责把匹配到的修饰器转换成最终的样式/类名。你可以在 getStyleForModifiers.test.ts 和 createGetModifiers.test.ts 中看到对应的测试用例,例如如何为单个日期同时应用多个修饰器样式。
修饰器的计算与传播
每个日期的完整修饰器集合由 createGetModifiers 计算(在 DayPicker.tsx:199 中调用),它合并了两部分:
- 内部修饰器(
InternalModifier):根据selected、disabled、hidden、today、范围选择状态等 props 自动计算; - 自定义修饰器(
DayModifiers):来自modifiersprop。
结果通过 DayPickerContext 提供给各个子组件(day 按钮、day 内容等),从而统一影响样式、类名以及可访问性标签。
在可访问性标签中使用修饰器
修饰器还可以驱动可访问性文本。labelDayButton 的测试展示了如何根据修饰器(如selected、disabled)生成日期按钮的aria-label,让屏幕阅读器用户能够了解日期的状态:
const dayModifiers: Modifiers = { selected: true, disabled: false }; // 生成类似 "2024 年 10 月 1 日,已选中" 的标签这也是 DayPicker 在 可访问性指南 中承诺的基础之一。
总结
Modifier类型虽然只是一个string,却是 DayPicker 修饰器系统的“胶水”:它作为修饰器名称(modifier name),把Modifier → Matcher → 匹配结果 → 样式/标签这条链路串起来。理解了它,你就理解了 DayPicker 如何通过selected、disabled、hidden、today等内部修饰器和modifiers自定义修饰器,灵活地控制日期的外观、状态与可访问性。
- UI组件
- 前端
【免费下载链接】react-day-picker
DayPicker is a customizable date picker component for React. Add date pickers, calendars, and date inputs to your web applications.
相关推荐
@daypicker/react v10 API 全解析:从 DayPicker 组件到类型系统的完整指南
@daypicker/react v10 API 全解析:从 DayPicker 组件到类型系统的完整指南 本文以 react day picker 仓库中 a
UI组件前端React DayPicker v8 DayModifiers 类型详解:自定义日期修饰器的声明与实战用法
React DayPicker v8 DayModifiers 类型详解:自定义日期修饰器的声明与实战用法 导读 本文围绕 React DayPicker v8
UI组件前端30 分钟出 EFI:OpCore Simplify 生成 OpenCore EFI 配置的完整路径
30 分钟出 EFI:OpCore Simplify 生成 OpenCore EFI 配置的完整路径 OpCore Simplify 是一款 Python 写的
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考