Skip to content

Commit 90b78fb

Browse files
dancormierallejogiamir
authored
fix(table): improve sortable table accessibility (#1280)
* Improve a11y support for table sorting * Remove extra classes; add column highlighting * Add quick comment * Fix missing ending tag * aria-sort shouldn't always be set on every header * Remove column highlighting on sort * Port table.less changes to refactored styles * test(table): add test for sortable table * Have eslint apply to tests as well * It's okay to have unused vars for array destructures * Prettify table code + start more unit tests * Changes for latest develop changes * Unit tests for column indicators + aria-sort values * Apparently DOM tests are async? * Make unit tests + eslint happy by void'ing a promise * update th button styling * small tweak * minor styling tweak * Update test to check current and legacy markup * lint * Update test description to reflect legacy markup * add comments addresses #1280 (comment) * Add scope attr to sortable examples --------- Co-authored-by: Vlad Jimenez <[email protected]> Co-authored-by: Giamir Buoncristiani <[email protected]>
1 parent eb08145 commit 90b78fb

File tree

7 files changed

+566
-123
lines changed

7 files changed

+566
-123
lines changed

.eslintrc.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,11 @@ module.exports = {
1717
"no-console": "error",
1818
"no-alert": "error",
1919
"no-process-env": "error",
20+
"@typescript-eslint/no-unused-vars": [
21+
"error",
22+
{
23+
"destructuredArrayIgnorePattern": "^_"
24+
},
25+
]
2026
},
2127
};

docs/_data/tables.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
},
6363
{
6464
"attribute": "data-action=\"click->s-table#sort\"",
65-
"applies": "th",
65+
"applies": "button",
6666
"description": "Causes a click on the header cell to sort by this column"
6767
},
6868
{

docs/product/components/tables.html

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -748,16 +748,16 @@
748748
<table class="wmn4 s-table s-table__bx-simple">
749749
<thead>
750750
<tr>
751-
<th class="s-table--cell5" scope="col">Attribute</th>
752-
<th class="s-table--cell2" scope="col">Applied to</th>
751+
<th scope="col" class="s-table--cell5">Attribute</th>
752+
<th scope="col" class="s-table--cell2">Applied to</th>
753753
<th scope="col">Description</th>
754754
</tr>
755755
</thead>
756756
<tbody class="fs-caption">
757757
{% for item in tables.data-attributes %}
758758
<tr>
759759
<th scope="row"><code class="stacks-code">{{ item.attribute }}</code></th>
760-
<td><code class="stacks-code">{{ item.applies }}</td>
760+
<td><code class="stacks-code">{{ item.applies }}</code></td>
761761
<td class="p8">{{ item.description }}</td>
762762
</tr>
763763
{% endfor %}
@@ -772,19 +772,25 @@
772772
<table class="s-table s-table__sortable" data-controller="s-table">
773773
<thead>
774774
<tr>
775-
<th data-s-table-target="column" data-action="click->s-table#sort">
776-
Season
777-
@Svg.ArrowUpSm.With("js-sorting-indicator js-sorting-indicator-asc d-none")
778-
@Svg.ArrowDownSm.With("js-sorting-indicator js-sorting-indicator-desc d-none")
779-
@Svg.ArrowUpDownSm.With("js-sorting-indicator js-sorting-indicator-none")
775+
<th scope="col" data-s-table-target="column">
776+
<button data-action="click->s-table#sort">
777+
Season
778+
@Svg.ArrowUpSm.With("js-sorting-indicator js-sorting-indicator-asc d-none")
779+
@Svg.ArrowDownSm.With("js-sorting-indicator js-sorting-indicator-desc d-none")
780+
@Svg.ArrowUpDownSm.With("js-sorting-indicator js-sorting-indicator-none")
781+
</button>
780782
</th>
781-
<th data-s-table-target="column" data-action="click->s-table#sort">
782-
Starts in month
783-
783+
<th scope="col" data-s-table-target="column">
784+
<button data-action="click->s-table#sort">
785+
Starts in month
786+
787+
</button>
784788
</th>
785-
<th data-s-table-target="column" data-action="click->s-table#sort">
786-
Typical temperature in °C
787-
789+
<th scope="col" data-s-table-target="column">
790+
<button data-action="click->s-table#sort">
791+
Typical temperature in °C
792+
793+
</button>
788794
</th>
789795
</tr>
790796
</thead>
@@ -806,23 +812,29 @@
806812
<table class="s-table s-table__sortable" data-controller="s-table">
807813
<thead>
808814
<tr>
809-
<th data-s-table-target="column" data-action="click->s-table#sort">
810-
Season
811-
{% icon "ArrowUpSm", "js-sorting-indicator js-sorting-indicator-asc d-none" %}
812-
{% icon "ArrowDownSm", "js-sorting-indicator js-sorting-indicator-desc d-none" %}
813-
{% icon "ArrowUpDownSm", "js-sorting-indicator js-sorting-indicator-none" %}
815+
<th scope="col" data-s-table-target="column">
816+
<button data-action="click->s-table#sort">
817+
Season
818+
{% icon "ArrowUpSm", "js-sorting-indicator js-sorting-indicator-asc d-none" %}
819+
{% icon "ArrowDownSm", "js-sorting-indicator js-sorting-indicator-desc d-none" %}
820+
{% icon "ArrowUpDownSm", "js-sorting-indicator js-sorting-indicator-none" %}
821+
</button>
814822
</th>
815-
<th data-s-table-target="column" data-action="click->s-table#sort">
816-
Starts in month
817-
{% icon "ArrowUpSm", "js-sorting-indicator js-sorting-indicator-asc d-none" %}
818-
{% icon "ArrowDownSm", "js-sorting-indicator js-sorting-indicator-desc d-none" %}
819-
{% icon "ArrowUpDownSm", "js-sorting-indicator js-sorting-indicator-none" %}
823+
<th scope="col" data-s-table-target="column">
824+
<button data-action="click->s-table#sort">
825+
Starts in month
826+
{% icon "ArrowUpSm", "js-sorting-indicator js-sorting-indicator-asc d-none" %}
827+
{% icon "ArrowDownSm", "js-sorting-indicator js-sorting-indicator-desc d-none" %}
828+
{% icon "ArrowUpDownSm", "js-sorting-indicator js-sorting-indicator-none" %}
829+
</button>
820830
</th>
821-
<th data-s-table-target="column" data-action="click->s-table#sort">
822-
Typical temperature in °C
823-
{% icon "ArrowUpSm", "js-sorting-indicator js-sorting-indicator-asc d-none" %}
824-
{% icon "ArrowDownSm", "js-sorting-indicator js-sorting-indicator-desc d-none" %}
825-
{% icon "ArrowUpDownSm", "js-sorting-indicator js-sorting-indicator-none" %}
831+
<th scope="col" data-s-table-target="column">
832+
<button data-action="click->s-table#sort">
833+
Typical temperature in °C
834+
{% icon "ArrowUpSm", "js-sorting-indicator js-sorting-indicator-asc d-none" %}
835+
{% icon "ArrowDownSm", "js-sorting-indicator js-sorting-indicator-desc d-none" %}
836+
{% icon "ArrowUpDownSm", "js-sorting-indicator js-sorting-indicator-none" %}
837+
</button>
826838
</th>
827839
</tr>
828840
</thead>
@@ -882,8 +894,8 @@
882894
<th scope="col">Status</th>
883895
<th scope="col">Owner</th>
884896
<th scope="col">Source</th>
885-
<th colspan="2" scope="col">Views</th>
886-
<th colspan="2" scope="col">Applies</th>
897+
<th colspan="2" scope="colgroup">Views</th>
898+
<th colspan="2" scope="colgroup">Applies</th>
887899
</tr>
888900
</thead>
889901
<tbody>

lib/components/table/table.less

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,25 @@
122122

123123
&&__sortable {
124124
thead th {
125-
a { // If an anchor is used, it should appear like a normal header
125+
a,
126+
button { // If an anchor is used, it should appear like a normal header
126127
color: inherit;
127128
}
128129

130+
button {
131+
appearance: none;
132+
background-color: transparent;
133+
border: 0;
134+
cursor: pointer;
135+
display: flex;
136+
gap: var(--su-static4);
137+
font-weight: inherit;
138+
margin: calc(var(--_ta-th-p) * -1);
139+
padding: var(--_ta-th-p);
140+
text-align: left;
141+
width: calc(100% + calc(var(--_ta-th-p) * 2));
142+
}
143+
129144
&.is-sorted { // Selected state
130145
color: var(--black-900);
131146
}

0 commit comments

Comments
 (0)