Timeline 时间线
按时间顺序排列的一串事件,每条有标记、连接线与内容。
用法
一条竖向的事件流:每条一个圆点,圆点之间连一段线,末条的线自动收起
- 订单已创建下单来源:网页端
- 已发货承运商已揽收
- 已签收本人签收
组件结构
加粗的是必需部件。
data-scope="timeline":root · item · label · indicator · connector · content · title · description · time
示例
逐条语气
tone 写在条目上,只为该条的圆点上色;不写 tone 的条目是中性圆点
- 收到请求队列长度 3
- 开始构建拉取依赖
- 两条依赖有告警已按锁文件继续
- 单元测试失败3 个用例未通过
- 重跑后通过产物已上传
内容所在的一侧
placement 决定内容落在线的哪一侧;alternate 是逐条交替,线位于中间
- 立项需求评审通过
- 开发三个迭代
- 上线灰度两周
- 立项需求评审通过
- 开发三个迭代
- 上线灰度两周
- 立项需求评审通过
- 开发三个迭代
- 上线灰度两周
横排
orientation="horizontal" 把事件从左向右排列,连线随之转为横向
- 内测
- 公测
- 商业化
- 海外版
尺寸
size 改变圆点直径、条目间距与字号,不传 size 即默认档
- 提交12 个文件
- 合并两条评审意见
- 提交12 个文件
- 合并两条评审意见
- 提交12 个文件
- 合并两条评审意见
坐标列
label 与内容对置:逐条交替排布时时间戳仍停在同一侧,不随内容左右跳动
- 2026-05-121.0.0首个正式版
- 2026-06-301.1.0拖拽排序与滚动条
- 2026-08-101.2.0AI 组件族
设计指引
何时使用
- 展示已经发生的事件序列:审批记录、物流轨迹、变更历史。
何时不用
特性
- 逐条可以有自己的语气(成功 / 失败 / 进行中)。
- 内容可以固定在一侧,也可以左右交替。
- 支持横排。
label是与内容对置的一列,承载该条的坐标(日期、版本号);逐条交替排布时时间戳不随内容左右跳动。
组合
最佳实践
- 顺序保持一致:始终最新在上,或始终最早在上,不混用。
- 每条写明时刻,只写“刚刚”在回溯时没有价值。
反模式
- 条数很多却不折叠,一条时间线占据十屏。
- 用颜色区分事件类型却不提供文字。
API 参考
产物
| 层 | 值 |
|---|---|
| 自定义元素 | <xh-timeline> |
| Vue 组件 | XhTimelineConnector XhTimelineContent XhTimelineDescription XhTimelineIndicator XhTimelineItem XhTimelineLabel XhTimelineRoot XhTimelineTime XhTimelineTitle |
| 状态机 | 无,connect 直接由 props 算属性 |
| 皮肤 | @xihan-ui/styles/timeline.css |
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
orientation | Orientation | 事件排列方向:vertical 自上而下、horizontal 自起点向终点,默认 vertical。 | |
placement | TimelinePlacement | 内容位于线的哪一侧:start / end / alternate,未提供时内容落在结束侧。 | |
size | Size | 尺寸:sm / md / lg,决定圆点直径、条目间距与字号。 |
React 适配器 props
只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。
| React 组件 | 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
XhTimelineItem | tone | Tone | 该条的语气,只在本条内生效,下传给它自己的圆点。 |
connect API
getXxxProps() 返回对应部件的宿主属性。
| 成员 | 类型 | 说明 |
|---|---|---|
getRootProps | () => T['element'] | |
getItemProps | () => T['element'] | |
getLabelProps | () => T['element'] | 与内容对置的一列,放置该条的坐标;排布随整条线的方向与侧别变化。 |
getIndicatorProps | (props: TimelineItemProps) => T['element'] | 圆点的语气取自它所属的条目。 |
getConnectorProps | () => T['element'] | |
getContentProps | () => T['element'] | |
getTitleProps | () => T['element'] | |
getDescriptionProps | () => T['element'] | |
getTimeProps | () => T['element'] |
无障碍
键盘
规格出处:W3C APG
无键盘交互(不接收焦点,或焦点行为完全由原生元素提供)。
ARIA
以下属性由 connect 生成。
| 部件 | 属性 | 值 |
|---|---|---|
root | role | 'list' |
item | role | 'listitem' |
indicator | aria-hidden | 'true' |
connector | aria-hidden | 'true' |
样式参考
皮肤
@xihan-ui/styles/timeline.css 使用 [data-scope="timeline"][data-part="root"] 部件选择器,位于 xihan.components 层。覆盖样式使用 xihan.overrides。
数据属性
由 connect 生成;条件不成立时不输出无值属性。
| 部件 | 属性 | 值 |
|---|---|---|
root | data-orientation | props.orientation |
root | data-placement | props.placement |
root | data-size | props.size |
item | data-orientation | props.orientation |
item | data-placement | props.placement |
label | data-orientation | props.orientation |
label | data-placement | props.placement |
indicator | data-tone | item.tone |
connector | data-orientation | props.orientation |
CSS 变量
本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。
| 变量 | 部件 | CSS 属性 | 状态 | 默认来源 | 说明 |
|---|---|---|---|---|---|
--xh-timeline-connector-bg | connector | background | default | --xh-border-default | timeline 的 connector 部件 background 覆盖槽。 |
--xh-timeline-connector-min-length | connectoritem | min-block-sizemin-inline-size | @media (min-width: 768px)defaulthas(> [data-scope='timeline'][data-part='label'])orientation=horizontal | --xh-space-4 | timeline 的 connector、item 部件 min-block-size、min-inline-size 覆盖槽。 |
--xh-timeline-connector-radius | connector | border-radius | default | --xh-shape-pill | timeline 的 connector 部件 border-radius 覆盖槽。 |
--xh-timeline-connector-thickness | connectoritem | block-sizeinline-size | @media (min-width: 768px)defaulthas(> [data-scope='timeline'][data-part='label'])orientation=horizontal | --xh-stroke-thick | timeline 的 connector、item 部件 block-size、inline-size 覆盖槽。 |
--xh-timeline-content-gap | content | gap | default | --xh-space-1 | timeline 的 content 部件 gap 覆盖槽。 |
--xh-timeline-content-pb | contentitem | padding-block-end | @media (min-width: 768px)nth-child(even)orientation=horizontalplacement=alternateplacement=start | --xh-space-2 | timeline 的 content、item 部件 padding-block-end 覆盖槽。 |
--xh-timeline-content-pt | contentitem | padding-block-start | @media (min-width: 768px)has(> [data-scope='timeline'][data-part='label'])orientation=horizontal | --xh-space-2 | timeline 的 content、item 部件 padding-block-start 覆盖槽。 |
--xh-timeline-description-fg | description | color | default | --xh-fg-muted | timeline 的 description 部件 color 覆盖槽。 |
--xh-timeline-description-font-size | description | font-size | default | --xh-text-secondary-size | timeline 的 description 部件 font-size 覆盖槽。 |
--xh-timeline-fg | root | color | default | --xh-fg-default | timeline 的 root 部件 color 覆盖槽。 |
--xh-timeline-gutter | item | column-gap | default | --xh-_timeline-gutter | timeline 的 item 部件 column-gap 覆盖槽。 |
--xh-timeline-indicator-bg | indicator | background | default | --xh-_tone-soft | timeline 的 indicator 部件 background 覆盖槽。 |
--xh-timeline-indicator-fg | indicator | color | default | --xh-_tone-on | timeline 的 indicator 部件 color 覆盖槽。 |
--xh-timeline-indicator-font-size | indicator | font-size | default | --xh-_timeline-caption-font-size | timeline 的 indicator 部件 font-size 覆盖槽。 |
--xh-timeline-indicator-radius | indicator | border-radius | default | --xh-shape-circle | timeline 的 indicator 部件 border-radius 覆盖槽。 |
--xh-timeline-indicator-size | indicatoritem | block-sizeinline-sizemargin-block-start | default | --xh-_timeline-dot-size | timeline 的 indicator、item 部件 block-size、inline-size、margin-block-start 覆盖槽。 |
--xh-timeline-item-gap | contentitem | padding-block-endpadding-inline-end | @media (min-width: 768px)defaulthas(> [data-scope='timeline'][data-part='label'])orientation=horizontal | --xh-_timeline-item-gap | timeline 的 content、item 部件 padding-block-end、padding-inline-end 覆盖槽。 |
--xh-timeline-label-fg | label | color | default | --xh-fg-subtle | timeline 的 label 部件 color 覆盖槽。 |
--xh-timeline-label-font-size | label | font-size | default | --xh-_timeline-caption-font-size | timeline 的 label 部件 font-size 覆盖槽。 |
--xh-timeline-time-fg | time | color | default | --xh-fg-subtle | timeline 的 time 部件 color 覆盖槽。 |
--xh-timeline-time-font-size | time | font-size | default | --xh-_timeline-caption-font-size | timeline 的 time 部件 font-size 覆盖槽。 |
--xh-timeline-title-fg | title | color | default | --xh-fg-default | timeline 的 title 部件 color 覆盖槽。 |
--xh-timeline-title-font-size | indicatoritemroottitle | font-sizemargin-block-start | default | --xh-_timeline-title-font-size | timeline 的 indicator、item、root、title 部件 font-size、margin-block-start 覆盖槽。 |
--xh-timeline-title-font-weight | title | font-weight | default | --xh-text-label-weight | timeline 的 title 部件 font-weight 覆盖槽。 |
动效
动效角色:状态(见动效规范)。
background-color · color 走 transition 过渡。时长与缓动读动效令牌,改令牌即改全局节奏。
系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。
响应式
皮肤按视口分档:min-width: 768px。
RTL
皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像。
