基础
Tooltip
Tooltip component for displaying contextual information on hover or focus
"use client";
import { Tooltip } from "@/components/composed/tooltip/tooltip";
import { Button } from "@/components/ui/button";
/**
* 基础 Tooltip 示例
*/
export function TooltipBasic() {
return (
<div className="flex items-center gap-4">
<Tooltip content="这是一个提示信息">
<Button variant="outline">悬停查看提示</Button>
</Tooltip>
<Tooltip content="点击按钮执行操作" side="bottom">
<Button>操作按钮</Button>
</Tooltip>
</div>
);
}
Tooltip 组件用于在用户悬停或聚焦元素时显示额外的上下文信息、帮助文本或操作说明,提供简化的 API 便于快速使用。
概述
- 简化的 API:单个组件封装,无需手动组合多个子组件
- 灵活定位:支持四个方向的定位(top, right, bottom, left)
- 响应式宽度:最小宽度 36px,最大宽度 480px,自动适应内容
- 深色背景:使用设计系统变量,确保样式一致性
- 流畅动画:内置淡入淡出和缩放动画
- 完整的可访问性:基于 Radix UI,支持键盘导航和屏幕阅读器
快速开始
import { Tooltip } from "@/registry/wuhan/composed/tooltip";
export function Example() {
return (
<Tooltip content="这是提示信息">
<Button>悬停查看</Button>
</Tooltip>
);
}特性
- 快速集成:单个组件即可完成,无需额外配置
- 自动换行:长文本自动换行,保持良好的可读性
- 灵活定位:支持 4 个方向和 3 种对齐方式
- 自定义样式:支持自定义类名和样式
- 性能优化:延迟加载和按需渲染
- 类型安全:完整的 TypeScript 类型定义
安装
代码演示
基本
基础用法,快速添加提示信息。
"use client";
import { Tooltip } from "@/components/composed/tooltip/tooltip";
import { Button } from "@/components/ui/button";
/**
* 基础 Tooltip 示例
*/
export function TooltipBasic() {
return (
<div className="flex items-center gap-4">
<Tooltip content="这是一个提示信息">
<Button variant="outline">悬停查看提示</Button>
</Tooltip>
<Tooltip content="点击按钮执行操作" side="bottom">
<Button>操作按钮</Button>
</Tooltip>
</div>
);
}
不同位置
不同位置的提示框展示。
"use client";
import { Tooltip } from "@/components/composed/tooltip/tooltip";
import { Button } from "@/components/ui/button";
/**
* 不同位置的 Tooltip 示例
*/
export function TooltipPositions() {
return (
<div className="flex items-center justify-center gap-4 flex-wrap">
<Tooltip content="顶部提示信息" side="top">
<Button variant="outline">顶部</Button>
</Tooltip>
<Tooltip content="右侧提示信息" side="right">
<Button variant="outline">右侧</Button>
</Tooltip>
<Tooltip content="底部提示信息" side="bottom">
<Button variant="outline">底部</Button>
</Tooltip>
<Tooltip content="左侧提示信息" side="left">
<Button variant="outline">左侧</Button>
</Tooltip>
</div>
);
}
配合图标
图标按钮配合 Tooltip 使用。
"use client";
import { Tooltip } from "@/components/composed/tooltip/tooltip";
import { Button } from "@/components/ui/button";
import { Info, HelpCircle, AlertCircle, Settings } from "lucide-react";
/**
* 带图标的 Tooltip 示例
*/
export function TooltipWithIcons() {
return (
<div className="flex items-center gap-4">
<Tooltip content="了解更多信息">
<Button variant="ghost" size="icon">
<Info className="w-4 h-4" />
</Button>
</Tooltip>
<Tooltip content="获取帮助" side="bottom">
<Button variant="ghost" size="icon">
<HelpCircle className="w-4 h-4" />
</Button>
</Tooltip>
<Tooltip content="重要提示" side="right">
<Button variant="ghost" size="icon">
<AlertCircle className="w-4 h-4" />
</Button>
</Tooltip>
<Tooltip content="打开设置" side="left">
<Button variant="ghost" size="icon">
<Settings className="w-4 h-4" />
</Button>
</Tooltip>
</div>
);
}
长文本
长文本自动换行显示。
"use client";
import { Tooltip } from "@/components/composed/tooltip/tooltip";
import { Button } from "@/components/ui/button";
/**
* 长文本 Tooltip 示例
*/
export function TooltipLongText() {
return (
<div className="flex items-center gap-4">
<Tooltip
content="这是一段比较长的提示文本,用于展示 Tooltip 组件如何处理较长的内容。组件会自动换行并保持适当的宽度。"
side="top"
>
<Button variant="outline">查看长文本提示</Button>
</Tooltip>
<Tooltip
content="Tooltip 最大宽度为 480px,超过这个宽度的内容会自动换行显示,确保内容的可读性和美观性。"
side="bottom"
>
<Button variant="outline">底部长文本</Button>
</Tooltip>
</div>
);
}
API
Tooltip
简化的 Tooltip 组件,封装了常用的配置和用法。
Props
| Prop | Type | Default | Description |
|---|---|---|---|
content | React.ReactNode | - | 提示内容(必填) |
children | React.ReactNode | - | 触发器元素(必填) |
side | "top" | "right" | "bottom" | "left" | "top" | 提示框位置 |
sideOffset | number | 4 | 与触发器的距离(像素) |
align | "start" | "center" | "end" | "center" | 对齐方式 |
contentClassName | string | - | 自定义内容容器类名 |
delayDuration | number | 0 | 延迟显示时间(毫秒) |
Example
import { Tooltip } from "@/registry/wuhan/composed/tooltip";
import { Button } from "@/components/ui/button";
import { Info } from "lucide-react";
function Example() {
return (
<div className="space-y-4">
{/* 基础用法 */}
<Tooltip content="这是提示信息">
<Button>悬停查看</Button>
</Tooltip>
{/* 指定位置 */}
<Tooltip content="右侧提示" side="right">
<Button variant="outline">右侧提示</Button>
</Tooltip>
{/* 图标按钮 */}
<Tooltip content="了解更多">
<Button variant="ghost" size="icon">
<Info className="w-4 h-4" />
</Button>
</Tooltip>
{/* 长文本 */}
<Tooltip
content="这是一段较长的提示文本,会自动换行显示"
side="bottom"
>
<Button variant="outline">查看详情</Button>
</Tooltip>
</div>
);
}位置和对齐
Side(位置)
top- 显示在触发器上方(默认)right- 显示在触发器右侧bottom- 显示在触发器下方left- 显示在触发器左侧
Align(对齐)
start- 与触发器起始边对齐center- 与触发器中心对齐(默认)end- 与触发器结束边对齐
使用场景
- 图标按钮说明:为图标按钮提供文字说明
- 表单字段帮助:在表单字段旁显示帮助信息
- 功能介绍:介绍功能按钮或选项的作用
- 状态说明:解释状态标签或指示器的含义
- 操作提示:提示用户可以执行的操作
- 数据展示:在表格或列表中显示完整信息
最佳实践
- 内容简洁:提示内容应简短明了,通常不超过 1-2 句话
- 及时响应:使用默认的 0ms 延迟,确保用户悬停时立即显示
- 位置选择:根据触发器位置和屏幕空间选择合适的方向
- 避免重复:不要在已有文字说明的元素上重复添加 Tooltip
- 键盘友好:确保触发器元素可以通过键盘访问
- 移动端考虑:移动端建议使用其他方式展示提示信息
注意事项
- Tooltip 需要触发器元素支持
asChild模式,建议使用 Button 或其他可交互元素 - 长文本会自动换行,但建议控制在合理长度以保持可读性
- 在移动设备上,Tooltip 可能不够友好,考虑使用替代方案
- 避免在 Tooltip 中放置交互元素,因为内容在失去焦点时会关闭
- 确保提示内容不会遮挡重要信息或操作按钮
原语组件
Tooltip 基于以下原语组件构建:
BlockTooltip- Tooltip 根组件BlockTooltipTrigger- 触发器组件BlockTooltipContent- 内容组件BlockTooltipProvider- 提供者组件
原语组件提供了更底层的控制,可以在 registry/wuhan/blocks/tooltip/tooltip-01.tsx 中找到。
样式定制
组件使用 CSS 变量,可以通过以下方式定制:
// 自定义内容样式
<Tooltip
content="自定义样式"
contentClassName="bg-primary text-primary-foreground"
>
<Button>自定义</Button>
</Tooltip>设计系统变量
- 背景色:
--bg-mask(深色半透明背景) - 文本颜色:
--text-inverse(白色文本) - 字体:
--font-family-cn(中文字体) - 字号:12px
- 行高:
--line-height-1 - 圆角:
--radius-sm(4px) - 内边距:上下
--gap-xs(4px),左右--gap-sm(6px) - 宽度范围:36px - 480px
扩展示例
Toolbar Integration
工具栏中集成多个 Tooltip。
"use client";
import { Tooltip } from "@/components/composed/tooltip/tooltip";
import { Button } from "@/components/ui/button";
import { Copy, Download, Share2, Trash2 } from "lucide-react";
/**
* 工具栏 Tooltip 示例
*/
export function TooltipToolbar() {
return (
<div className="inline-flex items-center gap-1 p-2 border rounded-lg bg-background">
<Tooltip content="复制">
<Button variant="ghost" size="icon">
<Copy className="w-4 h-4" />
</Button>
</Tooltip>
<Tooltip content="下载">
<Button variant="ghost" size="icon">
<Download className="w-4 h-4" />
</Button>
</Tooltip>
<Tooltip content="分享">
<Button variant="ghost" size="icon">
<Share2 className="w-4 h-4" />
</Button>
</Tooltip>
<div className="w-px h-6 bg-border mx-1" />
<Tooltip content="删除" side="bottom">
<Button variant="ghost" size="icon">
<Trash2 className="w-4 h-4 text-destructive" />
</Button>
</Tooltip>
</div>
);
}
Table Usage
在表格中使用 Tooltip 显示额外信息。
| 姓名 | 邮箱 | 状态 |
|---|---|---|
| 张三 | zhangsan@example.com | 激活 |
| 李四 | lisi@example.com | 未激活 |
| 王五 | wangwu@example.com | 激活 |
"use client";
import { Tooltip } from "@/components/composed/tooltip/tooltip";
/**
* 表格中的 Tooltip 示例
*/
export function TooltipTable() {
const data = [
{ id: 1, name: "张三", email: "zhangsan@example.com", status: "active" },
{ id: 2, name: "李四", email: "lisi@example.com", status: "inactive" },
{ id: 3, name: "王五", email: "wangwu@example.com", status: "active" },
];
return (
<div className="rounded-md border">
<table className="w-full text-sm">
<thead>
<tr className="border-b bg-muted/50">
<th className="px-4 py-3 text-left font-medium">姓名</th>
<th className="px-4 py-3 text-left font-medium">邮箱</th>
<th className="px-4 py-3 text-left font-medium">状态</th>
</tr>
</thead>
<tbody>
{data.map((row) => (
<tr key={row.id} className="border-b last:border-0">
<td className="px-4 py-3">
<Tooltip content={`用户 ID: ${row.id}`} side="right">
<span className="cursor-help">{row.name}</span>
</Tooltip>
</td>
<td className="px-4 py-3">
<Tooltip content="点击复制邮箱地址" side="top">
<span className="cursor-help text-muted-foreground">
{row.email}
</span>
</Tooltip>
</td>
<td className="px-4 py-3">
<Tooltip
content={
row.status === "active" ? "用户已激活" : "用户未激活"
}
side="left"
>
<span
className={`inline-flex items-center px-2 py-1 rounded-full text-xs font-medium cursor-help ${
row.status === "active"
? "bg-green-50 text-green-700"
: "bg-gray-50 text-gray-700"
}`}
>
{row.status === "active" ? "激活" : "未激活"}
</span>
</Tooltip>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
Form Help Text
在表单中使用 Tooltip 提供帮助信息。
"use client";
import { Tooltip } from "@/components/composed/tooltip/tooltip";
import { Button } from "@/components/ui/button";
import { Info } from "lucide-react";
/**
* 表单中的 Tooltip 示例
*/
export function TooltipForm() {
return (
<div className="max-w-md space-y-4">
<div className="space-y-2">
<label className="flex items-center gap-2 text-sm font-medium">
用户名
<Tooltip content="用户名必须为 3-20 个字符,只能包含字母、数字和下划线">
<Info className="w-4 h-4 text-muted-foreground cursor-help" />
</Tooltip>
</label>
<input
type="text"
placeholder="请输入用户名"
className="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary"
/>
</div>
<div className="space-y-2">
<label className="flex items-center gap-2 text-sm font-medium">
邮箱地址
<Tooltip content="我们会向此邮箱发送验证码" side="right">
<Info className="w-4 h-4 text-muted-foreground cursor-help" />
</Tooltip>
</label>
<input
type="email"
placeholder="example@email.com"
className="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary"
/>
</div>
<div className="space-y-2">
<label className="flex items-center gap-2 text-sm font-medium">
密码
<Tooltip
content="密码至少 8 位,必须包含大小写字母、数字和特殊字符"
side="bottom"
>
<Info className="w-4 h-4 text-muted-foreground cursor-help" />
</Tooltip>
</label>
<input
type="password"
placeholder="请输入密码"
className="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-primary"
/>
</div>
<Button className="w-full">提交</Button>
</div>
);
}
自定义触发时机
import { Tooltip } from "@/registry/wuhan/composed/tooltip";
function CustomTrigger() {
return (
<Tooltip content="自定义延迟" delayDuration={500}>
<Button>延迟 500ms 显示</Button>
</Tooltip>
);
}富文本内容
import { Tooltip } from "@/registry/wuhan/composed/tooltip";
function RichContent() {
return (
<Tooltip
content={
<div className="space-y-1">
<div className="font-semibold">快捷键</div>
<div className="text-xs">⌘ + K 打开搜索</div>
</div>
}
>
<Button variant="outline">快捷键</Button>
</Tooltip>
);
}条件显示
import { Tooltip } from "@/registry/wuhan/composed/tooltip";
function ConditionalTooltip({ showTooltip }: { showTooltip: boolean }) {
const button = <Button>悬停查看</Button>;
if (!showTooltip) {
return button;
}
return (
<Tooltip content="这是提示信息">
{button}
</Tooltip>
);
}与其他组件结合
import { Tooltip } from "@/registry/wuhan/composed/tooltip";
import { Badge } from "@/components/ui/badge";
function CombinedComponents() {
return (
<div className="flex items-center gap-2">
<span>状态:</span>
<Tooltip content="项目当前处于开发阶段" side="right">
<Badge variant="secondary" className="cursor-help">
开发中
</Badge>
</Tooltip>
</div>
);
}动态内容
import { Tooltip } from "@/registry/wuhan/composed/tooltip";
import { useState } from "react";
function DynamicContent() {
const [count, setCount] = useState(0);
return (
<Tooltip content={`点击次数:${count}`}>
<Button onClick={() => setCount(count + 1)}>
点击我
</Button>
</Tooltip>
);
}多语言支持
import { Tooltip } from "@/registry/wuhan/composed/tooltip";
import { useTranslation } from "react-i18next";
function I18nTooltip() {
const { t } = useTranslation();
return (
<Tooltip content={t("tooltip.help")}>
<Button>{t("button.help")}</Button>
</Tooltip>
);
}