Skip to content

Commit fa0bf55

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

File tree

5 files changed

+280
-65
lines changed

5 files changed

+280
-65
lines changed

assets/css/_partial/_header.scss

Lines changed: 113 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,80 @@ 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: $global-link-hover-color;
275+
}
276+
}
277+
}
207278
}
208279
}
209280

210281
&.open .header-wrapper .menu .menu-item.search {
211-
margin: 0 .25rem 0 .5rem;
282+
padding: 0 .25rem 0 .5rem;
212283

213284
input {
214285
width: 24rem;
@@ -319,6 +390,7 @@ header {
319390
.menu-item {
320391
display: block;
321392
line-height: 2.5rem;
393+
padding: 0 .5rem;
322394
&.language {
323395
&:hover {
324396
color: $global-link-hover-color;
@@ -329,6 +401,42 @@ header {
329401
}
330402
}
331403

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

assets/js/theme.js

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

83139
initSwitchTheme() {

0 commit comments

Comments
 (0)