-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change top nav from accordion to two rows on mobile #1690
Changes from all commits
c3f35c5
8503548
4fa4314
92b2a2e
386fc8f
506cb14
d18a902
fe1e578
270a51b
b3dd82f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,29 +2,18 @@ | |
<div> | ||
<nav ref="navbar" :class="['navbar', 'navbar-expand-md', themeOptions, addClass, fixedOptions]"> | ||
<div class="container-fluid"> | ||
<div class="navbar-brand"> | ||
<div class="navbar-left"> | ||
<slot name="brand"></slot> | ||
</div> | ||
<button | ||
v-if="!slots.collapse" | ||
class="navbar-toggler" | ||
type="button" | ||
aria-expanded="false" | ||
aria-label="Toggle navigation" | ||
@click="toggleCollapse" | ||
> | ||
<span class="navbar-toggler-icon"></span> | ||
<slot name="collapse"></slot> | ||
</button> | ||
|
||
<div :class="['navbar-collapse',{collapse:collapsed}]"> | ||
<div ref="navbarDefault" class="navbar-default"> | ||
<ul class="navbar-nav mr-auto mt-2 mt-lg-0"> | ||
<slot></slot> | ||
</ul> | ||
<ul v-if="slots.right" class="navbar-nav navbar-right"> | ||
<slot name="right"></slot> | ||
</ul> | ||
</div> | ||
|
||
<ul v-if="slots.right" class="navbar-nav navbar-right"> | ||
<slot name="right"></slot> | ||
</ul> | ||
</div> | ||
</nav> | ||
<div | ||
|
@@ -73,12 +62,12 @@ export default { | |
provide() { | ||
return { | ||
toggleLowerNavbar: this.toggleLowerNavbar, | ||
isParentNavbar: true, | ||
}; | ||
}, | ||
data() { | ||
return { | ||
id: 'bs-example-navbar-collapse-1', | ||
collapsed: true, | ||
styles: {}, | ||
isLowerNavbarShowing: false, | ||
}; | ||
|
@@ -111,10 +100,6 @@ export default { | |
}, | ||
}, | ||
methods: { | ||
toggleCollapse(e) { | ||
if (e) { e.preventDefault(); } | ||
this.collapsed = !this.collapsed; | ||
}, | ||
// Splits a normalised URL into its parts, | ||
// e.g http://site.org/foo/bar/index.html -> ['foo','bar','index.html'] | ||
splitUrl(url) { | ||
|
@@ -167,7 +152,8 @@ export default { | |
}, | ||
highlightLink(url) { | ||
const defHlMode = this.defaultHighlightOn; | ||
const navLis = Array.from(this.$el.querySelector('.navbar-nav').children); | ||
const navLis = []; | ||
this.$el.querySelectorAll('.navbar-nav').forEach(nav => navLis.push(...Array.from(nav.children))); | ||
// attempt an exact match first | ||
for (let i = 0; i < navLis.length; i += 1) { | ||
const li = navLis[i]; | ||
|
@@ -254,35 +240,128 @@ export default { | |
if (!content.contains(e.target)) content.classList.remove('open'); | ||
}); | ||
}); | ||
$(this.$el).on('click', 'li:not(.dropdown)>a', (e) => { | ||
if (e.target.classList.contains('submenu-toggle')) { return; } | ||
setTimeout(() => { this.collapsed = true; }, 200); | ||
}).onBlur((e) => { | ||
if (!this.$el.contains(e.target)) { this.collapsed = true; } | ||
}); | ||
if (this.slots.collapse) $('[data-toggle="collapse"]', this.$el).on('click', e => this.toggleCollapse(e)); | ||
|
||
// highlight current nav link | ||
this.highlightLink(window.location.href); | ||
|
||
// scroll default navbar horizontally to current link if it is beyond the current scroll | ||
const currentNavlink = $(this.$refs.navbarDefault).find('.current')[0]; | ||
if (currentNavlink && window.innerWidth < 768 | ||
&& currentNavlink.offsetLeft + currentNavlink.offsetWidth > window.innerWidth) { | ||
this.$refs.navbarDefault.scrollLeft = currentNavlink.offsetLeft + currentNavlink.offsetWidth | ||
- window.innerWidth; | ||
} | ||
|
||
this.toggleLowerNavbar(); | ||
$(window).on('resize', this.toggleLowerNavbar); | ||
|
||
// scroll default navbar horizontally when mousewheel is scrolled | ||
$(this.$refs.navbarDefault).on('wheel', (e) => { | ||
const isDropdown = (nodes) => { | ||
for (let i = 0; i < nodes.length; i += 1) { | ||
if (nodes[i].classList && nodes[i].classList.contains('dropdown-menu')) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
|
||
// prevent horizontal scrolling if the scroll is on dropdown menu | ||
if (window.innerWidth < 768 && !isDropdown(e.path)) { | ||
e.preventDefault(); | ||
this.$refs.navbarDefault.scrollLeft += e.deltaY; | ||
} | ||
}); | ||
}, | ||
beforeDestroy() { | ||
$('.dropdown', this.$el).off('click').offBlur(); | ||
if (this.slots.collapse) $('[data-toggle="collapse"]', this.$el).off('click'); | ||
$(window).off('resize', this.toggleLowerNavbar); | ||
$(this.$refs.navbarDefault).off('wheel'); | ||
}, | ||
}; | ||
</script> | ||
|
||
<style scoped> | ||
@media (max-width: 767px) { | ||
.navbar-collapse { | ||
max-height: 80vh !important; | ||
overflow-x: hidden !important; | ||
overflow-y: scroll !important; | ||
.navbar { | ||
padding-left: 0; | ||
padding-right: 0; | ||
padding-bottom: 0; | ||
} | ||
|
||
.navbar-left { | ||
max-width: 50%; | ||
order: 1; | ||
padding-left: 1rem; | ||
} | ||
|
||
.navbar-left * { | ||
white-space: normal; | ||
} | ||
|
||
.navbar-right { | ||
order: 1; | ||
max-width: 50%; | ||
padding: 0 16px; | ||
} | ||
|
||
.navbar-default { | ||
display: block; | ||
margin-top: 0.3125rem; | ||
width: 100%; | ||
order: 2; | ||
overflow-x: scroll; | ||
|
||
/* Hide overflow scroll bar */ | ||
-ms-overflow-style: none; /* IE and Edge */ | ||
scrollbar-width: none; /* Firefox */ | ||
} | ||
|
||
/* Hide overflow scroll bar for Chrome and Safari */ | ||
.navbar-default::-webkit-scrollbar { | ||
display: none; | ||
} | ||
|
||
.navbar-default ul { | ||
flex-direction: row; | ||
margin-top: 0 !important; | ||
width: 100%; | ||
} | ||
|
||
.navbar-default > ul > * { | ||
background: rgba(0, 0, 0, 0.2); | ||
padding: 0.3125rem 0.625rem; | ||
flex-grow: 1; | ||
} | ||
|
||
.navbar-light .navbar-default > ul > * { | ||
background: rgba(0, 0, 0, 0.05); | ||
} | ||
|
||
.navbar-default > ul > .current { | ||
background: transparent; | ||
} | ||
|
||
.navbar-default a, | ||
>>> .dropdown-toggle { | ||
margin: 0 auto; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this seems to push the last few item(s) after the dropdown to the right (if there's extra space) tried removing it and looks good; what's it for? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm in this case would all the items be better flushed to the left (or center or right), not stretched out? It makes the location and blank space of elements slightly more predictable with respect to how much content they contain (and more consistent to the design when overflow occurs). e.g. huge space between dropdown and "home" leads to inconsistent "eye travel distance", since the content here can be of varying lengths. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahh ok got it. I've flushed all items to the left and it looks alot better. |
||
width: max-content; | ||
jonahtanjz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
>>> .dropdown { | ||
display: flex; | ||
align-items: center; | ||
} | ||
} | ||
|
||
.navbar-left { | ||
display: inline-block; | ||
font-size: 1.25rem; | ||
line-height: inherit; | ||
padding-right: 1rem; | ||
padding-top: 0.3125rem; | ||
padding-bottom: 0.3125rem; | ||
white-space: nowrap; | ||
} | ||
|
||
.navbar-fixed { | ||
|
@@ -291,6 +370,13 @@ export default { | |
z-index: 1000; | ||
} | ||
|
||
.navbar-default { | ||
display: flex; | ||
flex-basis: auto; | ||
flex-grow: 1; | ||
align-items: center; | ||
} | ||
|
||
>>> .dropdown-current { | ||
color: #fff !important; | ||
background: #007bff; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(also need to take note
50%
does not account for themargin-right
set bynavbar-brand
in bootstrap)Discovered a few pre-existing issues with the navbar's flex parameters while reviewing as well:
(and a few others, try resizing with a long list of navbar contents)
Would be good if you are able to get a generalised fix / implementation out here, if there's one😃 (on second thought let's keep in mind and fix separately; found a few more issues that seems to be out of scope here)But if not we can always keep in mind to to fix soon in the next PR or so, and just focus on the mobile version here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the catch! I've factored the margin into the
max-width
now and also setwhite-space: normal
so that items withinnavbar-brand
can wrap to next line when it exceeds50%
.Yup sure. I can open an issue after this PR to keep track of it :)