refactor(ui): unify confirm-dropdown Enter behavior via useAcceptOnEnter
Operator-flagged (again) on the tag-merge picker: Enter on the dropdown re-opens it instead of accepting the selection. I'd already patched this twice (fandom picker + fandom set dialog) with copy-pasted capture-phase handlers, so DRY it. New composable useAcceptOnEnter(accept): tracks the menu state and, on a capture-phase Enter, lets Vuetify pick when the menu is open but calls accept() (and blocks the re-open) when it's closed. Applied to every confirm-style picker: - TagsView merge-into picker (the reported one) - AliasPickerDialog - PostSeriesMenu add-to-existing - FandomPicker + FandomSetDialog (refactored off their bespoke handlers) One behavior, one place to change it.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { ref } from 'vue'
|
||||
|
||||
/**
|
||||
* Unifies keyboard behavior for confirm-style `v-autocomplete` / `v-select`
|
||||
* dropdowns — a single picker whose Enter should trigger the surrounding
|
||||
* modal's primary action (Merge, Add, Save, Use…).
|
||||
*
|
||||
* The recurring bug (operator-flagged across the merge / fandom / series / alias
|
||||
* dialogs): pressing Enter with the menu CLOSED re-opens the dropdown instead of
|
||||
* accepting the chosen value, because Vuetify's own Enter handler opens the menu.
|
||||
* We bind in the CAPTURE phase so this runs BEFORE Vuetify's handler:
|
||||
* - menu OPEN → return; let Vuetify pick the highlighted item (it sets the
|
||||
* value and closes the menu).
|
||||
* - menu CLOSED → preventDefault + stopPropagation so Vuetify can't re-open the
|
||||
* menu, then call `accept()` — the modal's confirm. `accept`
|
||||
* should itself no-op when nothing valid is selected.
|
||||
*
|
||||
* Usage:
|
||||
* const { menuOpen, onEnter } = useAcceptOnEnter(onConfirm)
|
||||
* <v-autocomplete v-model:menu="menuOpen" @keydown.enter.capture="onEnter" … />
|
||||
*
|
||||
* `menuOpen` is exposed so a component that programmatically focuses the field
|
||||
* can force the menu shut (so the very next Enter accepts rather than being
|
||||
* swallowed as a menu interaction).
|
||||
*/
|
||||
export function useAcceptOnEnter(accept) {
|
||||
const menuOpen = ref(false)
|
||||
function onEnter(e) {
|
||||
if (menuOpen.value) return
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
accept()
|
||||
}
|
||||
return { menuOpen, onEnter }
|
||||
}
|
||||
Reference in New Issue
Block a user