From 2bdde5dc6119df61cd35e6d173990addd10be017 Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 7 Aug 2024 13:18:10 -0600 Subject: [PATCH] =?UTF-8?q?Context=20menu=20checkbox=20changes=20-=20Make?= =?UTF-8?q?=20sure=20check=20item=20does=20not=20close=20sub-menu=20-=20Us?= =?UTF-8?q?e=20different=20icons=20=E2=98=90/=E2=98=91=20instead=20of=20sh?= =?UTF-8?q?oelace's=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/js/egw_action/EgwMenuShoelace.ts | 61 ++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/api/js/egw_action/EgwMenuShoelace.ts b/api/js/egw_action/EgwMenuShoelace.ts index be69b9d60a..aadd2cbe93 100644 --- a/api/js/egw_action/EgwMenuShoelace.ts +++ b/api/js/egw_action/EgwMenuShoelace.ts @@ -1,5 +1,5 @@ -import {css, html, LitElement, nothing} from "lit"; -import {SlMenu, SlMenuItem} from "@shoelace-style/shoelace"; +import {css, html, LitElement, nothing, PropertyValues} from "lit"; +import {SlIcon, SlMenu, SlMenuItem} from "@shoelace-style/shoelace"; import {egwMenuItem} from "./egw_menu"; import {customElement} from "lit/decorators/custom-element.js"; import {repeat} from "lit/directives/repeat.js"; @@ -35,6 +35,16 @@ export class EgwMenuShoelace extends LitElement min-width: var(--sl-spacing-2x-large); } + /* Customise checkbox menuitem */ + + sl-menu-item[type="checkbox"]::part(checked-icon) { + visibility: visible; + } + + sl-menu-item[type="checkbox"]:not([checked])::part(checked-icon) { + color: var(--sl-color-neutral-300); + } + et2-image { line-height: normal; width: 1.3em; @@ -82,6 +92,24 @@ export class EgwMenuShoelace extends LitElement } } + protected updated(_changedProperties : PropertyValues) + { + super.updated(_changedProperties); + + // Checkbox indicators + this.shadowRoot.querySelectorAll("sl-menu-item[type=checkbox]").forEach(async(item : SlMenuItem) => + { + await item.updateComplete; + const icon : SlIcon = item.shadowRoot.querySelector("[part=\"checked-icon\"] sl-icon"); + if(!icon) + { + return; + } + icon.name = item.checked ? "check-square" : "square"; + icon.library = "default"; + }) + } + public showAt(_x, _y, _onHide) { this.removeCallback = _onHide; @@ -148,7 +176,12 @@ export class EgwMenuShoelace extends LitElement const item = event.detail.item.value; if(item.checkbox) { - item.checked = event.detail.item.checked; + // Update our internal data + item.data.checked = item.checked = event.detail.item.checked; + + // Update icon since updated won't fire + const icon : SlIcon = event.detail.item.shadowRoot.querySelector("[part=\"checked-icon\"] sl-icon"); + icon.name = item.checked ? "check-square" : "square"; return; } if(typeof item.onClick == "function") @@ -159,6 +192,27 @@ export class EgwMenuShoelace extends LitElement } } + handleCheckboxClick(event) + { + const check = event.target.closest("sl-menu-item"); + if(!check || check.parentElement == this) + { + return; + } + + // Make sure sub-menu does not close + event.stopPropagation(); + + // Normal select event + check.checked = !check.checked; + check.dispatchEvent(new CustomEvent("sl-select", { + bubbles: true, + cancelable: false, + composed: true, + detail: {item: check} + })); + } + handleDocumentClick(event) { if(!event.composedPath().includes(this)) @@ -195,6 +249,7 @@ export class EgwMenuShoelace extends LitElement ?checked=${item.checkbox && item.checked} ?disabled=${!item.enabled} .value=${item} + @click=${item.checkbox ? this.handleCheckboxClick : nothing} > ${item.iconUrl ? html` ` : nothing}