- Modified docker-compose.dev.yml to conditionally run npm install based on the presence of package-lock.json. - Upgraded Nuxt version in package-lock.json from 3.21.1 to 4.3.1 for enhanced features. - Enhanced ConfirmModal component with aria-modal attribute for better accessibility. - Updated MapErrorBoundary component's error message for clarity. - Added role and aria-label attributes to MapView and MapSearch components for improved screen reader support. - Refactored various components to manage focus behavior on modal close, enhancing user experience. - Improved ToastContainer styling for better responsiveness and visibility. - Updated layout components to include skip navigation links for improved accessibility.
81 lines
2.5 KiB
Vue
81 lines
2.5 KiB
Vue
<template>
|
|
<dialog
|
|
ref="modalRef"
|
|
class="modal"
|
|
aria-modal="true"
|
|
aria-labelledby="coord-set-modal-title"
|
|
@cancel="$emit('close')"
|
|
@close="onDialogClose"
|
|
>
|
|
<div class="modal-box transition-all duration-200" @click.stop>
|
|
<h3 id="coord-set-modal-title" class="font-bold text-lg">Rewrite tile coords</h3>
|
|
<p class="py-2">From ({{ coordSetFrom.x }}, {{ coordSetFrom.y }}) to:</p>
|
|
<div class="flex gap-2">
|
|
<input ref="firstInputRef" v-model.number="localTo.x" type="number" class="input flex-1" placeholder="X" />
|
|
<input v-model.number="localTo.y" type="number" class="input flex-1" placeholder="Y" />
|
|
</div>
|
|
<div class="modal-action">
|
|
<form method="dialog" @submit.prevent="onSubmit">
|
|
<button type="submit" class="btn btn-primary">Submit</button>
|
|
<button type="button" class="btn" @click="$emit('close')">Cancel</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="modal-backdrop cursor-pointer" aria-label="Close" @click="$emit('close')" />
|
|
</dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
const props = defineProps<{
|
|
coordSetFrom: { x: number; y: number }
|
|
coordSet: { x: number; y: number }
|
|
open: boolean
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
close: []
|
|
submit: [from: { x: number; y: number }, to: { x: number; y: number }]
|
|
}>()
|
|
|
|
const modalRef = ref<HTMLDialogElement | null>(null)
|
|
const firstInputRef = ref<HTMLInputElement | null>(null)
|
|
const localTo = ref({ x: props.coordSet.x, y: props.coordSet.y })
|
|
let previousActiveElement: HTMLElement | null = null
|
|
|
|
watch(
|
|
() => props.open,
|
|
(open) => {
|
|
if (open) {
|
|
previousActiveElement = (import.meta.client ? document.activeElement : null) as HTMLElement | null
|
|
localTo.value = { x: props.coordSet.x, y: props.coordSet.y }
|
|
nextTick(() => {
|
|
modalRef.value?.showModal()
|
|
firstInputRef.value?.focus()
|
|
})
|
|
} else {
|
|
modalRef.value?.close()
|
|
}
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
function onDialogClose() {
|
|
if (import.meta.client && previousActiveElement && typeof previousActiveElement.focus === 'function' && document.contains(previousActiveElement)) {
|
|
nextTick(() => previousActiveElement?.focus())
|
|
}
|
|
}
|
|
|
|
watch(
|
|
() => props.coordSet,
|
|
(c) => {
|
|
localTo.value = { x: c.x, y: c.y }
|
|
},
|
|
{ deep: true }
|
|
)
|
|
|
|
function onSubmit() {
|
|
emit('submit', props.coordSetFrom, localTo.value)
|
|
emit('close')
|
|
}
|
|
</script>
|