TimePicker
- 组件说明:时间选择组件,用于选择小时、分钟与可选的秒。API 参考 antd
TimePicker(value/defaultValue/onChange/hourStep/minuteStep/disabledHours/showSecond)。 - 尺寸基线:Trigger 高 32px,面板列宽 106px,列最大高 332px,单项高 38px,圆角 5px。
- 实现约定:Trigger 复用 DatePicker 视觉规范;面板是多列可滚动列表,挂在
unstyledVisual模式的 Popover 中;点击任一列即时提交变更,面板保持打开方便继续调整其他列。 - TimePicker 面板 Figma 规范
基础用法
点击 Trigger 打开面板,点击任一列条目即时提交变更(可以继续调整其他列)。
结果
Loading...
实时编辑器
const Demo = () => { const [time, setTime] = useState(undefined) return ( <div style={{ padding: '40px 0' }}> <TimePicker className="w-62" value={time} onChange={setTime} placeholder="选择时间" /> </div> ) } render(<Demo />)
状态
禁用
结果
Loading...
实时编辑器
const Demo = () => { return ( <div style={{ display: 'flex', gap: 16, padding: '40px 0' }}> <TimePicker className="w-62" disabled placeholder="禁用(空)" /> <TimePicker className="w-62" disabled value={new Date(2026, 3, 20, 10, 30)} /> </div> ) } render(<Demo />)
有值(可清除)
Hover Trigger 展示清除按钮。
结果
Loading...
实时编辑器
const Demo = () => { const [time, setTime] = useState(new Date(2026, 3, 20, 13, 30)) return ( <div style={{ padding: '40px 0' }}> <TimePicker className="w-62" value={time} onChange={setTime} /> </div> ) } render(<Demo />)
步长
minuteStep={5} 对齐 Figma 参考样式:分钟列展开为 00、05、10 … 55。
结果
Loading...
实时编辑器
const Demo = () => { const [time, setTime] = useState(new Date(2026, 3, 20, 13, 0)) return ( <div style={{ padding: '40px 0' }}> <TimePicker className="w-62" value={time} onChange={setTime} minuteStep={5} /> </div> ) } render(<Demo />)
显示秒
打开 showSecond 渲染第三列。
结果
Loading...
实时编辑器
const Demo = () => { const [time, setTime] = useState(new Date(2026, 3, 20, 13, 30, 15)) return ( <div style={{ padding: '40px 0' }}> <TimePicker className="w-72" value={time} onChange={setTime} showSecond /> </div> ) } render(<Demo />)
禁用小时
通过 disabledHours 限制可选小时,对应项会变为不可交互。
结果
Loading...
实时编辑器
const Demo = () => { const [time, setTime] = useState(undefined) return ( <div style={{ padding: '40px 0' }}> <TimePicker className="w-62" value={time} onChange={setTime} disabledHours={() => [0, 1, 2, 3, 4, 5, 6, 22, 23]} placeholder="仅工作时间" /> </div> ) } render(<Demo />)
自定义格式
结果
Loading...
实时编辑器
const Demo = () => { const [time, setTime] = useState(new Date(2026, 3, 20, 13, 5)) const format = (d) => { const hh = d.getHours() const mm = String(d.getMinutes()).padStart(2, '0') const suffix = hh >= 12 ? 'PM' : 'AM' const h12 = ((hh + 11) % 12) + 1 return `${h12}:${mm} ${suffix}` } return ( <div style={{ padding: '40px 0' }}> <TimePicker className="w-62" value={time} onChange={setTime} formatTime={format} /> </div> ) } render(<Demo />)
Token 表
| 元素 | 属性 | Token / 值 |
|---|---|---|
| Trigger | 边框(默认) | Separators/Emphasized#CCCCCC |
| Trigger | 边框(激活) | Grays/Black#000000 |
| Trigger | 底色 | Backgrounds/Primary#FFFFFF |
| Trigger(禁用) | 底色 | Grays/Gray-1#EBEBEB |
| 值文本 | 颜色 | Labels/Primary#000000 |
| Placeholder | 颜色 | Labels/Tertiary#757575 |
| 单项文本 | 颜色 | Labels/Secondary#3D3D3D |
| 单项 hover | 底色 | Grays/Gray-1#EBEBEB |
| 面板 | 底色 | Grays/White#FFFFFF |
| 面板 | 投影 | Effects/Shadow/Defaultrgba(0,0,0,0.1) |
| Check 图标 | 颜色 | Labels/Primary#000000 |
尺寸规范
| 维度 | 值 |
|---|---|
| Trigger 高度 | 32px |
| Trigger 内边距 | Spacing_16 / Spacing_12 |
| Trigger 圆角 | Radius_5 (5px) |
| Trigger 字号 | Body/Regular (14px) |
| 面板列宽 | 106px |
| 面板列最大高度 | 332px(可滚动) |
| 单项内边距 | Spacing_8 / Spacing_16 |
| 单项高度 | 38px |
| Check 占位 | 20×20px(选中 / 未选中无布局抖动) |
| Popover offset | 4px |
Props
| Prop | 类型 | 默认 | 说明 |
|---|---|---|---|
value | Date | — | 受控时间值 |
defaultValue | Date | — | 非受控初始值 |
placeholder | string | 'Select time' | Trigger placeholder 文本 |
formatTime | (date: Date) => string | HH:mm(showSecond 时为 HH:mm:ss) | 显示格式化函数 |
hourStep | number | 1 | 小时步长 |
minuteStep | number | 1 | 分钟步长 |
secondStep | number | 1 | 秒步长 |
showSecond | boolean | false | 是否渲染秒列 |
disabledHours | () => number[] | — | 禁用小时 |
disabledMinutes | (hour: number) => number[] | — | 禁用分钟(基于当前小时) |
disabledSeconds | (hour: number, minute: number) => number[] | — | 禁用秒 |
disabled | boolean | false | 禁用整体 |
allowClear | boolean | true | hover 时显示清除按钮 |
open | boolean | — | 受控 open |
defaultOpen | boolean | false | 默认 open |
onOpenChange | (open: boolean) => void | — | open 变更回调 |
onChange | (date: Date | undefined) => void | — | 值变更回调 |
className | string | — | Trigger 自定义 class |
与 antd 的差异
value/onChange使用原生Date,不依赖dayjs。- 点击任一列即时提交变更,面板保持打开,便于继续调整其他列。
- 暂未实现
use12Hours、showNow与范围 TimePicker。
Changelog
2026-05-29 — 首次发布
新增组件:TimePicker(小时 + 分钟,可选秒)。支持 hourStep / minuteStep / secondStep、disabledHours / disabledMinutes / disabledSeconds、受控/非受控值、Trigger 可清除、受控 open、以及自定义时间格式。