100 lines
3.6 KiB
JavaScript
100 lines
3.6 KiB
JavaScript
document.addEventListener('DOMContentLoaded', () => {
|
|
const header = document.querySelector('.site-header');
|
|
const toastElement = document.getElementById('siteToast');
|
|
const toastBody = toastElement ? toastElement.querySelector('.toast-body') : null;
|
|
const pageToastMessage = document.body.dataset.toastMessage || '';
|
|
|
|
const showToast = (message) => {
|
|
if (!toastElement || !toastBody || !window.bootstrap) {
|
|
return;
|
|
}
|
|
toastBody.textContent = message;
|
|
window.bootstrap.Toast.getOrCreateInstance(toastElement, { delay: 3000 }).show();
|
|
};
|
|
|
|
if (header) {
|
|
const toggleHeaderState = () => {
|
|
header.classList.toggle('is-scrolled', window.scrollY > 10);
|
|
};
|
|
toggleHeaderState();
|
|
window.addEventListener('scroll', toggleHeaderState, { passive: true });
|
|
}
|
|
|
|
if (pageToastMessage) {
|
|
showToast(pageToastMessage);
|
|
}
|
|
|
|
document.querySelectorAll('[data-copy-target]').forEach((button) => {
|
|
button.addEventListener('click', async () => {
|
|
const target = document.querySelector(button.dataset.copyTarget || '');
|
|
if (!target) {
|
|
return;
|
|
}
|
|
|
|
const value = target.textContent.trim();
|
|
if (!value) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
await navigator.clipboard.writeText(value);
|
|
showToast('Reference copied to clipboard.');
|
|
} catch (error) {
|
|
showToast('Copy is unavailable in this browser.');
|
|
}
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll('[data-filter-group]').forEach((group) => {
|
|
const targetSelector = group.dataset.filterTarget;
|
|
const emptySelector = group.dataset.emptyState;
|
|
const resetButton = document.querySelector('[data-reset-filter]');
|
|
const target = targetSelector ? document.querySelector(targetSelector) : null;
|
|
const emptyState = emptySelector ? document.querySelector(emptySelector) : null;
|
|
const buttons = Array.from(group.querySelectorAll('[data-filter]'));
|
|
const items = target ? Array.from(target.querySelectorAll('[data-filter-item]')) : [];
|
|
|
|
if (!target || buttons.length === 0 || items.length === 0) {
|
|
return;
|
|
}
|
|
|
|
const applyFilter = (filter) => {
|
|
let visibleCount = 0;
|
|
items.forEach((item) => {
|
|
const matches = filter === 'all' || item.dataset.filterItem === filter;
|
|
item.classList.toggle('is-hidden', !matches);
|
|
if (matches) {
|
|
visibleCount += 1;
|
|
}
|
|
});
|
|
|
|
buttons.forEach((button) => {
|
|
button.classList.toggle('is-active', button.dataset.filter === filter);
|
|
});
|
|
|
|
if (emptyState) {
|
|
emptyState.classList.toggle('d-none', visibleCount > 0);
|
|
}
|
|
};
|
|
|
|
buttons.forEach((button) => {
|
|
button.addEventListener('click', () => applyFilter(button.dataset.filter || 'all'));
|
|
});
|
|
|
|
if (resetButton) {
|
|
resetButton.addEventListener('click', () => applyFilter('all'));
|
|
}
|
|
});
|
|
|
|
const navbarCollapse = document.getElementById('primaryNav');
|
|
if (navbarCollapse && window.bootstrap) {
|
|
document.querySelectorAll('#primaryNav .nav-link').forEach((link) => {
|
|
link.addEventListener('click', () => {
|
|
if (window.innerWidth < 992) {
|
|
window.bootstrap.Collapse.getOrCreateInstance(navbarCollapse).hide();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
});
|