diff --git a/frontend/src/components/modal/SuggestionsPanel.vue b/frontend/src/components/modal/SuggestionsPanel.vue index e56d7a5..8b61677 100644 --- a/frontend/src/components/modal/SuggestionsPanel.vue +++ b/frontend/src/components/modal/SuggestionsPanel.vue @@ -46,6 +46,9 @@ import SuggestionsCategoryGroup from './SuggestionsCategoryGroup.vue' import AliasPickerDialog from './AliasPickerDialog.vue' const props = defineProps({ imageId: { type: Number, required: true } }) +// 'accepted' lets the parent return focus to the tag input after a suggestion is +// applied (operator-asked 2026-06-08). +const emit = defineEmits(['accepted']) const store = useSuggestionsStore() const modal = useModalStore() @@ -72,6 +75,7 @@ async function onAccept(s) { try { await store.accept(s) await modal.reloadTags() + emit('accepted') } catch (e) { toast({ text: `Accept failed: ${e.message}`, type: 'error' }) } @@ -85,6 +89,7 @@ async function onAliasConfirm(canonicalTagId) { await store.aliasAccept(aliasTarget.value, canonicalTagId) aliasDialog.value = false await modal.reloadTags() + emit('accepted') } catch (e) { toast({ text: `Alias failed: ${e.message}`, type: 'error' }) } diff --git a/frontend/src/components/modal/TagAutocomplete.vue b/frontend/src/components/modal/TagAutocomplete.vue index 7200f09..87c1a20 100644 --- a/frontend/src/components/modal/TagAutocomplete.vue +++ b/frontend/src/components/modal/TagAutocomplete.vue @@ -123,6 +123,10 @@ function focusInput () { nextTick(() => inputRef.value?.focus?.()) } onMounted(focusInput) +// Exposed so the parent (TagPanel) can hand focus back to this field after an +// auto-suggestion is accepted, keeping the keyboard flow on the input instead +// of dropping to (operator-asked 2026-06-08). Mobile guard preserved. +defineExpose({ focus: focusInput }) // Single text input; no kind dropdown. Client-side mirror of the // backend's parse_kind_prefix lives below — kept in sync with diff --git a/frontend/src/components/modal/TagPanel.vue b/frontend/src/components/modal/TagPanel.vue index dfd00c2..64aafa3 100644 --- a/frontend/src/components/modal/TagPanel.vue +++ b/frontend/src/components/modal/TagPanel.vue @@ -13,6 +13,7 @@ @@ -24,6 +25,7 @@ @@ -60,6 +62,12 @@ import FandomSetDialog from './FandomSetDialog.vue' const modal = useModalStore() const suggestions = useSuggestionsStore() const errorMsg = ref(null) +const tagInputRef = ref(null) + +// Return focus to the tag input after a suggestion is accepted (from the +// Suggestions panel or the autocomplete dropdown) so the operator can keep +// typing the next tag without re-clicking the field (operator-asked 2026-06-08). +function focusTagInput() { tagInputRef.value?.focus?.() } async function onRemove(tagId) { errorMsg.value = null @@ -84,6 +92,7 @@ async function onAcceptSuggestion(s) { try { await suggestions.accept(s) await modal.reloadTags() + focusTagInput() } catch (e) { errorMsg.value = e.message } }