Files
PVM/public_html/js/modules/TabsViewModule.ts

82 lines
2.7 KiB
TypeScript

import ViewModule from "@js/modules/ViewModule";
const {store} = reef;
export interface Tab {
id: string
title: string
content: () => Promise<string>
}
export default abstract class TabsViewModule extends ViewModule {
readonly currentTab: typeof store
readonly tabs: Array<Tab>
protected constructor(selector: string | null, tabs: Array<Tab>, currentTab: string | null = null) {
if (tabs.length === 0) {
throw new Error("Array tabs vuoto in creazione TabViewModule");
}
super(selector);
this.currentTab = store(currentTab || tabs[0].id, "tab");
this.tabs = store(tabs, "tabs");
}
async onLoad(): Promise<void> {
try {
if (this.$container) {
const onTabChange = () => {
$(`[href=#${this.currentTab.value}]`).tab("show");
};
const onTabsChange = async () => {
this.$container.html(await this.content());
this.$container.find("[role=tab]")
.on("shown.bs.tab", (e) => {
document.removeEventListener("reef:store-tab", onTabChange);
this.currentTab.value = $(e.target).attr("aria-controls");
document.addEventListener("reef:store-tab", onTabChange);
});
}
document.addEventListener("reef:store-tab", onTabChange);
document.addEventListener("reef:store-tabs", onTabsChange);
await onTabsChange();
}
} finally {
_APP.setSplashScreen();
}
}
async content(): Promise<string> {
// language=HTML
return `
<div>
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
${this.tabs.map(tab => `
<li role="presentation" class="${tab.id === this.currentTab.value && "active" || ""}">
<a href="#${tab.id}" aria-controls="${tab.id}" role="tab" data-toggle="tab">
${ucfirst(tab.title, true)}
</a>
</li>
`).join("")}
</ul>
<!-- Tab panes -->
<div class="tab-content">
${(await Promise.all(this.tabs.map(async tab => `
<div role="tabpanel" class="tab-pane ${tab.id === this.currentTab.value && "active" || ""}" id="${tab.id}">
${await tab.content()}
</div>
`))).join("")}
</div>
</div>
`;
}
}