PMCORE-2521
This commit is contained in:
160
resources/assets/js/components/tabs/Tabs.vue
Normal file
160
resources/assets/js/components/tabs/Tabs.vue
Normal file
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div class="tabs-component">
|
||||
<ul role="tablist" class="tabs-component-tabs">
|
||||
<li
|
||||
v-for="(tab, i) in tabs"
|
||||
:key="i"
|
||||
:class="{ 'is-active': tab.isActive, 'is-disabled': tab.isDisabled }"
|
||||
class="tabs-component-tab"
|
||||
role="presentation"
|
||||
v-show="tab.isVisible"
|
||||
>
|
||||
<span
|
||||
v-html="tab.header"
|
||||
:aria-controls="tab.hash"
|
||||
:aria-selected="tab.isActive"
|
||||
@click="selectTab(tab.hash, $event)"
|
||||
class="tabs-component-tab-a"
|
||||
role="tab"
|
||||
></span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tabs-component-panels">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import expiringStorage from "./expiringStorage";
|
||||
export default {
|
||||
props: {
|
||||
cacheLifetime: {
|
||||
default: 5,
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({
|
||||
useUrlFragment: true,
|
||||
defaultTabHash: null,
|
||||
}),
|
||||
},
|
||||
},
|
||||
data: () => ({
|
||||
tabs: [],
|
||||
activeTabHash: "",
|
||||
activeTabIndex: 0,
|
||||
lastActiveTabHash: "",
|
||||
}),
|
||||
computed: {
|
||||
storageKey() {
|
||||
return `vue-tabs-component.cache.${window.location.host}${window.location.pathname}`;
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.tabs = this.$children;
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener("hashchange", () =>
|
||||
this.selectTab(window.location.hash)
|
||||
);
|
||||
if (this.findTab(window.location.hash)) {
|
||||
this.selectTab(window.location.hash);
|
||||
return;
|
||||
}
|
||||
const previousSelectedTabHash = expiringStorage.get(this.storageKey);
|
||||
if (this.findTab(previousSelectedTabHash)) {
|
||||
this.selectTab(previousSelectedTabHash);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
this.options.defaultTabHash !== null &&
|
||||
this.findTab("#" + this.options.defaultTabHash)
|
||||
) {
|
||||
this.selectTab("#" + this.options.defaultTabHash);
|
||||
return;
|
||||
}
|
||||
if (this.tabs.length) {
|
||||
this.selectTab(this.tabs[0].hash);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
findTab(hash) {
|
||||
return this.tabs.find((tab) => tab.hash === hash);
|
||||
},
|
||||
selectTab(selectedTabHash, event) {
|
||||
// See if we should store the hash in the url fragment.
|
||||
if (event && !this.options.useUrlFragment) {
|
||||
event.preventDefault();
|
||||
}
|
||||
const selectedTab = this.findTab(selectedTabHash);
|
||||
if (!selectedTab) {
|
||||
return;
|
||||
}
|
||||
if (selectedTab.isDisabled) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (this.lastActiveTabHash === selectedTab.hash) {
|
||||
this.$emit("clicked", { tab: selectedTab });
|
||||
return;
|
||||
}
|
||||
this.tabs.forEach((tab) => {
|
||||
tab.isActive = tab.hash === selectedTab.hash;
|
||||
});
|
||||
this.$emit("changed", { tab: selectedTab });
|
||||
this.activeTabHash = selectedTab.hash;
|
||||
this.activeTabIndex = this.getTabIndex(selectedTabHash);
|
||||
this.lastActiveTabHash = this.activeTabHash = selectedTab.hash;
|
||||
expiringStorage.set(
|
||||
this.storageKey,
|
||||
selectedTab.hash,
|
||||
this.cacheLifetime
|
||||
);
|
||||
},
|
||||
setTabVisible(hash, visible) {
|
||||
const tab = this.findTab(hash);
|
||||
if (!tab) {
|
||||
return;
|
||||
}
|
||||
tab.isVisible = visible;
|
||||
if (tab.isActive) {
|
||||
// If tab is active, set a different one as active.
|
||||
tab.isActive = visible;
|
||||
this.tabs.every((tab, index, array) => {
|
||||
if (tab.isVisible) {
|
||||
tab.isActive = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getTabIndex(hash) {
|
||||
const tab = this.findTab(hash);
|
||||
|
||||
return this.tabs.indexOf(tab);
|
||||
},
|
||||
|
||||
getTabHash(index) {
|
||||
const tab = this.tabs.find((tab) => this.tabs.indexOf(tab) === index);
|
||||
|
||||
if (!tab) {
|
||||
return;
|
||||
}
|
||||
|
||||
return tab.hash;
|
||||
},
|
||||
|
||||
getActiveTab() {
|
||||
return this.findTab(this.activeTabHash);
|
||||
},
|
||||
|
||||
getActiveTabIndex() {
|
||||
return this.getTabIndex(this.activeTabHash);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user