工具提示
<script setup lang="ts">
import { TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger } from 'radix-vue'
import { Icon } from '@iconify/vue'
</script>
<template>
<TooltipProvider>
<TooltipRoot>
<TooltipTrigger
class="text-grass11 shadow-blackA7 hover:bg-green3 inline-flex h-[35px] w-[35px] items-center justify-center rounded-full bg-white shadow-[0_2px_10px] outline-none focus:shadow-[0_0_0_2px] focus:shadow-black"
>
<Icon icon="radix-icons:plus" />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent
class="data-[state=delayed-open]:data-[side=top]:animate-slideDownAndFade data-[state=delayed-open]:data-[side=right]:animate-slideLeftAndFade data-[state=delayed-open]:data-[side=left]:animate-slideRightAndFade data-[state=delayed-open]:data-[side=bottom]:animate-slideUpAndFade text-grass11 select-none rounded-[4px] bg-white px-[15px] py-[10px] text-[15px] leading-none shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] will-change-[transform,opacity]"
:side-offset="5"
>
Add to library
<TooltipArrow
class="fill-white"
:width="8"
/>
</TooltipContent>
</TooltipPortal>
</TooltipRoot>
</TooltipProvider>
</template>
功能
- 提供者用于全局控制显示延迟。
- 当触发器获得焦点或悬停时打开。
- 当触发器被激活或按下 Escape 键时关闭。
- 支持自定义计时。
解剖学
导入所有部分并将它们拼凑在一起。
<script setup lang="ts">
import { TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger } from 'radix-vue'
</script>
<template>
<TooltipProvider>
<TooltipRoot>
<TooltipTrigger />
<TooltipPortal>
<TooltipContent>
<TooltipArrow />
</TooltipContent>
</TooltipPortal>
</TooltipRoot>
</TooltipProvider>
</template>
API 参考
提供者
包装您的应用程序以向您的工具提示提供全局功能。
道具 | 默认 | 类型 |
---|---|---|
delayDuration | 700 | number 指针进入触发器到工具提示打开的时间间隔。 |
disableClosingTrigger | boolean 当 | |
disabled | boolean 当 | |
disableHoverableContent | false | boolean 当 |
ignoreNonKeyboardFocus | false | boolean 如果焦点不是来自键盘,则通过与 |
skipDelayDuration | 300 | number 用户在进入另一个触发器而不会再次产生延迟之前需要多少时间。 |
根
包含工具提示的所有部分。
道具 | 默认 | 类型 |
---|---|---|
defaultOpen | false | boolean 工具提示最初渲染时的打开状态。当您不需要控制其打开状态时使用。 |
delayDuration | number 覆盖提供给 | |
disableClosingTrigger | boolean 当 | |
disabled | boolean 当 | |
disableHoverableContent | boolean 阻止 | |
ignoreNonKeyboardFocus | boolean 如果焦点不是来自键盘,则通过与 | |
open | boolean 工具提示的受控打开状态。 |
发射 | 有效载荷 |
---|---|
update:open | [value: boolean] 工具提示的打开状态发生变化时调用的事件处理程序。 |
插槽(默认) | 有效载荷 |
---|---|
open | boolean 当前打开状态 |
触发器
切换工具提示的按钮。默认情况下,TooltipContent
会将自身定位在触发器上。
道具 | 默认 | 类型 |
---|---|---|
as | 'button' | AsTag | Component 此组件应渲染为的元素或组件。可以被 |
asChild | boolean 更改为子级传递的默认渲染元素,合并它们的道具和行为。 阅读我们的 组合 指南以了解更多详细信息。 |
数据属性 | 价值 |
---|---|
[data-state] | "closed" | "delayed-open" | "instant-open" |
传送门
使用时,将内容部分传送到 body
中。
道具 | 默认 | 类型 |
---|---|---|
disabled | boolean 禁用传送并内联渲染组件 | |
forceMount | boolean 用于在需要更多控制时强制安装。在使用 Vue 动画库控制动画时很有用。 | |
to | string | HTMLElement Vue 原生传送组件道具 |
内容
工具提示打开时弹出的组件。
道具 | 默认 | 类型 |
---|---|---|
align | 'start' | 'center' | 'end' 相对于触发器的首选对齐方式。在发生碰撞时可能会改变。 | |
alignOffset | number 从 | |
ariaLabel | string 默认情况下,屏幕阅读器会宣布组件内部的内容。如果这不够描述,或者您有无法宣布的内容,请使用 aria-label 作为更具描述性的标签。 | |
arrowPadding | number 箭头和内容边缘之间的填充。如果您的内容有边框半径,这将阻止它溢出角落。 | |
as | 'div' | AsTag | Component 此组件应渲染为的元素或组件。可以被 |
asChild | boolean 更改为子级传递的默认渲染元素,合并它们的道具和行为。 阅读我们的 组合 指南以了解更多详细信息。 | |
avoidCollisions | boolean 当 | |
collisionBoundary | Element | (Element | null)[] | null 用作碰撞边界的元素。默认情况下,这是视口,尽管您可以提供要包含在此检查中的其他元素。 | |
collisionPadding | number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>> 从边界边缘的距离(以像素为单位),在该距离处应发生碰撞检测。接受一个数字(所有边都相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。 | |
forceMount | boolean 用于在需要更多控制时强制安装。在使用 Vue 动画库控制动画时很有用。 | |
hideWhenDetached | boolean 当触发器被完全遮挡时是否隐藏内容。 | |
side | 'top' | 'top' | 'right' | 'bottom' | 'left' 打开时渲染的触发器首选侧边。当发生碰撞并且启用 |
sideOffset | number 距触发器的距离(以像素为单位)。 | |
sticky | 'partial' | 'always' 对齐轴上的粘性行为。 |
发射 | 有效载荷 |
---|---|
escapeKeyDown | [event: KeyboardEvent] 在打开后焦点移动到破坏性操作时调用的事件处理程序。可以通过调用 |
pointerDownOutside | [event: Event] 在组件边界之外发生指针事件时调用的事件处理程序。可以通过调用 |
数据属性 | 价值 |
---|---|
[data-state] | "closed" | "delayed-open" | "instant-open" |
[data-side] | "left" | "right" | "bottom" | "top" |
[data-align] | "start" | "end" | "center" |
CSS 变量 | 描述 |
---|---|
--radix-tooltip-content-transform-origin | 从内容和箭头位置/偏移量计算的 transform-origin |
--radix-tooltip-content-available-width | 触发器和边界边缘之间的剩余宽度 |
--radix-tooltip-content-available-height | 触发器和边界边缘之间的剩余高度 |
--radix-tooltip-trigger-width | 触发器的宽度 |
--radix-tooltip-trigger-height | 触发器的高度 |
箭头
一个可选的箭头元素,用于与工具提示一起渲染。这可以用来帮助从视觉上将触发器与 TooltipContent
联系起来。必须在 TooltipContent
内渲染。
道具 | 默认 | 类型 |
---|---|---|
as | 'svg' | AsTag | Component 此组件应渲染为的元素或组件。可以被 |
asChild | boolean 更改为子级传递的默认渲染元素,合并它们的道具和行为。 阅读我们的 组合 指南以了解更多详细信息。 | |
height | 5 | number 箭头的以像素为单位的高度。 |
width | 10 | number 箭头的以像素为单位的宽度。 |
示例
全局配置
使用 Provider
全局控制 delayDuration
和 skipDelayDuration
。
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'radix-vue'
</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 'radix-vue'
</script>
<template>
<TooltipRoot :delay-duration="0">
<TooltipTrigger>…</TooltipTrigger>
<TooltipContent>…</TooltipContent>
</TooltipRoot>
</template>
从禁用按钮显示工具提示
由于禁用的按钮不会触发事件,因此您需要
- 将
Trigger
渲染为span
。 - 确保
button
没有pointerEvents
。
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'radix-vue'
</script>
<template>
<TooltipRoot>
<TooltipTrigger as-child>
<span tabindex="0">
<button
disabled
style="{ pointerEvents: 'none' }"
>…</button>
</span>
</TooltipTrigger>
<TooltipContent>…</TooltipContent>
</TooltipRoot>
</template>
约束内容大小
您可能希望约束内容的宽度以使其与触发器宽度匹配。您可能还想约束其高度以不超过视口。
我们公开了几个 CSS 自定义属性,例如 --radix-tooltip-trigger-width
和 --radix-tooltip-content-available-height
来支持这一点。使用它们来约束内容尺寸。
<!-- index.vue -->
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'radix-vue'
</script>
<template>
<TooltipRoot>
<TooltipTrigger>…</TooltipTrigger>
<TooltipPortal>
<TooltipContent
class="TooltipContent"
:side-offset="5"
>
…
</TooltipContent>
</TooltipPortal>
</TooltipRoot>
</template>
/* styles.css */
.TooltipContent {
width: var(--radix-tooltip-trigger-width);
max-height: var(--radix-tooltip-content-available-height);
}
支持原点的动画
我们公开了 CSS 自定义属性 --radix-tooltip-content-transform-origin
。使用它根据 side
、sideOffset
、align
、alignOffset
和任何碰撞从其计算出的原点对内容进行动画处理。
<!-- index.vue -->
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'radix-vue'
</script>
<template>
<TooltipRoot>
<TooltipTrigger>…</TooltipTrigger>
<TooltipContent class="TooltipContent">
…
</TooltipContent>
</TooltipRoot>
</template>
/* styles.css */
.TooltipContent {
transform-origin: var(--radix-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
属性。它们的值将在运行时更改以反映碰撞。使用它们来创建与碰撞和方向感知的动画。
<!-- index.vue -->
<script setup>
import { TooltipContent, TooltipProvider, TooltipRoot, TooltipTrigger } from 'radix-vue'
</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 | 打开/关闭工具提示,无需延迟。 |
空格 | 如果打开,则关闭工具提示,无需延迟。 |
Enter | 如果打开,则关闭工具提示,无需延迟。 |
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 { TooltipArrow, TooltipContent, TooltipRoot, type TooltipRootEmits, type TooltipRootProps, TooltipTrigger, useForwardPropsEmits } from 'radix-vue'
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>