基础

Bubble 对话气泡

用于对话气泡场景的 MoriUI 组件。

资源

导入

import { Bubble, BubbleContent, BubbleGroup, BubbleReactions } from 'moriui'

组合方式

Bubble 负责变体与对齐,BubbleContent 承载消息,BubbleReactions 和 BubbleGroup 分别组织回应与连续消息。

特性

当前公开能力包括七种视觉变体、起止对齐以及回应区域的 side/align;不登记 MoriUI 尚未导出的 Popover。

回应标签

仅图标回应按钮必须使用 aria-label,回应容器应有描述其用途的可访问名称。

交互气泡

只有整个气泡确实触发操作时才将 Bubble 渲染为 button 或链接;普通消息保持非交互元素。

不只依赖颜色

错误、发送中等状态应同时提供文字或图标,不能只依赖 variant 颜色。

示例

概览

组合接收与发送消息。

今天的设计评审已准备好。
收到,我会准时参加。
<script setup lang="ts">
  import { ref } from 'vue'
  import {
    Bubble,
    BubbleContent,
    BubbleGroup
  } from 'moriui'

  const expanded = ref(false)
</script>

<template>
  <BubbleGroup class="w-full max-w-md">
    <Bubble><BubbleContent>今天的设计评审已准备好。</BubbleContent></Bubble><Bubble align="end" variant="secondary">
      <BubbleContent>收到,我会准时参加。</BubbleContent>
    </Bubble>
  </BubbleGroup>
</template>

变体

展示当前公开视觉变体。

默认消息
次要消息
描边消息
发送失败
<script setup lang="ts">
  import { ref } from 'vue'
  import {
    Bubble,
    BubbleContent,
    BubbleGroup
  } from 'moriui'

  const expanded = ref(false)
</script>

<template>
  <BubbleGroup class="w-full max-w-md">
    <Bubble><BubbleContent>默认消息</BubbleContent></Bubble><Bubble variant="secondary">
      <BubbleContent>次要消息</BubbleContent>
    </Bubble><Bubble variant="outline">
      <BubbleContent>描边消息</BubbleContent>
    </Bubble><Bubble variant="destructive">
      <BubbleContent>发送失败</BubbleContent>
    </Bubble>
  </BubbleGroup>
</template>

对齐

使用 align 区分会话双方。

来自协作者
来自当前用户
<script setup lang="ts">
  import { ref } from 'vue'
  import {
    Bubble,
    BubbleContent,
    BubbleGroup
  } from 'moriui'

  const expanded = ref(false)
</script>

<template>
  <BubbleGroup class="w-full max-w-md">
    <Bubble align="start">
      <BubbleContent>来自协作者</BubbleContent>
    </Bubble><Bubble align="end" variant="secondary">
      <BubbleContent>来自当前用户</BubbleContent>
    </Bubble>
  </BubbleGroup>
</template>

消息组

连续消息由 BubbleGroup 统一排列。

第一条连续消息
第二条连续消息
<script setup lang="ts">
  import { ref } from 'vue'
  import {
    Bubble,
    BubbleContent,
    BubbleGroup
  } from 'moriui'

  const expanded = ref(false)
</script>

<template>
  <BubbleGroup class="w-full max-w-md">
    <Bubble variant="muted">
      <BubbleContent>第一条连续消息</BubbleContent>
    </Bubble><Bubble variant="muted">
      <BubbleContent>第二条连续消息</BubbleContent>
    </Bubble>
  </BubbleGroup>
</template>

链接与按钮

消息内容可包含语义明确的操作。

文档已经更新。查看 API
<script setup lang="ts">
  import { ref } from 'vue'
  import {
    Bubble,
    BubbleContent,
    Button
  } from 'moriui'

  const expanded = ref(false)
</script>

<template>
  <Bubble variant="tinted">
    <BubbleContent>
      文档已经更新。<a href="#bubble-api" class="underline underline-offset-4">查看 API</a><Button class="ml-2" size="xs">
        确认
      </Button>
    </BubbleContent>
  </Bubble>
</template>

回应

BubbleReactions 组织紧凑操作。

这套交互很清晰。
<script setup lang="ts">
  import { ref } from 'vue'
  import { Heart, Reply } from '@lucide/vue'
  import {
    Bubble,
    BubbleContent,
    BubbleReactions,
    Button
  } from 'moriui'

  const expanded = ref(false)
</script>

<template>
  <Bubble>
    <BubbleContent>这套交互很清晰。</BubbleContent><BubbleReactions aria-label="消息回应">
      <Button size="icon-xs" variant="ghost" aria-label="喜欢">
        <Heart class="size-3" />
      </Button><Button size="icon-xs" variant="ghost" aria-label="回复">
        <Reply class="size-3" />
      </Button>
    </BubbleReactions>
  </Bubble>
</template>

展开更多

与 Collapsible 组合长消息。

这是一段较长的会话摘要。
<script setup lang="ts">
  import { ref } from 'vue'
  import {
    Bubble,
    BubbleContent,
    Button,
    Collapsible,
    CollapsibleContent,
    CollapsibleTrigger
  } from 'moriui'

  const expanded = ref(false)
</script>

<template>
  <Collapsible v-model:open="expanded" class="w-full max-w-md">
    <Bubble variant="muted">
      <BubbleContent>
        这是一段较长的会话摘要。<CollapsibleContent><span class="block pt-2">展开后显示补充细节,并保留清晰的阅读层级。</span></CollapsibleContent><CollapsibleTrigger as-child>
          <Button class="mt-2" size="xs" variant="ghost">
            {{ expanded ? '收起' : '显示更多' }}
          </Button>
        </CollapsibleTrigger>
      </BubbleContent>
    </Bubble>
  </Collapsible>
</template>

提示

交互气泡可与 Tooltip 组合。

<script setup lang="ts">
  import { ref } from 'vue'
  import {
    Bubble,
    BubbleContent,
    Tooltip,
    TooltipContent,
    TooltipProvider,
    TooltipTrigger
  } from 'moriui'

  const expanded = ref(false)
</script>

<template>
  <TooltipProvider>
    <Tooltip>
      <TooltipTrigger as-child>
        <Bubble as="button" type="button">
          <BubbleContent>悬停查看时间</BubbleContent>
        </Bubble>
      </TooltipTrigger><TooltipContent>今天 13:48</TooltipContent>
    </Tooltip>
  </TooltipProvider>
</template>

API

属性 类型 默认值 说明
Bubble variant'default' | 'secondary' | 'muted' | 'tinted' | 'outline' | 'ghost' | 'destructive''default'消息视觉层级。
Bubble align'start' | 'end''start'消息在会话流中的对齐方向。
BubbleContent classHTMLAttributes["class"]undefined合并到消息内容区域的调用方类。
BubbleReactions side'top' | 'bottom''bottom'回应区域相对气泡的位置。
BubbleReactions align'start' | 'end''end'回应区域的水平对齐。
BubbleGroup classHTMLAttributes["class"]undefined合并到连续消息分组的调用方类。
Bubble as / asChildstring | Component / boolean'div' / false根、内容、分组与回应均支持 Reka Primitive 组合。

无障碍说明

对话列表应由页面提供 log/list 等上下文;可交互气泡使用 button 或 a,回应按钮提供 aria-label,状态不能只靠颜色表达。

关联组件