/**
* VMK UI Kit browser table helper.
*
* Mirrors the public surface of gnexus-ui-kit tables:
* init(root), selectRow(row), sortBy(column)
*/
const initializedRoots = new WeakSet();
function getRows(table) {
return [...table.querySelectorAll("tbody tr")];
}
function getHeaders(table) {
return [...table.querySelectorAll("thead th")];
}
function selectRow(row, options = {}) {
const table = row?.closest("table");
if (!table) return;
if (table.classList.contains("table-selectable")) {
getRows(table).forEach(r => r.classList.toggle("is-selected", r === row));
}
if (options.focus !== false) {
row.focus?.();
}
}
function parseValue(cell) {
const text = cell.textContent.trim();
const num = Number(text.replace(/[^0-9.\-]/g, ""));
return Number.isNaN(num) ? text.toLowerCase() : num;
}
function sortBy(table, columnIndex, direction = "asc") {
const rows = getRows(table);
const sorted = rows.slice().sort((a, b) => {
const aValue = parseValue(a.children[columnIndex] || a.children[0]);
const bValue = parseValue(b.children[columnIndex] || b.children[0]);
if (aValue < bValue) return direction === "asc" ? -1 : 1;
if (aValue > bValue) return direction === "asc" ? 1 : -1;
return 0;
});
const tbody = table.querySelector("tbody");
sorted.forEach(row => tbody.appendChild(row));
getHeaders(table).forEach((header, index) => {
header.setAttribute("aria-sort", index === columnIndex ? direction : "none");
});
}
function handleClick(event) {
const header = event.target.closest("thead th[data-sortable]");
if (header) {
const table = header.closest("table");
const index = getHeaders(table).indexOf(header);
const current = header.getAttribute("aria-sort") || "none";
const direction = current === "asc" ? "desc" : "asc";
sortBy(table, index, direction);
return;
}
const row = event.target.closest("tbody tr");
if (row) {
selectRow(row, { focus: false });
}
}
function prepare(table) {
if (table.classList.contains("table-sortable")) {
getHeaders(table).forEach((header, index) => {
if (header.hasAttribute("data-sortable")) return;
header.setAttribute("data-sortable", "");
header.setAttribute("aria-sort", "none");
header.style.cursor = "pointer";
});
}
}
function init(root = document) {
if (initializedRoots.has(root)) return;
root.querySelectorAll("table.table").forEach(prepare);
root.addEventListener("click", handleClick);
initializedRoots.add(root);
}
export default {
init,
selectRow,
sortBy
};