55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
|
export class TimelineFilter {
|
||
|
public name: string = "";
|
||
|
public filter: string = "";
|
||
|
}
|
||
|
|
||
|
export class TimelineFilterElement extends HTMLElement {
|
||
|
static observedAttributes = [ "data-filters", "data-target", "data-latest" ];
|
||
|
|
||
|
private _filters: TimelineFilter[] = [];
|
||
|
private _target: string = "";
|
||
|
|
||
|
constructor() {
|
||
|
super();
|
||
|
this.innerHTML = "<select class='filter_select'></select>"
|
||
|
|
||
|
}
|
||
|
|
||
|
connectedCallback() {
|
||
|
this._target = this.getAttribute("data-target") ?? "";
|
||
|
this._filters = (this.getAttribute("data-filters") ?? "").split("/").map(f=>{
|
||
|
const ff = f.split("::");
|
||
|
return <TimelineFilter>{ name: ff[0], filter: ff[1] };
|
||
|
});
|
||
|
let html = "<select class='filter_select'>";
|
||
|
html += this._filters.reduce((self: string, f: TimelineFilter)=>{
|
||
|
self += `<option value='${f.filter}'>${f.name}</option>`;
|
||
|
return self;
|
||
|
}, "");
|
||
|
html += "</select>";
|
||
|
this.innerHTML = html;
|
||
|
const select = this.querySelector(".filter_select");
|
||
|
if (select) {
|
||
|
select.addEventListener("change", this.onChanges.bind(this));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
onChanges() {
|
||
|
const select = this.querySelector(".filter_select") as HTMLSelectElement;
|
||
|
|
||
|
// change target's target!
|
||
|
const target = document.getElementById(this._target);
|
||
|
if (target) {
|
||
|
target.setAttribute("data-target", select?.options[select.selectedIndex].value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
attributeChangedCallback(attr: string, prev: string, next: string) {
|
||
|
switch (attr) {
|
||
|
case "data-latest":
|
||
|
const select = this.querySelector(".filter_select") as HTMLSelectElement;
|
||
|
select.selectedIndex = this._filters.findIndex(f=>f.name == next);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|