跳转到内容

会话线程 thread

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

示例

基础用法

root 的高度由外部给定,滚动才发生在 viewport 里面;root / viewport / content 三层缺一不可

用户:这个对话区是怎么分层的?

助手:root 定框,viewport 负责滚动,content 包住全部消息。

用户:为什么一定要给高度?

助手:不给一个确定的框,内容永远不溢出,滚动与粘底都无从谈起。

用户:消息本身归谁管?

助手:归你。组件不碰数据,content 里放什么都行。

粘底与回到底部

内容长高时自动跟到底;往上滚一下当场撒手,回到底部按钮随即露出,滚回阈值内又自动粘上

用户:粘底是按什么判的?

助手:按滚动位置离底还差多少像素,差值落在阈值内就算在底。

用户:我自己往上滚一段呢?

助手:当场撒手,此后再长多少都不跟,右下角给你一条回去的路。

用户:滚回去要不要再点一下按钮?

助手:不用,滚进阈值内的那一下自动重新粘上。

在底:是 · 粘附:是

运行态与播报

status 由宿主持有,组件只把它透出成 data-status;viewport 恒 aria-live="off",播报只发生在 live-region 里

用户:帮我写一段开场白。

status:idle

触底加载更多

stick-change 报到底,宿主据此去取下一页;先往上滚一段再滚回底部,取回来的消息追加在后面

第 1 条 · 先往上滚一段,再滚回底部

第 2 条 · 先往上滚一段,再滚回底部

第 3 条 · 先往上滚一段,再滚回底部

第 4 条 · 先往上滚一段,再滚回底部

第 5 条 · 先往上滚一段,再滚回底部

第 6 条 · 先往上滚一段,再滚回底部

第 7 条 · 先往上滚一段,再滚回底部

第 8 条 · 先往上滚一段,再滚回底部

已加载 8 条 · 第 1 / 3 页

自己画回到底部的入口

root 的作用域插槽给出 showScrollButton 与 scrollToBottom,不用内置那颗浮动按钮也能拼出一条自己的提示栏

第 1 条 · 往上滚一段,下面那条提示栏就露出来

第 2 条 · 往上滚一段,下面那条提示栏就露出来

第 3 条 · 往上滚一段,下面那条提示栏就露出来

第 4 条 · 往上滚一段,下面那条提示栏就露出来

第 5 条 · 往上滚一段,下面那条提示栏就露出来

第 6 条 · 往上滚一段,下面那条提示栏就露出来

第 7 条 · 往上滚一段,下面那条提示栏就露出来

第 8 条 · 往上滚一段,下面那条提示栏就露出来

第 9 条 · 往上滚一段,下面那条提示栏就露出来

第 10 条 · 往上滚一段,下面那条提示栏就露出来

第 11 条 · 往上滚一段,下面那条提示栏就露出来

第 12 条 · 往上滚一段,下面那条提示栏就露出来

会话页

线程管滚动与粘底,编辑器管收话:发出去先落一条自己的消息,回话一段段写进来时消息区自动跟到底

助手:有什么想问的?

向上加载更早的消息

视口的滚动事件直接监听:滚到接近顶部就去取上一页,取回来的插在最前面

第 33 条 · 会话记录

第 34 条 · 会话记录

第 35 条 · 会话记录

第 36 条 · 会话记录

第 37 条 · 会话记录

第 38 条 · 会话记录

第 39 条 · 会话记录

第 40 条 · 会话记录

已加载 8 条 · 最早到第 33 条

跳到指定的一条

视口节点与消息节点都在宿主手上:滚到顶、定位到某一条都是一次普通的 DOM 操作

第 1 条 · 会话记录

第 2 条 · 会话记录

第 3 条 · 会话记录

第 4 条 · 会话记录

第 5 条 · 会话记录

第 6 条 · 会话记录

第 7 条 · 会话记录

第 8 条 · 会话记录

第 9 条 · 会话记录

第 10 条 · 会话记录

第 11 条 · 会话记录

第 12 条 · 会话记录

第 13 条 · 会话记录

第 14 条 · 会话记录

第 15 条 · 会话记录

第 16 条 · 会话记录

第 17 条 · 会话记录

第 18 条 · 会话记录

第 19 条 · 会话记录

第 20 条 · 会话记录

第 21 条 · 会话记录

第 22 条 · 会话记录

第 23 条 · 会话记录

第 24 条 · 会话记录

(还没跳过)

产物

自定义元素<xh-thread>
Vue 组件XhThreadContent XhThreadLiveRegion XhThreadRoot XhThreadScrollButton XhThreadViewport
组合式函数useThread
状态机threadMachine
皮肤@xihan-ui/styles/thread.css

解剖

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

data-scope="thread"root · viewport · content · scroll-button · live-region

Props

属性类型必填说明
statusThreadStatus这一轮的运行态,由宿主传入。
thresholdnumber距底多少 px 视为在底,缺省用粘底原语的默认值。
translationsPartial<ThreadTranslations>
onStickChange(details: ThreadStickChangeDetails) => void粘底状态变化时通知宿主。

状态机

状态idle

事件STICK.CHANGE · SCROLL_TO_BOTTOM

connect API

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

成员类型说明
statusThreadStatus
atBottomboolean
stickingboolean
showScrollButtonboolean是否显示回到底部按钮,不在底部时为 true。
scrollToBottom() => void
getRootProps() => T['element']
getViewportProps() => T['element']
getContentProps() => T['element']
getScrollButtonProps() => T['button']
getLiveRegionProps() => T['element']

键盘

规格出处:W3C APG

按键生效条件行为
Tab焦点进入消息区消息区自身可聚焦,方向键/PageUp/PageDown 交给浏览器滚动,组件不接管
Space / Enter焦点在"回到底部"按钮上滚回底部并重新粘附

Released under The MIT License