Tooltip 文字提示

悬停或聚焦时显示的简短说明。

<script setup lang="ts">
  import { Bold, Italic, Link2, Strikethrough } from '@lucide/vue'
  import { ButtonGroup, IconButton } from '@hina-ui/vue'
</script>

<template>
  <ButtonGroup label="文字格式">
    <IconButton label="加粗" variant="outline">
      <Bold />
    </IconButton>
    <IconButton label="斜体" variant="outline">
      <Italic />
    </IconButton>
    <IconButton label="删除线" variant="outline">
      <Strikethrough />
    </IconButton>
    <IconButton label="插入链接" variant="outline">
      <Link2 />
    </IconButton>
  </ButtonGroup>
</template>
vue

用法

import { Tooltip, vTooltip } from '@hina-ui/vue'
ts

默认插槽是触发器,content 属性是提示的文字。指针悬停或键盘聚焦时显示,指针移开或按 Esc 时隐藏。

<script setup lang="ts">
  import { Button, Tooltip } from '@hina-ui/vue'
</script>

<template>
  <Tooltip content="保存后立刻发布">
    <Button variant="outline" tone="neutral">发布</Button>
  </Tooltip>
</template>
vue

IconButton 自带提示:label 既是无障碍名称,也是提示文字,不需要再包一层 Tooltip。

Tooltip 需要外层有 TooltipProvider,AppShell 已经包含了一个。没有 Provider 时,组件只渲染触发器。

示例

指令

导入 vTooltip 后,可以直接在已有元素上使用 v-tooltip。字符串绑定提示文字;对象绑定 content、side、align、sideOffset、disabled 和 class。绑定值变化时提示同步更新,空字符串、null、undefined 或 false 隐藏提示。

指令与组件共享 TooltipProvider 的延迟和跳过延迟状态,沿用相同的样式、定位与键盘焦点规则。它保留元素已有的 aria-describedby,元素卸载时移除提示及事件监听。提示文字作为纯文本渲染;需要富内容时使用组件的 content 插槽。

禁用对象提示

<script setup lang="ts">
  import { ref } from 'vue'
  import { Button, Inline, Input, Stack, Switch, Text, vTooltip } from '@hina-ui/vue'

  const content = ref('提示文字')
  const disabled = ref(false)
</script>

<template>
  <Stack align="start">
    <Inline>
      <Button v-tooltip="'直接绑定已有元素'" variant="outline" tone="neutral">字符串</Button>
      <Button v-tooltip="{ content, side: 'bottom', disabled }" variant="outline" tone="neutral">
        对象配置
      </Button>
    </Inline>
    <Input v-model="content" aria-label="提示文字" class="w-64" />
    <Inline>
      <Switch v-model="disabled" aria-label="禁用对象提示" />
      <Text>禁用对象提示</Text>
    </Inline>
  </Stack>
</template>
vue

位置

side 指定提示出现在哪一侧,align 指定它与触发器的对齐方式。默认在正上方,空间不足时翻转到相反一侧。

<script setup lang="ts">
  import { Button, Inline, Tooltip } from '@hina-ui/vue'
</script>

<template>
  <Inline align="center" class="gap-6">
    <Tooltip content="浮在头顶" side="top">
      <Button variant="outline" tone="neutral">top</Button>
    </Tooltip>
    <Tooltip content="浮在右侧" side="right">
      <Button variant="outline" tone="neutral">right</Button>
    </Tooltip>
    <Tooltip content="浮在下方" side="bottom">
      <Button variant="outline" tone="neutral">bottom</Button>
    </Tooltip>
    <Tooltip content="与起始边对齐" side="top" align="start">
      <Button variant="outline" tone="neutral">top start</Button>
    </Tooltip>
  </Inline>
</template>
vue

间距

sideOffset 是提示与触发器之间的距离,单位为像素。

<script setup lang="ts">
  import { Button, Inline, Tooltip } from '@hina-ui/vue'
</script>

<template>
  <Inline align="center" class="gap-6">
    <Tooltip content="sideOffset 为 0" :side-offset="0">
      <Button variant="outline" tone="neutral">紧贴</Button>
    </Tooltip>
    <Tooltip content="sideOffset 为 16" :side-offset="16">
      <Button variant="outline" tone="neutral">远离</Button>
    </Tooltip>
  </Inline>
</template>
vue

提示内容

content 插槽不限于文字,例如可以放快捷键。超过最大宽度的文字会自动换行。

<script setup lang="ts">
  import { Info, Save } from '@lucide/vue'
  import { IconButton, Inline, Kbd, Tooltip } from '@hina-ui/vue'
</script>

<template>
  <Inline align="center" class="gap-6">
    <Tooltip>
      <IconButton label="保存" variant="outline" :tooltip="false">
        <Save />
      </IconButton>
      <template #content>
        <Inline align="center" class="gap-1.5">
          保存草稿
          <Kbd>Ctrl S</Kbd>
        </Inline>
      </template>
    </Tooltip>
    <Tooltip content="这段说明比较长,超过气泡的最大宽度之后会自动折成多行,不会一直往外撑。">
      <IconButton label="说明" variant="outline" :tooltip="false">
        <Info />
      </IconButton>
    </Tooltip>
  </Inline>
</template>
vue

延迟

delayDuration 是显示提示前的悬停时长。skipDelayDuration 是一个时间窗:提示关闭后的这段时间内移到下一个触发器,会跳过延迟直接显示。两者对 TooltipProvider 内的所有 Tooltip 生效。

<script setup lang="ts">
  import { Button, Inline, Tooltip, TooltipProvider } from '@hina-ui/vue'
</script>

<template>
  <TooltipProvider :delay-duration="600" :skip-delay-duration="0">
    <Inline align="center" class="gap-6">
      <Tooltip content="等待 600 毫秒后出现">
        <Button variant="outline" tone="neutral">慢一点</Button>
      </Tooltip>
      <Tooltip content="同样等待 600 毫秒">
        <Button variant="outline" tone="neutral">再一个</Button>
      </Tooltip>
    </Inline>
  </TooltipProvider>
</template>
vue

受控

传入 open 后,显示与隐藏由调用方决定,悬停与键盘焦点不再起作用;受控时提示的定位改为逐帧更新,可以跟随移动中的触发器,Slider 的取值标签即采用这种方式。

<script setup lang="ts">
  import { ref } from 'vue'
  import { Button, Inline, Switch, Tooltip } from '@hina-ui/vue'

  const shown = ref(true)
</script>

<template>
  <Inline gap="lg" align="center">
    <Tooltip content="由右边的开关控制" :open="shown">
      <Button variant="outline" tone="neutral">提示的触发器</Button>
    </Tooltip>
    <Switch v-model="shown">显示提示</Switch>
  </Inline>
</template>
vue

禁用

设置 disabled 后不创建浮层,只渲染触发器。

当前:已禁用

<script setup lang="ts">
  import { ref } from 'vue'
  import { Button, Inline, Text, Tooltip } from '@hina-ui/vue'

  const off = ref(true)
</script>

<template>
  <Inline align="center">
    <Tooltip content="侧栏收起时才需要这句话" :disabled="off">
      <Button variant="outline" tone="neutral">悬停试试</Button>
    </Tooltip>
    <Button size="sm" variant="soft" tone="neutral" @click="off = !off">
      {{ off ? '启用提示' : '禁用提示' }}
    </Button>
    <Text tone="muted" size="sm">当前:{{ off ? '已禁用' : '已启用' }}</Text>
  </Inline>
</template>
vue

行为

  • 只有来自键盘的焦点会显示提示;鼠标点击留下的焦点、浮层关闭后归还的焦点都不会。
  • 提示不会锁定页面滚动,页面滚动时它跟随触发器。

无障碍

  • 触发器的 aria-describedby 指向提示,屏幕阅读器读完触发器后会读出提示。
  • 提示不获得焦点,也不在 Tab 顺序中。需要交互的内容应放在 Popover 里。

API

Tooltip

属性
类型
默认值
说明
content
string
—
提示的文字
side
'top' | 'right' | 'bottom' | 'left'
'top'
出现在哪一侧
align
'start' | 'center' | 'end'
'center'
与触发器的对齐方式
sideOffset
number
8
与触发器的距离
open
boolean
—
受控的显示状态,未传入时由悬停与键盘焦点决定
disabled
boolean
false
是否禁用提示
class
string
—
追加到提示上的类名
插槽
说明
default
触发器
content
提示的内容,优先于同名属性

vTooltip

局部导入 vTooltip 即可在模板中使用 v-tooltip;也可以通过 app.directive('tooltip', vTooltip) 全局注册。需要外层有 TooltipProvider。原生元素与渲染为单一元素的组件都可以作为宿主。

TooltipDirectiveValue 为 string | TooltipDirectiveOptions | null | undefined | false。TooltipDirectiveOptions 必须包含 content: string,其他字段与上方 Tooltip 属性相同,不包含 open。

TooltipProvider

属性
类型
默认值
说明
delayDuration
number
150
显示提示前的悬停时长,单位为毫秒
skipDelayDuration
number
300
跳过延迟的时间窗,单位为毫秒
插槽
说明
default
共用这两个时长的子树