Skip to content

fix: clear stack hover when hovered notices unmount - #414

Closed
zombieJ wants to merge 2 commits into
masterfrom
codex/notification-hover-unmount
Closed

zombieJ wants to merge 2 commits into
masterfrom
codex/notification-hover-unmount

Conversation

@zombieJ

@zombieJ zombieJ commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

问题与修复

移除正在悬停的通知时,React 可能不会触发 mouseleave,导致列表持续展开且剩余通知无法自动关闭。

由 Notification.tsx 卡片组件自身用 useRef 记录悬停状态,通过 onHover(boolean) 上报,卸载时仅对仍悬停的卡片上报清理,并按 key 避免旧卡片清掉新卡片的悬停状态。保留列表原有的移入、移出处理,维持卡片间隙的悬停行为。

这是 #413 的另一种修复方案:通过卡片卸载清理状态,无需文档级 mousemove 监听。若移除后鼠标落在另一张卡片上,暂停状态依赖该卡片的后续 mouseenter。

Fixes ant-design/ant-design#59412

验证

  • 全量单测:58 个通过,包含 6 个新增回归用例。
  • TypeScript 检查通过。
  • 改动文件 ESLint 检查通过。
  • 未进行真实浏览器交互验证。

Summary by CodeRabbit

  • Bug Fixes
    • 修复堆叠通知的悬停状态处理。悬停中的通知移除后,剩余通知的计时会正确恢复;移除无关通知或在列表内移动鼠标时,当前悬停状态会保持。
    • 鼠标离开整个通知列表后,悬停状态会正确清除,避免影响后续通知的显示与计时。

@vercel

vercel Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
notification Ready Ready Preview Sep 28, 2026 10:42am UTC

@coderabbitai

coderabbitai Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 7d4f0d43-b19e-452d-b031-580adb0cb876

📥 Commits

Reviewing files that changed from the base of the PR and between 18bc46c and 45640f2.

📒 Files selected for processing (2)
  • src/Notification.tsx
  • src/NotificationList/index.tsx

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 0 remain after this review.


Walkthrough

通知项现在会向列表报告悬停状态。列表按当前悬停项的 key 处理退出和卸载事件,并在列表离开时清除悬停跟踪。新增测试覆盖悬停状态和通知自动关闭计时行为。

Changes

堆叠通知悬停状态

Layer / File(s) Summary
悬停状态协调与回归验证
src/Notification.tsx, src/NotificationList/index.tsx, tests/stack-hover.test.tsx
通知项通过新增的 onHover 回调报告悬停状态。列表仅在退出项与当前记录项匹配时清除悬停状态;列表离开时清除当前 key。测试覆盖通知卸载、鼠标移至列表间隙、悬停项切换及剩余展示时长。

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: qdyanbing

Merge Risk: ⚪ Minimal · up to 45640

Removing a hovered notice clears its list hover state and resumes the remaining notices’ timers; the reviewed changes show no unresolved merge-blocking risk.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 45640

The change is confined to notification hover and dismissal behavior; no security-sensitive access path was identified. Tests cover the principal removal and hover-transfer cases, but animated exits and replacement of a notice with the same key remain unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The evidenced effect is confined to stacked notification expansion and whether remaining notices stay paused or resume their dismissal timers; no independently attackable service or data-store boundary is shown.

Trust Boundaries and Controls

  • observed — List configuration cannot provide onHover through its declared interface; NotificationListItem supplies the list-owned keyed handler. Direct Notification consumers can supply the newly exposed callback.

Resilience and Maintainability Implications

  • inferred — Key equality protects a newer hover with a different key from stale cleanup. It does not by itself distinguish two component instances bearing the same key; whether such instances can overlap during motion exit is unresolved.

Hardening Proposals

  • proposed — If same-key replacement during an animated exit is supported, verify its cleanup ordering with a motion-enabled regression case; use instance-aware ownership if overlapping instances are possible.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed 直接关联问题 #59412 要求:悬停通知关闭后,剩余通知恢复堆叠收起状态,并继续自动关闭计时。src/Notification.tsx 在通知项卸载且仍处于悬停状态时报告清理;src/NotificationList/index.tsx 按通知项处理悬停状态,并保留列表进入、离开和间隙行为。tests/stack-hover.test.tsx 覆盖悬停项卸载、自动关闭计时恢复、无关项…
Out of Scope Changes check ✅ Passed 变更涉及 src/Notification.tsx、src/NotificationList/index.tsx 和 tests/stack-hover.test.tsx。回调和列表状态变更直接支持 #59412 的悬停清理。新增测试验证修复及其边界行为。未发现与直接关联问题无关的变更。
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了主要变更:当悬停通知卸载时清除堆叠通知的悬停状态。标题简洁、明确,并与变更内容一致。
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

我是小兔,轻点通知边,
悬停状态传到列表间。
旧项离开,不扰新项安,
列表离开,展开终归还。
计时恢复,测试来把关。
胡萝卜旁,蹦跳庆收官。

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

React Doctor found 1 new issue in 1 file · 1 warning · score 70 / 100 (Needs work) · 1 fixed · vs master

1 warning

src/Notification.tsx

  • ⚠️ L74 React function has high control-flow complexity no-high-complexity-react-function

Reviewed by React Doctor for commit 45640f2. See inline comments for fixes.

@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

❌ Deploy failed

PR preview ❌ Failed ❌ Failed
🔗 Preview https://react-component-notification-preview-pr-414.surge.sh (may be unavailable)
📝 Commit45640f2
🪵 LogsView logs
📋 Build log (last lines)
npm error     @eslint-community/eslint-utils@"^4.9.1" from @typescript-eslint/utils@8.70.1
npm error     node_modules/@typescript-eslint/utils
npm error       @typescript-eslint/utils@"8.70.1" from @typescript-eslint/eslint-plugin@8.70.1
npm error       node_modules/@typescript-eslint/eslint-plugin
npm error         peerOptional @typescript-eslint/eslint-plugin@"^8.0.0" from eslint-plugin-jest@29.16.6
npm error         node_modules/eslint-plugin-jest
npm error         1 more (typescript-eslint)
npm error       3 more (@typescript-eslint/type-utils, eslint-plugin-jest, typescript-eslint)
npm error     @eslint-community/eslint-utils@"^4.8.0" from eslint@10.11.0
npm error   10 more (@eslint/compat, @eslint/js, ...)
npm error
npm error Could not resolve dependency:
npm error peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" from eslint-plugin-react@7.37.5
npm error node_modules/eslint-plugin-react
npm error   dev eslint-plugin-react@"^7.37.5" from the root project
npm error
npm error Conflicting peer dependency: eslint@9.39.5
npm error node_modules/eslint
npm error   peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" from eslint-plugin-react@7.37.5
npm error   node_modules/eslint-plugin-react
npm error     dev eslint-plugin-react@"^7.37.5" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /home/runner/.npm/_logs/2026-09-28T10_42_46_791Z-eresolve-report.txt
npm error A complete log of this run can be found in: /home/runner/.npm/_logs/2026-09-28T10_42_46_791Z-debug-0.log

🤖 Powered by surge-preview

@codecov

codecov Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.23%. Comparing base (dd2ba0b) to head (45640f2).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #414      +/-   ##
==========================================
+ Coverage   99.20%   99.23%   +0.03%     
==========================================
  Files          12       12              
  Lines         376      394      +18     
  Branches      102      105       +3     
==========================================
+ Hits          373      391      +18     
  Misses          3        3              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@yoyo837

yoyo837 commented Sep 28, 2026

Copy link
Copy Markdown
Member

有这个的话,#413 #383 都不需要了吧

@QDyanbing

Copy link
Copy Markdown
Contributor

看看这个case算不算问题:打开 5 条通知,悬停展开后关闭倒数第二条,鼠标保持不动。此时下面还有一条通知会补到原来的位置,按理说鼠标仍在通知区域内;这里卸载时直接清掉 listHovering,会不会先触发收起并恢复计时,导致剩余通知自动关闭?是否应该继续保持暂停。

@zombieJ zombieJ closed this Sep 29, 2026
@yoyo837

yoyo837 commented Sep 29, 2026

Copy link
Copy Markdown
Member

咋,不要了吗?

This branch was successfully deployed

1 active deployment
Preview – notification — 45640f24 Deployed Sep 28, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

点击 Notification 关闭按钮后,通知未关闭且保持 hover 展开状态

3 participants