You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.9 KiB
JavaScript
127 lines
3.9 KiB
JavaScript
const _pfui = {
|
|
fadeOutElement: ($el, duration = 150, useHidden = false) => {
|
|
return new Promise(resolve => {
|
|
$el.style.transition = `opacity ${duration}ms linear`;
|
|
$el.style.opacity = '0';
|
|
setTimeout(() => {
|
|
if (useHidden) {
|
|
$el.hidden = true;
|
|
} else {
|
|
$el.style.display = 'none';
|
|
}
|
|
resolve();
|
|
}, duration);
|
|
});
|
|
},
|
|
fadeInElement: ($el, duration = 150, useHidden = false, display = 'block') => {
|
|
return new Promise(resolve => {
|
|
if (useHidden) {
|
|
$el.hidden = false;
|
|
} else {
|
|
$el.style.display = display;
|
|
}
|
|
$el.style.opacity = '0';
|
|
$el.style.transition = `opacity ${duration}ms`;
|
|
requestAnimationFrame(() => {
|
|
$el.style.opacity = '1';
|
|
});
|
|
setTimeout(() => {
|
|
resolve();
|
|
}, duration);
|
|
});
|
|
},
|
|
compControllers: [],
|
|
init: () => {
|
|
// Initialize components if any
|
|
document.querySelectorAll('.pf-v5-c-tabs').forEach($tabsBar => {
|
|
if (!_pfui.compControllers.find(c => c.$el === $tabsBar)) {
|
|
const tabs = new Tabs($tabsBar);
|
|
_pfui.compControllers.push({ $el: $tabsBar, controller: tabs });
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
class Tabs {
|
|
constructor($tabsBar) {
|
|
this.$tabsBar = $tabsBar;
|
|
this._handleTabClickEvent = this._handleTabClick.bind(this);
|
|
|
|
// Find the associated tab panel
|
|
if (this.$tabsBar && this.$tabsBar.dataset.tabPanel) {
|
|
this.$tabPanel = document.getElementById(this.$tabsBar.dataset.tabPanel);
|
|
if (this.$tabPanel) {
|
|
this._init();
|
|
}
|
|
}
|
|
}
|
|
|
|
_init() {
|
|
this.$tabsBar.querySelectorAll('.pf-v5-c-tabs__link').forEach($tab => {
|
|
$tab.addEventListener('click', this._handleTabClickEvent);
|
|
});
|
|
}
|
|
|
|
destroy() {
|
|
this.$tabsBar.querySelectorAll('.pf-v5-c-tabs__link').forEach($tab => {
|
|
$tab.removeEventListener('click', this._handleTabClickEvent);
|
|
});
|
|
}
|
|
|
|
_handleTabClick(e) {
|
|
e.preventDefault();
|
|
const $tab = e.currentTarget;
|
|
this._activateTab($tab);
|
|
}
|
|
|
|
_activateTab($tab) {
|
|
const targetId = $tab.dataset.tabTarget;
|
|
if (!targetId) {
|
|
return;
|
|
}
|
|
|
|
// Deactivate all tabs
|
|
this.$tabsBar.querySelectorAll('.pf-v5-c-tabs__item').forEach($item => {
|
|
$item.classList.remove('pf-m-current');
|
|
const $link = $item.querySelector('.pf-v5-c-tabs__link');
|
|
if ($link) {
|
|
$link.setAttribute('aria-selected', 'false');
|
|
}
|
|
});
|
|
|
|
// Activate the clicked tab
|
|
const $tabItem = $tab.closest('.pf-v5-c-tabs__item');
|
|
if ($tabItem) {
|
|
$tabItem.classList.add('pf-m-current');
|
|
}
|
|
$tab.setAttribute('aria-selected', 'true');
|
|
|
|
// Hide all tab panels
|
|
let promises = [];
|
|
this.$tabPanel.querySelectorAll('.pf-v5-c-tab-content').forEach($panel => {
|
|
if (!$panel.hidden) {
|
|
promises.push(_pfui.fadeOutElement($panel, 200, true));
|
|
}
|
|
});
|
|
|
|
// Show the corresponding tab panel
|
|
Promise.all(promises).then(() => {
|
|
const $targetPanel = this.$tabPanel.querySelector(`.pf-v5-c-tab-content[data-tab-id="${targetId}"]`);
|
|
if ($targetPanel) {
|
|
_pfui.fadeInElement($targetPanel, 200, true);
|
|
}
|
|
});
|
|
|
|
// Send pf.tab.activate event
|
|
const activateEvent = new CustomEvent('pf.tab.activate', {
|
|
detail: {
|
|
tabId: targetId
|
|
}
|
|
});
|
|
this.$tabsBar.dispatchEvent(activateEvent);
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
_pfui.init();
|
|
}); |