Skip to content

Commit c92d0ec

Browse files
ppvgricklambrechts
andauthored
feat: sortable table (#391)
* refactor: rename manon.js to main.js * feat: improve sortable table example * fix: example sidemenu.js paths Co-authored-by: Rick Lambrechts <[email protected]> * fix: numeric sort example * fix: add aria-hidden to sortable table icons --------- Co-authored-by: Rick Lambrechts <[email protected]>
1 parent d077840 commit c92d0ec

File tree

1 file changed

+216
-34
lines changed
  • docs/src/routes/(docs)/components/table-sortable

1 file changed

+216
-34
lines changed

docs/src/routes/(docs)/components/table-sortable/+page.svelte

+216-34
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,38 @@
66
import { base } from "$app/paths";
77
import Code from "$lib/Code.svelte";
88
import SideMenu from "$lib/SideMenu.svelte";
9+
10+
const demoTableRows = [
11+
{ firstname: "Janine", lastname: "Hinde", age: 16 },
12+
{ firstname: "Henk", lastname: "de Vries", age: 8 },
13+
{ firstname: "Maria", lastname: "Lin", age: 32 },
14+
{ firstname: "John", lastname: "Doe", age: 64 },
15+
];
16+
17+
/** @type {'firstname'|'lastname'|'age'|undefined} */
18+
let sortColumn = undefined;
19+
20+
/** @type {'ascending'|'descending'} */
21+
let sortDirection = "ascending";
22+
23+
$: numeric = sortColumn === "age";
24+
25+
$: sortedDemoTableRows = demoTableRows
26+
.slice()
27+
.sort(
28+
sortDirection === "ascending"
29+
? (a, b) => ("" + a[sortColumn]).localeCompare(b[sortColumn], undefined, { numeric })
30+
: (a, b) => ("" + b[sortColumn]).localeCompare(a[sortColumn], undefined, { numeric }),
31+
)
32+
33+
const toggleSort = (column) => {
34+
if (column === sortColumn) {
35+
sortDirection = sortDirection === "ascending" ? "descending" : "ascending";
36+
} else {
37+
sortColumn = column;
38+
sortDirection = "ascending";
39+
}
40+
};
941
</script>
1042

1143
<svelte:head>
@@ -26,61 +58,184 @@
2658
<h1>Sorteerbare tabel</h1>
2759
<p>
2860
Om inzicht te krijgen in de data kan het behulpzaam zijn om de gebruiker de data te laten
29-
sorteren. Bijvoorbeeld op basis van op of aflopende data.
61+
sorteren.
3062
</p>
3163

3264
<h2>Benodigde stappen:</h2>
3365
<ol>
3466
<li>
35-
Voeg een <code>button</code> toe binnen de <code>th</code> om sorteerelemeent klikbaar te
36-
maken.
67+
Voeg een <code>&lt;button></code> toe binnen de <code>&lt;th></code> van elke
68+
sorteerbare kolom.
69+
<ul>
70+
<li>
71+
Voeg de <code>&lt;button></code> alleen toe aan sorteerbare kolommen. Niet elke kolom
72+
hoeft sorteerbaar te zijn.
73+
</li>
74+
<li>
75+
Plaats de tekst van de kolomkop in de <code>&lt;button></code>, zodat de hele
76+
kolomkop klikbaar is.
77+
</li>
78+
</ul>
3779
</li>
3880
<li>
39-
Voeg binnen de knop een icoon toe indien gewenst. Voor meer informatie zie:
40-
<a href="{base}/components/button-icon">Icoonknoppen</a>
81+
Voeg binnen de knop van elke sorteerbare kolom een icoon toe. Voor meer informatie zie:
82+
<a href="./icons.html">Iconen</a>.
83+
<ul>
84+
<li>
85+
Voeg <code>aria-hidden="true"</code> aan de <code>&lt;span></code> van het icoon, om
86+
te voorkomen dat het icoon in de toegankelijke naam van de knop opgenomen wordt.
87+
</li>
88+
<li>
89+
Zorg dat de gebruikte Icoonset iconen heeft voor ongesoorteerde data, oplopend
90+
gesorteerde data en aflopend gesorteerde data.
91+
</li>
92+
<li>
93+
Gebruik bij voorkeur iconen met ingevulde driehoeken, bijvoorbeeld <span
94+
class="icon icon-sortable">driehoeken omhoog en omlaag</span
95+
>
96+
voor ongesorteerd, <span class="icon icon-ascending">driehoek omhoog</span> voor
97+
oplopend gesorteerd en <span class="icon icon-descending">driehoek omlaag</span> voor
98+
aflopend gesorteerd.
99+
</li>
100+
</ul>
41101
</li>
42102
<li>
43-
Voeg <code>abbr=""</code> toe aan de <code>&lt;th&gt;</code> met een korte duidelijke omschrijving
44-
om de gebruikerservaring te verbeteren voor gebruikers die gebruik maken van een screenreader.
103+
Voeg een toelichting over de sorteerknoppen toe aan de <code>&lt;caption></code>.
104+
Bijvoorbeeld: "kolomkoppen met knoppen zijn sorteerbaar".
105+
<ul>
106+
<li>
107+
Indien gewenst kan deze tekst visueel verborgen worden met de <code
108+
>visually-hidden</code
109+
> class.
110+
</li>
111+
<li>
112+
Zorg ervoor dat er een punt of komma staat tussen de bestaande caption-tekst en deze
113+
hint-tekst. Bij gebruik van een <code>visually-hidden</code> <code>&lt;>span></code>
114+
kan bijvoorbeeld een komma toegevoegd worden voorafgaand aan de hint-tekst.
115+
</li>
116+
</ul>
117+
</li>
118+
<li>
119+
Voeg een <code>abbr=""</code> toe aan de <code>&lt;th></code> indien de tekst in de
120+
<code>&lt;th></code>
121+
erg lang is.
122+
<ul>
123+
<li>
124+
De kortere omschrijving in de <code>abbr=""</code> wordt gebruikt door screenreaders
125+
bij het voorlezen van een cel in de bijbehorende kolom.
126+
</li>
127+
</ul>
128+
</li>
129+
<li>
130+
Voeg JavaScript toe voor het dynamische gedrag van het component. De exacte
131+
implementatie is afhankelijk van de context.
132+
<ul>
133+
<li>
134+
Sorteer de inhoud van de tabel wanneer de gebruiker op één van de knoppen in de
135+
kolomkoppen klikt.
136+
</li>
137+
<li>
138+
Draai de sorteervolgorde om, wanneer de gebruiker op de knop klikt van de kolom waar
139+
op dit moment op gesorteerd wordt.
140+
</li>
141+
<li>
142+
Zorg ervoor dat elke kolomkop het juiste icoon heeft, afhankelijk van de huidige
143+
sortering van de tabel.
144+
</li>
145+
<li>
146+
Voeg <code>aria-sort="ascending"</code> / <code>aria-sort="descending"</code> toe
147+
aan de <code>&lt;th></code> van de kolom waarop gesorteerd wordt.
148+
</li>
149+
</ul>
45150
</li>
46151
</ol>
47152

48153
<h2>Aandachtspunten</h2>
49154
<ul>
50-
<li>Dit element bevat momenteel geen JavaScript of logica voorbeeld.</li>
155+
<li>
156+
<strong
157+
>Het is voor dit component nodig om het dynamische gedrag zelf via JavaScript te
158+
implementeren.</strong
159+
>
160+
</li>
161+
<li>De exacte implementatie in JavaScript is afhankelijk van de context.</li>
162+
<li>
163+
De manier waarop de data gesorteerd moet worden, kan afhankelijk zijn van het soort data
164+
(bijvoorbeeld tekstueel of numeriek). Dit kan per kolom verschillen.
165+
</li>
51166
</ul>
52167
</section>
53168

54169
<section id="examples">
55170
<h2>Voorbeelden</h2>
56171
<h3>Visueel voorbeeld:</h3>
57172
<div class="horizontal-scroll">
58-
<table>
59-
<caption> Tabelvoorbeeld met sorteerbare data: </caption>
173+
<table id="sortable-table-example">
174+
<caption>
175+
Tabelvoorbeeld met sorteerbare data
176+
<span class="visually-hidden">, kolomkoppen met knoppen zijn sorteerbaar</span>
177+
</caption>
60178
<thead>
61179
<tr>
62-
<th scope="col" abbr="Ascending data">
63-
<button title="Sort descending">
64-
Descending <span class="icon icon-ascending"></span>
180+
<th scope="col" aria-sort={sortColumn === "firstname" ? sortDirection : undefined}>
181+
<button class="sort" on:click={() => toggleSort("firstname")}>
182+
Voornaam
183+
<span
184+
aria-hidden="true"
185+
class="icon"
186+
class:icon-sortable={sortColumn !== "firstname"}
187+
class:icon-ascending={sortColumn === "firstname" &&
188+
sortDirection === "ascending"}
189+
class:icon-descending={sortColumn === "firstname" &&
190+
sortDirection === "descending"}
191+
/>
192+
</button>
193+
</th>
194+
<th
195+
scope="col"
196+
abbr="Achternaam"
197+
aria-sort={sortColumn === "lastname" ? sortDirection : undefined}
198+
>
199+
<button class="sort" on:click={() => toggleSort("lastname")}>
200+
Achternaam (met tussenvoegsel)
201+
<span
202+
aria-hidden="true"
203+
class="icon"
204+
class:icon-sortable={sortColumn !== "lastname"}
205+
class:icon-ascending={sortColumn === "lastname" &&
206+
sortDirection === "ascending"}
207+
class:icon-descending={sortColumn === "lastname" &&
208+
sortDirection === "descending"}
209+
/>
65210
</button>
66211
</th>
67-
<th scope="col" abbr="Descending data">
68-
<button title="Sort ascending">
69-
Ascending <span class="icon icon-descending"></span>
212+
<th
213+
scope="col"
214+
class="number"
215+
aria-sort={sortColumn === "age" ? sortDirection : undefined}
216+
>
217+
<button class="sort" on:click={() => toggleSort("age")}>
218+
Leeftijd
219+
<span
220+
aria-hidden="true"
221+
class="icon"
222+
class:icon-sortable={sortColumn !== "age"}
223+
class:icon-ascending={sortColumn === "age" && sortDirection === "ascending"}
224+
class:icon-descending={sortColumn === "age" && sortDirection === "descending"}
225+
/>
70226
</button>
71227
</th>
72228
</tr>
73229
</thead>
74230

75231
<tbody>
76-
<tr>
77-
<td>Lorem</td>
78-
<td>Ipsum</td>
79-
</tr>
80-
<tr>
81-
<td>Lorem</td>
82-
<td>Ipsum</td>
83-
</tr>
232+
{#each sortedDemoTableRows as row}
233+
<tr>
234+
<td>{row.firstname}</td>
235+
<td>{row.lastname}</td>
236+
<td class="number">{row.age}</td>
237+
</tr>
238+
{/each}
84239
</tbody>
85240
</table>
86241
</div>
@@ -91,31 +246,58 @@
91246
code={`
92247
<div class="horizontal-scroll">
93248
<table>
94-
<caption>Tabelvoorbeeld met sorteerbare data:</caption>
249+
<caption>
250+
Tabelvoorbeeld met sorteerbare data
251+
<span class="visually-hidden">, kolomkoppen met knoppen zijn sorteerbaar</span>
252+
</caption>
95253
<thead>
96254
<tr>
97-
<th scope="col" abbr="Ascending data">
98-
<button title="Sort descending">Descending <span class="icon icon-ascending"></button>
255+
<th scope="col">
256+
<button>
257+
Voornaam
258+
<span class="icon icon-sortable" aria-hidden="true"></span>
259+
</button>
260+
</th>
261+
<th scope="col" abbr="Achternaam">
262+
<button>
263+
Achternaam (met tussenvoegsel)
264+
<span class="icon icon-sortable" aria-hidden="true"></span>
265+
</button>
99266
</th>
100-
<th scope="col" abbr="Descending data">
101-
<button title="Sort ascending">Ascending <span class="icon icon-descending"></span></button>
267+
<th scope="col">
268+
<button>
269+
Leeftijd
270+
<span class="icon icon-sortable" aria-hidden="true"></span>
271+
</button>
102272
</th>
103273
</tr>
104274
</thead>
105275
106276
<tbody>
107277
<tr>
108-
<td>Lorem</td>
109-
<td>Ipsum</td>
278+
<td>Janine</td>
279+
<td>Hinde</td>
280+
<td class="number">16</td>
281+
</tr>
282+
<tr>
283+
<td>Henk</td>
284+
<td>de Vries</td>
285+
<td class="number">8</td>
286+
</tr>
287+
<tr>
288+
<td>Maria</td>
289+
<td>Lin</td>
290+
<td class="number">32</td>
110291
</tr>
111292
<tr>
112-
<td>Lorem</td>
113-
<td>Ipsum</td>
293+
<td>John</td>
294+
<td>Doe</td>
295+
<td class="number">64</td>
114296
</tr>
115297
</tbody>
116298
</table>
117299
</div>
118-
`}
300+
`}
119301
/>
120302
</section>
121303

0 commit comments

Comments
 (0)