Blame Raw
Cohee · e3f41666 · · 104 lines (3.3 KB)
1 contributor
1import { SubMenu } from './SubMenu.js';
2
3export class MenuItem {
4 /**@type {string}*/ icon;
5 /**@type {boolean}*/ showLabel;
6 /**@type {string}*/ label;
7 /**@type {string}*/ title;
8 /**@type {object}*/ value;
9 /**@type {function}*/ callback;
10 /**@type {MenuItem[]}*/ childList = [];
11 /**@type {SubMenu}*/ subMenu;
12
13 /**@type {HTMLElement}*/ root;
14
15 /**@type {function}*/ onExpand;
16
17
18 /**
19 *
20 * @param {?string} icon
21 * @param {?boolean} showLabel
22 * @param {string} label
23 * @param {?string} title Tooltip
24 * @param {object} value
25 * @param {function} callback
26 * @param {MenuItem[]} children
27 */
28 constructor(icon, showLabel, label, title, value, callback, children = []) {
29 this.icon = icon;
30 this.showLabel = showLabel;
31 this.label = label;
32 this.title = title;
33 this.value = value;
34 this.callback = callback;
35 this.childList = children;
36 }
37
38
39 render() {
40 if (!this.root) {
41 const item = document.createElement('li'); {
42 this.root = item;
43 item.classList.add('list-group-item');
44 item.classList.add('ctx-item');
45
46 // if a title/tooltip is set, add it, otherwise use the QR content
47 // same as for the main QR list
48 item.title = this.title || this.value;
49
50 if (this.callback) {
51 item.addEventListener('click', (evt) => this.callback(evt, this));
52 }
53 const icon = document.createElement('div'); {
54 icon.classList.add('qr--button-icon');
55 icon.classList.add('fa-solid');
56 if (!this.icon) icon.classList.add('qr--hidden');
57 else icon.classList.add(this.icon);
58 item.append(icon);
59 }
60 const lbl = document.createElement('div'); {
61 lbl.classList.add('qr--button-label');
62 if (this.icon && !this.showLabel) lbl.classList.add('qr--hidden');
63 lbl.textContent = this.label;
64 item.append(lbl);
65 }
66 if (this.childList.length > 0) {
67 item.classList.add('ctx-has-children');
68 const sub = new SubMenu(this.childList);
69 this.subMenu = sub;
70 const trigger = document.createElement('div'); {
71 trigger.classList.add('ctx-expander');
72 trigger.textContent = '⋮';
73 trigger.addEventListener('click', (evt) => {
74 evt.stopPropagation();
75 this.toggle();
76 });
77 item.append(trigger);
78 }
79 item.addEventListener('mouseover', () => sub.show(item));
80 item.addEventListener('mouseleave', () => sub.hide());
81 }
82 }
83 }
84 return this.root;
85 }
86
87
88 expand() {
89 this.subMenu?.show(this.root);
90 if (this.onExpand) {
91 this.onExpand();
92 }
93 }
94 collapse() {
95 this.subMenu?.hide();
96 }
97 toggle() {
98 if (this.subMenu.isActive) {
99 this.expand();
100 } else {
101 this.collapse();
102 }
103 }
104}