egroupware_official/api/js/etemplate/Et2Checkbox/Et2Checkbox.ts
ralf d7391b4dc6 allow to set (string) "true" as selectedValue for a checkbox, while default is (boolean) true and false for unselectedValue
also fix validation in case an old eTemplate with attribute (un)selected_value is used
2024-08-07 09:21:37 +02:00

142 lines
2.8 KiB
TypeScript

/**
* EGroupware eTemplate2 - Checkbox 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} from "lit";
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
import '../Et2Image/Et2Image';
import {SlCheckbox} from "@shoelace-style/shoelace";
import shoelace from "../Styles/shoelace";
import {property} from "lit/decorators/property.js";
export class Et2Checkbox extends Et2InputWidget(SlCheckbox)
{
/**
* Value to set checkbox in (third) indeterminate state
*/
static readonly INDETERMINATE = '***undefined***';
static get styles()
{
return [
...shoelace,
...super.styles,
css`
:host {
/* Make it line up with the middle of surroundings */
margin: auto 0px;
vertical-align: baseline;
}
:host([disabled]) {
display: initial;
}
/* Fix positioning */
.checkbox {
position: relative;
}
/* Extend hover highlight to label */
.checkbox:not(.checkbox--disabled):hover {
color: var(--sl-input-border-color-hover);
}
/* Use normal color even when required */
:host([required]) .checkbox__control {
color: var(--input-text-color);
}
`,
];
}
@property({type: String})
selectedValue = true;
@property({type: String})
unselectedValue = false;
constructor()
{
super();
this.isSlComponent = true;
}
connectedCallback()
{
super.connectedCallback();
}
get label()
{
return this._labelNode?.textContent || "";
}
set label(label_text)
{
if(this._labelNode)
{
this._labelNode.textContent = label_text;
}
else
{
this.updateComplete.then(() =>
{
this.label = label_text;
})
}
}
get value() : string | boolean
{
return this.indeterminate ? undefined :
(this.checked ? this.selectedValue : this.unselectedValue);
}
set value(new_value : string | boolean)
{
this.requestUpdate("checked");
this.indeterminate = false;
if(typeof new_value === "boolean")
{
this.checked = new_value;
}
else if(new_value == this.selectedValue)
{
this.checked = true;
}
else if(new_value == this.unselectedValue)
{
this.checked = false;
}
// concept of an indeterminate value did not exist in eT2 and set value gets called with all kind of truthy of falsy values
// therefore we can NOT set everything not matching our (un)selectedValue to indeterminate!
// For now, we only do that for an explicit Et2Checkbox.INDETERMINATE value
else if (new_value === Et2Checkbox.INDETERMINATE)
{
this.indeterminate = true;
}
else
{
this.checked = !!new_value;
}
}
private get _labelNode()
{
return this.shadowRoot?.querySelector("slot:not([name])");
}
}
customElements.define("et2-checkbox", Et2Checkbox);