@fiscozen/tooltip

中文文档
3.1.1发布于 2026/10/23ISCES Module近 30 天下载 2767

Design System Tooltip Component

原始使用文档
文档目录23 节
  1. Features
  2. Installation
  3. Basic Usage
  4. Simple Text Tooltip
  5. Rich Content with Slots
  6. Status-based Tooltips
  7. API Reference
  8. Props
  9. Slots
  10. FzTruncatedLabel
  11. Status Types
  12. Styling & Theming
  13. Status Color Mapping
  14. Accessibility Features
  15. WCAG 2.1 AA Compliance
  16. Interactive Elements & Auto-detection
  17. Keyboard Interactions
  18. Design Review in Storybook
  19. ⚠️ Important Warning
  20. Usage in Storybook
  21. When to Use
  22. Storybook Story
  23. Why Not Use in Production?

@fiscozen/tooltip

A fully accessible, WCAG 2.1 AA compliant tooltip component for Vue 3 applications. Built with enterprise-grade accessibility features, keyboard navigation support, and optimized for screen readers.

Features

  • Auto-detection - Automatically detects interactive components (FzButton, FzLink) to prevent double tab stops
  • Status-based Styling - Visual variants with semantic color coding
  • Flexible Content - Support for both text props and rich slot content
  • WCAG 2.1 AA Compliant - Full accessibility support with ARIA roles and properties
  • Screen Reader Optimized - Proper semantic markup and screen reader announcements
  • Keyboard Navigation - Complete keyboard accessibility with focus management
  • Hover Persistence - WCAG 1.4.13 compliant hover behavior for improved UX

Installation

npm install @fiscozen/tooltip

Basic Usage

Simple Text Tooltip

<script setup>
import { FzTooltip } from '@fiscozen/tooltip'
import { FzButton } from '@fiscozen/button'
</script>

<template>
  <!-- Non-interactive element (wrapper gets tabindex="0") -->
  <FzTooltip text="User profile settings">
    Settings
  </FzTooltip>
  
  <!-- Interactive component - auto-detected (no wrapper tabindex) -->
  <FzTooltip text="Save your changes">
    <FzButton>Save</FzButton>
  </FzTooltip>
  
  <!-- Native HTML element (not auto-detected, wrapper gets tabindex="0") -->
  <FzTooltip text="Submit form">
    <span @click="someAction">Submit</span>
  </FzTooltip>
  
  <!-- Native HTML element with manual override (no wrapper tabindex) -->
  <FzTooltip text="Submit form" :interactive="true">
    <span @click="someAction">Submit</span>
  </FzTooltip>
</template>

Rich Content with Slots

<template>
  <FzTooltip aria-label="Account information">
    <img src="/avatar.jpg" alt="User avatar" class="avatar" />
    
    <template #text>
      <strong>John Doe</strong><br>
      <span>Premium Member</span><br>
      <small>Last active: 2 hours ago</small>
    </template>
  </FzTooltip>
</template>

Status-based Tooltips

<template>
  <div class="dashboard-actions">
    <!-- Error state -->
    <FzTooltip 
      status="error" 
      :with-icon="true"
      text="Action failed: Insufficient permissions"
      aria-label="Delete operation status"
    >
      <button disabled>Delete Item</button>
    </FzTooltip>
    
    <!-- Success state -->
    <FzTooltip 
      status="positive" 
      :with-icon="true"
      text="Backup completed successfully at 14:32"
    >
      <span class="status-badge success">Backup Complete</span>
    </FzTooltip>
    
    <!-- Alert/Warning state -->
    <FzTooltip 
      status="alert" 
      :with-icon="true"
      text="System maintenance scheduled for tonight"
      aria-label="Maintenance warning"
    >
      <strong class="warning-text">Maintenance Notice</strong>
    </FzTooltip>
    
    <!-- Informative state -->
    <FzTooltip 
      status="informative" 
      :with-icon="true"
      text="This feature is currently in beta testing"
    >
      <div class="feature-card">
        <span class="beta-label">BETA</span>
        <p>New Analytics Dashboard</p>
      </div>
    </FzTooltip>
  </div>
</template>

API Reference

Props

PropTypeDefaultDescription
textstringundefinedTooltip content text. Alternative to using the text slot
statusFzTooltipStatus'neutral'Visual status: 'neutral' | 'informative' | 'positive' | 'alert' | 'error'
positionFzFloatingPosition'auto'Tooltip positioning relative to trigger element
withIconbooleanfalseDisplay status-appropriate icon in tooltip content
ariaLabelstringundefinedAccessible label for the trigger element
interactiveboolean | 'auto''auto'Controls keyboard accessibility: undefined/'auto' for auto-detection (FzButton, FzLink), true to force interactive, false to force non-interactive
truncatebooleanfalseShows the content on one line, cut with an ellipsis when it does not fit, and opens the tooltip only while the content is cut. The trigger takes no tab stop and no aria-describedby: the full content is already in the DOM. In a flex layout, flex ancestors need min-w-0 for the content to be cut
externalFocusbooleanfalseWhether focus sits on an element the trigger stands for but does not contain, such as the control a label names. While true, the tooltip behaves as if the trigger had focus: it opens (with truncate, only while the content is cut), stays open when the pointer leaves, and closes on Escape. FzTruncatedLabel sets it for you
_forceOpenForDesignReviewbooleanfalse⚠️ FOR DESIGN REVIEW ONLY - Forces tooltip to remain visible. DO NOT USE IN PRODUCTION

Slots

SlotDescription
defaultTrigger element content (required)
textTooltip content - supports rich HTML content

FzTruncatedLabel

A field label kept on one line, for form components laid side by side. The label is cut with an ellipsis when it is wider than the field and shows in full in a tooltip on hover and while the labelled control has focus. The <label> keeps the full text, so the control keeps it as its accessible name. An uncut label never widens the field. Text styles go on the component: the label, the ellipsis and the asterisk inherit them.

<FzTruncatedLabel
  class="text-base text-grey-500"
  label="Data di versamento dell’imposta sostitutiva"
  labelId="payment-date-label"
  controlId="payment-date"
  required
/>
<input id="payment-date" aria-labelledby="payment-date-label" required />
PropTypeDefaultDescription
labelstring-Text of the label (required)
labelIdstring-id of the <label> element, for the control's aria-labelledby (required)
controlIdstring-id of the control the label names, rendered as the label's for (required)
requiredbooleanfalseAppends a visual asterisk outside the cut. Hidden from assistive technology: mark the control itself as required

Status Types

type FzTooltipStatus = 
  | 'neutral'     // Default dark background
  | 'informative' // Blue semantic info color
  | 'positive'    // Green semantic success color  
  | 'alert'       // Orange semantic warning color
  | 'error'       // Red semantic error color

Styling & Theming

Status Color Mapping

StatusUse CaseBackground ClassIcon
neutralGeneral information, help text!bg-core-blackNone
informativeTips, additional contextbg-semantic-infocircle-info
positiveSuccess states, confirmationsbg-semantic-successcircle-check
alertWarnings, attention neededbg-semantic-warningtriangle-exclamation
errorErrors, validation failuresbg-semantic-errorcircle-exclamation

Accessibility Features

WCAG 2.1 AA Compliance

This component implements comprehensive accessibility features:

  • Keyboard Navigation: Support for Tab, focus, and Escape keys
  • Screen Reader Support: Proper ARIA roles and descriptions
  • Focus Management: Accessible focus indicators and logical tab order
  • Hover Persistence: WCAG 1.4.13 compliant hover behavior
  • High Contrast: Color combinations meeting WCAG AA contrast ratios

Interactive Elements & Auto-detection

The tooltip automatically detects interactive components to prevent double tab stops by directly comparing component types at runtime.

Auto-detected Components:

  • ✅ FzButton - Automatically recognized as interactive
  • ✅ FzIconButton - Automatically recognized as interactive
  • ✅ FzLink - Automatically recognized as interactive

How it works: The auto-detection uses direct component type comparison, which is production-safe and works regardless of build configuration or minification settings. When you wrap an FzButton, FzIconButton, or FzLink in a tooltip, the wrapper automatically omits the tabindex="0" attribute to prevent double tab stops.

Extending auto-detection: To add support for new interactive components:

  1. Import the component in FzTooltip.vue
  2. Add it to the INTERACTIVE_COMPONENTS array
  3. Add it as a peerDependency in package.json

Example:

// In FzTooltip.vue
import { FzNewComponent } from '@fiscozen/newComponent'

const INTERACTIVE_COMPONENTS = [FzButton, FzLink, FzNewComponent] as const;

Not Auto-detected (require manual override if needed):

  • ❌ Native HTML elements: <button>, <a>, <input>, <select>, <textarea>
  • ❌ Custom interactive elements with @click handlers
  • ❌ Other custom components (even if interactive)
<!-- Auto-detection (recommended) - no prop needed -->
<FzTooltip text="Save your changes">
  <FzButton>Save</FzButton>
</FzTooltip>

<!-- Span with @click - not auto-detected, creates double tab stop -->
<FzTooltip text="Submit form">
  <span @click="someAction">Submit</span>
</FzTooltip>

<!-- Manual override - prevents double tab stop -->
<FzTooltip text="Submit form" :interactive="true">
  <span @click="someAction">Submit</span>
</FzTooltip>

<!-- Force non-interactive (e.g., disabled button) -->
<FzTooltip text="Action disabled" :interactive="false">
  <FzButton disabled>Save</FzButton>
</FzTooltip>

The interactive prop:

  • undefined or 'auto' (default): Auto-detects FzButton and FzLink
  • true: Forces interactive behavior (removes wrapper tabindex)
  • false: Forces non-interactive behavior (adds wrapper tabindex="0")

Why it matters: Without proper interactive handling, the tooltip wrapper adds tabindex="0" for keyboard accessibility, creating two consecutive tab stops (wrapper + inner element). Auto-detection or explicit interactive={true} removes the wrapper's tabindex, resulting in clean keyboard navigation with a single tab stop.

Keyboard Interactions

KeyAction
TabFocus wrapper and show tooltip
Shift + TabFocus previous element and hide tooltip
EscapeHide tooltip while maintaining focus

Note: When the wrapped element is interactive (button/link), its native keyboard behavior (Enter/Space activation) continues to work normally.

Note: With externalFocus, focus sits outside the trigger: Escape pressed anywhere hides the tooltip while externalFocus is true.

Design Review in Storybook

For design inspection and review purposes, the tooltip component provides a special _forceOpenForDesignReview prop that keeps tooltips visible regardless of hover or focus state.

⚠️ Important Warning

This prop is intended ONLY for design review in Storybook and should NEVER be used in production code. The underscore prefix indicates this is an internal/development-only feature.

Usage in Storybook

<template>
  <!-- Force tooltip to remain visible for design inspection -->
  <FzTooltip 
    text="Review this tooltip styling" 
    status="informative"
    :withIcon="true"
    _forceOpenForDesignReview
  >
    <FzButton>Inspect Me</FzButton>
  </FzTooltip>
</template>

When to Use

  • Design Review: Inspecting tooltip colors, typography, spacing, and layout
  • Visual QA: Comparing tooltip variants side-by-side
  • Screenshot Documentation: Capturing tooltip states for design systems documentation
  • Accessibility Audit: Reviewing tooltip content and ARIA attributes

Storybook Story

The component includes a dedicated "DesignReview" story in Storybook that demonstrates all tooltip variants with _forceOpenForDesignReview enabled. Use the control panel to toggle the prop on/off and see the effect.

Why Not Use in Production?

  • Bypasses all normal tooltip visibility logic (hover, focus, keyboard)
  • Creates poor user experience with always-visible tooltips
  • Violates WCAG guidelines for dismissible content
  • Intended solely as a development/design tool

版本与发布记录

@fiscozen/tooltip 共发布 28 个版本,首次发布于 2024/05/28;过去 12 个月发布了 16 个版本。

版本发布日期距今
3.1.1latest2026/10/2322 天前
3.1.02026/10/2025 天前
3.0.92026/09/142 个月前
3.0.82026/09/072 个月前
3.0.72026/08/043 个月前
3.0.62026/08/033 个月前

关于 @fiscozen/tooltip 的常见问题

@fiscozen/tooltip 是什么?

Design System Tooltip Component

如何安装 @fiscozen/tooltip?

在项目目录运行 npm install @fiscozen/tooltip,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:vue(^3.4.13)、tailwindcss(^3.4.1)、@fiscozen/icons(^1.0.8)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@fiscozen/tooltip 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/fiscozen__tooltip 是否存在。

@fiscozen/tooltip 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@fiscozen/tooltip 可以商用吗?

@fiscozen/tooltip 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@fiscozen/tooltip 的下载量有多少?

根据 npm 官方下载统计,@fiscozen/tooltip 在 2026/10/15 – 2026/11/13 这 30 天内被下载 2,767 次,日均约 92 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@fiscozen/tooltip 还在维护吗?

最新版本 3.1.1 发布于 2026/10/23(22 天前);至今共发布 28 个版本,其中过去 12 个月发布了 16 个;首次发布于 2024/05/28。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。