@n8d/htwoo-core
Version:
hTWOo is a Fluent Design Framework purely in HTML and CSS
145 lines (122 loc) • 4.01 kB
text/typescript
/**
* Position types for sticky tables
*/
enum Position {
LEFT = 'left',
RIGHT = 'right',
TOP = 'top',
BOTTOM = 'bottom'
}
/**
* Handle collapse and expand actions for collapsible tables
* @param event - Click event
*/
const collapseAndExpand = (event: Event): void => {
const target = event.target as HTMLElement;
const parentRow = target.closest("tr");
if (!parentRow) return;
const parentTable = target.closest("table");
if (!parentTable) return;
const section = parentRow.dataset.sectionheader;
if (!section) return;
let query: string;
if (section === "all") {
query = "tr[data-section]";
} else {
query = `tr[data-section=${section}]`;
}
const sectionRows = parentTable.querySelectorAll(query);
for (let i = 0; i < sectionRows.length; i++) {
const currentItem = sectionRows[i];
if (currentItem.classList.contains('is-hidden')) {
currentItem.classList.remove('is-hidden');
currentItem.classList.add('is-visible');
currentItem.setAttribute('aria-hidden', 'false');
parentRow.setAttribute('aria-expanded', 'true');
} else {
currentItem.classList.add('is-hidden');
currentItem.classList.remove('is-visible');
currentItem.setAttribute('aria-hidden', 'true');
parentRow.setAttribute('aria-expanded', 'false');
}
}
if (section === "all") {
const subSection = document.querySelectorAll("tbody tr.collapsable");
if (parentRow.getAttribute('aria-expanded') === "true") {
for (let i = 0; i < subSection.length; i++) {
const currentItem = subSection[i];
currentItem.setAttribute('aria-hidden', 'false');
currentItem.setAttribute('aria-expanded', 'true');
}
} else {
for (let i = 0; i < subSection.length; i++) {
const currentItem = subSection[i];
currentItem.setAttribute('aria-hidden', 'true');
currentItem.setAttribute('aria-expanded', 'false');
}
}
}
}
/**
* Initialize collapsible functionality for tables
*/
const initCollapsability = (): void => {
const collapseTables = document.querySelectorAll('.hoo-table.is-collapsable');
collapseTables.forEach(table => {
const collapseRows = table.querySelectorAll('.collapsable');
collapseRows.forEach(tableRow => {
tableRow.addEventListener('click', collapseAndExpand);
});
});
}
/**
* The position object for sticky positioning
*/
const position = {
"left": Position.LEFT,
"right": Position.RIGHT,
"top": Position.TOP,
"bottom": Position.BOTTOM
};
/**
* Fix the offset for sticky elements
* @param parent - Parent element
* @param selector - Selector for sticky elements
* @param offset - Position offset type
*/
const stickyOffsetFixup = (parent: Element, selector: string, offset: Position): void => {
const innerDefinition = parent.querySelectorAll(selector);
for (let j = 0; j < innerDefinition.length; j++) {
const innerElement = innerDefinition[j] as HTMLElement;
if (offset === Position.LEFT) {
innerElement.style[offset] = innerElement.offsetLeft + "px";
}
if (offset === Position.RIGHT) {
innerElement.style[offset] = (innerElement as any).offsetRight + "px";
}
if (offset === Position.TOP) {
innerElement.style[offset] = innerElement.offsetTop + "px";
}
if (offset === Position.BOTTOM) {
innerElement.style[offset] = (innerElement as any).offsetBottom + "px";
}
}
}
/**
* Initialize sticky table functionality
*/
const initSticky = (): void => {
const allStickyTables = document.querySelectorAll("table.sticky");
for (let i = 0; i < allStickyTables.length; i++) {
const stickyTable = allStickyTables[i];
stickyOffsetFixup(stickyTable, "tr td.is-sticky.left", Position.LEFT);
stickyOffsetFixup(stickyTable, "tr th.is-sticky.left", Position.LEFT);
}
}
/**
* Initialize all table functionality
*/
export const initTables = (): void => {
initCollapsability();
initSticky();
}