Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions _includes/js.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script src="/assets/bootstrap/js/bootstrap-trimmed.min.js" defer></script>
<script src="/js/tablesort-vendor.js"></script>
<script src="/js/tablesort-init.js"></script>
<script>
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
document.documentElement.setAttribute('data-bs-theme', e.matches ? 'dark' : 'light');
Expand Down
37 changes: 0 additions & 37 deletions _includes/standards-table-sort.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,3 @@
&middot;
<a href="/guidance/">Guidance</a>
</div>
<script>
(function() {
var tbody = document.getElementById('standards-table');
if (!tbody) return;
var table = tbody.closest('table');
var headers = table.querySelectorAll('th.sortable');
var sortState = { col: -1, dir: 'asc' };

function setIcon(th, dir) {
th.querySelector('.sort-neutral').classList.toggle('d-none', dir !== null);
th.querySelector('.sort-asc').classList.toggle('d-none', dir !== 'asc');
th.querySelector('.sort-desc').classList.toggle('d-none', dir !== 'desc');
}

headers.forEach(function(th) {
th.addEventListener('click', function() {
var col = parseInt(this.getAttribute('data-col'));
if (sortState.col === col) {
sortState.dir = sortState.dir === 'asc' ? 'desc' : 'asc';
} else {
sortState.col = col;
sortState.dir = 'asc';
}
headers.forEach(function(h) { setIcon(h, null); });
setIcon(this, sortState.dir);

var rows = Array.from(tbody.querySelectorAll('tr'));
rows.sort(function(a, b) {
var aVal = a.cells[col].getAttribute('data-sort') || '';
var bVal = b.cells[col].getAttribute('data-sort') || '';
return sortState.dir === 'asc' ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
});
rows.forEach(function(row) { tbody.appendChild(row); });
});
});
})();
</script>
8 changes: 4 additions & 4 deletions _includes/table_header.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<thead>
<tr>
<th scope="col" class="p-3 sortable" data-col="0">Indicators <span class="sort-icons"><i class="fa-solid fa-sort sort-neutral"></i><i class="fa-solid fa-sort-up sort-asc d-none"></i><i class="fa-solid fa-sort-down sort-desc d-none"></i></span></th>
<th scope="col" class="p-3 sortable" data-col="1">Standard <span class="sort-icons"><i class="fa-solid fa-sort sort-neutral"></i><i class="fa-solid fa-sort-up sort-asc d-none"></i><i class="fa-solid fa-sort-down sort-desc d-none"></i></span></th>
<th scope="col" class="p-3">Why</th>
<th scope="col" class="p-3">Guidance</th>
<th scope="col" class="p-3">Indicators <i class="fa-solid fa-sort sort-neutral"></i><i class="fa-solid fa-sort-up sort-asc"></i><i class="fa-solid fa-sort-down sort-desc"></i></th>
<th scope="col" class="p-3">Standard <i class="fa-solid fa-sort sort-neutral"></i><i class="fa-solid fa-sort-up sort-asc"></i><i class="fa-solid fa-sort-down sort-desc"></i></th>
<th scope="col" class="p-3" data-sort-method="none">Why</th>
<th scope="col" class="p-3" data-sort-method="none">Guidance</th>
</tr>
</thead>
2 changes: 1 addition & 1 deletion content/index.njk
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ topics:

{% include "filter.html" %}
<div class="table-responsive">
<table class="table">
<table class="table" data-sortable>
<caption class="visually-hidden">Digital experience standards</caption>
{% include "table_header.html" %}
<tbody id="standards-table">
Expand Down
2 changes: 1 addition & 1 deletion content/topic.njk
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ eleventyComputed:
{% set value = audits[topic] %}

<div class="table-responsive">
<table class="table">
<table class="table" data-sortable>
<caption class="visually-hidden">{{ audits[topic].displayName }} standards</caption>
{% include "table_header.html" %}
<tbody id="standards-table">
Expand Down
41 changes: 41 additions & 0 deletions public/css/scangov.css
Original file line number Diff line number Diff line change
Expand Up @@ -2817,6 +2817,47 @@ th a:focus i, th a:focus svg {
text-decoration: none;
}

/* Sortable tables (tablesort library, public/js/tablesort-vendor.js): the icon is
driven entirely by the aria-sort attribute the library sets on the sorted <th> -
a plain CSS rule, not a second piece of JS guessing at sort state. */
table[data-sortable] th[role="columnheader"] {
cursor: pointer;
}

th[aria-sort="ascending"] .fa-sort {
--fa: "\f0de" !important;
}

th[aria-sort="descending"] .fa-sort {
--fa: "\f0dd" !important;
}

/* Same aria-sort-driven icon convention, expressed as three sibling icons instead
of one - needed on the Eleventy static sites, where @11ty/font-awesome rewrites
every <i class="fa-*"> into an inline SVG <use> sprite at build time. A sprite's
shape is fixed by which <symbol> it references, so it can't be repainted via a
CSS content/custom-property swap the way a font glyph can; toggling which of
three fixed icons is visible works regardless of that rewrite. */
th .sort-asc,
th .sort-desc {
display: none;
}

th[aria-sort="ascending"] .sort-neutral,
th[aria-sort="ascending"] .sort-desc,
th[aria-sort="descending"] .sort-neutral,
th[aria-sort="descending"] .sort-asc {
display: none;
}

th[aria-sort="ascending"] .sort-asc {
display: inline;
}

th[aria-sort="descending"] .sort-desc {
display: inline;
}

/* Docs */
#post h2 {
margin-top: 2.5rem;
Expand Down
3 changes: 3 additions & 0 deletions public/js/tablesort-init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('table[data-sortable]').forEach(t => new Tablesort(t));
});
Loading