Skip to content

feat(desktop): hover X close button on zone tabs - #69392

Closed
austinpickett wants to merge 1 commit into
mainfrom
feat/pane-tab-hover-close
Closed

feat(desktop): hover X close button on zone tabs#69392
austinpickett wants to merge 1 commit into
mainfrom
feat/pane-tab-hover-close

Conversation

@austinpickett

Copy link
Copy Markdown
Collaborator

What

Adds a hover-to-close X button to PaneTab — the shared tab shell used by the fancy-zones layout, the file-preview rail, and collapsed vertical rails.

Why

Closing a tab required middle-click or ⌘-click — discoverable only by reading the code. A hover X is the standard IDE affordance and makes the feature self-evident.

How

  • The close button slot is always reserved inline (shrink-0 size-4 mr-1.5) when onClose is set on a horizontal tab. The X is opacity-0 by default and opacity-100 on group-hover/tab. Because the slot is always present, the tab width never shifts when the X appears.
  • The dirty dot yields to the X: when both onClose and dirty are present, the X renders (visible on hover) and the dirty dot is suppressed. Without onClose, the dirty dot still renders as before.
  • Vertical tabs skip the Xwriting-mode: vertical-rl makes an inline button awkward. The absolute-positioned dirty dot still works there.
  • onPointerDown on the button is stopped so the tab's drag/activate pointerdown handlers never fire — the X is a leaf close action, not a drag start.

Files

  • apps/desktop/src/components/ui/pane-tab.tsx — the close button + dirty-dot coordination
  • apps/desktop/src/components/ui/pane-tab.test.tsx — tests for the new button (render, click, vertical skip, no-onClose skip)

Verification

cd apps/desktop
npx vitest run src/components/ui/pane-tab.test.tsx   # 10 passed
npx tsc --noEmit                                        # clean
npx eslint src/components/ui/pane-tab.tsx src/components/ui/pane-tab.test.tsx  # clean

Add a hover-to-close X button to PaneTab (the fancy-zones tab shell).
The button slot is always reserved inline (shrink-0) so the tab width
stays stable whether the X is visible or not — no layout shift on hover.
Visible on group-hover/tab, hidden by default via opacity transition.

The dirty dot yields to the X when both are present (closeable + dirty):
the X wins on hover, the dot shows otherwise. Vertical tabs skip the X
(writing-mode:vertical-rl makes an inline button awkward) and keep the
absolute-positioned dirty dot.

Pointerdown on the X is stopped so the tab's drag/activate handlers
never fire — the X is a leaf close action, not a drag start.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/desktop Electron desktop app (apps/desktop/*) labels Jul 22, 2026
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

running on b281134

CI timings

CI timings · View job

Wall time 7m21s vs 8m32s (-13.9%). 3 job(s) slower, 4 faster,

  • Build&Test Docker image / build (amd64, ubuntu-latest, linux/amd64, type=gha,scope=docker-amd64, type=gha,mode=max,scope=do...: -39.0s
  • Build&Test Docker image / build (arm64, ubuntu-24.04-arm, linux/arm64, type=gha,scope=docker-arm64, type=gha,mode=max,scope...: +32.0s
  • OSV scan / Emit review status: +7.0s
  • Detect affected areas: -3.0s
  • Check uv.lock / uv lock --check: +3.0s

@austinpickett
austinpickett force-pushed the feat/pane-tab-hover-close branch from 5b3265b to b281134 Compare July 22, 2026 14:40
@rwxyx518-prog

Copy link
Copy Markdown

Real-world user here: I hit this today on v0.20.0 — the preview rail opens and there's no visible way to close it. I literally had to read the source to find the middle-click/Ctrl-click gestures. A hover X (or any visible close affordance) on preview tabs would save a lot of confusion. This PR would have fixed my exact complaint — hoping it gets merged soon. 🙏

@spfcraze

spfcraze commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

This was generated by AI during triage.

Summary:
The new close button has no focus-visible state: it sits at opacity-0 until group-hover/tab, and since apps/desktop/src/styles.css removes focus outlines globally (outline: none on *:focus-visible), keyboard focus lands on an invisible button.

Problems:

  • The button's className in apps/desktop/src/components/ui/pane-tab.tsx is opacity-0 group-hover/tab:opacity-100 — the only reveal path is pointer hover, with no focus-visible:opacity-100.
  • apps/desktop/src/styles.css:993 sets outline: none for *:focus, *:focus-visible, so there is no native focus ring to fall back on either.
  • The minimize button in the same strip (apps/desktop/src/components/pane-shell/tree/renderer/tree-group.tsx:435) carries focus-visible:opacity-100 — the established pattern for hover-reveal buttons in the desktop app.

Solution:
Add focus-visible:opacity-100 to the button's className, matching the minimize-button pattern.


Checked against b281134 — the tip of feat/pane-tab-hover-close when this was written — and 83a1ca6, main at the same moment.

@angel12

angel12 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Confirmed this exact UX failure on Hermes v0.20.3 for a macOS artifact preview: the visible toolbar offered Copy and Download but no discoverable close action. Because this branch is now unmergeable against main and maintainer_can_modify is false, I opened #89243 as a current-main replacement by cherry-picking b281134 to preserve Austin’s authorship. The follow-up commit also adds the requested focus-visible path and keeps the dirty marker visible until hover/focus. This PR remains the source credited in the replacement body.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants