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
|
import Menu from '@src/Menu';
const CLASSNAME_OPENED = 'jsxc-menu--opened';
const menuTemplate = require('../../template/menu.hbs');
export default class MenuComponent<Params extends unknown[]> {
private element: JQuery<HTMLElement>;
private timer: number;
constructor(
label: string | { text: string; icon: string },
type: 'pushup' | 'vertical-left' | 'vertical-right',
private menu: Menu<Params>,
private params: Params,
theme: 'dark' | 'light' = 'light'
) {
this.element = $(
menuTemplate({
classes: `jsxc-menu--${type} jsxc-menu--${theme}`,
labelText: typeof label === 'object' ? label.text : '',
})
);
const icon = typeof label === 'string' ? label : label.icon;
if (icon) {
this.element.find('.jsxc-menu__button').prepend($('<i>').addClass(`jsxc-icon-${icon} jsxc-icon--center`));
}
this.registerHandlers();
}
public getElement(): JQuery<HTMLElement> {
return this.element;
}
public getButtonElement(): JQuery {
return this.element.find('.jsxc-menu__button');
}
public toggle(): void {
if (this.element.hasClass(CLASSNAME_OPENED)) {
this.closeMenu();
} else {
this.openMenu();
}
}
private addEntry(
label: string,
handler: (ev: JQuery.ClickEvent) => void,
icon?: string,
disabled?: boolean
): JQuery {
let itemElement = $('<li>');
if (disabled) {
itemElement.addClass('jsxc-disabled');
}
itemElement.text(label);
itemElement.on('click', handler);
if (icon) {
itemElement.prepend($('<i>').addClass(`jsxc-icon-${icon} jsxc-icon--center`));
}
this.element.find('ul').append(itemElement);
return itemElement;
}
private clearEntries() {
this.element.find('ul').empty();
}
private registerHandlers() {
this.element.on('click', this.onClick);
this.element.on('mouseleave', this.onMouseLeave);
this.element.on('mouseenter', this.onMouseEnter);
}
private onClick = (ev: JQuery.ClickEvent) => {
ev.stopPropagation();
ev.preventDefault();
this.toggle();
};
private onMouseLeave = () => {
if (this.element.hasClass(CLASSNAME_OPENED)) {
this.timer = window.setTimeout(this.closeMenu, 2000);
}
};
private onMouseEnter = () => {
window.clearTimeout(this.timer);
};
private openMenu = () => {
this.clearEntries();
this.menu.getMenuItems(...this.params).map(({ label, handler, disabled, icon }) => {
this.addEntry(label, (ev: JQuery.ClickEvent) => handler(ev.originalEvent), icon, disabled);
});
$('body').off('click', null, this.closeMenu);
// hide other lists
$('body').trigger('click');
window.clearTimeout(this.timer);
this.element.addClass(CLASSNAME_OPENED);
$('body').on('click', this.closeMenu);
};
private closeMenu = () => {
this.element.removeClass(CLASSNAME_OPENED);
this.clearEntries();
$('body').off('click', null, this.closeMenu);
};
}
|