feat(modal): keyboard-friendly tagging — fandom dialogs, Tab-accept, jump hotkey, cheatsheet
CI / lint (push) Successful in 2s
CI / backend-lint-and-test (push) Successful in 27s
CI / frontend-build (push) Successful in 29s
CI / integration (push) Successful in 3m1s

Operator-requested modal/tagging keyboard improvements:
- A2/A3: fandom dialogs autofocus their autocomplete on open; in the character-
  creation FandomPicker, picking a fandom (keyboard Enter or click) confirms in
  one step. FandomSetDialog stays autofocus-only (its Save can trigger a merge).
- B5: Tab accepts the highlighted autocomplete row (standard convention).
- C9: T or / jumps focus to the tag input from anywhere in the modal.
- C8: ? toggles a keyboard cheatsheet (corner hint advertises it; Esc closes the
  cheatsheet first, then the viewer).

Builds on the same-batch regression fixes (kebab #711, ESC-after-accept #700,
autocomplete scroll-into-view). B6 (keep focus after add) is covered — the input
retains focus after adding a tag, and Esc now works after accepting a suggestion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 23:46:46 -04:00
parent 22dc516dc7
commit 1819caaf5b
4 changed files with 95 additions and 1 deletions
@@ -2,12 +2,17 @@
<v-card>
<v-card-title>Pick a fandom</v-card-title>
<v-card-text>
<!-- A2/A3 (2026-06-07): autofocus so the operator types immediately, and
picking a fandom (keyboard: type arrow Enter, or a click) confirms
in one step selecting IS the decision in this dialog. -->
<v-autocomplete
v-model="selectedId"
:items="store.fandomCache"
:item-title="(f) => f.name"
:item-value="(f) => f.id"
label="Fandom" clearable density="compact"
autofocus
@update:model-value="onSelect"
/>
<v-divider class="my-3" />
<p class="text-caption mb-2">Or create a new fandom:</p>
@@ -50,6 +55,12 @@ function onConfirm() {
const f = store.fandomCache.find(x => x.id === selectedId.value)
if (f) emit('confirm', f)
}
// Picking a fandom (keyboard Enter or click) confirms immediately. Ignore the
// clear action (null) so clearing the field doesn't fire a confirm.
function onSelect(id) {
if (id == null) return
onConfirm()
}
// Create the character with no fandom. Emits null so the caller knows this
// was a deliberate "unassigned", not a cancel.
function onNoFandom() {