ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

用 shadcn Chat 原语搭建 AI 对话界面:MessageScroller、Bubble、Attachment 与 Marker 完整实战指南

用 shadcn Chat 原语搭建 AI 对话界面:MessageScroller、Bubble、Attachment 与 Marker 完整实战指南 【免费下载链接】open-slideA slide framework built for agents.项目地址https://gitcode.com/gh_mirrors/op/open-slide点击查看免费下载本文以 open-slide 仓库中 shadcn Agent Skill 的规则文档 chat.md 为核心系统讲解 shadcn/ui 为会话类界面提供的五组专用原语可滚动会话MessageScroller、消息行Message、消息表面Bubble、附件Attachment与系统标记Marker。读完本文你将掌握如何用组合式声明替代手写滚动逻辑与气泡 div实现流式跟随、锚定、跳转最新等完整聊天体验。安装与整体定位一次添加五组组件Chat 相关的组件以一条命令整体安装npx shadcnlatest add message-scroller message bubble attachment marker按项目实际包管理器也可用pnpm dlx shadcnlatest或bunx --bun shadcnlatest替代npx参考 SKILL.md 中的说明。安装后会话类 UI 的所有场景都由这五组原语覆盖而不是手写气泡、滚动容器、分割线或附件卡片可滚动会话线程—— 用MessageScroller消息行—— 用Message消息表面气泡—— 用Bubble文件/图片附件—— 用Attachment系统备注与分割线—— 用Marker流式跟随、锚定与跳转最新—— 全部内置在MessageScroller中逃生舱—— scroller 系列 hooks在 SKILL.md 的“Component Selection”表中聊天/会话 UI 的推荐组件正是MessageScroller、Message、Bubble、Attachment、Marker这一组而不是把ScrollArea、Separator、Badge拼凑成聊天界面。base 与 radix 双版本同一组件名同一套 props这五组组件在base与radix两种底层库下拥有相同的组件名和相同的 props区别只在组合方式base 用renderradix 用asChild。具体差异可查阅 base-vs-radix.md。当前项目的底层库由npx shadcnlatest info输出的base字段决定radix或base无需在编写聊天 UI 时区分两套 API。可滚动会话线程MessageScroller一段「可滚动、跟随新消息、恢复位置、可跳转到指定消息」的会话应该使用MessageScroller。规则文档明确指出不要构建裸的 overflow 容器并手工接线滚动逻辑也不要退而使用ScrollArea。反例手写滚动容器 手动贴底逻辑// Hand-rolled scroll container with manual stick-to-bottom logic. div ref{scrollRef} onScroll{handleScroll} classNameflex-1 overflow-y-auto div classNameflex flex-col gap-6 p-4 {messages.map((m) ( ChatMessage key{m.id} message{m} / ))} /div /div这段代码的问题在于滚动监听、贴底判断、位置恢复全部要靠自己维护而这些行为正是MessageScroller内置的。正例声明式组合MessageScrollerProvider autoScroll MessageScroller MessageScrollerViewport MessageScrollerContent {messages.map((message) ( MessageScrollerItem key{message.id} messageId{message.id} scrollAnchor{message.role user} Message align{message.role user ? end : start} {/* ...message content... */} /Message /MessageScrollerItem ))} /MessageScrollerContent /MessageScrollerViewport MessageScrollerButton / /MessageScroller /MessageScrollerProvider固定的嵌套顺序各部件按固定顺序嵌套这一顺序也被 composition.md 的「Chat components nest in a fixed order」所强调MessageScrollerProvider → MessageScroller → MessageScrollerViewport → MessageScrollerContent → MessageScrollerItem → MessageScrollerButton其中MessageScrollerContent的每个直接子元素都必须被MessageScrollerItem包裹这样滚动器才能测量、锚定、保持位置、跟踪可见性并跳转到它。MessageScrollerButton则位于MessageScroller内部、viewport 之后。消息行Message 与 MessageGroupMessage负责布局单行消息头像avatar、头部header、内容content、底部footer并支持对齐。连续同一发送者的多行消息用MessageGroup分组不要用 flex div 重新拼装消息行。对齐语义很直观alignend表示当前用户一侧alignstart表示其他所有人。Message alignstart MessageAvatar Avatar AvatarImage src{sender.avatar} alt{sender.name} / AvatarFallback{initials}/AvatarFallback /Avatar /MessageAvatar MessageContent MessageHeader{sender.name}/MessageHeader Bubble BubbleContent{text}/BubbleContent /Bubble MessageFooter{time}/MessageFooter /MessageContent /Message注意示例中Avatar始终带AvatarFallback这是 composition.md 的强制规则图片加载失败时要有兜底展示。消息表面Bubble 与 BubbleReactions消息的彩色表面是BubbleBubbleContent绝不使用手工bg-muted/bg-primary且手管圆角的 styleddiv。variant 与 alignvariantdefault、secondary、muted、tinted、outline、ghost、destructivealignstart或end与Message所在侧保持一致反例手写气泡 divdiv classNamew-fit rounded-2xl bg-primary px-3 py-2 text-primary-foreground {text} /div正例Bubble BubbleReactionsBubble variantdefault alignend BubbleContent{text}/BubbleContent BubbleReactions sidebottom alignend Badge variantsecondary 2/Badge /BubbleReactions /BubbleBubbleReactions渲染表情回应簇用sidetop|bottom和alignstart|end相对气泡定位。规则明确禁止用绝对定位的Badge手工摆放回应表情。附件Attachment文件与图片附件使用Attachment而不是Item或自定义卡片。Attachment自带上传状态因此要把state接到真实上传状态上而不是单独渲染一个 spinner。state五种上传状态state取值idle、uploading、processing、error、done。其中uploading与processing会自动对标题应用shimmer动画见 styling.mdAttachment 在上传时对标题做 shimmerMessageScrollerViewport 自带边缘淡化。size 与 orientationsizedefault、sm、xsorientationhorizontal、vertical多个附件用AttachmentGroup排成可横向滚动的行这一「Item 必须放在 Group 内」的规则同样出现在 composition.md 的分组表中Attachment statedone AttachmentMedia varianticon FileTextIcon / /AttachmentMedia AttachmentContent AttachmentTitlehomepage-feedback.pdf/AttachmentTitle AttachmentDescriptionPDF · 2.4 MB/AttachmentDescription /AttachmentContent AttachmentActions AttachmentAction DownloadIcon / /AttachmentAction /AttachmentActions /Attachment图片附件只需把媒体换成图片变体AttachmentMedia variantimage并内嵌img子元素。系统备注与分割线Marker状态行如“Sarah joined the conversation”、日期分割线如“Today”和带标签的分隔条应使用Marker而不是Separator加一个居中 span。三种 variantdefault普通行separator居中标签、两侧带分隔线border底部带边框的行MarkerIcon承载前导图标MarkerContent承载标签文本。反例Separator 居中 labeldiv classNameflex items-center gap-3 py-2 Separator classNameflex-1 / span classNametext-xs text-muted-foregroundToday/span Separator classNameflex-1 / /div正例MarkerMarker variantseparator MarkerContentToday/MarkerContent /Marker内置行为流式跟随、锚定与跳转最新MessageScroller已经把聊天 UI 通常需要“重新发明”的行为全部内置。规则文档明确禁止自己编写useStickToBottomhook、ResizeObserver或手算scrollTop。流式跟随autoScrollMessageScrollerProvider加上autoScroll即可让视口钉住新内容并在用户向上滚动时立即让位。流式生成时不断变长的最后一条消息会被自动跟随无需额外代码。锚定一轮对话scrollAnchorMessageScrollerItem上的scrollAnchor标记要保持在视口中的行——通常是发起本轮对话的用户消息MessageScrollerItem key{message.id} messageId{message.id} scrollAnchor{message.role user} 跳转最新MessageScrollerButton当用户滚离最新位置时MessageScrollerButton自动出现点击即滚回。direction默认end也可设为start。它是一个自管理控件不要再用自己的滚动位置 state 去开关它。“thinking…” 指示器模型生成期间的“思考中”指示直接对文本应用shimmer工具类span classNameshimmerThinking…/span不要自创keyframes动画或bg-clip-text渐变扫光styling.md 中给出了对应的反例与正例。逃生舱scroller hooks当组合式部件无法表达某些行为时可以从 hooks 读取状态而不是重写滚动器useMessageScroller、useMessageScrollerVisibility、useMessageScrollerScrollable。它们来自自动安装的shadcn/react依赖无需额外安装。规则给出的边界是只有在组合无法表达需求时才使用。与风格与组合规则的协同聊天 UI 并非孤立组件使用时应同时遵守 shadcn 的通用规则全部以 Incorrect/Correct 代码对维护在 styling.md 与 composition.md语义色优先bg-primary、text-muted-foreground禁止bg-blue-500等裸色值间距用 gapflex gap-4而不是space-y-4/space-x-*等宽高用 size-*size-10而非w-10 h-10Item 必须放进 GroupMessageScrollerItem→MessageScrollerContent连续同发送者的Message→MessageGroup叠放的Bubble→BubbleGroup成行的Attachment→AttachmentGroup暗色模式交给语义 token不做手工dark:覆盖状态颜色用 Badge 变体或语义 token表情回应用Badge variantsecondary而不是手写 emerald/green span滚动边缘淡化MessageScrollerViewport已内部应用scroll-fade系列工具无需手写遮罩渐变。在仓库中的验证与延伸阅读本规则并非孤立的规范文本仓库中配套材料可交叉验证chat.md —— 本文主体含全部 Incorrect/Correct 代码对SKILL.md —— 将聊天规则列为 Critical Rules“Chat Messaging”一节并给出组件选择表与安装工作流composition.md —— 定义了聊天组件的固定嵌套顺序与「Item 进 Group」的强制规则styling.md —— 定义shimmer/scroll-fade工具类、语义色与间距规范base-vs-radix.md —— 说明聊天组件在base/radix下组件名与 props 一致、仅组合方式不同evals.json —— 其中第 4、5 号评估用例正是针对聊天界面一条要求组合MessageScroller、Message、Bubble、Attachment、Marker搭建双人会话视图含图片/PDF 附件与 “Today” 分割线另一条要求用autoScrollscrollAnchorMessageScrollerButtonshimmer搭建流式 AI 聊天 UI并逐一列明验收点可作为自测清单使用。小结一句话决策清单场景用这个别用可滚动的会话线程MessageScrollerProvider → Scroller → Viewport → Content → Item裸overflow-y-autodiv、ScrollArea单条消息行MessageMessageGroup分组flex div 手拼消息表面BubbleBubbleContentrounded-2xl bg-primarydiv表情回应BubbleReactions绝对定位的Badge文件/图片附件AttachmentAttachmentGroupItem、自定义卡片、手写 spinner系统备注/日期分割线MarkerSeparator 居中 label流式跟随/锚定/跳转最新MessageScrollerProvider autoScroll、scrollAnchor、MessageScrollerButtonuseStickToBottomhook、ResizeObserver、手算scrollTop思考中指示shimmer工具类自定义keyframes、bg-clip-text扫光遵循这条决策链会话界面就能以最少的自定义代码获得完整、可维护、可访问的聊天体验同时保持与 shadcn 组件体系的一致性与可升级性。赞分享【免费下载链接】open-slideA slide framework built for agents.项目地址https://gitcode.com/gh_mirrors/op/open-slide点击查看免费下载相关推荐Comp AI CRM 聊天 UI 组件指南用 shadcn 的 MessageScroller、Bubble 与 Attachment 构建 Agent 对话界面Comp AI CRM 聊天 UI 组件指南用 shadcn 的 MessageScroller、Bubble 与 Attachment 构建 Agent 对后端前端CRM人工智能AI AgentSemi Design Chat 组件实战指南用 douyinfe/semi-ui 快速搭建 AI 对话界面Semi Design Chat 组件实战指南用 douyinfe/semi ui 快速搭建 AI 对话界面 本篇技术指南以 Semi Design d前端UI组件设计系统SRS低延迟直播调优3个参数把首屏从2秒压到300毫秒SRS低延迟直播调优3个参数把首屏从2秒压到300毫秒 做互动直播的朋友应该都有体会观众发个弹幕主播3秒后才看到互动感直接没了。SRS 是开源的高性能实音视频后端直播上一篇LogicFlow 自动布局插件 logicflow/layout 完全指南Dagre 与 ElkLayout 的配置、分组布局与源码原理下一篇Sunshine 游戏串流快速教程10 分钟把 PC 游戏送上电视创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表