webpack-bootstrap-ui-kit/src/js/ui/dropdown.js

148 lines
3.6 KiB
JavaScript
Raw Normal View History

2022-05-03 20:50:57 +02:00
import Events from '../_events'
2021-09-05 21:05:55 +02:00
/*
* Bootstrap compatible dropdowns without popover library
*
* [data-bs-toggle="hover"] - shows/hides dropdown on mouseover/mouseout
* [data-bs-toggle="dropdown"], .js-dropdown - shows/hides dropdown on click
*
*/
2021-09-05 21:05:55 +02:00
const DropdownHoverUI = ((window) => {
2022-05-03 20:50:57 +02:00
const NAME = 'js-dropdown'
2022-05-05 15:08:13 +02:00
const ACTIVECLS = ['active', 'active-dropdown']
2021-09-05 21:05:55 +02:00
2022-01-03 05:59:41 +01:00
const HideAll = () => {
2021-12-28 02:01:36 +01:00
// hide others
document.querySelectorAll('.dropdown-menu').forEach((el, i) => {
2023-03-28 13:25:33 +02:00
const next = el.closest('.dropdown')
if (next) {
next.classList.remove(...ACTIVECLS)
}
2022-05-03 20:50:57 +02:00
el.classList.remove('show')
})
}
2022-01-03 05:59:41 +01:00
const Toggle = (el) => {
2022-05-03 20:50:57 +02:00
HideAll()
2021-12-28 02:01:36 +01:00
2023-03-28 13:25:33 +02:00
const menu = el.querySelector('.dropdown-menu')
if(menu) {
menu.classList.toggle('show')
}
2022-05-03 20:50:57 +02:00
}
2021-09-05 21:05:55 +02:00
2022-09-12 22:07:08 +02:00
const Show = (e) => {
e.stopPropagation()
const el = e.currentTarget
2022-05-05 15:08:13 +02:00
el.classList.add(...ACTIVECLS)
2023-03-28 13:25:33 +02:00
const menu = el.querySelector('.dropdown-menu')
if(menu){
menu.classList.add('show')
}
2022-05-03 20:50:57 +02:00
}
2021-09-05 21:05:55 +02:00
2022-09-12 22:07:08 +02:00
const Hide = (e) => {
e.stopPropagation()
const el = e.currentTarget
2022-05-05 15:08:13 +02:00
el.classList.remove(...ACTIVECLS)
2023-03-28 13:25:33 +02:00
const menu = el.querySelector('.dropdown-menu')
if(menu){
menu.classList.remove('show')
}
2022-05-03 20:50:57 +02:00
}
2021-09-05 21:05:55 +02:00
const init = () => {
2022-05-03 20:50:57 +02:00
console.log(`${NAME}: init`)
2021-09-05 21:05:55 +02:00
2023-04-20 15:28:54 +02:00
const clickableEls = document.querySelectorAll(`.${NAME},[data-bs-toggle="dropdown"],.dropdown-toggle`)
2022-05-03 20:50:57 +02:00
const hoverableEls = document.querySelectorAll('[data-bs-toggle="hover"]')
2022-03-18 13:09:51 +01:00
2021-09-05 21:05:55 +02:00
const attachHoverEvents = (el) => {
2022-09-12 22:07:08 +02:00
el.addEventListener('mouseover', Show, false)
el.addEventListener('mouseleave', Hide, false)
2021-09-05 21:05:55 +02:00
2022-05-03 20:50:57 +02:00
el.classList.add(`${NAME}-active`)
}
2021-09-05 21:05:55 +02:00
const attachClickEvents = (el) => {
2021-12-28 02:01:36 +01:00
el.addEventListener('click', (e) => {
2022-05-03 20:50:57 +02:00
e.preventDefault()
2022-05-03 20:50:57 +02:00
const el = e.currentTarget
const parent = el.closest('.dropdown')
2023-04-20 14:55:51 +02:00
const href = el.getAttribute('href')
// nav second click
if(href && el.dataset.firstClick) {
2023-04-20 21:22:29 +02:00
console.log(`${NAME}: nav second click`)
window.location.href = href
2023-04-20 14:55:51 +02:00
}
2023-04-20 21:22:29 +02:00
el.dataset.firstClick = true
2023-04-20 14:55:51 +02:00
2023-04-20 21:22:29 +02:00
if(parent){
// big screen click
2023-05-18 02:49:02 +02:00
if(href && window.innerWidth > 768 && parent.classList.contains('active-dropdown')){
2023-04-20 21:22:29 +02:00
console.log(`${NAME}: big screen | nav click the dropdown is shown already`)
window.location.href = href
}
console.log(`${NAME}: nav toggle`)
Toggle(parent)
}
2022-05-03 20:50:57 +02:00
})
2021-09-05 21:05:55 +02:00
2022-05-03 20:50:57 +02:00
el.classList.add(`${NAME}-active`)
}
2021-09-05 21:05:55 +02:00
2022-03-18 13:09:51 +01:00
// Hide all for outside clicks
2022-05-03 20:50:57 +02:00
/* document.addEventListener('click', function (event) {
2022-05-05 15:08:13 +02:00
const isClickInside = clickableEls.contains(event.target)
2022-03-18 13:09:51 +01:00
if (!isClickInside) {
2022-05-05 15:08:13 +02:00
HideAll()
2022-03-18 13:09:51 +01:00
}
2022-05-05 15:08:13 +02:00
}) */
2022-03-18 13:09:51 +01:00
2022-01-03 05:59:41 +01:00
document.addEventListener('click', (event) => {
2022-05-03 20:50:57 +02:00
let breakPath = false
const path = event.path || (event.composedPath && event.composedPath())
2022-03-18 13:09:51 +01:00
if (!path) {
2022-05-03 20:50:57 +02:00
console.warn('Browser does not provide event path to hide dropdowns on outside click')
2022-03-18 13:09:51 +01:00
}
path.forEach((el, i) => {
2022-01-03 05:59:41 +01:00
if (breakPath) {
2022-05-03 20:50:57 +02:00
return
2022-01-03 05:59:41 +01:00
}
if (el === document) {
2022-05-03 20:50:57 +02:00
HideAll()
2022-01-03 05:59:41 +01:00
}
if (el.classList && el.classList.contains('dropdown-toggle')) {
2022-05-03 20:50:57 +02:00
breakPath = true
2022-01-03 05:59:41 +01:00
}
2022-05-03 20:50:57 +02:00
})
})
2022-01-03 05:59:41 +01:00
2022-03-18 13:09:51 +01:00
hoverableEls.forEach((el, i) => {
2022-05-03 20:50:57 +02:00
const parent = el.closest('.dropdown')
2023-03-28 13:25:33 +02:00
if(parent){
attachHoverEvents(parent)
}
2022-05-03 20:50:57 +02:00
})
2021-09-05 21:05:55 +02:00
2022-03-18 13:09:51 +01:00
clickableEls.forEach((el, i) => {
2022-05-03 20:50:57 +02:00
attachClickEvents(el)
})
}
2021-09-05 21:05:55 +02:00
2022-05-03 20:50:57 +02:00
window.addEventListener(`${Events.LODEDANDREADY}`, init)
window.addEventListener(`${Events.AJAX}`, init)
})(window)
2021-09-05 21:05:55 +02:00
2022-05-03 20:50:57 +02:00
export default DropdownHoverUI