Client - fix keyboard navigation when modal is displayed
This commit is contained in:
parent
651d2204b2
commit
94274a5ea2
@ -16,14 +16,15 @@
|
|||||||
<div class="modal-buttons">
|
<div class="modal-buttons">
|
||||||
<button
|
<button
|
||||||
class="confirm"
|
class="confirm"
|
||||||
|
id="confirm-button"
|
||||||
v-if="!errorMessages"
|
v-if="!errorMessages"
|
||||||
@click="emit('confirmAction')"
|
@click="emit('confirmAction')"
|
||||||
>
|
>
|
||||||
{{ $t('buttons.YES') }}
|
{{ $t('buttons.YES') }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:tabindex="0"
|
tabindex="0"
|
||||||
:id="`${name}-cancel-button`"
|
id="cancel-button"
|
||||||
class="cancel"
|
class="cancel"
|
||||||
@click="emit('cancelAction')"
|
@click="emit('cancelAction')"
|
||||||
>
|
>
|
||||||
@ -37,7 +38,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ComputedRef, computed, toRefs, withDefaults, onUnmounted } from 'vue'
|
import {
|
||||||
|
ComputedRef,
|
||||||
|
computed,
|
||||||
|
onUnmounted,
|
||||||
|
onMounted,
|
||||||
|
toRefs,
|
||||||
|
withDefaults,
|
||||||
|
} from 'vue'
|
||||||
|
|
||||||
import { ROOT_STORE } from '@/store/constants'
|
import { ROOT_STORE } from '@/store/constants'
|
||||||
import { useStore } from '@/use/useStore'
|
import { useStore } from '@/use/useStore'
|
||||||
@ -46,11 +54,9 @@
|
|||||||
title: string
|
title: string
|
||||||
message: string
|
message: string
|
||||||
strongMessage?: string | null
|
strongMessage?: string | null
|
||||||
name?: string | null
|
|
||||||
}
|
}
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
strongMessage: () => null,
|
strongMessage: () => null,
|
||||||
name: 'modal',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['cancelAction', 'confirmAction'])
|
const emit = defineEmits(['cancelAction', 'confirmAction'])
|
||||||
@ -61,7 +67,35 @@
|
|||||||
const errorMessages: ComputedRef<string | string[] | null> = computed(
|
const errorMessages: ComputedRef<string | string[] | null> = computed(
|
||||||
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGES]
|
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGES]
|
||||||
)
|
)
|
||||||
onUnmounted(() => store.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES))
|
let confirmButton: HTMLElement | null = null
|
||||||
|
let cancelButton: HTMLElement | null = null
|
||||||
|
let previousFocusedElement: Element | null = null
|
||||||
|
|
||||||
|
function focusTrap(e: KeyboardEvent) {
|
||||||
|
if (e.key === 'Tab' || e.keyCode === 9) {
|
||||||
|
e.preventDefault()
|
||||||
|
if (document.activeElement?.id === 'cancel-button') {
|
||||||
|
confirmButton?.focus()
|
||||||
|
} else {
|
||||||
|
cancelButton?.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
previousFocusedElement = document.activeElement
|
||||||
|
cancelButton = document.getElementById('cancel-button')
|
||||||
|
confirmButton = document.getElementById('confirm-button')
|
||||||
|
if (cancelButton) {
|
||||||
|
cancelButton.focus()
|
||||||
|
}
|
||||||
|
document.addEventListener('keydown', focusTrap)
|
||||||
|
})
|
||||||
|
onUnmounted(() => {
|
||||||
|
store.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
|
||||||
|
document.removeEventListener('keydown', focusTrap)
|
||||||
|
previousFocusedElement?.focus()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<header id="nav">
|
<header id="nav">
|
||||||
<Modal
|
<Modal
|
||||||
v-show="displayModal"
|
v-if="displayModal"
|
||||||
:title="$t('common.CONFIRMATION')"
|
:title="$t('common.CONFIRMATION')"
|
||||||
:message="$t('user.LOGOUT_CONFIRMATION')"
|
:message="$t('user.LOGOUT_CONFIRMATION')"
|
||||||
@confirmAction="logout"
|
@confirmAction="logout"
|
||||||
@ -138,12 +138,6 @@
|
|||||||
}
|
}
|
||||||
function updateDisplayModal(display: boolean) {
|
function updateDisplayModal(display: boolean) {
|
||||||
displayModal.value = display
|
displayModal.value = display
|
||||||
if (display) {
|
|
||||||
const button = document.getElementById('modal-cancel-button')
|
|
||||||
if (button) {
|
|
||||||
button.focus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
<div id="user-infos" class="description-list">
|
<div id="user-infos" class="description-list">
|
||||||
<Modal
|
<Modal
|
||||||
v-if="displayModal"
|
v-if="displayModal"
|
||||||
name="user"
|
|
||||||
:title="$t('common.CONFIRMATION')"
|
:title="$t('common.CONFIRMATION')"
|
||||||
:message="
|
:message="
|
||||||
displayModal === 'delete'
|
displayModal === 'delete'
|
||||||
@ -192,10 +191,6 @@
|
|||||||
function updateDisplayModal(value: string) {
|
function updateDisplayModal(value: string) {
|
||||||
displayModal.value = value
|
displayModal.value = value
|
||||||
if (value !== '') {
|
if (value !== '') {
|
||||||
const button = document.getElementById('user-cancel-button')
|
|
||||||
if (button) {
|
|
||||||
button.focus()
|
|
||||||
}
|
|
||||||
store.commit(USERS_STORE.MUTATIONS.UPDATE_IS_SUCCESS, false)
|
store.commit(USERS_STORE.MUTATIONS.UPDATE_IS_SUCCESS, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
<div id="user-infos-edition">
|
<div id="user-infos-edition">
|
||||||
<Modal
|
<Modal
|
||||||
v-if="displayModal"
|
v-if="displayModal"
|
||||||
name="account"
|
|
||||||
:title="$t('common.CONFIRMATION')"
|
:title="$t('common.CONFIRMATION')"
|
||||||
:message="$t('user.CONFIRM_ACCOUNT_DELETION')"
|
:message="$t('user.CONFIRM_ACCOUNT_DELETION')"
|
||||||
@confirmAction="deleteAccount(user.username)"
|
@confirmAction="deleteAccount(user.username)"
|
||||||
@ -215,12 +214,6 @@
|
|||||||
}
|
}
|
||||||
function updateDisplayModal(value: boolean) {
|
function updateDisplayModal(value: boolean) {
|
||||||
displayModal.value = value
|
displayModal.value = value
|
||||||
if (displayModal.value) {
|
|
||||||
const button = document.getElementById('account-cancel-button')
|
|
||||||
if (button) {
|
|
||||||
button.focus()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
function deleteAccount(username: string) {
|
function deleteAccount(username: string) {
|
||||||
store.dispatch(AUTH_USER_STORE.ACTIONS.DELETE_ACCOUNT, { username })
|
store.dispatch(AUTH_USER_STORE.ACTIONS.DELETE_ACCOUNT, { username })
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
<div id="oauth2-app" class="description-list">
|
<div id="oauth2-app" class="description-list">
|
||||||
<Modal
|
<Modal
|
||||||
v-if="displayModal"
|
v-if="displayModal"
|
||||||
name="app"
|
|
||||||
:title="$t('common.CONFIRMATION')"
|
:title="$t('common.CONFIRMATION')"
|
||||||
:message="$t(messageToDisplay)"
|
:message="$t(messageToDisplay)"
|
||||||
@confirmAction="confirmAction(client.id)"
|
@confirmAction="confirmAction(client.id)"
|
||||||
@ -180,11 +179,6 @@
|
|||||||
displayModal.value = value
|
displayModal.value = value
|
||||||
if (!value) {
|
if (!value) {
|
||||||
messageToDisplay.value = null
|
messageToDisplay.value = null
|
||||||
} else {
|
|
||||||
const button = document.getElementById('app-cancel-button')
|
|
||||||
if (button) {
|
|
||||||
button.focus()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function confirmAction(clientId: number) {
|
function confirmAction(clientId: number) {
|
||||||
|
@ -45,13 +45,13 @@
|
|||||||
<button
|
<button
|
||||||
id="delete-workout-button"
|
id="delete-workout-button"
|
||||||
class="transparent icon-button"
|
class="transparent icon-button"
|
||||||
@click="displayDeleteModal"
|
@click.prevent="displayDeleteModal"
|
||||||
:aria-label="$t(`workouts.DELETE_WORKOUT`)"
|
:aria-label="$t(`workouts.DELETE_WORKOUT`)"
|
||||||
>
|
>
|
||||||
<i class="fa fa-trash" aria-hidden="true" />
|
<i class="fa fa-trash" aria-hidden="true" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="workout-title" v-else>
|
<div class="workout-title" v-else-if="workoutObject.segmentId">
|
||||||
{{ workoutObject.title }}
|
{{ workoutObject.title }}
|
||||||
<span class="workout-segment">
|
<span class="workout-segment">
|
||||||
—
|
—
|
||||||
@ -69,7 +69,7 @@
|
|||||||
v-if="workoutObject.type === 'SEGMENT'"
|
v-if="workoutObject.type === 'SEGMENT'"
|
||||||
:to="{
|
:to="{
|
||||||
name: 'Workout',
|
name: 'Workout',
|
||||||
params: { workoutId: workoutObject.workoutId }
|
params: { workoutId: workoutObject.workoutId },
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
> {{ $t('workouts.BACK_TO_WORKOUT') }}
|
> {{ $t('workouts.BACK_TO_WORKOUT') }}
|
||||||
@ -129,8 +129,7 @@
|
|||||||
gpxLink.click()
|
gpxLink.click()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function displayDeleteModal(event: Event & { target: HTMLInputElement }) {
|
function displayDeleteModal() {
|
||||||
event.target.blur()
|
|
||||||
emit('displayModal', true)
|
emit('displayModal', true)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
<div class="workout-detail">
|
<div class="workout-detail">
|
||||||
<Modal
|
<Modal
|
||||||
v-if="displayModal"
|
v-if="displayModal"
|
||||||
name="workout"
|
|
||||||
:title="$t('common.CONFIRMATION')"
|
:title="$t('common.CONFIRMATION')"
|
||||||
:message="$t('workouts.WORKOUT_DELETION_CONFIRMATION')"
|
:message="$t('workouts.WORKOUT_DELETION_CONFIRMATION')"
|
||||||
@confirmAction="deleteWorkout(workoutObject.workoutId)"
|
@confirmAction="deleteWorkout(workoutObject.workoutId)"
|
||||||
@ -37,7 +36,6 @@
|
|||||||
ComputedRef,
|
ComputedRef,
|
||||||
Ref,
|
Ref,
|
||||||
computed,
|
computed,
|
||||||
nextTick,
|
|
||||||
ref,
|
ref,
|
||||||
toRefs,
|
toRefs,
|
||||||
watch,
|
watch,
|
||||||
@ -164,21 +162,9 @@
|
|||||||
}
|
}
|
||||||
function updateDisplayModal(value: boolean) {
|
function updateDisplayModal(value: boolean) {
|
||||||
displayModal.value = value
|
displayModal.value = value
|
||||||
if (displayModal.value) {
|
|
||||||
nextTick(() => {
|
|
||||||
const button = document.getElementById('workout-cancel-button')
|
|
||||||
if (button) {
|
|
||||||
button.focus()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
function cancelDelete() {
|
function cancelDelete() {
|
||||||
updateDisplayModal(false)
|
updateDisplayModal(false)
|
||||||
const button = document.getElementById('delete-workout-button')
|
|
||||||
if (button) {
|
|
||||||
button.focus()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
function deleteWorkout(workoutId: string) {
|
function deleteWorkout(workoutId: string) {
|
||||||
updateDisplayModal(false)
|
updateDisplayModal(false)
|
||||||
|
Loading…
Reference in New Issue
Block a user