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

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();
});