egroupware_official/api/js/etemplate/Layout/Et2Box/Et2Box.ts
2023-11-09 11:12:16 -07:00

187 lines
3.8 KiB
TypeScript

/**
* EGroupware eTemplate2 - Box 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 {css, html, LitElement} from "lit";
import {classMap} from "lit/directives/class-map.js";
import {Et2Widget} from "../../Et2Widget/Et2Widget";
import {et2_IDetachedDOM} from "../../et2_core_interfaces";
/**
* @summary A basic wrapper to group other widgets
*
* @slot - Any other widget
*/
export class Et2Box extends Et2Widget(LitElement) implements et2_IDetachedDOM
{
static get styles()
{
return [
...super.styles,
css`
:host {
display: block;
}
:host > div {
display: flex;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: stretch;
gap: 5px;
height: 100%;
}
:host([align="right"]) > div {
justify-content: flex-end;
}
:host([align="left"]) > div {
justify-content: flex-start;
}
:host([align="center"]) > div {
justify-content: center;
}
/* CSS for child elements */
::slotted(*) {
flex: 1 1 auto;
}
::slotted(img),::slotted(et2-image) {
/* Stop images from growing. In general we want them to stay */
flex-grow: 0;
}
::slotted([align="left"]) {
margin-right: auto;
order: -1;
}
::slotted([align="right"]) {
margin-left: auto;
order: 1;
}
/* work around for chromium print bug, see render() */
:host > .no-print-gap {
gap: 0px;
}
`,
];
}
render()
{
/**
* Work around Chromium bug
* https://bugs.chromium.org/p/chromium/issues/detail?id=1161709
*
* Printing with gap on empty element gives huge print output
*/
let noGap = false;
if(this.querySelectorAll(":scope > :not([disabled])").length == 0)
{
noGap = true;
}
return html`
<div part="base" ${this.id ? html`id="${this.id}"` : ''} class=${classMap({
"no-print-gap": noGap
})}>
<slot></slot>
</div> `;
}
set_label(new_label)
{
// Boxes don't have labels
}
_createNamespace() : boolean
{
return true;
}
/**
* Code for implementing et2_IDetachedDOM
*
* Individual widgets are detected and handled by the grid, but the interface is needed for this to happen
*
* @param {array} _attrs array to add further attributes to
*/
getDetachedAttributes(_attrs)
{
_attrs.push('data', 'onclick');
}
getDetachedNodes()
{
return [this.getDOMNode()];
}
setDetachedAttributes(_nodes, _values)
{
if(_values.data)
{
this.data = _values.data;
}
}
}
customElements.define("et2-box", Et2Box);
export class Et2HBox extends Et2Box
{
static get styles()
{
return [
...super.styles,
css`
:host > div {
flex-direction: row;
}`
];
}
}
customElements.define("et2-hbox", Et2HBox);
/**
* @summary Vertically align child widgets
*
* This box includes styling to stop children from growing vertically.
* Set css```flex-grow: 1``` on the child to allow it to grow.
*
* @slot - Any other widget
*/
export class Et2VBox extends Et2Box
{
static get styles()
{
return [
...super.styles,
css`
:host > div {
flex-direction: column;
}
:host([align="center"]) > div {
align-items: center;
}
/* CSS for child elements */
::slotted(*) {
/* Stop children from growing vertically. In general we want them to stay their "normal" height */
flex-grow: 0;
}
`
];
}
}
customElements.define("et2-vbox", Et2VBox);