117 lines
3.8 KiB
JavaScript
117 lines
3.8 KiB
JavaScript
document.addEventListener("DOMContentLoaded", () => {
|
|
const table = document.querySelector("[data-project-table]");
|
|
const rows = table ? Array.from(table.querySelectorAll("tbody tr")) : [];
|
|
const filterInput = document.querySelector("[data-project-filter]");
|
|
|
|
if (table && filterInput) {
|
|
filterInput.addEventListener("input", () => {
|
|
const query = filterInput.value.trim().toLowerCase();
|
|
rows.forEach((row) => {
|
|
const match = row.textContent.toLowerCase().includes(query);
|
|
row.style.display = match ? "" : "none";
|
|
});
|
|
});
|
|
}
|
|
|
|
const sidebar = document.querySelector(".app-sidebar");
|
|
const appMain = document.querySelector(".app-main");
|
|
if (!sidebar || !appMain) {
|
|
return;
|
|
}
|
|
|
|
const body = document.body;
|
|
const mobileQuery = window.matchMedia("(max-width: 900px)");
|
|
let toggleButton = document.querySelector("[data-sidebar-toggle]");
|
|
|
|
if (!toggleButton) {
|
|
toggleButton = document.createElement("button");
|
|
toggleButton.type = "button";
|
|
toggleButton.className = "sidebar-toggle";
|
|
toggleButton.setAttribute("data-sidebar-toggle", "");
|
|
toggleButton.setAttribute("aria-expanded", "false");
|
|
toggleButton.setAttribute("aria-label", "Toggle primary navigation");
|
|
toggleButton.hidden = true;
|
|
toggleButton.innerHTML = [
|
|
'<span class="sidebar-toggle-icon" aria-hidden="true"></span>',
|
|
'<span class="sidebar-toggle-label">Menu</span>',
|
|
].join("");
|
|
appMain.insertBefore(toggleButton, appMain.firstChild);
|
|
}
|
|
|
|
let overlay = document.querySelector("[data-sidebar-overlay]");
|
|
if (!overlay) {
|
|
overlay = document.createElement("div");
|
|
overlay.className = "sidebar-overlay";
|
|
overlay.setAttribute("data-sidebar-overlay", "");
|
|
overlay.setAttribute("aria-hidden", "true");
|
|
document.body.appendChild(overlay);
|
|
}
|
|
|
|
const primaryNav = document.querySelector(".sidebar-nav");
|
|
if (primaryNav) {
|
|
if (!primaryNav.id) {
|
|
primaryNav.id = "primary-navigation";
|
|
}
|
|
toggleButton.setAttribute("aria-controls", primaryNav.id);
|
|
}
|
|
|
|
const openSidebar = () => {
|
|
body.classList.remove("sidebar-collapsed");
|
|
body.classList.add("sidebar-open");
|
|
toggleButton.setAttribute("aria-expanded", "true");
|
|
overlay.setAttribute("aria-hidden", "false");
|
|
};
|
|
|
|
const closeSidebar = (focusToggle = false) => {
|
|
body.classList.add("sidebar-collapsed");
|
|
body.classList.remove("sidebar-open");
|
|
toggleButton.setAttribute("aria-expanded", "false");
|
|
overlay.setAttribute("aria-hidden", "true");
|
|
if (focusToggle) {
|
|
toggleButton.focus({ preventScroll: true });
|
|
}
|
|
};
|
|
|
|
const toggleSidebar = () => {
|
|
if (body.classList.contains("sidebar-open")) {
|
|
closeSidebar();
|
|
} else {
|
|
openSidebar();
|
|
sidebar.setAttribute("aria-hidden", "false");
|
|
}
|
|
};
|
|
|
|
const applyResponsiveState = (mql) => {
|
|
if (!mql.matches) {
|
|
toggleButton.hidden = true;
|
|
body.classList.remove("sidebar-open", "sidebar-collapsed");
|
|
sidebar.setAttribute("aria-hidden", "true");
|
|
overlay.setAttribute("aria-hidden", "true");
|
|
sidebar.removeAttribute("aria-hidden");
|
|
return;
|
|
}
|
|
|
|
toggleButton.hidden = false;
|
|
if (!body.classList.contains("sidebar-open")) {
|
|
body.classList.add("sidebar-collapsed");
|
|
sidebar.setAttribute("aria-hidden", "true");
|
|
}
|
|
};
|
|
|
|
toggleButton.addEventListener("click", toggleSidebar);
|
|
overlay.addEventListener("click", () => closeSidebar());
|
|
|
|
document.addEventListener("keydown", (event) => {
|
|
if (event.key === "Escape" && body.classList.contains("sidebar-open")) {
|
|
closeSidebar(true);
|
|
}
|
|
});
|
|
|
|
applyResponsiveState(mobileQuery);
|
|
if (typeof mobileQuery.addEventListener === "function") {
|
|
mobileQuery.addEventListener("change", applyResponsiveState);
|
|
} else if (typeof mobileQuery.addListener === "function") {
|
|
mobileQuery.addListener(applyResponsiveState);
|
|
}
|
|
});
|