Skip to content

fix(tab-bar): animate tab close to prevent layout flicker - #177

Closed
yanzhaohui1999 wants to merge 1 commit into
omdsh-dev:mainfrom
yanzhaohui1999:fix/tab-close-flicker
Closed

fix(tab-bar): animate tab close to prevent layout flicker#177
yanzhaohui1999 wants to merge 1 commit into
omdsh-dev:mainfrom
yanzhaohui1999:fix/tab-close-flicker

Conversation

@yanzhaohui1999

Copy link
Copy Markdown
Contributor

Summary / 概述

当两个 pane 并列时,关闭一个 tab 会导致另一个 pane 闪烁。这是因为 tab 被立即从 DOM 移除,导致浏览器瞬间重排布局。

本 PR 添加了两阶段关闭动画:tab 先淡出+收缩(120ms CSS 过渡),然后再从 DOM 移除,让浏览器有时间平滑地重新分配空间。

Changes / 变更

src/client/TabBar.tsx:

  • 新增 closingTabs 状态追踪正在关闭的 tab
  • 新增 handleClose 两阶段关闭函数:先添加动画类,120ms 后再调用实际的 onClose
  • 关闭按钮和中键关闭都走 handleClose 路径
  • 组件卸载时清理所有定时器

src/client/sidebar.module.css:

  • .tab 新增 transition 属性(opacity/min-width/max-width,120ms)
  • 新增 .tabClosing 类:opacity → 0, min-width/max-width → 0, 隐藏溢出,禁用交互
  • Reduced motion 媒体查询中加入 .tabClosing

Root cause / 根因

Tab 被关闭时,onClose 直接更新 React state,tab 立即从数组中移除。Flex 布局在下一帧重算,相邻 pane 的宽度瞬间变化,导致视觉闪烁。

Fix / 修复

两阶段关闭:

  1. 点击关闭 → tab 添加 .tabClosing 类 → 开始 120ms 过渡动画(淡出+收缩)
  2. 动画结束后 → 调用 onClose → tab 从 state 移除 → 布局平滑重排

Testing / 验证

  • pnpm typecheck 通过
  • pnpm build 通过
  • 全套测试通过(2 个 pty 环境性失败与本次改动无关)
  • 所有 tab 相关测试通过:state (68) + service (68) + builtins (18) + side-card-section (7) + orphaned-tab (3) + tab-bar-wheel (7) = 171 tests

When two panes are side-by-side, closing a tab caused the other pane
to flicker due to an instant layout reflow. This adds a two-phase
close: the tab fades out and shrinks (120ms CSS transition) before
being removed from the DOM, giving the browser time to smoothly
rebalance the layout.

Changes:
- TabBar: two-phase close — animate out first, then remove from state
- CSS: .tabClosing class with opacity/width/min-width/max-width transitions
- Reduced motion: respect prefers-reduced-motion for closing animation
@yanzhaohui1999

Copy link
Copy Markdown
Contributor Author

Closing to test locally first — will reopen after manual verification.

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.

1 participant