-
-
Notifications
You must be signed in to change notification settings - Fork 18.2k
/
treeview.ts
135 lines (108 loc) · 3.51 KB
/
treeview.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
* --------------------------------------------
* @file AdminLTE treeview.ts
* @description Treeview plugin for AdminLTE.
* @license MIT
* --------------------------------------------
*/
import {
onDOMContentLoaded,
slideDown,
slideUp
} from './util/index'
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
// const NAME = 'Treeview'
const DATA_KEY = 'lte.treeview'
const EVENT_KEY = `.${DATA_KEY}`
const EVENT_EXPANDED = `expanded${EVENT_KEY}`
const EVENT_COLLAPSED = `collapsed${EVENT_KEY}`
// const EVENT_LOAD_DATA_API = `load${EVENT_KEY}`
const CLASS_NAME_MENU_OPEN = 'menu-open'
const SELECTOR_NAV_ITEM = '.nav-item'
const SELECTOR_NAV_LINK = '.nav-link'
const SELECTOR_TREEVIEW_MENU = '.nav-treeview'
const SELECTOR_DATA_TOGGLE = '[data-lte-toggle="treeview"]'
const Default = {
animationSpeed: 300,
accordion: true
}
type Config = {
animationSpeed: number;
accordion: boolean;
}
/**
* Class Definition
* ====================================================
*/
class Treeview {
_element: HTMLElement
_config: Config
constructor(element: HTMLElement, config: Config) {
this._element = element
this._config = { ...Default, ...config }
}
open(): void {
const event = new Event(EVENT_EXPANDED)
if (this._config.accordion) {
const openMenuList = this._element.parentElement?.querySelectorAll(`${SELECTOR_NAV_ITEM}.${CLASS_NAME_MENU_OPEN}`)
openMenuList?.forEach(openMenu => {
if (openMenu !== this._element.parentElement) {
openMenu.classList.remove(CLASS_NAME_MENU_OPEN)
const childElement = openMenu?.querySelector(SELECTOR_TREEVIEW_MENU) as HTMLElement | undefined
if (childElement) {
slideUp(childElement, this._config.animationSpeed)
}
}
})
}
this._element.classList.add(CLASS_NAME_MENU_OPEN)
const childElement = this._element?.querySelector(SELECTOR_TREEVIEW_MENU) as HTMLElement | undefined
if (childElement) {
slideDown(childElement, this._config.animationSpeed)
}
this._element.dispatchEvent(event)
}
close(): void {
const event = new Event(EVENT_COLLAPSED)
this._element.classList.remove(CLASS_NAME_MENU_OPEN)
const childElement = this._element?.querySelector(SELECTOR_TREEVIEW_MENU) as HTMLElement | undefined
if (childElement) {
slideUp(childElement, this._config.animationSpeed)
}
this._element.dispatchEvent(event)
}
toggle(): void {
if (this._element.classList.contains(CLASS_NAME_MENU_OPEN)) {
this.close()
} else {
this.open()
}
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
onDOMContentLoaded(() => {
const button = document.querySelectorAll(SELECTOR_DATA_TOGGLE)
button.forEach(btn => {
btn.addEventListener('click', event => {
const target = event.target as HTMLElement
const targetItem = target.closest(SELECTOR_NAV_ITEM) as HTMLElement | undefined
const targetLink = target.closest(SELECTOR_NAV_LINK) as HTMLAnchorElement | undefined
if (target?.getAttribute('href') === '#' || targetLink?.getAttribute('href') === '#') {
event.preventDefault()
}
if (targetItem) {
const data = new Treeview(targetItem, Default)
data.toggle()
}
})
})
})
export default Treeview