Skip to content

Commit 82e25c0

Browse files
authored
fix(navbar): menu positions (#804)
* fix: menu positions * refactor: factorize menu management and handle window resize * chore: the placement is better with +4 then +10 * chore: the placement is better with -10 than -15
1 parent bbffff1 commit 82e25c0

File tree

4 files changed

+60
-63
lines changed

4 files changed

+60
-63
lines changed

assets/js/lang.js

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,18 @@
11
(function () {
22
const languageSwitchers = document.querySelectorAll('.hextra-language-switcher');
3+
34
languageSwitchers.forEach((switcher) => {
45
switcher.addEventListener('click', (e) => {
56
e.preventDefault();
67

78
switcher.dataset.state = switcher.dataset.state === 'open' ? 'closed' : 'open';
89

9-
const optionsElement = switcher.nextElementSibling;
10-
11-
optionsElement.classList.toggle('hx:hidden');
12-
13-
// Calculate the position of a language options element.
14-
const switcherRect = switcher.getBoundingClientRect();
15-
16-
// Must be called before optionsElement.clientWidth.
17-
optionsElement.style.minWidth = `${Math.max(switcherRect.width, 50)}px`;
18-
19-
const isOnTop = switcher.dataset.location === 'top';
20-
const isRTL = document.body.dir === 'rtl'
21-
22-
// Stuck on the left side of the switcher.
23-
let translateX = switcherRect.left;
24-
25-
if (isOnTop && !isRTL || !isOnTop && isRTL) {
26-
// Stuck on the right side of the switcher.
27-
translateX = switcherRect.right - optionsElement.clientWidth;
28-
}
29-
30-
// Stuck on the top of the switcher.
31-
let translateY = switcherRect.top - window.innerHeight - 15;
32-
33-
if (isOnTop) {
34-
// Stuck on the bottom of the switcher.
35-
translateY = switcherRect.top - window.innerHeight + 180;
36-
}
37-
38-
optionsElement.style.transform = `translate3d(${translateX}px, ${translateY}px, 0)`;
10+
toggleMenu(switcher);
3911
});
4012
});
4113

14+
window.addEventListener("resize", () => languageSwitchers.forEach(resizeMenu))
15+
4216
// Dismiss language switcher when clicking outside
4317
document.addEventListener('click', (e) => {
4418
if (e.target.closest('.hextra-language-switcher') === null) {

assets/js/switcher-menu.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
function computeMenuTranslation(switcher, optionsElement) {
2+
// Calculate the position of a language options element.
3+
const switcherRect = switcher.getBoundingClientRect();
4+
5+
// Must be called before optionsElement.clientWidth.
6+
optionsElement.style.minWidth = `${Math.max(switcherRect.width, 50)}px`;
7+
8+
const isOnTop = switcher.dataset.location === 'top';
9+
const isOnBottom = switcher.dataset.location === 'bottom';
10+
const isOnBottomRight = switcher.dataset.location === 'bottom-right';
11+
const isRTL = document.body.dir === 'rtl'
12+
13+
// Stuck on the left side of the switcher.
14+
let x = switcherRect.left;
15+
16+
if (isOnTop && !isRTL || isOnBottom && isRTL || isOnBottomRight && !isRTL) {
17+
// Stuck on the right side of the switcher.
18+
x = switcherRect.right - optionsElement.clientWidth;
19+
}
20+
21+
// Stuck on the top of the switcher.
22+
let y = switcherRect.top - window.innerHeight - 10;
23+
24+
if (isOnTop) {
25+
// Stuck on the bottom of the switcher.
26+
y = switcherRect.top - window.innerHeight + optionsElement.clientHeight + switcher.clientHeight + 4;
27+
}
28+
29+
return { x: x, y: y };
30+
}
31+
32+
function toggleMenu(switcher) {
33+
const optionsElement = switcher.nextElementSibling;
34+
35+
optionsElement.classList.toggle('hx:hidden');
36+
37+
// Calculate the position of a language options element.
38+
const translate = computeMenuTranslation(switcher, optionsElement);
39+
40+
optionsElement.style.transform = `translate3d(${translate.x}px, ${translate.y}px, 0)`;
41+
}
42+
43+
function resizeMenu(switcher) {
44+
const optionsElement = switcher.nextElementSibling;
45+
46+
if (optionsElement.classList.contains('hx:hidden')) return;
47+
48+
// Calculate the position of a language options element.
49+
const translate = computeMenuTranslation(switcher, optionsElement);
50+
51+
optionsElement.style.transform = `translate3d(${translate.x}px, ${translate.y}px, 0)`;
52+
}

assets/js/theme.js

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,41 +36,11 @@
3636
toggler.addEventListener("click", function (e) {
3737
e.preventDefault();
3838

39-
const optionsElement = toggler.nextElementSibling;
40-
41-
optionsElement.classList.toggle('hx:hidden');
42-
43-
// Calculate the position of a language options element.
44-
const switcherRect = toggler.getBoundingClientRect();
45-
46-
// Must be called before optionsElement.clientWidth.
47-
optionsElement.style.minWidth = `${Math.max(switcherRect.width, 50)}px`;
48-
49-
const isOnTop = toggler.dataset.location === 'top';
50-
const isOnBottom = toggler.dataset.location === 'bottom';
51-
const isOnBottomRight = toggler.dataset.location === 'bottom-right';
52-
const isRTL = document.body.dir === 'rtl'
53-
54-
// Stuck on the left side of the switcher.
55-
let translateX = switcherRect.left;
56-
57-
if (isOnTop && !isRTL || isOnBottom && isRTL || isOnBottomRight && !isRTL) {
58-
// Stuck on the right side of the switcher.
59-
translateX = switcherRect.right - optionsElement.clientWidth;
60-
}
61-
62-
// Stuck on the top of the switcher.
63-
let translateY = switcherRect.top - window.innerHeight - 15;
64-
65-
if (isOnTop) {
66-
// Stuck on the bottom of the switcher.
67-
translateY = switcherRect.top - window.innerHeight + 150;
68-
}
69-
70-
optionsElement.style.transform = `translate3d(${translateX}px, ${translateY}px, 0)`;
39+
toggleMenu(toggler);
7140
});
7241
});
7342

43+
window.addEventListener("resize", () => themeToggleButtons.forEach(resizeMenu))
7444

7545
// Dismiss the menu when clicking outside
7646
document.addEventListener('click', (e) => {

layouts/_partials/scripts/core.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{{- $jsSwitcherMenu := resources.Get "js/switcher-menu.js" -}}
12
{{- $jsTheme := resources.Get "js/theme.js" | resources.ExecuteAsTemplate "theme.js" . -}}
23
{{- $jsBanner := resources.Get "js/banner.js" | resources.ExecuteAsTemplate "banner.js" . -}}
34
{{- $jsMenu := resources.Get "js/menu.js" -}}
@@ -11,7 +12,7 @@
1112
{{- $jsTocScroll := resources.Get "js/toc-scroll.js" -}}
1213
{{- $jsFavicon := resources.Get "js/favicon.js" | resources.ExecuteAsTemplate "favicon.js" . -}}
1314

14-
{{- $scripts := slice $jsTheme $jsBanner $jsMenu $jsCodeCopy $jsTabs $jsLang $jsNavMenu $jsFileTree $jsSidebar $jsBackToTop $jsTocScroll $jsFavicon | resources.Concat "js/main.js" -}}
15+
{{- $scripts := slice $jsSwitcherMenu $jsTheme $jsBanner $jsMenu $jsCodeCopy $jsTabs $jsLang $jsNavMenu $jsFileTree $jsSidebar $jsBackToTop $jsTocScroll $jsFavicon | resources.Concat "js/main.js" -}}
1516
{{- if hugo.IsProduction -}}
1617
{{- $scripts = $scripts | minify | fingerprint -}}
1718
{{- end -}}

0 commit comments

Comments
 (0)