fix(tags): Firefox Android — Enter to commit now works

The prior fix (a94a380) handled Chrome Android via the keydown path.
Firefox Android does something different: the soft-keyboard Enter is
intercepted at the input layer as "advance to next form field" — no
keydown fires for us to intercept, so the user's tag was lost and
focus jumped to the next ActivityForm input.

Add an onbeforeinput handler. InputEvent.inputType === 'insertLineBreak'
fires on every modern browser when the user submits via Enter,
even when keydown is suppressed at the IME/keyboard layer.
preventDefault'ing here cancels the focus-advance before it happens.

Idempotent with the existing onKey:
  - Chrome: keydown fires with Enter, our preventDefault cancels the
    line-break, so beforeinput never fires.
  - Firefox Android: no keydown for Enter, beforeinput fires with
    insertLineBreak, we commit there.
  - Android Chrome with IME composition: composing flag short-circuits
    both paths so we don't commit mid-composition.

Comma + button remain as platform-agnostic fallbacks.
This commit is contained in:
Ole-Morten Duesund 2026-05-25 22:22:22 +02:00
commit 4945204b7b

View file

@ -81,6 +81,25 @@
add(input);
}
/**
* beforeinput fires before the browser commits a value change. We use it
* to catch Enter on platforms where keydown doesn't deliver a usable
* Enter event — notably Firefox on Android, which treats the soft-
* keyboard Enter as "advance to next form field" at the input layer
* (no keydown for us to intercept). InputEvent.inputType === 'insertLineBreak'
* still fires here, so we get to preventDefault before focus moves.
* Idempotent with onKey: keydown's preventDefault on Chrome cancels
* the would-be insertion, so beforeinput never fires there.
*/
function onBeforeInput(e: Event) {
const ie = e as InputEvent;
if (composing) return;
if (ie.inputType === 'insertLineBreak') {
e.preventDefault();
add(input);
}
}
function onType(e: Event) {
input = (e.target as HTMLInputElement).value;
clearTimeout(timer);
@ -118,6 +137,7 @@
value={input}
oninput={onType}
onkeydown={onKey}
onbeforeinput={onBeforeInput}
oncompositionstart={() => (composing = true)}
oncompositionend={() => (composing = false)}
placeholder="Skriv etikett, trykk Enter eller «Legg til»"