Make QR context menu display options more consistent with QR bar Use QR title as tooltip if set on the QR Add qr--hidden class to "invisible" context items to allow hiding with CSS Add title and isHidden props to MenuItem Remove domIcon and domLabel props: not needed for ctx menu rendering; isForceExpanded: unimplemented

3a1a955164427cfbae63c4ad97845e500dba676b

ceruleandeep <deep@cerulean.navy>

3 files changed, +45 -9Ignore whitespace
public/scripts/extensions/quick-reply/src/ui/ctx/ContextMenu.js+5 -1
@@ -19,7 +19,7 @@ export class ContextMenu {
1919 this.itemList = this.build(qr).children;
2020 this.itemList.forEach(item => {
2121 item.onExpand = () => {
2222 this.itemList.filter(it => it !== item)
2323 .forEach(it => it.collapse());
2424 };
2525 });
@@ -36,7 +36,9 @@ export class ContextMenu {
3636 icon: qr.icon,
3737 showLabel: qr.showLabel,
3838 label: qr.label,
39+ title: qr.title,
3940 message: (chainedMessage && qr.message ? `${chainedMessage} | ` : '') + qr.message,
41+ isHidden: qr.isHidden,
4042 children: [],
4143 };
4244 qr.contextList.forEach((cl) => {
@@ -51,7 +53,9 @@ export class ContextMenu {
5153 subTree.icon,
5254 subTree.showLabel,
5355 subTree.label,
56+ subTree.title,
5457 subTree.message,
58+ subTree.isHidden,
5559 (evt) => {
5660 evt.stopPropagation();
5761 const finalQr = Object.assign(new QuickReply(), subQr);
public/scripts/extensions/quick-reply/src/ui/ctx/MenuHeader.js+1 -1
@@ -2,7 +2,7 @@ import { MenuItem } from './MenuItem.js';
22
33export class MenuHeader extends MenuItem {
44 constructor(/**@type {String}*/label) {
55 super(null, null, label, null, null, false, null, []);
66 }
77
88
public/scripts/extensions/quick-reply/src/ui/ctx/MenuItem.js+39 -7
@@ -4,11 +4,12 @@ export class MenuItem {
44 /**@type {string}*/ icon;
55 /**@type {boolean}*/ showLabel;
66 /**@type {string}*/ label;
7+ /**@type {string}*/ title;
78 /**@type {object}*/ value;
9+ /**@type {boolean}*/ isHidden = false;
810 /**@type {function}*/ callback;
911 /**@type {MenuItem[]}*/ childList = [];
1012 /**@type {SubMenu}*/ subMenu;
11- /**@type {boolean}*/ isForceExpanded = false;
1213
1314 /**@type {HTMLElement}*/ root;
1415
@@ -19,35 +20,67 @@ export class MenuItem {
1920
2021 /**
2122 *
2223 * @param {?string} icon
2324 * @param {?boolean} showLabel
2425 * @param {string} label
26+ * @param {?string} title Tooltip
2527 * @param {object} value
28+ * @param {boolean} isHidden QR is Invisible (auto-execute only)
2629 * @param {function} callback
2730 * @param {MenuItem[]} children
2831 */
2932 constructor(icon, showLabel, label, title, value, isHidden, callback, children = []) {
3033 this.icon = icon;
3134 this.showLabel = showLabel;
3235 this.label = label;
36+ this.title = title;
3337 this.value = value;
38+ this.isHidden = isHidden;
3439 this.callback = callback;
3540 this.childList = children;
3641 }
3742
3843
44+ /**
45+ * Renders the MenuItem
46+ *
47+ * A .qr--hidden class is added to:
48+ * - the item if it is "Invisible (auto-execute only)"
49+ * - the icon if no icon is set
50+ * - the label if an icon is set and showLabel is false
51+ *
52+ * There is no .qr--hidden class defined in default CSS, since having items
53+ * that are invisible on the QR bar but visible in the context menu,
54+ * or icon-only on the QR bar but labelled in the context menu, is a valid use case.
55+ *
56+ * To hide optional labels when icons are present, add this user CSS:
57+ * .ctx-menu .ctx-item .qr--button-label.qr--hidden {display: none;}
58+ * To hide icons when no icon is present (removes unwanted padding):
59+ * .ctx-menu .ctx-item .qr--button-icon.qr--hidden {display: none;}
60+ * To hide items that are set "invisible":
61+ * .ctx-menu .ctx-item.qr--hidden {display: none;}
62+ * To target submenus only, use .ctx-menu .ctx-sub-menu .qr--hidden {display: none;}
63+ *
64+ * @returns {HTMLElement}
65+ */
3966 render() {
4067 if (!this.root) {
4168 const item = document.createElement('li'); {
4269 this.root = item;
4370 item.classList.add('list-group-item');
4471 item.classList.add('ctx-item');
45- item.title = this.value;
72+
73+ // if this item is Invisible, add the hidden class
74+ if (this.isHidden) item.classList.add('qr--hidden');
75+
76+ // if a title/tooltip is set, add it, otherwise use the QR content
77+ // same as for the main QR list
78+ item.title = this.title || this.value;
79+
4680 if (this.callback) {
4781 item.addEventListener('click', (evt) => this.callback(evt, this));
4882 }
4983 const icon = document.createElement('div'); {
50- this.domIcon = icon;
5184 icon.classList.add('qr--button-icon');
5285 icon.classList.add('fa-solid');
5386 if (!this.icon) icon.classList.add('qr--hidden');
@@ -55,7 +88,6 @@ export class MenuItem {
5588 item.append(icon);
5689 }
5790 const lbl = document.createElement('div'); {
58- this.domLabel = lbl;
5991 lbl.classList.add('qr--button-label');
6092 if (this.icon && !this.showLabel) lbl.classList.add('qr--hidden');
6193 lbl.textContent = this.label;