工具提示
功能
- 提供全局控制显示延迟的功能。
- 当触发器获得焦点或被悬停时打开。
- 当触发器被激活或按下 Escape 键时关闭。
- 支持自定义时间。
结构
导入所有部分并将其组合。
<script setup lang="ts">
import { TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger } from 'reka-ui'
</script>
<template>
<TooltipProvider>
<TooltipRoot>
<TooltipTrigger />
<TooltipPortal>
<TooltipContent>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</TooltipRoot>
</TooltipProvider>
</template>
API 参考
提供者
封装您的应用程序,为工具提示提供全局功能。
属性 | 默认 | 类型 |
---|---|---|
延迟时间 | 700 | 数字 指针进入触发器到工具提示打开的持续时间。 |
禁用关闭触发器 | 布尔值 当 | |
禁用 | 布尔值 当 | |
禁用可悬停内容 | false | 布尔值 当 |
忽略非键盘焦点 | false | 布尔值 通过匹配 |
跳过延迟时间 | 300 | 数字 用户在不再次产生延迟的情况下进入另一个触发器所需的时间。 |
根
包含工具提示的所有部分。
属性 | 默认 | 类型 |
---|---|---|
默认打开 | false | 布尔值 工具提示首次渲染时的打开状态。当您不需要控制其打开状态时使用。 |
延迟时间 | 数字 覆盖提供给 | |
禁用关闭触发器 | 布尔值 当 | |
禁用 | 布尔值 当 | |
禁用可悬停内容 | 布尔值 防止 Tooltip.Content 在悬停时保持打开。禁用此功能会影响可访问性。继承自 Tooltip.Provider。 | |
忽略非键盘焦点 | 布尔值 通过匹配 | |
打开 | 布尔值 工具提示的受控打开状态。 |
事件触发 | 载荷 |
---|---|
更新:打开 | [value: boolean] 当工具提示的打开状态改变时调用的事件处理程序。 |
插槽(默认) | 载荷 |
---|---|
打开 | 布尔值 当前打开状态 |
触发器
切换工具提示的按钮。默认情况下,TooltipContent
将根据触发器进行定位。
属性 | 默认 | 类型 |
---|---|---|
as | 'button' | AsTag | Component 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
引用 | ReferenceElement 用于定位的参考(或锚点)元素。 如果未提供,将使用当前组件作为锚点。 |
数据属性 | 值 |
---|---|
[data-state] | "closed" | "delayed-open" | "instant-open" |
传送门
使用时,将内容部分传送到 body
中。
属性 | 默认 | 类型 |
---|---|---|
延迟 | 布尔值 延迟解析 Teleport 目标,直到应用程序的其他部分挂载(需要 Vue 3.5.0+) | |
禁用 | 布尔值 禁用传送并内联渲染组件 | |
强制挂载 | 布尔值 当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。 | |
至 | 字符串 | HTMLElement Vue 原生传送组件属性 |
内容
工具提示打开时弹出的组件。
属性 | 默认 | 类型 |
---|---|---|
对齐 | 'start' | 'center' | 'end' 相对于触发器的首选对齐方式。当发生碰撞时可能会改变。 | |
对齐偏移 | 数字 与 | |
aria标签 | string 默认情况下,屏幕阅读器会朗读组件内部的内容。如果这不够具描述性,或者您有无法朗读的内容,请使用 aria-label 作为更具描述性的标签。 | |
箭头内边距 | 数字 箭头与内容边缘之间的内边距。如果您的内容有 border-radius,这将防止它溢出角落。 | |
as | 'div' | AsTag | Component 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
避免碰撞 | 布尔值 当为 | |
碰撞边界 | Element | (Element | null)[] | null 用作碰撞边界的元素。默认情况下是视口,但您可以提供其他元素以包含在此检查中。 | |
碰撞内边距 | 数字 | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>> 碰撞检测应发生的距边界边缘的像素距离。接受一个数字(所有边相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。 | |
强制挂载 | 布尔值 当需要更多控制时,用于强制挂载。在与 Vue 动画库控制动画时很有用。 | |
分离时隐藏 | 布尔值 当触发器完全被遮挡时,是否隐藏内容。 | |
定位策略 | 'fixed' | 'absolute' 要使用的 CSS position 属性类型。 | |
侧边 | 'top' | 'top' | 'right' | 'bottom' | 'left' 打开时,相对于触发器渲染的首选侧边。当发生碰撞且启用 avoidCollisions 时,将反转。 |
侧边偏移 | 数字 与触发器的像素距离。 | |
粘性 | '部分' | '始终' 对齐轴上的粘性行为。 | |
更新定位策略 | '始终' | '优化' 在每个动画帧更新浮动元素位置的策略。 |
事件触发 | 载荷 |
---|---|
按下Escape键 | [事件: KeyboardEvent] 在打开后焦点移动到破坏性操作时调用的事件处理程序。可以通过调用 |
外部指针按下 | [事件: Event] 当指针事件发生在组件边界之外时调用的事件处理程序。可以通过调用 |
数据属性 | 值 |
---|---|
[data-state] | "closed" | "delayed-open" | "instant-open" |
[data-side] | "左" | "右" | "下" | "上" |
[data-align] | "开始" | "结束" | "居中" |
CSS 变量 | 描述 |
---|---|
--reka-tooltip-content-transform-origin | 从内容和箭头位置/偏移量计算的 transform-origin |
--reka-tooltip-content-available-width | 触发器与边界边缘之间的剩余宽度 |
--reka-tooltip-content-available-height | 触发器与边界边缘之间的剩余高度 |
--reka-tooltip-trigger-width | 触发器的宽度 |
--reka-tooltip-trigger-height | 触发器的高度 |
箭头
一个可选的箭头元素,与工具提示一同渲染。这可用于帮助视觉上将触发器与 TooltipContent
关联起来。必须在 TooltipContent
内部渲染。
属性 | 默认 | 类型 |
---|---|---|
as | 'svg' | AsTag | Component 此组件应渲染为的元素或组件。可通过 |
asChild | 布尔值 更改默认渲染元素为作为子项传递的元素,合并它们的属性和行为。 阅读我们的 组合指南了解更多详情。 | |
高度 | 5 | 数字 箭头的像素高度。 |
宽度 | 10 | 数字 箭头的像素宽度。 |
示例
全局配置
使用 Provider
全局控制 delayDuration
和 skipDelayDuration
。
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'reka-ui'
</script>
<template>
<TooltipProvider
:delay-duration="800"
:skip-delay-duration="500"
>
<TooltipRoot>
<TooltipTrigger>…</TooltipTrigger>
<TooltipContent>…</TooltipContent>
</TooltipRoot>
<TooltipRoot>
<TooltipTrigger>…</TooltipTrigger>
<TooltipContent>…</TooltipContent>
</TooltipRoot>
</TooltipProvider>
</template>
立即显示
使用 delayDuration
属性控制工具提示打开所需的时间。
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'reka-ui'
</script>
<template>
<TooltipRoot :delay-duration="0">
<TooltipTrigger>…</TooltipTrigger>
<TooltipContent>…</TooltipContent>
</TooltipRoot>
</template>
从禁用按钮显示工具提示
由于禁用按钮不触发事件,您需要
- 将
Trigger
渲染为span
。 - 确保
button
没有pointerEvents
。
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'reka-ui'
</script>
<template>
<TooltipRoot>
<TooltipTrigger as-child>
<span tabindex="0">
<button
disabled
style="{ pointerEvents: 'none' }"
>…</button>
</span>
</TooltipTrigger>
<TooltipContent>…</TooltipContent>
</TooltipRoot>
</template>
限制内容尺寸
您可能希望限制内容的宽度以匹配触发器的宽度。您可能还希望限制其高度,使其不超过视口。
我们公开了一些 CSS 自定义属性,例如 --reka-tooltip-trigger-width
和 --reka-tooltip-content-available-height
来支持此功能。使用它们来限制内容的尺寸。
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'reka-ui'
</script>
<template>
<TooltipRoot>
<TooltipTrigger>…</TooltipTrigger>
<TooltipPortal>
<TooltipContent
class="TooltipContent"
:side-offset="5"
>
…
</TooltipContent>
</TooltipPortal>
</TooltipRoot>
</template>
/* styles.css */
.TooltipContent {
width: var(--reka-tooltip-trigger-width);
max-height: var(--reka-tooltip-content-available-height);
}
感知原点的动画
我们公开了一个 CSS 自定义属性 --reka-tooltip-content-transform-origin
。使用它根据 side
、sideOffset
、align
、alignOffset
和任何碰撞来从其计算出的原点动画内容。
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'reka-ui'
</script>
<template>
<TooltipRoot>
<TooltipTrigger>…</TooltipTrigger>
<TooltipContent class="TooltipContent">
…
</TooltipContent>
</TooltipRoot>
</template>
/* styles.css */
.TooltipContent {
transform-origin: var(--reka-tooltip-content-transform-origin);
animation: scaleIn 0.5s ease-out;
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0);
}
to {
opacity: 1;
transform: scale(1);
}
}
感知碰撞的动画
我们公开了 data-side
和 data-align
属性。它们的值将在运行时改变以反映碰撞。使用它们来创建碰撞和方向感知的动画。
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'reka-ui'
</script>
<template>
<TooltipRoot>
<TooltipTrigger>…</TooltipTrigger>
<TooltipContent class="TooltipContent">
…
</TooltipContent>
</TooltipRoot>
</template>
/* styles.css */
.TooltipContent {
animation-duration: 0.6s;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.TooltipContent[data-side="top"] {
animation-name: slideUp;
}
.TooltipContent[data-side="bottom"] {
animation-name: slideDown;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
可访问性
键盘交互
键 | 描述 |
---|---|
Tab | 立即打开/关闭工具提示。 |
空格键 | 如果已打开,则立即关闭工具提示。 |
回车键 | 如果已打开,则立即关闭工具提示。 |
Escape | 如果已打开,则立即关闭工具提示。 |
自定义 API
通过将原始部件抽象到您自己的组件中来创建您自己的 API。
抽象组件并引入内容属性
此示例抽象了所有 Tooltip
组件并引入了一个新的 content
属性。
用法
<script setup lang="ts">
import { Tooltip } from './your-tooltip'
</script>
<template>
<Tooltip content="Tooltip content">
<button>Tooltip trigger</button>
</Tooltip>
</template>
实现
使用 asChild
属性 将触发器部分转换为可插槽区域。它将用传递给它的子元素替换触发器。
<!-- your-tooltip.vue -->
<script setup lang="ts">
import type { TooltipRootEmits, TooltipRootProps } from 'reka-ui'
import { TooltipArrow, TooltipContent, TooltipRoot, TooltipTrigger, useForwardPropsEmits } from 'reka-ui'
const props = defineProps<TooltipRootProps & { content?: string }>()
const emits = defineEmits<TooltipRootEmits>()
const forward = useForwardPropsEmits(props, emits)
</script>
<template>
<TooltipRoot v-bind="forward">
<TooltipTrigger as-child>
<slot />
</TooltipTrigger>
<TooltipContent
side="top"
align="center"
>
{{ content }}
<TooltipArrow
:width="11"
:height="5"
/>
</TooltipContent>
</TooltipRoot>
</template>