Et2DropdownButton WIP

This commit is contained in:
nathan 2022-05-12 15:22:49 -06:00
parent a7940fe4f6
commit 8172f6e72d
7 changed files with 142 additions and 4 deletions

View File

@ -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`
<sl-button-group>
<sl-button size="medium">${this.label}</sl-button>
<sl-dropdown placement="bottom-end">
<sl-button size="medium" slot="trigger" caret></sl-button>
<sl-menu>
${repeat(this.select_options, (option : SelectOption) => option.value, option =>
this._itemTemplate(option)
)}
</sl-menu>
</sl-dropdown>
</sl-button-group>
`;
}
protected _itemTemplate(option : SelectOption) : TemplateResult
{
let icon = option.icon ? html`
<et2-image slot="prefix" src=${option.icon} icon></et2-image>` : '';
return html`
<sl-menu-item value="${option.value}">
${icon}
${option.label}
</sl-menu-item>`;
}
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);

View File

@ -27,6 +27,9 @@ export class Et2Image extends Et2Widget(SlotMixin(LitElement)) implements et2_ID
max-height: 100%; max-height: 100%;
max-width: 100%; max-width: 100%;
} }
:host([icon]) {
height: 1.3rem;
}
`, `,
]; ];
} }

View File

@ -13,6 +13,8 @@ export interface SelectOption
label : string; label : string;
// Hover help text // Hover help text
title? : string; title? : string;
// Related image or icon
icon? : string;
} }
/** /**

View File

@ -214,7 +214,8 @@ const Et2WidgetMixin = (superClass) =>
super(...args); super(...args);
this.disabled = false; this.disabled = false;
this.addEventListener("click", this._handleClick.bind(this)); this._handleClick = this._handleClick.bind(this);
this.addEventListener("click", this._handleClick);
} }
connectedCallback() connectedCallback()
@ -231,7 +232,7 @@ const Et2WidgetMixin = (superClass) =>
{ {
this.egw()?.tooltipUnbind(this); this.egw()?.tooltipUnbind(this);
this.removeEventListener("click", this._handleClick.bind(this)); this.removeEventListener("click", this._handleClick);
} }
/** /**

View File

@ -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)
}
`];

View File

@ -37,6 +37,7 @@ import './Et2Date/Et2DateTimeReadonly';
import './Et2Date/Et2DateTimeToday'; import './Et2Date/Et2DateTimeToday';
import './Et2Description/Et2Description'; import './Et2Description/Et2Description';
import './Et2Dialog/Et2Dialog'; import './Et2Dialog/Et2Dialog';
import './Et2DropdownButton/Et2DropdownButton';
import './Expose/Et2ImageExpose'; import './Expose/Et2ImageExpose';
import './Expose/Et2DescriptionExpose'; import './Expose/Et2DescriptionExpose';
import './Et2Image/Et2Image'; import './Et2Image/Et2Image';

View File

@ -126,9 +126,10 @@ class filemanager_ui
$sel_options = array (); $sel_options = array ();
foreach ($actions as $action => $value) foreach ($actions as $action => $value)
{ {
$sel_options[$action] = array ( $sel_options[] = array(
'value' => $action,
'label' => $value['caption'], 'label' => $value['caption'],
'icon' => $value['icon'] 'icon' => $value['icon']
); );
} }
return $sel_options; return $sel_options;