Skip to content

Commit 2ad7187

Browse files
committed
feat(header): Add support for dropdown-menu
Resolves #71 Signed-off-by: Khusika Dhamar Gusti <[email protected]>
1 parent eae080e commit 2ad7187

File tree

5 files changed

+289
-65
lines changed

5 files changed

+289
-65
lines changed

assets/css/_partial/_header.scss

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,17 @@ header {
163163
}
164164

165165
.menu {
166-
overflow: hidden;
166+
overflow: visible;
167167
white-space: nowrap;
168168

169169
.menu-inner {
170170
float: right;
171+
overflow: visible;
171172
}
172173

173174
.menu-item {
174-
margin: 0 .5rem;
175+
display: inline-block;
176+
padding: 0 .5rem;
175177

176178
&.delimiter {
177179
border-left: 1.5px solid $global-font-color;
@@ -182,7 +184,7 @@ header {
182184
}
183185

184186
&.language {
185-
margin-right: 0;
187+
padding-right: 0;
186188
&:hover {
187189
color: $global-link-hover-color;
188190
[theme=dark] & {
@@ -192,7 +194,7 @@ header {
192194
}
193195

194196
&.search {
195-
margin: 0 -.5rem 0 0;
197+
padding: 0;
196198
}
197199
}
198200

@@ -204,11 +206,84 @@ header {
204206
color: $header-hover-color-dark;
205207
}
206208
}
209+
210+
.menu-item.has-children {
211+
padding: 0;
212+
}
213+
214+
.menu-item.has-children {
215+
> a {
216+
cursor: pointer;
217+
}
218+
219+
.dropdown-toggle {
220+
i {
221+
display: inline-block;
222+
font-size: 0.9em;
223+
vertical-align: middle;
224+
margin-left: .25rem;
225+
@include transition(transform 0.35s ease);
226+
}
227+
}
228+
229+
.dropdown-menu {
230+
display: none;
231+
position: absolute;
232+
overflow: hidden;
233+
top: 100%;
234+
left: 0;
235+
background: $header-background-color;
236+
z-index: 9999;
237+
@include border-radius(.25rem);
238+
@include box-shadow(0 0 1.5rem 0 rgba(0, 0, 0, .1));
239+
240+
[theme=dark] & {
241+
background: $header-background-color-dark;
242+
}
243+
}
244+
245+
&:hover .dropdown-menu,
246+
&:focus-within .dropdown-menu {
247+
display: block;
248+
}
249+
&:hover .dropdown-toggle i {
250+
@include transform(rotate(180deg));
251+
}
252+
&:hover {
253+
color: $header-hover-color;
254+
[theme=dark] & { color: $header-hover-color-dark; }
255+
}
256+
257+
&.active .dropdown-toggle i {
258+
@include transform(rotate(180deg));
259+
}
260+
261+
.dropdown-item {
262+
display: block;
263+
padding: 0 .5rem !important;
264+
color: $global-font-color;
265+
white-space: nowrap;
266+
@include transition(width 0.2s ease);
267+
@include border-radius(.25rem);
268+
[theme=dark] & {
269+
color: $global-font-color-dark;
270+
}
271+
272+
&:hover {
273+
background: darken($header-background-color, 5%);
274+
color: lighten($global-link-hover-color, 5%);
275+
[theme=dark] & {
276+
background: darken($header-background-color-dark, 5%);
277+
color: lighten($global-link-hover-color-dark, 5%);
278+
}
279+
}
280+
}
281+
}
207282
}
208283
}
209284

210285
&.open .header-wrapper .menu .menu-item.search {
211-
margin: 0 .25rem 0 .5rem;
286+
padding: 0 .25rem 0 .5rem;
212287

213288
input {
214289
width: 24rem;
@@ -319,6 +394,7 @@ header {
319394
.menu-item {
320395
display: block;
321396
line-height: 2.5rem;
397+
padding: 0 .5rem;
322398
&.language {
323399
&:hover {
324400
color: $global-link-hover-color;
@@ -329,6 +405,43 @@ header {
329405
}
330406
}
331407

408+
.menu-item.has-children {
409+
.dropdown-toggle i {
410+
@include transition(transform 0.35s ease);
411+
}
412+
413+
&.active .dropdown-toggle i {
414+
@include transform(rotate(180deg));
415+
}
416+
417+
.dropdown-menu {
418+
display: none;
419+
position: static;
420+
background: darken($header-background-color, 5%);
421+
box-shadow: none;
422+
min-width: 0;
423+
overflow: hidden;
424+
padding: 0;
425+
@include border-radius(.5rem);
426+
427+
[theme=dark] & {
428+
background: darken($header-background-color-dark, 5%);
429+
}
430+
}
431+
432+
.dropdown-item {
433+
display: block;
434+
padding: 0 .5rem !important;
435+
color: $global-font-color;
436+
white-space: nowrap;
437+
@include transition(width 0.2s ease);
438+
@include border-radius(.5rem);
439+
[theme=dark] & {
440+
color: $global-font-color-dark;
441+
}
442+
}
443+
}
444+
332445
&.active {
333446
display: block;
334447
}

assets/js/theme.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,75 @@ class Theme {
6868
initMenuMobile() {
6969
const $menuToggleMobile = document.getElementById('menu-toggle-mobile');
7070
const $menuMobile = document.getElementById('menu-mobile');
71+
const $menuItemsWithChildren = document.querySelectorAll('#menu-mobile .has-children');
72+
const closeAllSubmenus = () => {
73+
this.util.forEach($menuItemsWithChildren, $menuItem => {
74+
$menuItem.classList.remove('active');
75+
const $submenu = $menuItem.querySelector('.dropdown-menu');
76+
if ($submenu) {
77+
$submenu.style.display = 'none';
78+
$submenu.style.height = '';
79+
}
80+
});
81+
};
7182
$menuToggleMobile.addEventListener('click', () => {
7283
document.body.classList.toggle('blur');
7384
$menuToggleMobile.classList.toggle('active');
7485
$menuMobile.classList.toggle('active');
86+
if (!$menuMobile.classList.contains('active')) {
87+
closeAllSubmenus();
88+
}
7589
}, false);
7690
this._menuMobileOnClickMask = this._menuMobileOnClickMask || (() => {
7791
$menuToggleMobile.classList.remove('active');
7892
$menuMobile.classList.remove('active');
93+
closeAllSubmenus();
7994
});
8095
this.clickMaskEventSet.add(this._menuMobileOnClickMask);
96+
97+
this.util.forEach($menuItemsWithChildren, $menuItem => {
98+
const $submenu = $menuItem.querySelector('.dropdown-menu');
99+
if ($submenu) {
100+
$submenu.style.transition = 'height 0.35s ease';
101+
$submenu.style.overflow = 'hidden';
102+
$submenu.style.display = 'none';
103+
}
104+
});
105+
106+
$menuMobile.addEventListener('click', event => {
107+
const $clickedItem = event.target.closest('a.dropdown-toggle');
108+
if (!$clickedItem) return;
109+
110+
event.preventDefault();
111+
const $menuItem = $clickedItem.parentElement;
112+
const $submenu = $menuItem.querySelector('.dropdown-menu');
113+
if (!$submenu) return;
114+
115+
$menuItem.classList.toggle('active');
116+
const isSubmenuOpen = $submenu.style.display === 'block';
117+
118+
if (isSubmenuOpen) {
119+
$submenu.style.height = `${$submenu.scrollHeight}px`;
120+
window.setTimeout(() => ($submenu.style.height = '0'), 0);
121+
$submenu.addEventListener('transitionend', () => ($submenu.style.display = 'none'), { once: true });
122+
} else {
123+
$submenu.style.display = 'block';
124+
$submenu.style.height = '0';
125+
window.setTimeout(() => ($submenu.style.height = `${$submenu.scrollHeight}px`), 0);
126+
$submenu.addEventListener('transitionend', () => ($submenu.style.height = ''), { once: true });
127+
}
128+
});
129+
}
130+
131+
initDesktopMenu() {
132+
if (this.util.isMobile()) return;
133+
this.util.forEach(document.querySelectorAll('#header-desktop .has-children .dropdown-item.active'), $activeChild => {
134+
const $parentMenuItem = $activeChild.closest('.has-children');
135+
if ($parentMenuItem) {
136+
const $parentLink = $parentMenuItem.querySelector('a.dropdown-toggle');
137+
if ($parentLink) $parentLink.style.fontWeight = 'bold';
138+
}
139+
});
81140
}
82141

83142
initSwitchTheme() {
@@ -742,6 +801,7 @@ class Theme {
742801
this.initMenuMobile();
743802
this.initSwitchTheme();
744803
this.initSearch();
804+
this.initDesktopMenu();
745805
this.initDetails();
746806
this.initLightGallery();
747807
this.initHighlight();

0 commit comments

Comments
 (0)