跳转到内容

Tooltip 文字提示 ​

悬停或聚焦时出现的一句纯文字说明。

用法 ​

悬停或聚焦触发器即显示;指针停在提示上也不收起

组件结构 ​

加粗的是必需部件。

data-scope="tooltip":trigger · positioner · content · arrow

示例 ​

朝向 ​

placement 是请求值,空间不足时由定位引擎避让;箭头跟随最终落定的一面

延时 ​

openDelay 默认 700ms 用于防误触,closeDelay 默认 300ms 留出指针移动的余地;聚焦不经这两段等待

禁用 ​

disabled 只关闭提示本身,被包裹的触发器照常可点击、可聚焦

已点 0 次

颜色 ​

六种语气更换浮层实心底与其上的文字色,箭头一并随之变化;把指针停在触发器上(或用 Tab 聚焦)查看差别

尺寸 ​

三档改变浮层的内边距与字号,不写 size 即默认档;把指针停在触发器上(或用 Tab 聚焦)查看差别

受控 ​

传入 open 后由宿主决定;悬停、聚焦、Escape 都只发意图,最终是否写回由外部的这份状态决定

最近意图:(还没动过)

长文案 ​

提示到达宽度上限后换行,不会拉成一条横线;上限是 content 上的 --xh-tooltip-max-w 槽位

设计指引 ​

何时使用 ​

  • 补充说明图标按钮的含义,或截断文字的全文。
  • 内容是纯文字,且没有任何可交互元素。

何时不用 ​

  • 内容中有按钮或链接时,使用气泡卡片,提示无法交互。
  • 信息重要到不能错过时,写在界面上,不放进悬停。
  • 触摸设备是主要场景时,没有悬停。

特性 ​

  • openDelay / closeDelay 防止指针经过时连续闪烁。
  • 聚焦也能触发,键盘用户可以访问。
  • 语气与尺寸两轴。
  • 默认保持反白的小型 M2 表面(compact 档 frosted),与承载操作的 Popover 分开;六种语气都使用高遮蔽 tint 与不透明文字,箭头和气泡同色同边。边界由 on 色 20% 的拼色描边承担(frosted 的透明深边压在反白底上看不见),不画顶部高光;圆角取 4px 控件档。
  • 进退场只做侧向短移与透明度,不缩放文字和箭头:入场 --xh-motion-duration-enter(200ms),退场 --xh-motion-duration-exit(120ms),与其他锚定列表浮层同一节奏。

组合 ​

最佳实践 ​

  • 一句话说完,超过一行应换其他形式。
  • 必须显示较长的单句时让它在最大宽度内换行;连续长词也会断行,不会把浮层撑出窄屏。
  • 图标按钮的可访问名称写在按钮上(aria-label),提示只是视觉补充。

当前边界 ​

  • 当前尚无 TooltipProvider,多个目标间的统一 delay、skip-delay、同组互斥与触发器滚动关闭仍是后续独立行为功能;本次不以样式模拟这些时序。
  • 共享浮层位移原语当前最小档是 4px;Tooltip 先与 Menu 使用同一 xh-overlay-slide-in/out 定义。规格中的 2px 需要新增公共 motion distance 档后统一接入,不能局部改写现有语义令牌。

反模式 ​

  • 把唯一的操作说明放进提示,触摸用户无法看到。
  • 提示内放链接。

API 参考 ​

产物 ​

层值
自定义元素<xh-tooltip>
Vue 组件XhTooltipArrow XhTooltipContent XhTooltipPositioner XhTooltipRoot XhTooltipTrigger
组合式函数useTooltip
状态机tooltipMachine
皮肤@xihan-ui/styles/tooltip.css

Props ​

属性类型必填说明
openboolean
defaultOpenboolean
placementPlacement请求的浮层朝向,默认 bottom;空间不足时由定位引擎避让。
dirDirection文字方向,默认 ltr。只改写浮层在行内轴上 start 与 end 的落点。
offsetnumber浮层与锚点的间距(px)。
openDelaynumber悬停进入到展开的等待毫秒,默认 700。
closeDelaynumber悬停移出到收起的等待毫秒,默认 300。
disabledboolean只关闭提示本身,不影响被包裹控件的可用性。
toneTone语气:brand / neutral / success / warning / danger / info,决定提示的底色与其上的文字色。
sizeSize尺寸:sm / md / lg,决定内边距与字号档位。
onOpenChange(details: TooltipOpenChangeDetails) => voidopen 变化意图回调;受控时是唯一出口,非受控时随内部转移一并通知。

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
open-changeTooltipOpenChangeDetailsopen 状态变化;detail 为 { open: boolean }

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhTooltipRootdefaultTooltipRootSlotProps

React 适配器 props ​

只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。

React 组件属性类型必填说明
XhTooltipPositionercontainer() => Element | null浮层挂载的容器;未提供时按全局配置,再未提供时挂载到 body。
XhTooltipRootchildrenSlotChildren<TooltipRootSlotProps>

状态 ​

公开状态写入 data-state。

部件取值
trigger'open' | 'closed'
positioner'open' | 'closed'
content'open' | 'closed'

以下名称仅用于内部状态机。

状态:closed · opening · visible · visible.open · visible.closing

事件:POINTER.ENTER · POINTER.LEAVE · POINTER.DOWN · FOCUS · BLUR · ESCAPE · OPEN · CLOSE · after.openDelay · after.closeDelay · CONTROLLED.OPEN · CONTROLLED.CLOSE

判据:isOpenControlled · isDisabled · isFocusOpened

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
openboolean
setOpen(next: boolean) => void
getTriggerProps() => T['button']
getPositionerProps() => T['element']
getContentProps() => T['element']
getArrowProps() => T['element']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Tab / Shift+Tabnot disabled焦点进入 trigger 立即展开、离开立即收起,都不走延时
Escape展开中且本层在层栈栈顶,或 focus in trigger 且等待展开中立即收起,不等 closeDelay;下层浮层不受这一次按键影响

ARIA ​

以下属性由 connect 生成。

部件属性值
triggeraria-describedbycontent 部件的 id | undefined
contentaria-hidden!open || undefined
contentrole'tooltip'
arrowaria-hidden'true'

样式参考 ​

皮肤 ​

@xihan-ui/styles/tooltip.css 使用 [data-scope="tooltip"][data-part="trigger"] 部件选择器,位于 xihan.components 层。覆盖样式使用 xihan.overrides。

forced-colors: active 下另有一套规则:颜色交给系统,边框与状态标记改用系统色关键字。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
triggerdata-disabled''(条件成立时才出现)
triggerdata-state'open' | 'closed'
positionerdata-hidden''(条件成立时才出现)
positionerdata-placement定位引擎算出的实际落位
positionerdata-positioned''(条件成立时才出现)
positionerdata-state'open' | 'closed'
contentdata-sizeprops.size
contentdata-state'open' | 'closed'
contentdata-toneprops.tone
contentdata-xh-ink-surface''
arrowdata-placement定位引擎算出的实际落位

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-tooltip-arrow-sizearrow--xh-_overlay-arrow-sizedefault--xh-overlay-arrow-sizetooltip 的 arrow 部件 --xh-_overlay-arrow-size 覆盖槽。
--xh-tooltip-backdropcontent-webkit-backdrop-filter
backdrop-filter
default--xh-material-frosted-compact-backdroptooltip 的 content 部件 -webkit-backdrop-filter、backdrop-filter 覆盖槽。
--xh-tooltip-bgarrow
content
--xh-ink-surface
background
default
xh-ink-surface
--xh-_tooltip-solidtooltip 的 arrow、content 部件 --xh-ink-surface、background 覆盖槽。
--xh-tooltip-borderarrow
content
borderdefault--xh-_tooltip-bordertooltip 的 arrow、content 部件 border 覆盖槽。
--xh-tooltip-fgcontentcolordefault--xh-_tooltip-ontooltip 的 content 部件 color 覆盖槽。
--xh-tooltip-font-sizecontentfont-sizedefault--xh-_tooltip-font-sizetooltip 的 content 部件 font-size 覆盖槽。
--xh-tooltip-highlightcontentbox-shadowdefaulttransparenttooltip 的 content 部件 box-shadow 覆盖槽。
--xh-tooltip-layerpositionerz-indexdefault--xh-_layertooltip 的 positioner 部件 z-index 覆盖槽。
--xh-tooltip-max-wcontentmax-inline-sizedefault--xh-overlay-max-wtooltip 的 content 部件 max-inline-size 覆盖槽。
--xh-tooltip-pxcontentpadding-inlinedefault--xh-_tooltip-pxtooltip 的 content 部件 padding-inline 覆盖槽。
--xh-tooltip-pycontentpadding-blockdefault--xh-_tooltip-pytooltip 的 content 部件 padding-block 覆盖槽。
--xh-tooltip-radiuscontentborder-radiusdefault--xh-shape-controltooltip 的 content 部件 border-radius 覆盖槽。
--xh-tooltip-shadowcontentbox-shadowdefault--xh-material-frosted-compact-shadowtooltip 的 content 部件 box-shadow 覆盖槽。
--xh-tooltip-trigger-gaptriggergapdefault--xh-control-gap-smtooltip 的 trigger 部件 gap 覆盖槽。

动效 ​

动效角色:出现(锚定列表)(见动效规范)。

共享关键帧 xh-overlay-slide-in · xh-overlay-slide-out 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立。时长与缓动读动效令牌,改令牌即改全局节奏。

皮肤之外还有一段:退场由适配器的退场闸门把关,动画播完才真收起。

系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像。

Released under The MIT License