( table: HTMLTableElement, column: number, direction: SortDirection, )
| 561 | } |
| 562 | |
| 563 | function sortTable( |
| 564 | table: HTMLTableElement, |
| 565 | column: number, |
| 566 | direction: SortDirection, |
| 567 | ) { |
| 568 | const tbody = table.tBodies[0]; |
| 569 | const header = table.tHead?.rows[0]?.cells[column]; |
| 570 | if (!tbody || !header) return; |
| 571 | |
| 572 | const type = header.getAttribute("data-type"); |
| 573 | const rows = Array.from(tbody.rows).filter( |
| 574 | (row) => !row.classList.contains("empty-row"), |
| 575 | ); |
| 576 | |
| 577 | rows.sort((rowA, rowB) => { |
| 578 | const comparison = compareValues( |
| 579 | getCellSortValue(rowA, column), |
| 580 | getCellSortValue(rowB, column), |
| 581 | type, |
| 582 | ); |
| 583 | return direction === "asc" ? comparison : -comparison; |
| 584 | }); |
| 585 | |
| 586 | for (const row of rows) { |
| 587 | tbody.appendChild(row); |
| 588 | } |
| 589 | |
| 590 | for (const sortable of table.querySelectorAll("th.sortable")) { |
| 591 | sortable.removeAttribute("aria-sort"); |
| 592 | const indicator = sortable.querySelector(".sort-indicator"); |
| 593 | if (indicator) indicator.textContent = ""; |
| 594 | } |
| 595 | |
| 596 | header.setAttribute( |
| 597 | "aria-sort", |
| 598 | direction === "asc" ? "ascending" : "descending", |
| 599 | ); |
| 600 | const indicator = header.querySelector(".sort-indicator"); |
| 601 | if (indicator) indicator.textContent = direction === "asc" ? "↑" : "↓"; |
| 602 | } |
| 603 | |
| 604 | for (const table of tables) { |
| 605 | const headers = Array.from(table.querySelectorAll<HTMLTableCellElement>("th")); |
no test coverage detected