无障碍性

所有选择器组件都内置了无障碍性支持。键盘导航、ARIA 属性和焦点管理在每个变体中——Styled、Tailwind v3/v4 和 Headless——都可以开箱即用。

标准使用无需额外配置。本页记录了包含的内容,以便您可以在自定义 UI 中审核、扩展或复制这些模式。

键盘导航

日历选择器

按键操作
ArrowLeft将焦点移动到前一天
ArrowRight将焦点移动到后一天
ArrowUp将焦点移动到上一周(同一工作日)
ArrowDown将焦点移动到下一周(同一工作日)
Enter / Space选择聚焦的日期
Escape取消更改并关闭弹窗
Tab移动到下一个可聚焦元素(浏览器默认)

禁用日期跳过: 使用箭头键导航时,禁用的日期会自动跳过。选择器会在移动方向上最多搜索 365 天,以找到下一个启用的日期。

自动月份滚动: 当键盘焦点移动到不同月份的某一天时,日历视图会更新以显示该月份。

时间选择器

按键操作
Escape取消更改并关闭弹窗

时间选择使用带有点触交互的滚轮 UI。滚动列使用 scroll-snap 来实现精确的值选择。

ARIA 属性

每个交互元素都具有适当的 ARIA 角色和属性:

弹窗与容器

元素属性
弹窗容器role"dialog"
内联容器role"group"
容器aria-label来自 locale 的占位符文本
容器aria-activedescendant当前聚焦日期单元格的 ID

触发按钮

属性
aria-expanded弹窗打开时为 true
aria-haspopup"dialog"

日历网格

元素属性
网格包装器role"grid"
周行role"row"
工作日标题单元格role"columnheader"
日期单元格role"gridcell"
日期单元格aria-selected选中时为 true
日期单元格aria-current当单元格为今天时为 "date"
日期单元格aria-label格式化的日期字符串(例如 "2026-03-04"
日期单元格disabled在禁用日期上设置(原生 HTML 属性)

导航与下拉菜单

元素属性
上个月按钮aria-label"上个月" (来自 locale.prevMonthLabel)
下个月按钮aria-label"下个月" (来自 locale.nextMonthLabel)
月份下拉菜单aria-label"选择月份" (来自 locale.selectMonthLabel)
年份下拉菜单aria-label"选择年份" (来自 locale.selectYearLabel)

时间列

元素属性
小时列role"listbox"
小时列aria-orientation"vertical"
小时列aria-label"小时" (来自 locale.hourLabel)
分钟列role"listbox"
分钟列aria-orientation"vertical"
分钟列aria-label"分钟" (来自 locale.minuteLabel)
秒列role"listbox"
秒列aria-orientation"vertical"
秒列aria-label"秒" (来自 locale.secondLabel)
时间项role"option" (填充项: "presentation")
时间项aria-selected当项目为当前值时为 true
时段切换aria-label当前时段 + ”, 切换 AM/PM”
清除按钮aria-label"清除" (来自 locale.clear)

所有标签字符串都可以通过 locale 系统 进行自定义。

焦点管理

漫游 Tabindex

日历网格使用 roving tabindex (漫游 tabindex) 模式:

  • 只有当前聚焦的日期单元格具有 tabIndex={0}(可 tab 切换)。
  • 所有其他日期单元格都具有 tabIndex={-1}(不可 tab 切换,但可通过箭头键聚焦)。
  • 这意味着 Tab 将焦点移出日历网格(到下一个控件),而箭头键在网格内移动焦点。

弹窗焦点捕获

弹窗模式使用来自 @floating-ui/reactFloatingFocusManager 来:

  • 在弹窗打开时将焦点捕获在内部。
  • 在弹窗关闭时将焦点返回到触发按钮。
  • 防止通过 tab 键将焦点移出弹窗到背景内容。

原生元素

月份和年份选择使用原生的 <select> 元素,这些元素本身就是键盘可访问的。日期单元格使用带有适当禁用状态的原生 <button> 元素。