Fix some type issues to make everything play more nicely together

(Not complaining about things from parent classes being missing, mostly)
This commit is contained in:
nathan 2021-08-27 11:21:40 -06:00
parent fb69cf39fd
commit 8a2b717c51
6 changed files with 55 additions and 22 deletions

View File

@ -13,7 +13,6 @@ import {css, html} from "@lion/core";
import {LionButton} from "@lion/button"; import {LionButton} from "@lion/button";
import {SlotMixin} from "@lion/core"; import {SlotMixin} from "@lion/core";
import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget"; import {Et2InputWidget} from "../Et2InputWidget/Et2InputWidget";
import {Et2Widget} from "../Et2Widget/Et2Widget";
export class Et2Button extends Et2InputWidget(SlotMixin(LionButton)) export class Et2Button extends Et2InputWidget(SlotMixin(LionButton))
{ {
@ -179,4 +178,5 @@ export class Et2Button extends Et2InputWidget(SlotMixin(LionButton))
} }
} }
// @ts-ignore TypeScript is not recognizing that Et2Button is a LitElement
customElements.define("et2-button", Et2Button); customElements.define("et2-button", Et2Button);

View File

@ -159,7 +159,7 @@ export class Et2Date extends Et2InputWidget(LionInputDatepicker)
serializer(modelValue : Date) serializer(modelValue : Date)
{ {
// isValidDate() is hidden inside LionInputDate, and not exported // isValidDate() is hidden inside LionInputDate, and not exported
//if(!isValidDate(modelValue)) // @ts-ignore Can't call isNan(Date), but we're just checking
if(!(modelValue instanceof Date) || isNaN(modelValue)) if(!(modelValue instanceof Date) || isNaN(modelValue))
{ {
return ''; return '';
@ -183,4 +183,5 @@ export class Et2Date extends Et2InputWidget(LionInputDatepicker)
} }
} }
// @ts-ignore TypeScript is not recognizing that Et2Date is a LitElement
customElements.define("et2-date", Et2Date); customElements.define("et2-date", Et2Date);

View File

@ -6,19 +6,47 @@ import {dedupeMixin} from "@lion/core";
* This mixin will allow any LitElement to become an Et2InputWidget * This mixin will allow any LitElement to become an Et2InputWidget
* *
* Usage: * Usage:
* export class Et2Button extends Et2InputWidget(Et2Widget(LitWidget)) {...} * export class Et2Button extends Et2InputWidget(LitWidget)) {...}
*/ */
/**
* Need to define the interface first, to get around TypeScript issues with protected/public
* This must match the public API for Et2InputWidgetClass
* @see https://lit.dev/docs/composition/mixins/#typing-the-subclass
*/
export declare class Et2InputWidgetInterface
{
readOnly : boolean;
protected value : string | number | Object;
const Et2InputWidgetClass = superclass => public set_value(any) : void;
class extends Et2Widget(superclass) implements et2_IInput, et2_IInputNode
public get_value() : any;
public getValue() : any;
public isDirty() : boolean;
public resetDirty() : void;
public isValid(messages : string[]) : boolean;
}
const Et2InputWidgetMixin = (superclass) =>
{
class Et2InputWidgetClass extends Et2Widget(superclass) implements et2_IInput, et2_IInputNode
{ {
label : string = '';
protected value : string | number | Object; protected value : string | number | Object;
protected _oldValue : string | number | Object; protected _oldValue : string | number | Object;
/** WebComponent **/ /** WebComponent **/
static get styles()
{
return [
...super.styles
];
}
static get properties() static get properties()
{ {
return { return {
@ -111,6 +139,8 @@ const Et2InputWidgetClass = superclass =>
// From LionInput // From LionInput
return this._inputNode; return this._inputNode;
} }
}; }
export const Et2InputWidget = dedupeMixin(Et2InputWidgetClass); return Et2InputWidgetClass;
}
export const Et2InputWidget = dedupeMixin(Et2InputWidgetMixin);

View File

@ -79,4 +79,5 @@ export class Et2Textarea extends Et2InputWidget(LionTextarea)
} }
} }
// @ts-ignore TypeScript is not recognizing that Et2Textarea is a LitElement
customElements.define("et2-textarea", Et2Textarea); customElements.define("et2-textarea", Et2Textarea);

View File

@ -45,4 +45,5 @@ export class Et2Textbox extends Et2InputWidget(LionInput)
} }
} }
// @ts-ignore TypeScript is not recognizing that Et2Textbox is a LitElement
customElements.define("et2-textbox", Et2Textbox); customElements.define("et2-textbox", Et2Textbox);

View File

@ -7,7 +7,7 @@ import {et2_cloneObject, et2_csvSplit} from "../et2_core_common";
// @ts-ignore // @ts-ignore
import type {IegwAppLocal} from "../../jsapi/egw_global"; import type {IegwAppLocal} from "../../jsapi/egw_global";
import {ClassWithAttributes, ClassWithInterfaces} from "../et2_core_inheritance"; import {ClassWithAttributes, ClassWithInterfaces} from "../et2_core_inheritance";
import {LitElement} from "@lion/core"; import {dedupeMixin} from "@lion/core";
import type {et2_container} from "../et2_core_baseWidget"; import type {et2_container} from "../et2_core_baseWidget";
/** /**
@ -35,8 +35,7 @@ function applyMixins(derivedCtor : any, baseCtors : any[])
}); });
} }
type Constructor<T = {}> = new (...args : any[]) => T; const Et2WidgetMixin = (superClass) =>
export const Et2Widget = <T extends Constructor<LitElement>>(superClass : T) =>
{ {
class Et2WidgetClass extends superClass implements et2_IDOMNode class Et2WidgetClass extends superClass implements et2_IDOMNode
{ {
@ -55,9 +54,9 @@ export const Et2Widget = <T extends Constructor<LitElement>>(superClass : T) =>
/** /**
* Properties - default values, and actually creating them as fields * Properties - default values, and actually creating them as fields
*/ */
private label : string = ""; private _label : string = "";
private statustext : string = ""; private statustext : string = "";
private disabled : Boolean = false; protected disabled : Boolean = false;
/** WebComponent **/ /** WebComponent **/
@ -107,7 +106,7 @@ export const Et2Widget = <T extends Constructor<LitElement>>(superClass : T) =>
{ {
super.connectedCallback(); super.connectedCallback();
this.set_label(this.label); this.set_label(this._label);
if(this.statustext) if(this.statustext)
{ {
@ -132,7 +131,7 @@ export const Et2Widget = <T extends Constructor<LitElement>>(superClass : T) =>
*/ */
set_label(value : string) set_label(value : string)
{ {
let oldValue = this.label; let oldValue = this._label;
// Remove old // Remove old
let oldLabels = this.getElementsByClassName("et2_label"); let oldLabels = this.getElementsByClassName("et2_label");
@ -141,12 +140,12 @@ export const Et2Widget = <T extends Constructor<LitElement>>(superClass : T) =>
this.removeChild(oldLabels[0]); this.removeChild(oldLabels[0]);
} }
this.label = value; this._label = value;
if(value) if(value)
{ {
let label = document.createElement("span"); let label = document.createElement("span");
label.classList.add("et2_label"); label.classList.add("et2_label");
label.textContent = this.label; label.textContent = this._label;
// We should have a slot in the template for the label // We should have a slot in the template for the label
//label.slot="label"; //label.slot="label";
this.appendChild(label); this.appendChild(label);
@ -791,21 +790,22 @@ export const Et2Widget = <T extends Constructor<LitElement>>(superClass : T) =>
} }
}; };
// Add some more stuff in // Add some more stuff in
applyMixins(Et2WidgetClass, [ClassWithInterfaces]); applyMixins(Et2WidgetClass, [ClassWithInterfaces]);
return Et2WidgetClass as unknown as Constructor<et2_IDOMNode> & T; return Et2WidgetClass;
} }
export const Et2Widget = dedupeMixin(Et2WidgetMixin);
/** /**
* Load a Web Component * Load a Web Component
* @param _nodeName * @param _nodeName
* @param _template_node * @param _template_node
*/ */
export function loadWebComponent(_nodeName : string, _template_node, parent : Et2WidgetClass | et2_widget) : HTMLElement export function loadWebComponent(_nodeName : string, _template_node, parent : Et2Widget | et2_widget) : HTMLElement
{ {
let widget = <Et2WidgetClass>document.createElement(_nodeName); // @ts-ignore
let widget = <Et2Widget>document.createElement(_nodeName);
widget.textContent = _template_node.textContent; widget.textContent = _template_node.textContent;
const widget_class = window.customElements.get(_nodeName); const widget_class = window.customElements.get(_nodeName);