Skip to content

Commit e77cdc8

Browse files
author
Nikos Katsikanis
committed
animate nav burger
1 parent 9e08470 commit e77cdc8

File tree

1 file changed

+45
-28
lines changed

1 file changed

+45
-28
lines changed

js/components/nav.js

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -51,42 +51,34 @@ export default (hostComponent) => {
5151
display: flex;
5252
gap: 0.2rem;
5353
align-items: center;
54-
padding:0.5rem 0.3rem;
55-
border-radius:0.3rem;
54+
padding: 0.5rem 0.3rem;
55+
border-radius: 0.3rem;
56+
}
57+
a:hover {
58+
background-color: var(--secondary-color);
5659
}
57-
58-
a:hover{
59-
background-color:var(--secondary-color);
60-
}
61-
6260
a.active {
6361
color: var(--primary-color); /* Active link color */
6462
}
65-
6663
&.header-bar-mode {
67-
6864
flex-direction: row;
6965
justify-content: top;
7066
background-color: transparent;
7167
width: 100%;
72-
7368
@media (max-width: ${burgerPx}px) {
7469
flex-direction: column;
75-
7670
a {
7771
width: 100%;
7872
}
79-
8073
align-items: center;
8174
position: absolute;
8275
background-color: var(--nav-background-color);
8376
top: 0;
84-
bottom:0;
77+
bottom: 0;
8578
display: none;
8679
}
8780
}
8881
}
89-
9082
.burger-button {
9183
position: absolute;
9284
right: 0;
@@ -95,44 +87,62 @@ export default (hostComponent) => {
9587
cursor: pointer;
9688
z-index: 100;
9789
}
98-
9990
nav:not(.header-bar-mode) {
10091
@media (max-width: 499px) {
101-
padding: 10px 6px;
102-
92+
padding: 10px 6px;
10393
.text {
10494
display: none;
10595
}
10696
}
107-
a {padding:0.4rem 0.6rem;}
108-
97+
a {
98+
padding: 0.4rem 0.6rem;
99+
}
109100
@media (min-width: 500px) {
110101
.icon {
111102
display: none;
112103
}
113104
}
114105
}
115-
116106
@media (max-width: ${burgerPx}px) {
117107
nav.header-bar-mode.burger-open {
118108
display: flex !important;
119109
}
120110
}
121-
122111
@media (min-width: ${burgerPx}px) {
123112
.burger-button {
124113
display: none !important;
125114
}
126115
}
116+
/* Burger icon animation */
117+
.burger-button svg rect {
118+
transition: transform 0.3s ease, opacity 0.3s ease;
119+
transform-box: fill-box;
120+
transform-origin: center;
121+
}
122+
.burger-button.open svg rect:nth-child(1) {
123+
transform: translateY(30px) rotate(45deg);
124+
}
125+
.burger-button.open svg rect:nth-child(2) {
126+
opacity: 0;
127+
}
128+
.burger-button.open svg rect:nth-child(3) {
129+
transform: translateY(-30px) rotate(-45deg);
130+
}
127131
`;
128132

129133
if (headerBar === 'true') {
130134
hostComponent.classList.add('header-bar-mode');
131135
hostComponent.parentElement.style.flexDirection = 'column';
132136
}
133137

138+
// Declare burgerButton outside toggleNavVisibility to ensure accessibility within the closure.
139+
let burgerButton;
140+
134141
const toggleNavVisibility = () => {
135142
hostComponent.classList.toggle('burger-open');
143+
if (burgerButton) {
144+
burgerButton.classList.toggle('open');
145+
}
136146
};
137147

138148
hostComponent.innerHTML = `
@@ -171,7 +181,6 @@ export default (hostComponent) => {
171181
</a>
172182
`;
173183

174-
// Function to update the active link based on the current path
175184
const updateActiveLink = () => {
176185
const currentPath = window.location.pathname;
177186
hostComponent.querySelectorAll('a').forEach((link) => {
@@ -181,24 +190,23 @@ export default (hostComponent) => {
181190
};
182191
updateActiveLink();
183192

184-
// Listen for popstate events to update active link on browser navigation
185193
window.addEventListener('popstate', updateActiveLink);
186194

187195
if (headerBar === 'true' && burgerPx) {
188196
hostComponent.parentElement.insertAdjacentHTML(
189-
'afterbegin',
190-
`
197+
'afterbegin',
198+
`
191199
<button class="burger-button squarify wireframe border-none" title="Open or close nav menu">
192-
<svg class="icon" viewBox="0 0 100 80" width="20" height="20" fill="currentColor">
200+
<svg class="icon" viewBox="0 0 100 80" preserveAspectRatio="xMidYMid meet" width="20" height="20" fill="currentColor">
193201
<rect width="100" height="20"></rect>
194202
<rect y="30" width="100" height="20"></rect>
195203
<rect y="60" width="100" height="20"></rect>
196204
</svg>
197205
</button>
198-
`,
206+
`
199207
);
200208

201-
const burgerButton = hostComponent.parentElement.querySelector('.burger-button');
209+
burgerButton = hostComponent.parentElement.querySelector('.burger-button');
202210

203211
document.addEventListener('click', (event) => {
204212
const isBurgerOpen = hostComponent.classList.contains('burger-open');
@@ -208,14 +216,23 @@ export default (hostComponent) => {
208216
if (clickedBurgerButton) {
209217
event.stopPropagation();
210218
toggleNavVisibility();
219+
return;
211220
}
212221

213222
if (isBurgerOpen && clickedNavItem) {
214223
toggleNavVisibility();
224+
return;
215225
}
216226

217227
if (isBurgerOpen && !event.target.closest('nav') && !clickedBurgerButton) {
218228
toggleNavVisibility();
229+
return;
230+
}
231+
});
232+
233+
document.addEventListener('keydown', (event) => {
234+
if (event.key === 'Escape' && hostComponent.classList.contains('burger-open')) {
235+
toggleNavVisibility();
219236
}
220237
});
221238
}

0 commit comments

Comments
 (0)