Skip to content

Commit f90a182

Browse files
committed
fix: improve accessibility
1 parent fc0a3d4 commit f90a182

3 files changed

Lines changed: 75 additions & 42 deletions

File tree

app/components/ChartModal.vue

Lines changed: 66 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,78 @@
11
<script setup lang="ts">
22
const open = defineModel<boolean>('open', { default: false })
3+
4+
const dialogRef = useTemplateRef('dialogRef')
5+
6+
watch(open, isOpen => {
7+
if (isOpen) {
8+
dialogRef.value?.showModal()
9+
} else {
10+
dialogRef.value?.close()
11+
}
12+
})
13+
14+
function handleDialogClose() {
15+
open.value = false
16+
}
17+
18+
function handleBackdropClick(event: MouseEvent) {
19+
// Close when clicking the backdrop (the dialog element itself, not its contents)
20+
if (event.target === dialogRef.value) {
21+
open.value = false
22+
}
23+
}
324
</script>
425

526
<template>
627
<Teleport to="body">
7-
<Transition
8-
enter-active-class="transition-opacity duration-200"
9-
leave-active-class="transition-opacity duration-200"
10-
enter-from-class="opacity-0"
11-
leave-to-class="opacity-0"
28+
<dialog
29+
ref="dialogRef"
30+
class="bg-transparent backdrop:bg-black/60 max-w-3xl w-full p-4 m-auto"
31+
aria-labelledby="chart-modal-title"
32+
@close="handleDialogClose"
33+
@click="handleBackdropClick"
1234
>
13-
<div v-if="open" class="fixed inset-0 z-50 flex items-center justify-center p-4">
14-
<!-- Backdrop -->
15-
<button
16-
type="button"
17-
class="absolute inset-0 bg-black/60 cursor-default"
18-
aria-label="Close modal"
19-
@click="open = false"
20-
/>
21-
22-
<div
23-
class="relative w-full bg-bg border border-border rounded-lg shadow-xl max-h-[90vh] overflow-y-auto overscroll-contain max-w-3xl"
24-
role="dialog"
25-
aria-modal="true"
26-
aria-labelledby="package-download-stats"
27-
>
28-
<div class="p-6">
29-
<div class="flex items-center justify-between mb-6">
30-
<h2 id="package-download-stats" class="font-mono text-lg font-medium">
31-
<slot name="title" />
32-
</h2>
33-
<button
34-
type="button"
35-
class="text-fg-subtle hover:text-fg transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 rounded"
36-
aria-label="Close"
37-
@click="open = false"
38-
>
39-
<span class="i-carbon-close block w-5 h-5" aria-hidden="true" />
40-
</button>
41-
</div>
42-
<div class="flex items-center font-mono text-sm">
43-
<slot />
44-
</div>
35+
<div
36+
class="bg-bg border border-border rounded-lg shadow-xl max-h-[90vh] overflow-y-auto overscroll-contain"
37+
>
38+
<div class="p-6">
39+
<div class="flex items-center justify-between mb-6">
40+
<h2 id="chart-modal-title" class="font-mono text-lg font-medium">
41+
<slot name="title" />
42+
</h2>
43+
<button
44+
type="button"
45+
class="text-fg-subtle hover:text-fg transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 rounded"
46+
aria-label="Close"
47+
@click="open = false"
48+
>
49+
<span class="i-carbon-close block w-5 h-5" aria-hidden="true" />
50+
</button>
51+
</div>
52+
<div class="flex items-center font-mono text-sm">
53+
<slot />
4554
</div>
4655
</div>
4756
</div>
48-
</Transition>
57+
</dialog>
4958
</Teleport>
5059
</template>
60+
61+
<style scoped>
62+
dialog::backdrop {
63+
background: rgba(0, 0, 0, 0.6);
64+
}
65+
66+
dialog[open] {
67+
animation: fade-in 200ms ease-out;
68+
}
69+
70+
@keyframes fade-in {
71+
from {
72+
opacity: 0;
73+
}
74+
to {
75+
opacity: 1;
76+
}
77+
}
78+
</style>

app/components/PackageDownloadAnalytics.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,9 @@ async function load() {
323323
324324
evolution.value = (result as EvolutionData) ?? []
325325
displayedGranularity.value = selectedGranularity.value
326+
} catch {
327+
if (currentToken !== requestToken) return
328+
evolution.value = []
326329
} finally {
327330
if (currentToken === requestToken) {
328331
pending.value = false

app/components/PackageWeeklyDownloadStats.vue

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,15 @@ const config = computed(() => ({
8282
<h2 class="text-xs text-fg-subtle uppercase tracking-wider">
8383
{{ $t('package.downloads.title') }}
8484
</h2>
85-
<a
85+
<button
86+
type="button"
8687
@click="showModal = true"
87-
class="cursor-pointer link-subtle font-mono text-sm inline-flex items-center gap-1.5 ml-auto shrink-0 self-center"
88+
class="link-subtle font-mono text-sm inline-flex items-center gap-1.5 ml-auto shrink-0 self-center focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fg/50 rounded"
8889
:title="t('package.downloads.analyze')"
8990
>
90-
<span class="i-carbon-data-analytics w-4 h-4" />
91-
</a>
91+
<span class="i-carbon-data-analytics w-4 h-4" aria-hidden="true" />
92+
<span class="sr-only">{{ t('package.downloads.analyze') }}</span>
93+
</button>
9294
</div>
9395

9496
<div class="w-full overflow-hidden">

0 commit comments

Comments
 (0)