mirror of https://github.com/ColorlibHQ/AdminLTE
201 lines
5.4 KiB
TypeScript
201 lines
5.4 KiB
TypeScript
/**
|
|
* --------------------------------------------
|
|
* AdminLTE push-menu.ts
|
|
* License MIT
|
|
* --------------------------------------------
|
|
*/
|
|
|
|
import {
|
|
domReady
|
|
} from './util/index'
|
|
|
|
/**
|
|
* ------------------------------------------------------------------------
|
|
* Constants
|
|
* ------------------------------------------------------------------------
|
|
*/
|
|
|
|
const DATA_KEY = 'lte.push-menu'
|
|
const EVENT_KEY = `.${DATA_KEY}`
|
|
|
|
const EVENT_OPEN = `open${EVENT_KEY}`
|
|
const EVENT_COLLAPSE = `collapse${EVENT_KEY}`
|
|
|
|
const CLASS_NAME_SIDEBAR_MINI = 'sidebar-mini'
|
|
const CLASS_NAME_SIDEBAR_COLLAPSE = 'sidebar-collapse'
|
|
const CLASS_NAME_SIDEBAR_OPEN = 'sidebar-open'
|
|
const CLASS_NAME_SIDEBAR_IS_HOVER = 'sidebar-is-hover'
|
|
const CLASS_NAME_SIDEBAR_EXPAND = 'sidebar-expand'
|
|
const CLASS_NAME_SIDEBAR_OVERLAY = 'sidebar-overlay'
|
|
const CLASS_NAME_MENU_OPEN = 'menu-open'
|
|
|
|
const SELECTOR_SIDEBAR_WRAPPER = '.sidebar-wrapper'
|
|
const SELECTOR_SIDEBAR_MENU = '.sidebar-menu'
|
|
const SELECTOR_NAV_ITEM = '.nav-item'
|
|
const SELECTOR_NAV_TREEVIEW = '.nav-treeview'
|
|
const SELECTOR_APP_WRAPPER = '.app-wrapper'
|
|
const SELECTOR_SIDEBAR_EXPAND = `[class*="${CLASS_NAME_SIDEBAR_EXPAND}"]`
|
|
const SELECTOR_SIDEBAR_TOGGLE = '[data-lte-toggle="sidebar"]'
|
|
|
|
type Config = {
|
|
sidebarBreakpoint: number;
|
|
}
|
|
|
|
const Defaults = {
|
|
sidebarBreakpoint: 992
|
|
}
|
|
|
|
/**
|
|
* Class Definition
|
|
* ====================================================
|
|
*/
|
|
|
|
class PushMenu {
|
|
_element: HTMLElement
|
|
_config: Config
|
|
|
|
constructor(element: HTMLElement, config: Config) {
|
|
this._element = element
|
|
this._config = { ...Defaults, ...config }
|
|
}
|
|
|
|
// TODO
|
|
menusClose() {
|
|
const navTreeview = document.querySelectorAll<HTMLElement>(SELECTOR_NAV_TREEVIEW)
|
|
|
|
for (const navTree of navTreeview) {
|
|
navTree.style.removeProperty('display')
|
|
navTree.style.removeProperty('height')
|
|
}
|
|
|
|
const navSidebar = document.querySelector(SELECTOR_SIDEBAR_MENU)
|
|
const navItem = navSidebar?.querySelectorAll(SELECTOR_NAV_ITEM)
|
|
|
|
if (navItem) {
|
|
for (const navI of navItem) {
|
|
navI.classList.remove(CLASS_NAME_MENU_OPEN)
|
|
}
|
|
}
|
|
}
|
|
|
|
expand() {
|
|
const event = new Event(EVENT_OPEN)
|
|
|
|
document.body.classList.remove(CLASS_NAME_SIDEBAR_COLLAPSE)
|
|
document.body.classList.add(CLASS_NAME_SIDEBAR_OPEN)
|
|
|
|
this._element.dispatchEvent(event)
|
|
}
|
|
|
|
collapse() {
|
|
const event = new Event(EVENT_COLLAPSE)
|
|
|
|
document.body.classList.remove(CLASS_NAME_SIDEBAR_OPEN)
|
|
document.body.classList.add(CLASS_NAME_SIDEBAR_COLLAPSE)
|
|
|
|
this._element.dispatchEvent(event)
|
|
}
|
|
|
|
sidebarHover() {
|
|
const selSidebar = document.querySelector(SELECTOR_SIDEBAR_WRAPPER)
|
|
|
|
if (selSidebar) {
|
|
selSidebar.addEventListener('mouseover', () => {
|
|
document.body.classList.add(CLASS_NAME_SIDEBAR_IS_HOVER)
|
|
})
|
|
|
|
selSidebar.addEventListener('mouseout', () => {
|
|
document.body.classList.remove(CLASS_NAME_SIDEBAR_IS_HOVER)
|
|
})
|
|
}
|
|
}
|
|
|
|
addSidebarBreakPoint() {
|
|
const sidebarExpandList = document.querySelector(SELECTOR_SIDEBAR_EXPAND)?.classList ?? []
|
|
const sidebarExpand = [...sidebarExpandList].find(className => className.startsWith(CLASS_NAME_SIDEBAR_EXPAND)) ?? ''
|
|
const sidebar = document.getElementsByClassName(sidebarExpand)[0]
|
|
const sidebarContent = window.getComputedStyle(sidebar, '::before').getPropertyValue('content')
|
|
this._config = { ...this._config, sidebarBreakpoint: Number(sidebarContent.replace(/[^\d.-]/g, '')) }
|
|
|
|
if (window.innerWidth <= this._config.sidebarBreakpoint) {
|
|
this.collapse()
|
|
} else {
|
|
if (!document.body.classList.contains(CLASS_NAME_SIDEBAR_MINI)) {
|
|
this.expand()
|
|
}
|
|
|
|
if (document.body.classList.contains(CLASS_NAME_SIDEBAR_MINI)) {
|
|
this.collapse()
|
|
}
|
|
}
|
|
}
|
|
|
|
toggle() {
|
|
if (document.body.classList.contains(CLASS_NAME_SIDEBAR_COLLAPSE)) {
|
|
this.expand()
|
|
} else {
|
|
this.collapse()
|
|
}
|
|
}
|
|
|
|
init() {
|
|
this.addSidebarBreakPoint()
|
|
this.sidebarHover()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* ------------------------------------------------------------------------
|
|
* Data Api implementation
|
|
* ------------------------------------------------------------------------
|
|
*/
|
|
|
|
domReady(() => {
|
|
const data = new PushMenu(document.body, Defaults)
|
|
data.init()
|
|
|
|
window.addEventListener('resize', () => {
|
|
data.init()
|
|
})
|
|
|
|
const sidebarOverlay = document.createElement('div')
|
|
sidebarOverlay.className = CLASS_NAME_SIDEBAR_OVERLAY
|
|
document.querySelector(SELECTOR_APP_WRAPPER)?.append(sidebarOverlay)
|
|
|
|
sidebarOverlay.addEventListener('touchstart', event => {
|
|
event.preventDefault()
|
|
const target = event.currentTarget as HTMLElement
|
|
const data = new PushMenu(target, Defaults)
|
|
data.collapse()
|
|
})
|
|
sidebarOverlay.addEventListener('click', event => {
|
|
event.preventDefault()
|
|
const target = event.currentTarget as HTMLElement
|
|
const data = new PushMenu(target, Defaults)
|
|
data.collapse()
|
|
})
|
|
|
|
const fullBtn = document.querySelectorAll(SELECTOR_SIDEBAR_TOGGLE)
|
|
|
|
for (const btn of fullBtn) {
|
|
btn.addEventListener('click', event => {
|
|
event.preventDefault()
|
|
|
|
let button = event.currentTarget as HTMLElement | undefined
|
|
|
|
if (button?.dataset.lteToggle !== 'sidebar') {
|
|
button = button?.closest(SELECTOR_SIDEBAR_TOGGLE) as HTMLElement | undefined
|
|
}
|
|
|
|
if (button) {
|
|
event?.preventDefault()
|
|
const data = new PushMenu(button, Defaults)
|
|
data.toggle()
|
|
}
|
|
})
|
|
}
|
|
})
|
|
|
|
export default PushMenu
|
|
|