82 lines
2.7 KiB
TypeScript
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>
|
|
`;
|
|
}
|
|
} |