diff --git a/api/js/etemplate/Et2DropdownButton/Et2DropdownButton.ts b/api/js/etemplate/Et2DropdownButton/Et2DropdownButton.ts index aeacfa8dad..c4243a3c89 100644 --- a/api/js/etemplate/Et2DropdownButton/Et2DropdownButton.ts +++ b/api/js/etemplate/Et2DropdownButton/Et2DropdownButton.ts @@ -42,29 +42,65 @@ export class Et2DropdownButton extends Et2widgetWithSelectMixin(Et2Button) css` :host { display: contents; + /** + Adapt shoelace color variables to what we want + Maybe some logical variables from etemplate2.css here? + */ + --sl-color-primary-50: rgb(244, 246, 247); + --sl-color-primary-100: var(--gray-10); + --sl-color-primary-300: var(--input-border-color); + --sl-color-primary-400: var(--input-border-color); + --sl-color-primary-700: #505050; } - .menu-item { - width: --sl-input-height-medium; - max-height: var(--sl-input-height-medium) - } - - `, ]; } + static get properties() + { + return { + ...super.properties + }; + } + // Make sure imports stay private _group : SlButtonGroup; private _dropdow : SlDropdown; + constructor() + { + super(); + + // Bind handlers - parent already got click + this._handleSelect = this._handleSelect.bind(this); + } connectedCallback() { super.connectedCallback(); - // Rebind click to just the button + // Rebind click to just the main button, not the whole thing this.removeEventListener("click", this._handleClick); - this.buttonNode.addEventListener("click", this._handleClick); + + // Need to wait until update is done and these exist + this.updateComplete.then(() => + { + this.buttonNode.addEventListener("click", this._handleClick); + this.dropdownNode.addEventListener('sl-select', this._handleSelect); + }); + } + + disconnectedCallback() + { + super.disconnectedCallback(); + if(this.buttonNode) + { + this.buttonNode.removeEventListener("click", this._handleClick); + } + if(this.dropdownNode) + { + this.dropdownNode.removeEventListener('sl-select', this._handleSelect); + } } render() @@ -96,9 +132,42 @@ export class Et2DropdownButton extends Et2widgetWithSelectMixin(Et2Button) `; } + protected _handleSelect(ev) + { + let oldValue = this._value; + this._value = ev.detail.item.value; + + // Trigger a change event + this.dispatchEvent(new Event("change")); + + // Let it bubble, if anyone else is interested + } + + get value() : string + { + return this._value; + } + + set value(new_value) + { + let oldValue = this.value; + this._value = new_value; + this.requestUpdate("value", oldValue); + } + get buttonNode() { - return this.shadowRoot.querySelector("et2-button"); + return this.shadowRoot.querySelector("#main"); + } + + get triggerButtonNode() + { + return this.shadowRoot.querySelector("[slot='trigger']"); + } + + get dropdownNode() + { + return this.shadowRoot.querySelector("sl-dropdown"); } } diff --git a/api/js/etemplate/Styles/shoelace.ts b/api/js/etemplate/Styles/shoelace.ts index d57e0932e4..0a6d7eddff 100644 --- a/api/js/etemplate/Styles/shoelace.ts +++ b/api/js/etemplate/Styles/shoelace.ts @@ -1,8 +1,19 @@ import sl_css from '@shoelace-style/shoelace/dist/themes/light.styles.js'; import {css} from "lit"; +import {registerIconLibrary} from '@shoelace-style/shoelace/dist/utilities/icon-library.js'; +import {egw} from "../../jsapi/egw_global"; + +/** + * This makes sure the built-in icons can be found + */ +registerIconLibrary('default', { + resolver: name => `${egw.webserverUrl}/node_modules/@shoelace-style/shoelace/dist/assets/icons/${name}.svg`, +}); + /** * Customise shoelace styles to match our stuff + * External CSS will override this */ export default [sl_css, css` :root, @@ -17,8 +28,5 @@ export default [sl_css, css` --sl-input-border-radius-small: 2px; --sl-input-border-radius-medium: 3px; } - .menu-item { - width: --sl-input-height-medium; - max-height: var(--sl-input-height-medium) - } + `]; \ No newline at end of file diff --git a/filemanager/templates/default/index.xet b/filemanager/templates/default/index.xet index 0facea909f..139ac27493 100644 --- a/filemanager/templates/default/index.xet +++ b/filemanager/templates/default/index.xet @@ -57,7 +57,8 @@