/
treegrid-1.html
526 lines (516 loc) · 22.5 KB
/
treegrid-1.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Treegrid Email Inbox Example | WAI-ARIA Authoring Practices 1.1</title>
<!-- Core js and css shared by all examples; do not modify when using this template. -->
<link rel="stylesheet" href="https://www.w3.org/StyleSheets/TR/2016/base.css">
<link rel="stylesheet" href="../css/core.css">
<script src="../js/examples.js"></script>
<script src="../js/highlight.pack.js"></script>
<script src="../js/app.js"></script>
<!-- js and css for this example. -->
<link href="css/treegrid-1.css" rel="stylesheet">
<style>
/* Style the current cell focus option so user know what they're getting */
[aria-current] {
position: relative;
outline: 2px solid green;
outline-offset: 3px;
background-color: #fffff8;
}
[aria-current] > a::before {
display: inline-block;
position: absolute;
content: "Current";
font-size: 80%;
right: -3px;
top: -3px;
padding: 3px 1ch;
background-color: green;
color: white;
font-weight: bold;
}
</style>
<script src="js/treegrid-1.js" type="text/javascript"></script>
<script>
/* Init Script for TreeGrid */
/* Get an object where each field represents a URL parameter */
/* global TreeGrid */
function getQuery () {
if (!getQuery.cached) {
getQuery.cached = {};
const queryStr = window.location.search.substring(1);
const vars = queryStr.split('&');
for (let i = 0; i<vars.length; i++) {
const pair = vars[i].split('=');
// If first entry with this name
getQuery.cached[pair[0]] = pair[1] && decodeURIComponent(pair[1]);
}
}
return getQuery.cached;
}
document.addEventListener('DOMContentLoaded', function () {
// Supports url parameter ?cell=force or ?cell=start (or leave out parameter)
var cellParam = getQuery().cell;
var doAllowRowFocus = cellParam !== 'force';
var doStartRowFocus = doAllowRowFocus && cellParam !== 'start';
TreeGrid(document.getElementById('treegrid'), doAllowRowFocus, doStartRowFocus);
var choiceElem = document.getElementById('option-cell-focus-' + (cellParam || 'allow'));
choiceElem.setAttribute('aria-current', 'true');
});
</script>
</head>
<body>
<nav aria-label="Related Links" class="feedback">
<ul>
<li><a href="../../#browser_and_AT_support">Browser and Assistive Technology Support</a></li>
<li><a href="https://github.com/w3c/aria-practices/issues/new">Report Issue</a></li>
<li><a href="https://github.com/w3c/aria-practices/projects/17">Related Issues</a></li>
<li><a href="../../#treegrid">Treegrid Design Pattern</a></li>
</ul>
</nav>
<main>
<h1>Treegrid Email Inbox Example</h1>
<p>
<strong>NOTE:</strong> This example is new in APG 1.1 release 2.
Please provide feedback in
<a href="https://github.com/w3c/aria-practices/issues/790">issue 790.</a>
</p>
<p>
The following example demonstrates how the
<a href="../../#treegrid">treegrid design pattern</a>
can be used to make an interactive tree that enables users to both navigate the hierarchical structure of email conversations
and also navigate elements that describe each email, such as subject and sender.
</p>
<p>Similar examples include: </p>
<ul>
<li><a href="../grid/dataGrids.html">Data Grid Examples</a>: Three example implementations of grid that include features relevant to presenting tabular information, such as content editing, sort, and column hiding.</li>
<li><a href="../treeview/treeview-1/treeview-1a.html">File Directory Treeview using <em>computed</em> properties</a></li>
<li><a href="../treeview/treeview-1/treeview-1b.html">File Directory Treeview using <em>declared</em> properties</a></li>
<li><a href="../treeview/treeview-2/treeview-2a.html">Navigation Treeview using <em>computed</em> properties</a></li>
<li><a href="../treeview/treeview-2/treeview-2b.html">Navigation Treeview using <em>declared</em> properties</a></li>
</ul>
<h2>Example Usage Options</h2>
<p>
This example demonstrates three different ways of implementing the keyboard navigation specified in the treegrid pattern.
The following links change the behavior of the navigation keys :
</p>
<ul>
<li id="option-cell-focus-allow">
<a href="./treegrid-1.html">Rows are focused first, but cells can be focused</a>:<br>
Useful when the desired experience is for the treegrid to act primarily like a tree where each row is treated like a node in a tree,
but it is still possible for users to navigate across the cells in a row.
</li>
<li id="option-cell-focus-start">
<a href="./treegrid-1.html?cell=start">Cells are focused first, but rows can be focused</a>:<br>
Useful when the desired experience is for the treegrid to act primarily like a grid where arrow keys move among cells,
but it is still possible for users to focus a row and then start navigating the structure like a tree.
</li>
<li id="option-cell-focus-force">
<a href="./treegrid-1.html?cell=force">Only cells can be focused</a>:<br>
Useful when the desired experience is that the treegrid act primarily like a grid and there is no need to focus complete rows.
</li>
</ul>
<p>
Note: A row-only option is not provided.
A treegrid where cells cannot be focused would be implemented as a <a href="../../#TreeView">tree view</a>.
A treeview that has columns in its visual presentation may be appropriate when all the following conditions are present:
</p>
<ul>
<li>Columns are guaranteed to fit horizontally (no horizontal scrolling necessary).</li>
<li>Columns are merely for attractive presentation; there is no need to navigate them individually.</li>
<li>A screen reader user can easily understand the UI when all information in a row is announced as a single string without any separation.</li>
</ul>
<section>
<h2 id="ex_label">Example</h2>
<div role="separator" id="ex_start_sep" aria-labelledby="ex_start_sep ex_label" aria-label="Start of"></div>
<!--
Note the ID of the following div that contains the example HTML is used as a parameter for the sourceCode.add() function.
The sourceCode functions in the examples/js/examples.js render the HTML source to show it to the reader of the example page.
If you change the ID of this div, be sure to update the parameters of the sourceCode.add() function call, which is made following the div with id="sc1" where the HTML is render.
The div for the rendered HTML source is in the last section of the page.
-->
<div id="ex1">
<table id="treegrid" role="treegrid" aria-label="Inbox">
<colgroup>
<col id="treegrid-col1">
<col id="treegrid-col2">
<col id="treegrid-col3">
</colgroup>
<thead>
<tr>
<th scope="col">Subject</th>
<th scope="col">Summary</th>
<th scope="col">Email</th>
</tr>
</thead>
<tbody>
<tr role="row" aria-level="1" aria-posinset="1" aria-setsize="1" aria-expanded="true">
<td role="gridcell">Treegrids are awesome</td>
<td role="gridcell">Want to learn how to use them?</td>
<td role="gridcell"><a href="mailto:aaron@thegoogle.rocks">aaron@thegoogle.rocks</a></td>
</tr>
<tr role="row" aria-level="2" aria-posinset="1" aria-setsize="3">
<td role="gridcell">re: Treegrids are awesome</td>
<td role="gridcell">I agree with you, they are the shizzle</td>
<td role="gridcell"><a href="mailto:joe@blahblahblah.blahblah">joe@blahblahblah.blahblah</a></td>
</tr>
<tr role="row" aria-level="2" aria-posinset="2" aria-setsize="3" aria-expanded="false">
<td role="gridcell">re: Treegrids are awesome
<td role="gridcell">They are great for showing a lot of data, like a grid
<td role="gridcell"><a href="mailto:billy@dangerous.fish">billy@dangerous.fish</a></td>
</tr>
<tr role="row" aria-level="3" aria-posinset="1" aria-setsize="1" class="hidden">
<td role="gridcell">re: Treegrids are awesome</td>
<td role="gridcell">Cool, we've been needing an example and documentation</td>
<td role="gridcell"><a href="mailto:doris@rufflazydogs.sleep">doris@rufflazydogs.sleep</a></td>
</tr>
<tr role="row" aria-level="2" aria-posinset="3" aria-setsize="3" aria-expanded="false">
<td role="gridcell">re: Treegrids are awesome</td>
<td role="gridcell">I hear the Fancytree library is going to align with this example!</td>
<td role="gridcell"><a href="mailto:someone@please-do-it.company">someone@please-do-it.company</a></td>
</tr>
<tr role="row" aria-level="3" aria-posinset="1" aria-setsize="1" aria-expanded="false" class="hidden">
<td role="gridcell">re: Treegrids are awesome</td>
<td role="gridcell">Sometimes they are more like trees, others are more like grids</td>
<td role="gridcell"><a href="mailto:mari@beingpractical.com">mari@beingpractical.com</a></td>
</tr>
<tr role="row" aria-level="4" aria-posinset="1" aria-setsize="2" class="hidden">
<td role="gridcell">re: Treegrids are awesome</td>
<td role="gridcell">Cool, when it's a tree, let's keep left/right to collapse/expand</td>
<td role="gridcell"><a href="mailto:issie@imadeadcatsadly.wascute">issie@imadeadcatsadly.wascute</a></td>
</tr>
<tr role="row" aria-level="4" aria-posinset="2" aria-setsize="2" class="hidden">
<td role="gridcell">re: Treegrids are awesome
<td role="gridcell">I see, sometimes right arrow moves by column</td>
<td role="gridcell"><a href="mailto:kitten@kittenseason.future">kitten@kittenseason.future</a></td>
</tr>
</tbody>
</table>
</div>
<div role="separator" id="ex_end_sep" aria-labelledby="ex_end_sep ex_label" aria-label="End of"></div>
</section>
<section>
<h2 id="kbd_label">Keyboard Support</h2>
<p>
<strong>NOTE:</strong> The following table includes descriptions of how keyboard commands move focus among cells and rows in the treegrid implementation on this page.
In the example on this page, some cells contain a single focusable widget, and if a cell contains a widget, the cell is not focusable; the widget receives focus instead of the cell.
So, when a keyboard command description says a command moves focus to a cell, the command may either focus the cell or a widget inside the cell.
</p>
<table aria-labelledby="kbd_label" class="def">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">
<kbd>Right Arrow</kbd>
</th>
<td>
<ul>
<li>If a row is focused, and it is collapsed, expands the current row.</li>
<li>If a row is focused, and it is expanded, focuses the first cell in the row.</li>
<li>If a cell is focused, moves one cell to the right.</li>
<li>If focus is on the right most cell, focus does not move.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<kbd>Left Arrow</kbd>
</th>
<td>
<ul>
<li>If a row is focused, and it is expanded, collapses the current row.</li>
<li>If a row is focused, and it is collapsed, moves to the parent row (if there is one).</li>
<li>If a cell in the first column is focused, focuses the row.</li>
<li>If a cell in a different column is focused, moves focus one cell to the left.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<kbd>Down Arrow</kbd>
</th>
<td>
<ul>
<li>Moves focus one row or one cell down, depending on whether a row or cell is currently focused.</li>
<li>If focus is on the bottom row, focus does not move.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<kbd>Up Arrow</kbd>
</th>
<td>
<ul>
<li>Moves focus one row or one cell up, depending on whether a row or cell is currently focused.</li>
<li>If focus is on the top row, focus does not move.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<kbd>Tab</kbd>
</th>
<td>
<ul>
<li>Moves focus to the next interactive widget in the current row.</li>
<li>If there are no more interactive widgets in the current row, moves focus out of the treegrid.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<kbd>Shift + Tab</kbd>
</th>
<td>
<ul>
<li>If a cell is focused, moves focus to the previous interactive widget in the current row.</li>
<li>If a row is focused, moves focus out of the treegrid.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<kbd>Home</kbd>
</th>
<td>
<ul>
<li>If a row is focused, moves to the first row.</li>
<li>If a cell is focused, moves focus to the first cell in the row containing focus.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<kbd>End</kbd>
</th>
<td>
<ul>
<li>If a row is focused, moves to the last row.</li>
<li>If a cell is focused, moves focus to the last cell in the row containing focus.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<kbd>Control + Home</kbd>
</th>
<td>
<ul>
<li>If a row has focus, moves focus to the first row.</li>
<li>If a cell has focus, moves focus to the cell in the first row in the same column as the cell that had focus.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<kbd>Control + End</kbd>
</th>
<td>
<ul>
<li>If a row has focus, moves focus to the last row.</li>
<li>If a cell has focus, moves focus to the cell in the last row in the same column as the cell that had focus.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row">
<kbd>Enter</kbd>
</th>
<td>
<ul>
<li>Performs default action associated with row or cell that has focus, e.g. opens message or navigate to link.</li>
<li>If focus is on the cell with the expand/collapse button, and there is no other action, will toggle expansion of the current row.</li>
</ul>
</td>
</tr>
</tbody>
</table>
</section>
<section>
<h2 id="rps_label">Role, Property, State, and Tabindex Attributes</h2>
<table aria-labelledby="rps_label" class="data attributes">
<thead>
<tr>
<th scope="col">Role</th>
<th scope="col">Attribute</th>
<th scope="col">Element</th>
<th scope="col">Usage</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row"><code>treegrid</code></th>
<td></td>
<td><code>table</code></td>
<td>Identifies the element as a <code>treegrid</code>.</td>
</tr>
<tr>
<td>
</td>
<th scope="row"><code>aria-label="Inbox"</code></th>
<td><code>table</code></td>
<td>Provides an accessible name for the <code>treegrid</code>.</td>
</tr>
<tr>
<th scope="row"><code>row</code></th>
<td></td>
<td><code>tr</code></td>
<td>
<ul>
<li>Identifies the element as a <code>row</code>.</li>
<li>The <code>row</code> role is not an implicit semantic for the <code>tr</code> element when in a <code>treegrid</code>.</li>
</ul>
</td>
</tr>
<tr>
<td></td>
<th scope="row"><code>tabindex="-1"</code></th>
<td><code>tr</code> or <code>td</code></td>
<td>
<ul>
<li>Makes the element focusable without including it in the tab sequence of the page.</li>
<li>All <code>row</code> and <code>gridcell</code> elements are focusable, but only one is included in the tab sequence.</li>
</ul>
</td>
</tr>
<tr>
<td></td>
<th scope="row"><code>tabindex="0"</code></th>
<td><code>tr</code> or <code>td</code></td>
<td>
<ul>
<li>Includes the element in the tab sequence.</li>
<li>Only one <code>row</code> or <code>gridcell</code> in the <code>treegrid</code> has <code>tabindex="0"</code>.</li>
<li>In this implementation, the first <code>row</code> in the <code>treegrid</code> is included in the tab sequence when the page loads.</li>
<li>
When the user moves focus in the <code>treegrid</code>, the element included in the tab sequence changes to the element with focus as described in the section on
<a href="../../../#kbd_roving_tabindex">roving tabindex.</a>
</li>
</ul>
</td>
</tr>
<tr>
<td>
</td>
<th scope="row"><code>aria-expanded="false"</code></th>
<td><code>tr</code> or <code>td</code></td>
<td>
<ul>
<li>Applied only to parent row or first cell of parent row, i.e., next set of rows are responses to the message in this row</li>
<li>Indicates the parent row is closed, i.e., the descendant rows are not visible.</li>
<li>The visual indication of the collapsed state is synchronized by a CSS attribute selector.</li>
<li>When the treegrid is configured to support focus on rows <code>aria-expanded</code> is on the <code>tr</code> elements, but when the treegrid is configured to support focus on cells only, <code>aria-expanded</code> is on the first <code>td</code> element contained in each row.</li>
</ul>
</td>
</tr>
<tr>
<td>
</td>
<th scope="row"><code>aria-expanded="true"</code></th>
<td><code>tr</code> or <code>td</code></td>
<td>
<ul>
<li>Applied only to parent rows or the first cell in parent rows, i.e., next set of rows are responses to the message in this row</li>
<li>Indicates the parent row is open, i.e., the descendant rows are visible.</li>
<li>The visual indication of the open state is synchronized by a CSS attribute selector.</li>
<li>When the treegrid is configured to support focus on rows <code>aria-expanded</code> is on the <code>tr</code> elements, but when the treegrid is configured to support focus on cells only, <code>aria-expanded</code> is on the first <code>td</code> element contained in each row.</li>
</ul>
</td>
</tr>
<tr>
<td>
</td>
<th scope="row"><code>aria-level="<em>number</em>"</code></th>
<td><code>tr</code></td>
<td>
<ul>
<li>Defines the level of the row in the hierarchical treegrid structure.</li>
<li>Counting is one-based.</li>
<li>Root rows have aria-level=“1”.</li>
</ul>
</td>
</tr>
<tr>
<td>
</td>
<th scope="row"><code>aria-setsize="<em>number</em>"</code></th>
<td><code>tr</code></td>
<td>
Defines the number of rows in the set of rows that are in the same branch and at the same level within the hierarchy.
</td>
</tr>
<tr>
<td>
</td>
<th scope="row"><code>aria-posinset="<em>number</em>"</code></th>
<td><code>tr</code></td>
<td>
<ul>
<li>Defines the position of the row within the set of other rows that are in the same branch and at the same level within the hierarchy.</li>
<li>Counting is one-based, not zero-based.</li>
</ul>
</td>
</tr>
<tr>
<th scope="row"><code>gridcell</code></th>
<td></td>
<td><code>td</code></td>
<td>
<ul>
<li>Identifies the element as a <code>gridcell</code>.</li>
<li>The <code>gridcell</code> role is not an implicit semantic for the <code>td</code> element when in a <code>treegrid</code>.</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>
<strong>NOTE:</strong> Due to an error in the ARIA 1.1 specification, the <code>aria-posinset</code> and <code>aria-setsize</code> properties are not supported on row elements.
This is being corrected in ARIA 1.2.
Consequently, when validating the HTML in this example, errors are generated.
</p>
</section>
<section>
<h2>Javascript and CSS Source Code</h2>
<!-- After the js and css files are named with the name of this example, change the href and text of the following 2 links to refer to the appropriate js and css files. -->
<ul>
<li>
CSS:
<a href="css/treegrid-1.css" type="text/css">treegrid-1.css</a>
</li>
<li>
Javascript:
<a href="js/treegrid-1.js" type="text/javascript">treegrid-1.js</a>
</li>
</ul>
</section>
<section>
<h2 id="sc1_label">HTML Source Code</h2>
<div role="separator" id="sc1_start_sep" aria-labelledby="sc1_start_sep sc1_label" aria-label="Start of"></div>
<pre><code id="sc1"></code></pre>
<div role="separator" id="sc1_end_sep" aria-labelledby="sc1_end_sep sc1_label" aria-label="End of"></div>
<!--
The following script will show the reader the HTML source for the example that is in the div with ID 'ex1'.
It renders the HTML in the preceding pre element with ID 'sc1'.
If you change the ID of either the 'ex1' div or the 'sc1' pre, be sure to update the sourceCode.add function parameters.
-->
<script>
sourceCode.add('sc1', 'ex1');
sourceCode.make();
</script>
</section>
</main>
<nav>
<!-- Update the pattern_ID parameter of this link to refer to the APG design pattern section related to this example. -->
<a href="../../#treegrid">Treegrid Design Pattern in WAI-ARIA Authoring Practices 1.1</a>
</nav>
</body>
</html>