From 8172f6e72d16fe2b216f095aa31229042094385f Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 12 May 2022 15:22:49 -0600 Subject: [PATCH] Et2DropdownButton WIP --- .../Et2DropdownButton/Et2DropdownButton.ts | 106 ++++++++++++++++++ api/js/etemplate/Et2Image/Et2Image.ts | 3 + .../etemplate/Et2Select/FindSelectOptions.ts | 2 + api/js/etemplate/Et2Widget/Et2Widget.ts | 5 +- api/js/etemplate/Styles/shoelace.ts | 24 ++++ api/js/etemplate/etemplate2.ts | 1 + filemanager/inc/class.filemanager_ui.inc.php | 5 +- 7 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 api/js/etemplate/Et2DropdownButton/Et2DropdownButton.ts create mode 100644 api/js/etemplate/Styles/shoelace.ts diff --git a/api/js/etemplate/Et2DropdownButton/Et2DropdownButton.ts b/api/js/etemplate/Et2DropdownButton/Et2DropdownButton.ts new file mode 100644 index 0000000000..aeacfa8dad --- /dev/null +++ b/api/js/etemplate/Et2DropdownButton/Et2DropdownButton.ts @@ -0,0 +1,106 @@ +/** + * EGroupware eTemplate2 - Dropdown Button widget + * + * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License + * @package etemplate + * @subpackage api + * @link https://www.egroupware.org + * @author Nathan Gray + */ + + +import {Et2Button} from "../Et2Button/Et2Button"; +import {SlButtonGroup, SlDropdown} from "@shoelace-style/shoelace"; +import {css, html, repeat, TemplateResult} from "@lion/core"; +import {Et2widgetWithSelectMixin} from "../Et2Select/Et2WidgetWithSelectMixin"; +import {SelectOption} from "../Et2Select/FindSelectOptions"; +import {buttonStyles} from "../Et2Button/ButtonStyles"; +import shoelace from "../Styles/shoelace"; + +/** + * A split button - a button with a dropdown list + * + * There are several parts to the button UI: + * - Container: This is what is percieved as the dropdown button, the whole package together + * - Button: The part on the left that can be clicked + * - Arrow: The button to display the choices + * - Menu: The list of choices + * + * Menu options are passed via the select_options. They are normally the same + * as for a select box, but the title can also be full HTML if needed. + * + */ +export class Et2DropdownButton extends Et2widgetWithSelectMixin(Et2Button) +{ + + static get styles() + { + return [ + ...super.styles, + shoelace, + buttonStyles, + css` + :host { + display: contents; + } + .menu-item { + width: --sl-input-height-medium; + max-height: var(--sl-input-height-medium) + } + + + `, + ]; + } + + // Make sure imports stay + private _group : SlButtonGroup; + private _dropdow : SlDropdown; + + + connectedCallback() + { + super.connectedCallback(); + + // Rebind click to just the button + this.removeEventListener("click", this._handleClick); + this.buttonNode.addEventListener("click", this._handleClick); + } + + render() + { + return html` + + ${this.label} + + + + ${repeat(this.select_options, (option : SelectOption) => option.value, option => + this._itemTemplate(option) + )} + + + + `; + } + + protected _itemTemplate(option : SelectOption) : TemplateResult + { + let icon = option.icon ? html` + ` : ''; + + return html` + + ${icon} + ${option.label} + `; + } + + get buttonNode() + { + return this.shadowRoot.querySelector("et2-button"); + } +} + +// @ts-ignore TypeScript is not recognizing that Et2Button is a LitElement +customElements.define("et2-dropdown-button", Et2DropdownButton); \ No newline at end of file diff --git a/api/js/etemplate/Et2Image/Et2Image.ts b/api/js/etemplate/Et2Image/Et2Image.ts index 0d45262a6c..9d36751b87 100644 --- a/api/js/etemplate/Et2Image/Et2Image.ts +++ b/api/js/etemplate/Et2Image/Et2Image.ts @@ -27,6 +27,9 @@ export class Et2Image extends Et2Widget(SlotMixin(LitElement)) implements et2_ID max-height: 100%; max-width: 100%; } + :host([icon]) { + height: 1.3rem; + } `, ]; } diff --git a/api/js/etemplate/Et2Select/FindSelectOptions.ts b/api/js/etemplate/Et2Select/FindSelectOptions.ts index 10e1b2a22d..46aada6887 100644 --- a/api/js/etemplate/Et2Select/FindSelectOptions.ts +++ b/api/js/etemplate/Et2Select/FindSelectOptions.ts @@ -13,6 +13,8 @@ export interface SelectOption label : string; // Hover help text title? : string; + // Related image or icon + icon? : string; } /** diff --git a/api/js/etemplate/Et2Widget/Et2Widget.ts b/api/js/etemplate/Et2Widget/Et2Widget.ts index d53cf7c8ca..8e6f933b9d 100644 --- a/api/js/etemplate/Et2Widget/Et2Widget.ts +++ b/api/js/etemplate/Et2Widget/Et2Widget.ts @@ -214,7 +214,8 @@ const Et2WidgetMixin = (superClass) => super(...args); this.disabled = false; - this.addEventListener("click", this._handleClick.bind(this)); + this._handleClick = this._handleClick.bind(this); + this.addEventListener("click", this._handleClick); } connectedCallback() @@ -231,7 +232,7 @@ const Et2WidgetMixin = (superClass) => { this.egw()?.tooltipUnbind(this); - this.removeEventListener("click", this._handleClick.bind(this)); + this.removeEventListener("click", this._handleClick); } /** diff --git a/api/js/etemplate/Styles/shoelace.ts b/api/js/etemplate/Styles/shoelace.ts new file mode 100644 index 0000000000..d57e0932e4 --- /dev/null +++ b/api/js/etemplate/Styles/shoelace.ts @@ -0,0 +1,24 @@ +import sl_css from '@shoelace-style/shoelace/dist/themes/light.styles.js'; +import {css} from "lit"; + +/** + * Customise shoelace styles to match our stuff + */ +export default [sl_css, css` + :root, + :host, + .sl-theme-light { + --sl-input-height-small: 18px; + --sl-input-height-medium: 24px; + + --sl-spacing-small: 0.1rem; + --sl-spacing-medium: 0.5rem; + + --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/api/js/etemplate/etemplate2.ts b/api/js/etemplate/etemplate2.ts index 78daf183af..6e8d6916db 100644 --- a/api/js/etemplate/etemplate2.ts +++ b/api/js/etemplate/etemplate2.ts @@ -37,6 +37,7 @@ import './Et2Date/Et2DateTimeReadonly'; import './Et2Date/Et2DateTimeToday'; import './Et2Description/Et2Description'; import './Et2Dialog/Et2Dialog'; +import './Et2DropdownButton/Et2DropdownButton'; import './Expose/Et2ImageExpose'; import './Expose/Et2DescriptionExpose'; import './Et2Image/Et2Image'; diff --git a/filemanager/inc/class.filemanager_ui.inc.php b/filemanager/inc/class.filemanager_ui.inc.php index b4b44a1d4a..6dff89e1f5 100644 --- a/filemanager/inc/class.filemanager_ui.inc.php +++ b/filemanager/inc/class.filemanager_ui.inc.php @@ -126,9 +126,10 @@ class filemanager_ui $sel_options = array (); foreach ($actions as $action => $value) { - $sel_options[$action] = array ( + $sel_options[] = array( + 'value' => $action, 'label' => $value['caption'], - 'icon' => $value['icon'] + 'icon' => $value['icon'] ); } return $sel_options;