生态产品多个设计器现已发布正式版

查看生态总览
跳转到内容

Log 日志 ​

等宽排版的滚动区域,一行一条,可以自动跟随到底部。

用法 ​

root / viewport / content / line 四层;一行写什么由作者决定,组件只提供身份与等宽排版

12:00:01 boot 读取配置 config/app.yaml
12:00:01 boot 监听 0.0.0.0:8080
12:00:02 db 连接池就绪,最小 4 最大 32
12:00:02 cache 命中率统计已开启
12:00:03 http GET /health 200 3ms
12:00:04 http POST /api/orders 201 118ms
12:00:05 http GET /api/orders/8812 200 21ms
12:00:06 job 对账任务排入队列 batch-2026-08-10
12:00:07 http GET /api/orders/8813 404 9ms
12:00:08 job 对账任务完成,处理 1,204 笔

组件结构 ​

加粗的是必需部件。

data-scope="log":root · viewport · content · line · segment · scroll-to-end-trigger · live-region

示例 ​

按行数定高 ​

rows 决定可见几行,一行的高度归皮肤,修改 --xh-log-line-height 两者一起变化

12:00:00 http GET /api/items/1000 200
12:00:01 http GET /api/items/1001 200
12:00:02 http GET /api/items/1002 200
12:00:03 http GET /api/items/1003 200
12:00:04 http GET /api/items/1004 200
12:00:05 http GET /api/items/1005 200
12:00:06 http GET /api/items/1006 200
12:00:07 http GET /api/items/1007 200
12:00:08 http GET /api/items/1008 200
12:00:09 http GET /api/items/1009 200
12:01:00 http GET /api/items/1010 200
12:01:01 http GET /api/items/1011 200
12:01:02 http GET /api/items/1012 200
12:01:03 http GET /api/items/1013 200
12:01:04 http GET /api/items/1014 200
12:01:05 http GET /api/items/1015 200
12:01:06 http GET /api/items/1016 200
12:01:07 http GET /api/items/1017 200
12:01:08 http GET /api/items/1018 200
12:01:09 http GET /api/items/1019 200
12:02:00 http GET /api/items/1020 200
12:02:01 http GET /api/items/1021 200
12:02:02 http GET /api/items/1022 200
12:02:03 http GET /api/items/1023 200
12:00:00 http GET /api/items/1000 200
12:00:01 http GET /api/items/1001 200
12:00:02 http GET /api/items/1002 200
12:00:03 http GET /api/items/1003 200
12:00:04 http GET /api/items/1004 200
12:00:05 http GET /api/items/1005 200
12:00:06 http GET /api/items/1006 200
12:00:07 http GET /api/items/1007 200
12:00:08 http GET /api/items/1008 200
12:00:09 http GET /api/items/1009 200
12:01:00 http GET /api/items/1010 200
12:01:01 http GET /api/items/1011 200
12:01:02 http GET /api/items/1012 200
12:01:03 http GET /api/items/1013 200
12:01:04 http GET /api/items/1014 200
12:01:05 http GET /api/items/1015 200
12:01:06 http GET /api/items/1016 200
12:01:07 http GET /api/items/1017 200
12:01:08 http GET /api/items/1018 200
12:01:09 http GET /api/items/1019 200
12:02:00 http GET /api/items/1020 200
12:02:01 http GET /api/items/1021 200
12:02:02 http GET /api/items/1022 200
12:02:03 http GET /api/items/1023 200
12:00:00 http GET /api/items/1000 200
12:00:01 http GET /api/items/1001 200
12:00:02 http GET /api/items/1002 200
12:00:03 http GET /api/items/1003 200
12:00:04 http GET /api/items/1004 200
12:00:05 http GET /api/items/1005 200
12:00:06 http GET /api/items/1006 200
12:00:07 http GET /api/items/1007 200
12:00:08 http GET /api/items/1008 200
12:00:09 http GET /api/items/1009 200
12:01:00 http GET /api/items/1010 200
12:01:01 http GET /api/items/1011 200
12:01:02 http GET /api/items/1012 200
12:01:03 http GET /api/items/1013 200
12:01:04 http GET /api/items/1014 200
12:01:05 http GET /api/items/1015 200
12:01:06 http GET /api/items/1016 200
12:01:07 http GET /api/items/1017 200
12:01:08 http GET /api/items/1018 200
12:01:09 http GET /api/items/1019 200
12:02:00 http GET /api/items/1020 200
12:02:01 http GET /api/items/1021 200
12:02:02 http GET /api/items/1022 200
12:02:03 http GET /api/items/1023 200

自动跟随到底部 ​

新行进入时视口自动跟随;向上滚动一段即停止跟随,组件报告的 atBottom 与 scrollToBottom 足以自行绘制一条回到最新

12:00:00 boot 第 1 行 · 往上滚一段试试
12:00:01 boot 第 2 行 · 往上滚一段试试
12:00:02 boot 第 3 行 · 往上滚一段试试
12:00:03 boot 第 4 行 · 往上滚一段试试
12:00:04 boot 第 5 行 · 往上滚一段试试
12:00:05 boot 第 6 行 · 往上滚一段试试
12:00:06 boot 第 7 行 · 往上滚一段试试
12:00:07 boot 第 8 行 · 往上滚一段试试
12:00:08 boot 第 9 行 · 往上滚一段试试
12:00:09 boot 第 10 行 · 往上滚一段试试
跟随意图:开

取行中 ​

loading 使日志区报告 aria-busy 并把指针换为忙碌态;正在拉取那一行由作者自行渲染

12:00:01 boot 服务已启动
12:00:02 db 连接池就绪
12:00:03 http GET /health 200

级别 ​

行上写 level,四档 debug / info / warn / error 由皮肤染色;时间戳与行内标记仍归作者

12:00:01 [DEBUG] 读取配置 config/app.yaml
12:00:02 [INFO] 数据库连接池就绪
12:00:04 [INFO] POST /api/orders 201 118ms
12:00:05 [WARN] 慢查询 1,240ms select * from orders
12:00:06 [ERROR] 支付网关超时,第 1 次重试
12:00:08 [INFO] 支付网关恢复,订单 8812 已确认

换为自绘滚动条 ​

视口提供一个 id,用滚动条的 controls 挂载;滚动条浮在内容之上,不占宽度也不留空道

12:00:00 http GET /api/orders/8800 200 10ms
12:00:01 http GET /api/orders/8801 200 11ms
12:00:02 http GET /api/orders/8802 200 12ms
12:00:03 http GET /api/orders/8803 200 13ms
12:00:04 http GET /api/orders/8804 200 14ms
12:00:05 http GET /api/orders/8805 200 15ms
12:00:06 http GET /api/orders/8806 200 16ms
12:00:07 http GET /api/orders/8807 200 17ms
12:00:08 http GET /api/orders/8808 200 18ms
12:00:09 http GET /api/orders/8809 200 19ms
12:01:10 http GET /api/orders/8810 200 20ms
12:01:11 http GET /api/orders/8811 200 21ms
12:01:12 http GET /api/orders/8812 200 22ms
12:01:13 http GET /api/orders/8813 200 23ms
12:01:14 http GET /api/orders/8814 200 24ms
12:01:15 http GET /api/orders/8815 200 25ms
12:01:16 http GET /api/orders/8816 200 26ms
12:01:17 http GET /api/orders/8817 200 27ms
12:01:18 http GET /api/orders/8818 200 28ms
12:01:19 http GET /api/orders/8819 200 29ms
12:02:20 http GET /api/orders/8820 200 30ms
12:02:21 http GET /api/orders/8821 200 31ms
12:02:22 http GET /api/orders/8822 200 32ms
12:02:23 http GET /api/orders/8823 200 33ms
12:02:24 http GET /api/orders/8824 200 34ms
12:02:25 http GET /api/orders/8825 200 35ms
12:02:26 http GET /api/orders/8826 200 36ms
12:02:27 http GET /api/orders/8827 200 37ms
12:02:28 http GET /api/orders/8828 200 38ms
12:02:29 http GET /api/orders/8829 200 39ms
12:03:30 http GET /api/orders/8830 200 40ms
12:03:31 http GET /api/orders/8831 200 41ms
12:03:32 http GET /api/orders/8832 200 42ms
12:03:33 http GET /api/orders/8833 200 43ms
12:03:34 http GET /api/orders/8834 200 44ms
12:03:35 http GET /api/orders/8835 200 45ms
12:03:36 http GET /api/orders/8836 200 46ms
12:03:37 http GET /api/orders/8837 200 47ms
12:03:38 http GET /api/orders/8838 200 48ms
12:03:39 http GET /api/orders/8839 200 49ms

回到底部与播报 ​

向上翻一段,右下角的按钮自动显示,按下后归位并重新粘附;输出结束后在播报区朗读一句结论

12:00:00 build 编译 packages/module-1 · 往上翻一段试试
12:00:01 build 编译 packages/module-2 · 往上翻一段试试
12:00:02 build 编译 packages/module-3 · 往上翻一段试试
12:00:03 build 编译 packages/module-4 · 往上翻一段试试
12:00:04 build 编译 packages/module-5 · 往上翻一段试试
12:00:05 build 编译 packages/module-6 · 往上翻一段试试
12:00:06 build 编译 packages/module-7 · 往上翻一段试试
12:00:07 build 编译 packages/module-8 · 往上翻一段试试
12:00:08 build 编译 packages/module-9 · 往上翻一段试试
12:00:09 build 编译 packages/module-10 · 往上翻一段试试

ANSI 着色 ​

行上写 ansi 交出带转义的原文,按 SGR 拆成着色的段:颜色映射到语义色,粗体、暗淡、下划线各自生效,其余转义不显示

$ pnpm build
vite v7.1.2 building for production...
✓ 1,204 modules transformed.
(!) Some chunks are larger than 500 kB after minification.
error src/app.ts(12,3): Type 'string' is not assignable to type 'number'.
✓ built in 4.21s

级别过滤 ​

levels 只显示所选级别的行,用切换按钮组选;没写级别的行不受影响

12:00:02 数据库连接池就绪
12:00:04 POST /api/orders 201 118ms
12:00:05 慢查询 1,240ms select * from orders
12:00:06 支付网关超时,第 1 次重试
12:00:08 支付网关恢复,订单 8812 已确认

复制全部 ​

日志旁放一颗剪贴板按钮复制整段输出;带 ANSI 转义的原文先用 stripAnsi 去掉转义,复制出去的是纯文字

$ pnpm test
✓ tests/order.spec.ts (12 tests)
✗ tests/payment.spec.ts > 超时重试 FAILED
Tests 1 failed | 12 passed (13)

虚拟滚动 ​

行数很大时把日志与 Virtualizer 接线:virtualizer 交出 collectionVirtualizer,行放进 Virtualizer 的条目里,只挂窗口里的那些;粘底跟着 Virtualizer 的视口走

设计指引 ​

何时使用 ​

  • 构建输出、运行日志、命令行回显。
  • 任何从底部持续增长、需要始终跟随到底的内容:内容不需要区分条目身份,整段追加即可。

何时不用 ​

  • 内容是会话、条目有身份且需要逐条遍历时,使用消息流。
  • 展示结构化记录、需要筛选排序时,使用表格。
  • 展示一段代码时,使用代码视图。

特性 ​

  • 结构四层:root · viewport · content · line;每行内容由作者决定,组件只提供身份与等宽排版。另有两个可选部件:scroll-to-end-trigger 与 live-region。
  • rows 按行数定高。
  • 自动跟随到底部;用户向上翻时停止跟随,回到底部后恢复。
  • 内置“回到底部”:离开底部时出现,按下后归位并重新粘附。它是 Action Control floating 档的圆钮,比日志的 size 低一档、最低 sm(sm / md 时 32px,lg 时 40px)。留空时皮肤绘制向下的字形,放入节点即替换为自定义图形。
  • 应用设为 data-material="liquid" 时,“回到底部”换成液态面:按下层换色调,按住时液面随手指形变。
  • 视口自身可聚焦,整块日志占一个 Tab 停靠位,方向键与翻页键交给浏览器滚动。
  • ANSI 着色:行上写 ansi 交出带转义的原文(Web Components 在行上写 ansi 属性、文字就是原文),按 SGR 拆成 segment。八种前景色映射到语义色:红、绿、黄、蓝取语气前景,品红、青借代码着色的关键字与字符串色,黑与白取正文与次要前景,每一种都可经 --xh-log-ansi-<颜色> 覆盖;高亮色(90–97)与基础色同一档。粗体、暗淡、斜体、下划线各自生效;背景色、256 色的高位与真彩色不着色,清行、挪光标之类的转义直接去掉。parseAnsi 与 stripAnsi 同时导出,复制与播报用去掉转义的纯文字。
  • 级别过滤:levels 只显示所选级别的行,没写级别的行不受影响;接了虚拟滚动时 DOM 里只有窗口里的行,过滤在交给 Virtualizer 之前按 isLevelVisible 做。

组合 ​

  • 行内可以用文本高亮标出关键词。
  • 行数很大时与虚拟滚动接线:XhVirtualizerRoot 包在外面,把它交出的 collectionVirtualizer 传给 virtualizer,日志视口里放 Virtualizer 的视口,行放进 Virtualizer 的条目。日志视口只定高、不滚动,Tab 位与滚动都归里面那层 Virtualizer 视口,粘底跟着它走;这时不用 content 部件。Web Components 的行写在 Virtualizer 条目里,声明 data-xh-part-owner="log" 由外层日志认领。
  • 复制全部用剪贴板,下载用下载触发器,都放在日志旁边;带转义的原文先经 stripAnsi。
  • 给视口一个 id,把滚动条的 controls 指向它,滚动条与视口平级放在 root 内:它浮在内容之上,不占宽度。未挂自绘滚动条时视口自行预留一条通道,原生滚动条出现与消失不会推动文字。

最佳实践 ​

  • 用户向上翻时不强行拉回底部。
  • 行数很大时接虚拟滚动或截断,不把十万行全部挂载。

反模式 ​

  • 每到一行就整块重渲。
  • 不提供复制或下载全部日志的入口。
  • 把每一行都写进播报区,读屏会被逐行打断。

API 参考 ​

产物 ​

层值
自定义元素<xh-log>
Vue 组件XhLogContent XhLogLine XhLogLiveRegion XhLogRoot XhLogScrollToEndTrigger XhLogSegment XhLogViewport
组合式函数useLog
状态机logMachine
皮肤@xihan-ui/styles/log.css

Props ​

属性类型必填说明
thresholdnumber距底部多少 px 视为在底部,默认使用贴底原语的默认值。
virtualizerCollectionVirtualizer与虚拟滚动接线:传入 Virtualizer 的 collectionVirtualizer,行只挂载当前窗口里的那些。 粘底改跟 Virtualizer 的滚动层与内容层,日志视口只保留 role=log 与定高,由它里面的 Virtualizer 视口滚动。
onStickChange(details: LogStickChangeDetails) => void贴底状态变化时通知宿主。
levelsreadonly LogLevel[]只显示这几个级别的行,缺省全部显示。没写 level 的行不受过滤影响。 接了虚拟滚动时 DOM 里只有窗口里的行,过滤要在交给 Virtualizer 之前按 isLevelVisible 做。
loadingboolean行仍在传输中:日志区报告 aria-busy,根写 data-loading。
rowsnumber视口按多少行定高;未提供时高度由皮肤决定。
sizeSize尺寸:sm / md / lg。影响行文字号与内衬,行高不随档位变化;回到底部钮比它低一档、最低 sm(32 / 32 / 40px)。
translationsPartial<LogTranslations>

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
stick-changeLogStickChangeDetails贴底状态变化;detail 为 { atBottom: boolean, sticking: boolean }

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhLogRootdefaultLogRootSlotProps

React 适配器 props ​

只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。

React 组件属性类型必填说明
XhLogLinelevelLogLevel该行的级别,写为行上的 data-level。
XhLogLineansistring带 ANSI 转义的一行原文:按 SGR 拆成着色的段;写了 children 时以 children 为准。
XhLogRootchildrenSlotChildren<LogRootSlotProps>
XhLogSegmentsegmentLogAnsiSegment是parseAnsi 拆出的一段。

状态 ​

公开状态写入 data-state。

部件取值
scroll-to-end-trigger'visible' | 'hidden'

以下名称仅用于内部状态机。

状态:idle

事件:STICK.CHANGE · SCROLL_TO_BOTTOM · PRESS.START · PRESS.END · TRIGGER.RENDERED

判据:canPress

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
rowsnumber | undefined取整后的行数;rows 缺席或不是正数时为 undefined。
loadingboolean
atBottomboolean当前滚动位置是否落在底部阈值内。
stickingboolean新行到达时是否自动跟随到底部。
showScrollToEndTriggerboolean是否显示回到底部按钮,不在底部时为 true。
virtualizedboolean是否接了虚拟滚动。
isLevelVisible(level?: LogLevel) => boolean某级别的行此刻是否显示;没写级别的行始终显示。
scrollToBottom() => void滚动到底部并恢复贴附。
getRootProps() => T['element']
getViewportProps() => T['element']
getContentProps() => T['element']
getLineProps(props?: LogLineProps) => T['element']
getSegmentProps(segment: LogAnsiSegment) => T['element']一段 ANSI 文字:颜色与字形写成 data 属性,皮肤映射到语义令牌。
getScrollToEndTriggerProps() => T['button']
getLiveRegionProps() => T['element']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Tab焦点进入日志区日志区自身可聚焦,方向键/PageUp/PageDown/Home/End 交给浏览器滚动,组件不接管
Space / Enter焦点在"回到底部"按钮上滚回底部并重新粘附
Space / Enter按住"回到底部"按钮且视口不在底部按住期间 scroll-to-end-trigger 投影 data-pressed,与指针 :active 同一副按压面;抬起、失焦或回到底部(按钮收起)撤下

ARIA ​

以下属性由 connect 生成。

部件属性值
viewportaria-busy'true' | undefined
viewportaria-labellabel.log
viewportaria-live'off'
viewportrole'log'
scroll-to-end-triggeraria-labellabel.scrollToBottom
live-regionaria-atomic'true'
live-regionaria-live'polite'
live-regionrole'status'
  • 视口是 role=log,但其隐含的 aria-live 被显式关闭:逐行读出连续输出会成为读屏噪声。
  • 播报使用独立的 live-region:宿主决定读哪一句、何时读,例如一段输出结束后读出结论与错误条数。不要把每一行原样写入,否则等于重新打开逐行播报。
  • 成批取行期间视口报告 aria-busy;播报区是视口的兄弟节点,不受其影响。

样式参考 ​

皮肤 ​

@xihan-ui/styles/log.css 按 [data-scope="log"][data-part="root"] 部件选择器书写,发布产物以挂载类 .xh-scope-log 代替其中的 data-scope(特异性相同),位于 xihan.components 层。覆盖样式使用 xihan.overrides,部件选择器照常可用。

forced-colors: active 下另有一套规则:颜色交给系统,边框与状态标记改用系统色关键字。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
rootdata-at-bottom''(条件成立时才出现)
rootdata-loading''(条件成立时才出现)
rootdata-sizeprops.size
rootdata-sticking''(条件成立时才出现)
viewportdata-virtualized''(条件成立时才出现)
linedata-levelline?.level
segmentdata-bold''(条件成立时才出现)
segmentdata-bright''(条件成立时才出现)
segmentdata-dim''(条件成立时才出现)
segmentdata-fgsegment.fg
segmentdata-italic''(条件成立时才出现)
segmentdata-underline''(条件成立时才出现)
scroll-to-end-triggerdata-pressed''(条件成立时才出现)
scroll-to-end-triggerdata-state'visible' | 'hidden'
scroll-to-end-triggerdata-xh-action-control''
scroll-to-end-triggerdata-xh-action-display'always'
scroll-to-end-triggerdata-xh-action-profile'floating'
scroll-to-end-triggerdata-xh-action-sizefloatingSizeBelow(props.size)
scroll-to-end-triggerdata-xh-action-variant'ghost'
scroll-to-end-triggerdata-xh-liquid''
scroll-to-end-triggerdata-xh-material'frosted'

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-log-ansi-blacksegmentcolorfg=black--xh-fg-defaultlog 的 segment 部件 color 覆盖槽。
--xh-log-ansi-bluesegmentcolorfg=blue--xh-fg-infolog 的 segment 部件 color 覆盖槽。
--xh-log-ansi-bold-weightsegmentfont-weightbold--xh-font-weight-semiboldlog 的 segment 部件 font-weight 覆盖槽。
--xh-log-ansi-cyansegmentcolorfg=cyan--xh-syntax-stringlog 的 segment 部件 color 覆盖槽。
--xh-log-ansi-dim-fgsegmentcolordim
fg
not([data-fg])
--xh-fg-subtlelog 的 segment 部件 color 覆盖槽。
--xh-log-ansi-greensegmentcolorfg=green--xh-fg-successlog 的 segment 部件 color 覆盖槽。
--xh-log-ansi-magentasegmentcolorfg=magenta--xh-syntax-keywordlog 的 segment 部件 color 覆盖槽。
--xh-log-ansi-redsegmentcolorfg=red--xh-fg-dangerlog 的 segment 部件 color 覆盖槽。
--xh-log-ansi-whitesegmentcolorfg=white--xh-fg-mutedlog 的 segment 部件 color 覆盖槽。
--xh-log-ansi-yellowsegmentcolorfg=yellow--xh-fg-warninglog 的 segment 部件 color 覆盖槽。
--xh-log-bgrootbackgrounddefault--xh-bg-surfacelog 的 root 部件 background 覆盖槽。
--xh-log-borderrootborderdefault--xh-border-defaultlog 的 root 部件 border 覆盖槽。
--xh-log-content-pxcontent
line
viewport
padding-inlinedefault
virtualized
--xh-_log-content-pxlog 的 content、line、viewport 部件 padding-inline 覆盖槽。
--xh-log-fgrootcolordefault--xh-fg-defaultlog 的 root 部件 color 覆盖槽。
--xh-log-fontcontent
viewport
font-familydefault
virtualized
--xh-font-family-monolog 的 content、viewport 部件 font-family 覆盖槽。
--xh-log-font-sizecontent
viewport
font-sizedefault
virtualized
--xh-_log-font-sizelog 的 content、viewport 部件 font-size 覆盖槽。
--xh-log-icon-sizescroll-to-end-trigger--xh-icon-sizedefault--xh-_action-profile-glyph-sizelog 的 scroll-to-end-trigger 部件 --xh-icon-size 覆盖槽。
--xh-log-level-debug-fglinecolorlevel=debug--xh-fg-subtlelog 的 line 部件 color 覆盖槽。
--xh-log-level-error-fglinecolorlevel=error--xh-fg-dangerlog 的 line 部件 color 覆盖槽。
--xh-log-level-info-fglinecolorlevel=info--xh-fg-defaultlog 的 line 部件 color 覆盖槽。
--xh-log-level-warn-fglinecolorlevel=warn--xh-fg-warninglog 的 line 部件 color 覆盖槽。
--xh-log-line-heightline
root
viewport
block-size
line-height
default--xh-text-code-leadinglog 的 line、root、viewport 部件 block-size、line-height 覆盖槽。
--xh-log-line-pxline
viewport
padding-inlinevirtualized--xh-log-content-pxlog 的 line、viewport 部件 padding-inline 覆盖槽。
--xh-log-radiusrootborder-radiusdefault--xh-shape-surfacelog 的 root 部件 border-radius 覆盖槽。
--xh-log-rowsviewportblock-sizedefault16log 的 viewport 部件 block-size 覆盖槽。
--xh-log-scroll-to-end-trigger-bgscroll-to-end-trigger--xh-ink-surface
background-color
default
disabled
focus-visible
xh-ink-surface
--xh-_material-bg
--xh-_material-bg-focus
log 的 scroll-to-end-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-log-scroll-to-end-trigger-bg-hoverscroll-to-end-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_material-bg-hoverlog 的 scroll-to-end-trigger 部件 background-color 覆盖槽。
--xh-log-scroll-to-end-trigger-borderscroll-to-end-triggerborder
border-color
default
disabled
focus-visible
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_material-borderlog 的 scroll-to-end-trigger 部件 border、border-color 覆盖槽。
--xh-log-scroll-to-end-trigger-fgscroll-to-end-triggercolordefault
disabled
focus-visible
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_material-fglog 的 scroll-to-end-trigger 部件 color 覆盖槽。
--xh-log-scroll-to-end-trigger-insetscroll-to-end-triggerinset-block-end
inset-inline-end
default--xh-space-3log 的 scroll-to-end-trigger 部件 inset-block-end、inset-inline-end 覆盖槽。
--xh-log-scroll-to-end-trigger-radiusscroll-to-end-triggerborder-radiusdefault--xh-shape-circlelog 的 scroll-to-end-trigger 部件 border-radius 覆盖槽。
--xh-log-scroll-to-end-trigger-shadowscroll-to-end-triggerbox-shadowdefault
disabled
focus-visible
hover
is(:active, [data-pressed])
is(:hover, [data-loading])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_material-shadowlog 的 scroll-to-end-trigger 部件 box-shadow 覆盖槽。
--xh-log-scroll-to-end-trigger-sizescroll-to-end-triggerblock-size
inline-size
default
xh-action-profile=floating
--xh-_action-profile-visual-sizelog 的 scroll-to-end-trigger 部件 block-size、inline-size 覆盖槽。
--xh-log-shadowrootbox-shadowdefaultnonelog 的 root 部件 box-shadow 覆盖槽。
--xh-log-tab-sizelinetab-sizedefault4log 的 line 部件 tab-size 覆盖槽。

动效 ​

动效角色:按压 · 状态 · 出现(见动效规范)。

共享关键帧 xh-overlay-pop-in · xh-pop-out 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立。时长与缓动读动效令牌,改令牌即改全局节奏。

系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像。

Released under The MIT License