Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

背景

Ant Design 中一些弹层类组件会通过 hover 触发展示,例如:

  • Popover
  • Dropdown
  • Tooltip
  • Menu.SubMenu

在实际使用中,如果触发元素和弹层之间存在间距,用户从触发元素移动到弹层内容时,鼠标会短暂离开触发元素区域,导致弹层提前关闭:

Kapture.2026-04-25.at.15.33.48.mp4

这在弹层内容包含可交互元素时尤其明显

目前可以通过 mouseLeaveDelay 缓解:

<Popover mouseLeaveDelay={0.2} />

但 delay 只能延迟关闭,不能判断用户是否真的在移动向弹层。

更理想的行为是:

  • 鼠标从 trigger 移向 popup 时,保持弹层打开;
  • 鼠标移向其他方向时,正常关闭。

这类能力可以参考 Floating UI 的 safePolygon 思路:

safe-polygon.mp4

提案

为部分弹层组件增加 safeHover 属性。

API 设计

interface SafeHoverConfig {
  /**
   * Extra tolerant area around the safe area.
   * @default 0.5
   */
  buffer?: number;
  /**
   * Whether to require pointer movement intent toward popup.
   * @default true
   */
  requireIntent?: boolean;
}

组件 Props:

interface PopoverProps {
  safeHover?: boolean | SafeHoverConfig;
}

interface DropdownProps {
  safeHover?: boolean | SafeHoverConfig;
}

interface TooltipProps {
  safeHover?: boolean | SafeHoverConfig;
}

支持范围

建议第一阶段优先支持:

  • Dropdown
  • Menu.SubMenu

Popover、Tooltip 可以支持,但不是主要场景,因为它通常只展示简单说明,不承载复杂交互内容。

行为说明

safeHover 只在 trigger 包含 hover 时生效。

<Dropdown trigger="hover" safeHover />

以下场景不生效:

<Dropdown trigger="click" safeHover />

如果同时配置了 mouseLeaveDelay,两者可以共存:

可以理解为:

  • safeHover 判断鼠标是否正在移向弹层。
  • mouseLeaveDelay 控制最终关闭延迟。

默认关闭

safeHover: false

原因:

  • 不影响现有用户;
  • 不改变默认交互;
  • 避免已有测试或业务逻辑受到影响。

开发者可以在需要时手动开启。

风险:

  • 多个弹层相邻时可能互相影响,如果多个 trigger 离得很近,安全区域可能影响其他 trigger 的 hover。
  • 运行时性能问题会更明显
You must be logged in to vote

Replies: 2 comments · 1 reply

Comment options

安全三角形是不是可以考虑直接作为组件的默认行为,不用开 api 吧 🤔

You must be logged in to vote
1 reply
@afc163
Comment options

+1

Comment options

很赞的交互设计。

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.