Workaround for firefox radio button tab bug

https://bugzilla.mozilla.org/show_bug.cgi?id=1413213
This commit is contained in:
James Lyne 2022-06-27 23:19:43 +01:00
parent e143471fa8
commit edbdb712d5
7 changed files with 26 additions and 7 deletions

View File

@ -18,7 +18,7 @@
<input ref="searchInput" v-if="search && unfilteredTotal" id="markers__search" class="section__search" type="text" <input ref="searchInput" v-if="search && unfilteredTotal" id="markers__search" class="section__search" type="text"
name="search" :value="searchQuery" :placeholder="messageMarkersSearchPlaceholder" name="search" :value="searchQuery" :placeholder="messageMarkersSearchPlaceholder"
@keydown="e => e.stopImmediatePropagation()" @input="onSearchInput"> @keydown="e => e.stopImmediatePropagation()" @input="onSearchInput">
<RadioList v-if="markers.size" v-bind="$attrs" @keydown="onListKeydown"> <RadioList v-if="markers.size" name="marker" v-bind="$attrs" @keydown="onListKeydown">
<MarkerListItem v-for="[id, marker] in markers" :key="id" :marker="marker" :id="id"></MarkerListItem> <MarkerListItem v-for="[id, marker] in markers" :key="id" :marker="marker" :id="id"></MarkerListItem>
<button type="button" ref="showMoreButton" v-if="viewLimit < total" @click.prevent="showMore">{{ messageShowMore }}</button> <button type="button" ref="showMoreButton" v-if="viewLimit < total" @click.prevent="showMore">{{ messageShowMore }}</button>
</RadioList> </RadioList>

View File

@ -15,7 +15,7 @@
--> -->
<template> <template>
<RadioList ref="list" v-if="!currentSet" :aria-labelledby="ariaLabelledby"> <RadioList ref="list" v-if="!currentSet" name="marker-set" :aria-labelledby="ariaLabelledby">
<template v-for="[id, markerSet] in markerSets" :key="id"> <template v-for="[id, markerSet] in markerSets" :key="id">
<input :id="`marker-set-${id}`" type="radio" name="marker-set" v-model="currentSet" v-bind:value="markerSet"> <input :id="`marker-set-${id}`" type="radio" name="marker-set" v-model="currentSet" v-bind:value="markerSet">
<label :for="`marker-set-${id}`"> <label :for="`marker-set-${id}`">

View File

@ -17,7 +17,7 @@
<template> <template>
<input ref="searchInput" v-if="filteredPlayers && search" class="section__search" type="text" name="search" <input ref="searchInput" v-if="filteredPlayers && search" class="section__search" type="text" name="search"
v-model="searchQuery" :placeholder="messagePlayersSearchPlaceholder" @keydown="onKeydown"> v-model="searchQuery" :placeholder="messagePlayersSearchPlaceholder" @keydown="onKeydown">
<RadioList v-if="filteredPlayers.length" :aria-labelledby="ariaLabelledby"> <RadioList v-if="filteredPlayers.length" name="player" :aria-labelledby="ariaLabelledby">
<PlayerListItem v-for="player in filteredPlayers" :key="player.name" :player="player"></PlayerListItem> <PlayerListItem v-for="player in filteredPlayers" :key="player.name" :player="player"></PlayerListItem>
</RadioList> </RadioList>
<div v-else-if="searchQuery" class="section__skeleton">{{ messageSkeletonPlayersSearch }}</div> <div v-else-if="searchQuery" class="section__skeleton">{{ messageSkeletonPlayersSearch }}</div>

View File

@ -15,7 +15,7 @@
--> -->
<template> <template>
<RadioList aria-labelledby="servers-heading"> <RadioList name="server" aria-labelledby="servers-heading">
<ServerListItem :server="server" v-for="[name, server] in servers" :key="name"></ServerListItem> <ServerListItem :server="server" v-for="[name, server] in servers" :key="name"></ServerListItem>
</RadioList> </RadioList>
</template> </template>

View File

@ -15,7 +15,7 @@
--> -->
<template> <template>
<RadioList v-if="worlds.size" aria-labelledby="maps-heading"> <RadioList v-if="worlds.size" name="map" aria-labelledby="maps-heading">
<WorldListItem :world="world" v-for="[name, world] in worlds" :key="`${prefix}_${currentServer}_${name}`"></WorldListItem> <WorldListItem :world="world" v-for="[name, world] in worlds" :key="`${prefix}_${currentServer}_${name}`"></WorldListItem>
</RadioList> </RadioList>
</template> </template>

View File

@ -15,6 +15,8 @@
--> -->
<template> <template>
<fieldset class="menu" role="radiogroup" @keydown="onKeydown"> <fieldset class="menu" role="radiogroup" @keydown="onKeydown">
<!-- Always have a checked item to fix https://bugzilla.mozilla.org/show_bug.cgi?id=1413213 -->
<input type="radio" :name="name" checked data-ignore @focus="moveFocus">
<slot></slot> <slot></slot>
</fieldset> </fieldset>
</template> </template>
@ -26,13 +28,25 @@ import {handleKeyboardEvent} from "@/util/events";
export default defineComponent({ export default defineComponent({
name: 'RadioList', name: 'RadioList',
props: {
name: {
type: String,
required: true
}
},
setup() { setup() {
const onKeydown = (e: KeyboardEvent) => { const onKeydown = (e: KeyboardEvent) => {
handleKeyboardEvent(e, Array.from((e.currentTarget as HTMLFieldSetElement).elements) as HTMLElement[]) handleKeyboardEvent(e, Array.from((e.currentTarget as HTMLFieldSetElement).elements) as HTMLElement[])
} };
const moveFocus = (e: FocusEvent) => {
((e.target as HTMLElement).nextElementSibling as HTMLElement).focus();
};
return { return {
onKeydown onKeydown,
moveFocus
} }
}, },
}); });

View File

@ -76,6 +76,11 @@ export const handleKeyboardEvent = (e: KeyboardEvent, elements: HTMLElement[]) =
newPosition = 0; newPosition = 0;
} }
// Skip over firefox bugfix radio button in RadioList
if(typeof elements[newPosition].dataset.ignore !== 'undefined') {
newPosition = e.key == 'ArrowUp' || e.key == 'ArrowLeft' ? elements.length - 1 : newPosition + 1;
}
(elements[newPosition] as HTMLElement).focus(); (elements[newPosition] as HTMLElement).focus();
e.preventDefault(); e.preventDefault();
} else if(e.key === 'Enter' && e.target) { } else if(e.key === 'Enter' && e.target) {