Skip to content

Commit 23ad759

Browse files
committed
use better patterns?
1 parent dff2c03 commit 23ad759

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

app/components/AppFooter.vue

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<script setup lang="ts">
2-
import { ref, onMounted, onBeforeUnmount } from 'vue'
2+
import { ref, watch, nextTick } from 'vue'
3+
import { onClickOutside, onKeyDown } from '@vueuse/core'
4+
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
35
46
const route = useRoute()
57
const isHome = computed(() => route.name === 'index')
@@ -13,25 +15,32 @@ const togglePopover = (e?: Event) => {
1315
showPopover.value = !showPopover.value
1416
}
1517
16-
const onDocClick = (e: Event) => {
17-
const t = e.target as Node
18-
if (!popoverRef.value || !triggerRef.value) return
19-
if (!popoverRef.value.contains(t) && !triggerRef.value.contains(t)) {
18+
onClickOutside(
19+
popoverRef,
20+
() => {
2021
showPopover.value = false
21-
}
22-
}
22+
},
23+
{ ignore: [triggerRef] },
24+
)
2325
24-
const onKeydown = (e: KeyboardEvent) => {
25-
if (e.key === 'Escape') showPopover.value = false
26-
}
26+
onKeyDown(
27+
'Escape',
28+
() => {
29+
if (showPopover.value) showPopover.value = false
30+
},
31+
{ dedupe: true },
32+
)
2733
28-
onMounted(() => {
29-
document.addEventListener('click', onDocClick)
30-
document.addEventListener('keydown', onKeydown)
31-
})
32-
onBeforeUnmount(() => {
33-
document.removeEventListener('click', onDocClick)
34-
document.removeEventListener('keydown', onKeydown)
34+
const { activate, deactivate } = useFocusTrap(popoverRef, { allowOutsideClick: true })
35+
watch(showPopover, async open => {
36+
if (open) {
37+
await nextTick()
38+
activate()
39+
popoverRef.value?.focus?.()
40+
} else {
41+
deactivate()
42+
triggerRef.value?.focus?.()
43+
}
3544
})
3645
</script>
3746

@@ -79,21 +88,22 @@ onBeforeUnmount(() => {
7988

8089
<Teleport to="body">
8190
<Transition
82-
enter-active-class="transition-opacity duration-150 motion-reduce:transition-none"
83-
leave-active-class="transition-opacity duration-100 motion-reduce:transition-none"
91+
enter-active-class="transition-opacity duration-0 motion-reduce:transition-none"
92+
leave-active-class="transition-opacity duration-0 motion-reduce:transition-none"
8493
enter-from-class="opacity-0"
8594
leave-to-class="opacity-0"
8695
>
87-
<div v-if="showPopover">
96+
<div v-show="showPopover">
8897
<div
89-
class="fixed inset-0 bg-bg-elevated/70 dark:bg-bg-elevated/90 z-40"
98+
class="fixed inset-0 bg-bg-elevated/70 dark:bg-bg-elevated/90 z-[9998]"
9099
@click="showPopover = false"
91100
aria-hidden="true"
92101
></div>
93102

94-
<div class="fixed inset-0 z-50 flex items-center justify-center">
103+
<div class="fixed inset-0 z-[9999] flex items-center justify-center">
95104
<div
96105
ref="popoverRef"
106+
tabindex="-1"
97107
class="mx-4 max-w-lg w-full p-6 bg-bg border border-border rounded-lg shadow-xl text-sm text-fg"
98108
role="dialog"
99109
:aria-label="$t('footer.keyboard_shortcuts')"
@@ -107,7 +117,7 @@ onBeforeUnmount(() => {
107117
@click="showPopover = false"
108118
>
109119
<span aria-hidden="true" class="size-5 i-lucide-x" />
110-
<span class="sr-only">{{ $t('close') }}</span>
120+
<span class="sr-only">{{ $t('common.close') }}</span>
111121
</button>
112122
</div>
113123
<p class="mb-2 font-mono text-fg-subtle">

0 commit comments

Comments
 (0)