Skip to content

Commit 96395a4

Browse files
authored
Merge pull request #379 from vuejs-jp/fix/hamburger-menu-a11y
Fix/ replace hamburger menu with dialog element
2 parents 2f86df6 + 5c2e8d6 commit 96395a4

File tree

2 files changed

+52
-15
lines changed

2 files changed

+52
-15
lines changed

apps/web/app/components/GlobalHeader.vue

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const onSwitchLocale = () => {
1717
const { width } = useWindowSize()
1818
const { orientation } = useScreenOrientation()
1919
const shouldShowSpHeader = ref()
20+
const dialogRef = ref<HTMLDialogElement>()
2021
onMounted(() => {
2122
shouldShowSpHeader.value = width.value <= 1200
2223
})
@@ -27,6 +28,11 @@ watch([width, orientation], () => {
2728
const showMenu = ref(false)
2829
2930
const toggleMenu = () => {
31+
if (showMenu.value) {
32+
dialogRef.value!.close()
33+
} else {
34+
dialogRef.value!.show()
35+
}
3036
showMenu.value = !showMenu.value
3137
}
3238
@@ -48,26 +54,31 @@ const getAnchorPath = computed(
4854
class="navigation-mobile-toggle"
4955
name="menu"
5056
:class="{ 'isOpened': showMenu }"
57+
:aria-expanded="showMenu"
58+
aria-controls="navigation-mobile-menu-trigger"
59+
:aria-label="showMenu ? 'メニューを閉じる' : 'メニューを開く'"
5160
@click="toggleMenu"
5261
>
5362
<span /><span /><span />
5463
</button>
5564
<!-- <VFIcon name="menu" color="vue-blue" can-hover @click="toggleMenu" /> -->
5665
</div>
5766
<!-- hamburger-menu -->
58-
<Transition name="slide-down">
59-
<div v-show="showMenu" class="navigation-mobile-menu">
60-
<div>
61-
<ul>
62-
<li v-for="link in navLinks" :key="link.anchor">
63-
<nuxt-link :to="getAnchorPath(link.anchor)" @click="toggleMenu">
64-
<VFTypography variant="heading/200" color="vue-blue">{{ link.text }}</VFTypography>
65-
</nuxt-link>
66-
</li>
67-
</ul>
68-
</div>
69-
</div>
70-
</Transition>
67+
<dialog id="navigation-mobile-menu-trigger" ref="dialogRef" class="navigation-mobile-menu">
68+
<ul>
69+
<li v-for="(link, index) in navLinks" :key="link.anchor">
70+
<!-- eslint-disable vuejs-accessibility/no-autofocus -->
71+
<nuxt-link
72+
:to="getAnchorPath(link.anchor)"
73+
:autofocus="index === 0 && true"
74+
@click="toggleMenu"
75+
>
76+
<!-- eslint-enable vuejs-accessibility/no-autofocus -->
77+
<VFTypography variant="heading/200" color="vue-blue">{{ link.text }}</VFTypography>
78+
</nuxt-link>
79+
</li>
80+
</ul>
81+
</dialog>
7182
</VFSpHeader>
7283
<VFHeader v-else>
7384
<div class="navigation-pc">
@@ -95,6 +106,7 @@ const getAnchorPath = computed(
95106
align-items: center;
96107
gap: calc(var(--unit) * 2);
97108
margin-right: 27px;
109+
z-index: 10;
98110
}
99111
100112
.navigation-mobile-menu {
@@ -104,9 +116,23 @@ const getAnchorPath = computed(
104116
width: 100vw;
105117
text-align: center;
106118
background-color: var(--color-white);
119+
padding: calc(var(--unit) * 5) 0;
120+
border: 0;
121+
transition:
122+
translate 0.6s cubic-bezier(0.4, 0, 0.2, 1),
123+
display 0.6s cubic-bezier(0.4, 0, 0.2, 1) allow-discrete;
124+
z-index: 1;
125+
126+
&[open] {
127+
translate: 0 0;
128+
129+
@starting-style {
130+
translate: 0 -100dvh;
131+
}
132+
}
107133
108-
& > div {
109-
padding: calc(var(--unit) * 5) 0;
134+
&:not([open]) {
135+
translate: 0 -100dvh;
110136
}
111137
112138
ul {

packages/ui/components/common/SpHeader.vue

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,20 @@ header {
3939
display: flex;
4040
align-items: center;
4141
justify-content: space-between;
42+
&::before {
43+
content: '';
44+
position: absolute;
45+
top: 0;
46+
left: 0;
47+
width: 100%;
48+
height: 100%;
49+
background-color: var(--color-white);
50+
z-index: 5;
51+
}
4252
}
4353
.link {
4454
line-height: 0;
55+
z-index: 10;
4556
}
4657
.logo {
4758
height: 32px;

0 commit comments

Comments
 (0)