From 74b7ceaf4757f0b567517421b0fe8581b0a08b4c Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Mon, 29 Jun 2026 21:06:34 -0400 Subject: [PATCH] fix(tags): return focus to the tag input after reject/un-reject too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accept already re-focused the tag input (so you keep typing without re-clicking); reject (✗) and un-reject (↶) went straight to the store and skipped it. Route them through onDismiss/onUndismiss which emit 'dismissed', and wire that to focusTagInput in TagPanel — same return-to-input behaviour as accept. TagPanel is shared, so this covers both the image modal and the Explore workspace. The field's mobile-focus guard is preserved. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Ttrj5P7upUTueSfoJcxEqa --- .../src/components/modal/SuggestionsPanel.vue | 16 +++++++++++----- frontend/src/components/modal/TagPanel.vue | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/modal/SuggestionsPanel.vue b/frontend/src/components/modal/SuggestionsPanel.vue index e62fc8b..50779d5 100644 --- a/frontend/src/components/modal/SuggestionsPanel.vue +++ b/frontend/src/components/modal/SuggestionsPanel.vue @@ -21,14 +21,14 @@ v-show="store.byCategory[cat] && store.byCategory[cat].length" :label="labelFor(cat)" :items="store.byCategory[cat] || []" @accept="onAccept" @alias="onAlias" @remove-alias="onRemoveAlias" - @dismiss="store.dismiss" @undismiss="store.undismiss" + @dismiss="onDismiss" @undismiss="onUndismiss" /> @@ -57,9 +57,15 @@ const props = defineProps({ // so the same panel refreshes the right surface. See TagPanel. host: { type: Object, default: null }, }) -// 'accepted' lets the parent return focus to the tag input after a suggestion is -// applied (operator-asked 2026-06-08). -const emit = defineEmits(['accepted']) +// 'accepted'/'dismissed' let the parent return focus to the tag input after a +// suggestion is accepted OR rejected, so the operator keeps the keyboard flow on +// the input without re-clicking (operator-asked 2026-06-08, 2026-06-30). +const emit = defineEmits(['accepted', 'dismissed']) + +// Reject (✗) / un-reject (↶): apply the store change, then signal the parent to +// re-focus the tag input — same return-to-input behaviour as accept. +function onDismiss (s) { store.dismiss(s); emit('dismissed') } +function onUndismiss (s) { store.undismiss(s); emit('dismissed') } const store = useSuggestionsStore() const modalStore = useModalStore() const host = props.host || modalStore diff --git a/frontend/src/components/modal/TagPanel.vue b/frontend/src/components/modal/TagPanel.vue index 0e76142..a0619f6 100644 --- a/frontend/src/components/modal/TagPanel.vue +++ b/frontend/src/components/modal/TagPanel.vue @@ -28,6 +28,7 @@ :image-id="host.currentImageId" :host="host" @accepted="focusTagInput" + @dismissed="focusTagInput" />