import { LitElement, PropertyValues } from "lit";
import { reverseMap } from "./utils";
export abstract class LitWidget<
ModelType,
SubclassType extends LitWidget<any, any>
> extends LitElement {
private _model: any | undefined = undefined;
abstract modelNameToViewName(): Map<
keyof ModelType,
keyof SubclassType | null
>;
onCustomMessage?(_msg: any): void {}
viewNameToModelName(): Map<keyof SubclassType | null, keyof ModelType> {
return reverseMap(this.modelNameToViewName());
}
set model(model: any) {
this._model = model;
for (const [modelKey, widgetKey] of this.modelNameToViewName()) {
if (widgetKey) {
(this as any)[widgetKey] = model.get(modelKey);
model.on(`change:${String(modelKey)}`, () => {
(this as any)[widgetKey] = model.get(modelKey);
});
}
}
model.on("msg:custom", (msg: any) => {
this.onCustomMessage?.(msg);
});
}
get model(): any {
return this._model;
}
override updated(changedProperties: PropertyValues<SubclassType>): void {
const viewToModelMap = this.viewNameToModelName();
for (const [viewProp, _] of changedProperties) {
const castViewProp = viewProp as keyof SubclassType;
if (viewToModelMap.has(castViewProp)) {
const modelProp = viewToModelMap.get(castViewProp);
this._model?.set(
modelProp as any,
this[castViewProp as keyof this] as any
);
}
}
this._model?.save_changes();
}
}