Comfy-Org / Comfy-Org/ComfyUI_frontend
Workflow tab close (✕) button is unreachable on touch devices — can't close tabs without wiping local storage
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 699
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 490
Description
### Summary
On touch devices (phones/tablets), the **close (✕) button on workflow tabs is unreachable**, so it is effectively impossible to close most open workflow tabs. The only practical recourse on mobile is clearing browser local storage, which deletes *all* saved/open workflows — far more destructive than the user intends.
### What happens
The tab close button is `visibility: hidden` by default and is revealed **only on hover** (or when the tab is the active/checked one). Touch devices have no hover state, so:
| Tab state on touch | What the user sees | Closable? |
|---|---|---|
| Non-active, saved | nothing — ✕ is hidden | ❌ |
| Non-active, dirty | only the `•` dirty indicator (✕ hidden) | ❌ |
| Active, dirty | the `•` indicator sits **on top of** the ✕ (`z-10`, opaque background) and intercepts the tap | ❌ |
| Active, saved | ✕ visible | ✅ |
So as more tabs accumulate, the user is stuck: tapping a tab just activates it, the `•`/empty space where the ✕ should be can't close it, and the dirty dot physically covers the ✕ even on the active tab.
A long-press context menu (`Close tab` / `Close tabs to right` / `Close other tabs`) does exist, but it is undiscoverable on mobile and long-press commonly triggers text selection or the browser's own context menu instead.
### Steps to reproduce
1. On a touch device (or desktop Chrome DevTools device emulation / `@media (hover: none)`), open several workflows so multiple tabs are present.
2. Try to close any **non-active** tab — there is no visible ✕.
3. If a workflow is dirty, the `•` indicator appears where the ✕ would be and cannot close the tab; on the active dirty tab the `•` overlays and blocks the ✕.
### Root cause
Two cooperating pieces, both hover-dependent:
**`src/components/topbar/WorkflowTabs.vue`** — close button revealed only on `:hover` / checked:
```css
:deep(.p-togglebutton-checked) .close-button,
:deep(.p-togglebutton:hover) .close-button {
visibility: visible;
}
```
**`src/components/topbar/WorkflowTab.vue`** — the status/dirty indicator is stacked over the close button and hidden only via `group-hover`:
```html
```
On `@media (hover: none)` pointers, neither `:hover` nor `group-hover:hidden` ever fires, so the ✕ stays hidden (and the dot stays on top of it).
### Proposed fix
Gate on pointer capability: on hover-incapable devices, always show the close button and stop the indicator from overlaying it. Something like:
```css
/* WorkflowTabs.vue */
@media (hover: none) {
:deep(.close-button) { visibility: visible; }
}
```
plus a `[@media(hover:none)]:hidden` (or a side-by-side layout) on the indicator span in `WorkflowTab.vue` so `•`/status no longer covers the ✕. Desktop hover behavior is unchanged; only touch devices gain an always-visible close affordance. Happy to open a PR for this.
### Environment
- ComfyUI Frontend Version: 1.44.19 (verified present on `main` as of this writing)
- Browser: any mobile browser / any browser reporting `@media (hover: none)`
Contributor guide
Research direction
Start in src/components/topbar/WorkflowTabs.vue and src/components/topbar/WorkflowTab.vue, reviewing the close-button visibility and unsaved-indicator stacking rules. Reproduce with Chrome DevTools device emulation or @media (hover: none), then verify that saved and dirty tabs can be closed on touch devices while desktop hover behavior remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100