悬停中的 Toast 栈清空后恢复自动消失(WEB-1537)
版本: 0.10.0 · 类型: 🐛 Bug 修复
问题
鼠标停在 Toast 堆上时,自动消失计时会暂停。如果此时关闭最后一条可见 Toast,之后新出现的有限时长 Toast 可能一直停留在页面上,并继续使用悬停展开态布局,直到页面刷新。
根因
计时暂停保存在全局 toastManager.paused 状态中,但恢复完全依赖 Toaster 宿主的 mouseleave 事件。关闭最后一条可见 Toast 后,宿主 <ol> 会从 DOM 卸载;浏览器不会为已经移除的节点补发 mouseleave,因此 manager 一直保持暂停,后续 Toast 只登记定时器而不会启动。
堆叠展开态还单独保存在 Toaster 内,虽然它与暂停态由同一组 mouseenter / mouseleave 事件驱动,但两份状态会一起残留。
改动文件
packages/design/src/components/Toast/toast-manager.tspackages/design/src/components/Toast/Toaster.tsxpackages/design/src/components/Toast/__tests__/Toast.autoDismiss.test.tsx
改动内容
- 暴露
toastManager.isPaused(),并在pauseAll()/resumeAll()改变暂停态后通知订阅方。 dismiss()将 Toast 标记为不可见后,若已无可见记录则立即调用resumeAll()。该操作早于退场动画记录的真正移除,因此动画窗口内创建的新 Toast 也会正常启动计时。- 删除
Toaster本地的expandedstate,改为通过useSyncExternalStore读取 manager 的暂停快照,让计时暂停与堆叠布局共享单一事实源。 - 新增 5 条回归测试,覆盖普通自动消失、悬停暂停/恢复、悬停中关闭最后一条、退场动画期间创建下一条,以及恢复折叠堆叠布局。
影响范围
悬停期间清空 Toast 栈后,新 Toast 会按配置时长正常自动消失。既有的悬停暂停、移开后续跑计时行为保持不变。本次没有公开 API 或视觉规范变化。