跳转到内容

日期选择器 date-picker

数据录入组件。三层同源:无头内核给出解剖与状态机,Vue 组件与自定义元素只是它的两层外壳,行为完全一致。

示例

基础用法

段位与日历写的是同一个值,改哪边另一边当场跟着改口

交付日期
yyyy
-
mm
-
dd
当前值:(未选)

区间选择

起止各一组段位,两端都能敲;只落一端浮层不收,两端都在才算选完

起止日期
yyyy
-
mm
-
dd
yyyy
-
mm
-
dd
已选区间:(未选)

不可选的日子

周末由 isDateUnavailable 判不可用:方向键仍走得过去,只是落不了值

工作日
yyyy
-
mm
-
dd
当前值:(未选)

禁用 / 只读 / 校验失败

禁用整条退出 Tab 序,只读仍能展开翻月只是落不了值,invalid 只改标注

禁用
2026
-
07
-
28
只读
2026
-
07
-
28
校验失败
2026
-
07
-
28

浮层里的快捷选项

日历下面这排按钮是作者自己的节点,写值与收起都走根插槽给的入口

提醒日期
yyyy
-
mm
-
dd
当前值:(未选)

受控展开与事件

open 交给宿主持有,值、展开、聚焦日三条变化各自播报

排期
yyyy
-
mm
-
dd
值:(未选) · 聚焦日:(还没动过)

日期加时间

浮层里日历下面接一台时间输入,选中日期不收起,两份值由宿主拼成一条

会议开始
yyyy
-
mm
-
dd
拼出来的值:(未选完)

按月选择

浮层里换成年份翻页加十二个月,点完写值并收起;输入行只留年、月两段

结算月份
yyyy
mm
当前值:(未选)

产物

自定义元素<xh-date-picker>
Vue 组件XhDatePickerCalendar XhDatePickerCell XhDatePickerCellTrigger XhDatePickerClearTrigger XhDatePickerContent XhDatePickerControl XhDatePickerGrid XhDatePickerGridBody XhDatePickerGridHead XhDatePickerHeader XhDatePickerHeading XhDatePickerHiddenInput XhDatePickerInput XhDatePickerLabel XhDatePickerNextTrigger XhDatePickerPositioner XhDatePickerPrevTrigger XhDatePickerRoot XhDatePickerSegment XhDatePickerTrigger XhDatePickerWeekDay XhDatePickerWeekRow
组合式函数useDatePicker
状态机datePickerMachine
皮肤@xihan-ui/styles/date-picker.css

解剖

部件名即 data-part 属性值,也是皮肤的选择器。加粗的是必备部件,不渲染它组件不工作(Web Components 适配器会在诊断通道上报 wc.missing-part)。

data-scope="date-picker"root · label · control · input · trigger · clear-trigger · positioner · content · calendar

Props

属性类型必填说明
valuestring | string[]选中值,ISO 串。给定即受控:读直取 prop,写只发 onValueChange 不落内部值。 单选可写裸串,内部一律归一成数组。
defaultValuestring | string[]
openboolean展开态。给定即受控:内部不再自改,只发 onOpenChange。
defaultOpenboolean
minstring可选范围下界(含当天),ISO 串。日历与分段输入共用这一条。
maxstring可选范围上界(含当天),ISO 串。
localestring决定周首日、月份文案与段位先后(zh-CN 年月日、en-US 月日年)。
timeZonestring判定「今天」与格式化文案用的时区,默认取宿主本地时区。
selectionModeCalendarSelectionMode选择模式,默认 single;区间模式下两端都落定才算选完。
isDateUnavailable(value: string) => boolean不可用判定,收 ISO 串。界外与它判真的日子同等对待。
disabledboolean整个控件禁用:trigger 转原生 disabled,段位退出 Tab 序,日历格子全转 aria-disabled。
readOnlyboolean只读:浮层照常展开、日历照常翻月浏览,但选中值改不动。
invalidboolean校验失败:段位报 aria-invalid,各角色节点带 data-invalid。
requiredboolean必填标注,落到每一段的 aria-required 上。
namestring表单字段名;给了隐藏输入才带 name,ISO 串随表单一并提交。区间模式下是起点那一份。
endNamestring区间终点那份隐藏输入的表单字段名;不给即终点不参与提交。
placementPlacement
dirDirection文字方向,缺省 ltr。只改写浮层在行内轴上 start 与 end 的落点。
offsetnumber
translationsPartial<DatePickerTranslations>
closeOnSelectboolean选完即收起,默认 true。区间模式下要两端都落定才算选完。
onValueChange(details: DatePickerValueChangeDetails) => voidvalue 变化意图回调;受控时是唯一出口,非受控随内部写入一并通知。
onOpenChange(details: DatePickerOpenChangeDetails) => voidopen 变化意图回调;受控时是唯一出口,非受控时随内部转移一并通知。
onFocusedValueChange(details: DatePickerFocusChangeDetails) => void聚焦日变化(方向键、翻月、展开、段位输入都会发)。 网格由外部渲染,不监听这条日历不会换月。

状态机

状态open · closed

事件OPEN · TOGGLE · CLOSE · CONTROLLED.OPEN · CONTROLLED.CLOSE · VALUE.SET · VALUE.CLEAR · FOCUSED.SET · FORM.RESET

判据isOpenControlled · closesOnSelect

connect API

useDatePicker 产出的对象。getXxxProps() 铺到对应部件的宿主元素上,其余是可读状态与操作入口。

成员类型说明
openboolean
valuestring[]选中集合,ISO 串;形状不随模式变。 区间模式下按位存放,空缺的那一端是空串。
valueAsStringstring | null首个选中值(跳过空缺的那一端);无选中时为 null。
selectionModeCalendarSelectionMode
focusedValuestring生效聚焦日(三路收口后的结果),恒非空。日历展示哪个月由它决定。
disabledboolean
readOnlyboolean
invalidboolean
canClearboolean清空按钮此刻可不可按。
setOpen(next: boolean) => void
setValue(next: string[]) => void
clear() => void
calendarCalendarApi<T>内嵌日历:选日期、翻月、键盘导航都在它身上。
fieldDatePickerFieldApi<T>内嵌分段输入,区间模式下是起点那一组。
fieldEndDatePickerFieldApi<T> | null终点那组分段输入;非区间模式为 null。
getRootProps() => T['element']
getLabelProps() => T['element']
getControlProps() => T['element']
getInputProps(props?: DatePickerInputProps) => T['element']role=group 的分段容器,段位挂在它里面。区间模式下 index 选起止两组,不传即起点。
getTriggerProps() => T['button']
getClearTriggerProps() => T['button']
getPositionerProps() => T['element']
getContentProps() => T['element']
getCalendarProps() => T['element']内嵌日历的挂载点,同时充当日历的根节点。

键盘

规格出处:W3C APG

按键生效条件行为
Enter / Spacefocus in trigger, closed展开日历浮层,焦点落到当前聚焦日那一格
Enter / Spacefocus in trigger, open收起浮层,焦点回到 trigger
Escapeopen收起浮层并把焦点还给展开前那个控件(通常是 trigger),选中值不变
Tab / Shift+Tabopen不拦按键:焦点按 Tab 序列自然离开,浮层随即收起且不抢回焦点
Enter / Spaceopen, focus in grid选中聚焦日(由日历完成);closeOnSelect 时收起浮层——区间要两端都落定才算选完

Released under The MIT License