diff --git a/frontend/src/components/modal/TagPanel.vue b/frontend/src/components/modal/TagPanel.vue index 4f0d335..0e76142 100644 --- a/frontend/src/components/modal/TagPanel.vue +++ b/frontend/src/components/modal/TagPanel.vue @@ -30,7 +30,15 @@ @accepted="focusTagInput" /> - + + store.currentImageId, - (id) => { if (id != null) nextTick(() => tagPanelRef.value?.focusTagInput?.()) }, -) +// Auto-focus the tag input after any action so tagging needs no extra click — +// the whole point of the workspace (operator-asked 2026-06-26). nextTick waits +// for the post-navigation re-render, then rAF lands the focus AFTER paint so a +// neighbour/breadcrumb click that re-renders the grid can't steal it back. +// Reuses TagPanel/TagAutocomplete's focus, which keeps its mobile guard (no +// soft-keyboard pop on touch). +function refocusTag () { + nextTick(() => requestAnimationFrame(() => tagPanelRef.value?.focusTagInput?.())) +} +// Every focused-image change (seed + every walk: neighbour click, breadcrumb, +// Random image). +watch(() => store.currentImageId, (id) => { if (id != null) refocusTag() }) // The route is the source of truth. With an anchor, walk it; without one (the // bare /explore nav entry) seed a RANDOM image so the tab kick-starts a rabbit