DatePicker
date-picker点开日历浮层选一个日期,可限制可选范围
用法
基础用法
点触发器弹出单月日历,选一天即提交并关闭。对外值是 ISO 日期串 YYYY-MM-DD。
<DatePicker defaultValue="2026-06-08" />选月份 / 选年份
picker 决定粒度与值形状:month → YYYY-MM,year → YYYY。面板标题可点,逐层上卷到月/年视图。
<DatePicker picker="month" defaultValue="2026-06" />
<DatePicker picker="year" defaultValue="2026" />限定范围 + 禁用周末
minDate / maxDate 框定可选区间,disabledDate 进一步逐日禁选。
<DatePicker
defaultValue="2026-06-10"
minDate="2026-06-01"
maxDate="2026-06-30"
disabledDate={(iso) => {
const day = new Date(iso + "T00:00:00").getDay();
return day === 0 || day === 6;
}}
/>自定义显示格式
displayFormat 只改触发器上的显示,对外值形状不变。
<DatePicker defaultValue="2026-06-08" displayFormat="YYYY 年 M 月 D 日" />尺寸
size 与 Input / Select 共用同一套刻度(sm 32px / md 40px / lg 48px),同一行表单里高度天然对齐。
<DatePicker size="sm" defaultValue="2026-06-08" />
<DatePicker size="md" defaultValue="2026-06-08" />
<DatePicker size="lg" defaultValue="2026-06-08" />禁用 / 只读
disabled 整体置灰且打不开;readOnly 可以看面板但选不动。
<DatePicker defaultValue="2026-06-08" disabled />
<DatePicker defaultValue="2026-06-08" readOnly />何时用
表单里选一个日期、月份或年份时用。触发器 + 弹层,弹层里就是 Calendar
面板本身 —— 两者共用同一套下钻与禁用逻辑,所以行为完全一致。
要面板常驻铺开、不带触发器和浮层,直接用 Calendar;
选一段区间用 DateRangePicker;
连时间一起选用 DateTimePicker。
本组件在 0.15.0 之前叫DateField,同期还存在一个基于 MUI X 的DatePicker。 那份桥接件已随整个_mui目录移除,这个名字现在只指向这个自研零依赖实现。
导入
import { DatePicker } from "@hulianui/ui"Props
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| value | string | null | - | 受控值。形状随 picker:"YYYY-MM-DD" / "YYYY-MM" / "YYYY" |
| defaultValue | string | null | - | 非受控初始值,形状同上 |
| picker | "date" | "month" | "year" | "date" | 选择粒度,同时决定值形状与面板起始层 |
| size | "sm" | "md" | "lg" | "md" | 触发器尺寸档,刻度与 Input 一致(32 / 40 / 48px),同一行表单里高度天然对齐 |
| minDate | string | - | 最早可选日期(任意可解析日期串,内部规范化) |
| maxDate | string | - | 最晚可选日期 |
| disabledDate | (isoDate: string) => boolean | - | 逐日禁用判定,入参恒为 "YYYY-MM-DD"(月/年粒度传该月/该年首日) |
| placeholder | string | 随 picker | 触发器占位文本 |
| displayFormat | string | 随 picker | 触发器显示格式(dayjs format 串)。只影响显示,对外值形状不变 |
| clearable | boolean | true | 有值且非 disabled/readOnly 时显示清除按钮 |
| showToday | boolean | true | 面板底部「今天 / 本月 / 今年」快捷 |
| disabled | boolean | false | 整体置灰,面板打不开 |
| readOnly | boolean | false | 面板可看,但选不动 |
| aria-label | string | - | 触发器无障碍名(无可见 label 时给) |
| className | string | - | 落在触发器外层容器 |
Events
| 事件 | 类型 | 说明 |
|---|---|---|
| onValueChange | (value: string | null) => void | 选中/清空回调;清空回传 null |
国际化
未显式传 placeholder 时,日期、月份、年份占位文本以及清除按钮文案跟随最近的ConfigProvider locale;enUS 分别显示 “Select date / month / year”。显式placeholder 始终优先。为兼容旧自定义 Locale,components.datePicker 缺失,或只含旧版clear 字段时,缺少的占位文本仍回退到原有中文。
禁忌 / 坑
- 值是定宽文本,不是 `Date`:
"YYYY-MM-DD"定宽 → 字典序即时间序,区间比较可以直接比字符串,
也避开了 new Date("2026-06-08").toISOString() 在东八区少算 8 小时那类日界坑。要 Date 对象请自己转。
- `picker` 改了值形状:从
date切到month时旧值"2026-06-08"解析后会按月粒度提交成"2026-06"。
切粒度时请一并处理存量值,别指望组件替你迁移。
displayFormat只管显示。想改对外值形状只能通过picker。disabledDate在date粒度下逐日调用(一屏 42 次),请保持它是纯计算 —— 别在里面发请求或建对象。
月/年粒度下只对该月/该年首日调一次,判据也随之变粗:想精确到天就别用粗粒度 picker。
- 面板标题可点,逐层上卷 date → month → year;
picker决定「点到哪一层就提交」,
所以 picker="date" 时点月份只是下钻,不会提交。
- 从 0.15.0 之前的 MUI 版
DatePicker迁过来时注意值格式变了:那份对外是完整 ISO 时间戳,
这份是定宽日期串。另外 views / openTo 合并成了 picker,label 换成 placeholder + aria-label。
- 触发器是
role="combobox"的按钮:未在 Props 里列出的原生属性(aria-*/data-*/id/title/onBlur…)落到它身上,不是外层容器 —— 读屏念的、能聚焦的都是它(#293)。 - 放进 Field 时,
label的htmlFor、aria-describedby、invalid与disabled会自动串到触发器上;<Field required>注入的aria-required同理。0.54.0 之前这条链是断的(label 指向一个不存在的 id,读屏念不出字段名),升级后无需改调用代码。 - 测试里按角色取触发器要用
getByRole("combobox"),不再是"button"。
相关
Calendar · DateRangePicker · DateTimePicker · TimePicker · TimeField · ColorField
Playground
<DatePicker
value={date}
onValueChange={setDate}
/>