-
Notifications
You must be signed in to change notification settings - Fork 360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
File Viewer Tree Examples: Add aria-selected #1869
File Viewer Tree Examples: Add aria-selected #1869
Conversation
Address: w3c#1680 When an item receives a tab index of 0, then the aria-selected flag also turns to true.
@kdoberst Thanks for your PR as well as your patience. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for starting this PR! Let me know if you have questions on my feedback.
@@ -93,9 +93,11 @@ Tree.prototype.setFocusToItem = function (treeitem) { | |||
|
|||
if (ti === treeitem) { | |||
ti.domNode.tabIndex = 0; | |||
ti.domNode.ariaSelected = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To set the aria-selected
attribute, you'd need to use el.setAttribute('aria-selected', 'true')
. AOM attribute reflection isn't broadly supported, or stable.
The selected state should also likely be set to the actual selected item, and not the currently focused item. We should also probably look into adding a visual selected state, though we could conceivably add the attribute even without the visual state.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setAttribute
fixed. Visual selected indicator not fixed yet. What should it look like?
I don't see any aria-selected attribute from current treview example. |
@zcorpan The roles, properties and states table needs to be updated and also the regression tests for the additional |
@jongund I agree with you. |
The implementation at first was setting I've also written regression tests. |
00cb024
to
fbaacd6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading how tree.js
and treeitem.js
behave this example implements single selection and not multi selection. Is that right?
If that is right does the following apply to this example?
https://www.w3.org/TR/wai-aria-practices-1.2/#keyboard-interaction-23
- When a single-select tree receives focus:
- If none of the nodes are selected before the tree receives focus, focus is set on the first node.
- If a node is selected before the tree receives focus, focus is set on the selected node.
https://www.w3.org/TR/wai-aria-practices-1.2/#tree_roles_states_props
- If the tree does not support multiple selection, aria-selected is set to true for the selected node and it is not present on any other node in the tree.
- if the tree supports multiple selection:
- All selected nodes have aria-selected set to true.
- All nodes that are selectable but not selected have aria-selected set to false.
- If the tree contains nodes that are not selectable, those nodes do not have the aria-selected state.
If that applies, I think a few changes need to be made:
- No treeitem in the modified example html should have the attribute
aria-selected="false"
- Add event handling to select the first node when no node is selected
- Add event handling to focus the selected node when tree receives focus from outside the tree
- Regression test that clicking selects an item
- Regression test that Key.SPACE selects an item (ENTER is already covered in this PR)
@@ -87,6 +88,14 @@ Tree.prototype.init = function () { | |||
this.firstTreeitem.domNode.tabIndex = 0; | |||
}; | |||
|
|||
Tree.prototype.setSelectedToItem = function (treeitem) { | |||
if (this.selectedItem) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think of mirroring how setFocusToItem
is implemented with something like:
for (let i = 0; i < this.treeitems.length; i++) {
const ti = this.treeitems[i];
if (ti === treeitem) {
ti.domNode.setAttribute('aria-selected', 'true');
} else {
ti.domNode.removeAttribute('aria-selected');
}
}
t, | ||
ex.treeitemSelector + '[tabindex="0"]' | ||
); | ||
const focusMoved = items[i] !== nextItem; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an aside this will always be true. As I understand it, nextItem
may represent the same element in the dom but webdriver's js api doesn't guarentee that it will be the same object in this context. To test that they are the same I think you'd use WebElement.equals(items[i], nextItem)
or (await items[i].getId()) !== (await nextItem.getId())
.
test/tests/treeview_treeview-1a.js
Outdated
); | ||
|
||
ariaTest( | ||
'aria-selected attribute on treeitem on down arrow and enter', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this test tries to test too many behaviors in a single test and that one of the behaviors should also be tested with Key.SPACE
.
So maybe this should be tested with three tests? One to test that selection does not follow focus in response to Key.DOWN_ARROW
. One to test that Key.ENTER
selects on each treeitem. One to test that Key.SPACE
selects on each treeitem.
The 'does not follow focus' test could be something like:
ariaTest(
'aria-selected attribute does not follow focus',
exampleFile,
'treeitem-aria-selected-not-focus',
async (t) => {
t.plan((ex.treeitemCount - 1) * 2);
const items = await t.context.queryElements(t, ex.treeitemSelector);
// Test all but the last treeitem. The last treeitem does not lose focus when `Key.DOWN_ARROW` is pressed.
const itemsExcludeLast = items.slice(0, items.length - 1);
for (let i = 0; i < itemsExcludeLast.length; i++) {
const treeitem = itemsExcludeLast[i];
await treeitem.sendKeys(Key.ENTER);
await treeitem.sendKeys(Key.ARROW_DOWN);
const focusedItem = await t.context.queryElement(
t,
ex.treeitemSelector + '[tabindex="0"]'
);
t.is(
await treeitem.getAttribute('aria-selected'),
'true',
'selected treeitem does not change after sending ARROW DOWN'
);
t.is(
await focusedItem.getAttribute('aria-selected'),
'false',
'focused treeitem does not have aria-selected="true"'
);
}
}
);
With the changes made in ARIA 1.3 and already implemented in browsers, that statement in the pattern will need to change. I'll create a separate PR for that. If selection does not follow focus, like in this particular tree, then it is necessary to specify aria-selected on all selectable nodes. Otherwise, the browser might assume that selection follows focus and provide an implicit selected state to the focused treeitem. |
@mzgoddard pointed out this aspect of the pattern:
This example is not putting tabindex 0 on the item that is selected by pressing enter. In the navigation tree, we not only ensure the current item is kept in the tab sequence but also ensure that it is visible after blur. |
The example might be more clear if:
|
I noticed that enter both expands and selects a parent node. Shouldn't Enter only select? |
I've started drafting updated selection guidance for the tree pattern in #2121. I still have to add a note advising against using both selected and checked in the same tree and a note about when browsers imply selection. I'm hoping I can find time to finish it later tonight. |
APG meeting on Nov 9, 2021 (Note: plan to merge this tomorrow morning.)
|
FYI ... I was mistaken when I said the label change was good. I didn't actually look at this until I was editing other parts of the file:
Except in some very rare circumstances, none of which come to mind at the moment, it is not good practice to put aria-label on a heading. Headings get their name from content, and the aria-label overrides the name from content. Thus, in this case, screen reader users will think the heading is "My Documents", but the words on screen are "File Viewer". I was imagining that we would keep the "File Viewer" heading as a heading on the entire example (tree + edit field). And, I thought @smhigley had suggested adding a label of "My Documents" for just the tree. Instead, I just changed the heading to "My Documents" and removed the aria-label. This may have been what @smhigley was suggesting anyway. I may have initially misinterpreted her suggestion. BTW, for a more extensive description about name from content, which types of elements are named from content, and the dangers of aria-label, have a look at Section 5.3.2.1: Naming with Child Content. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finished editorial changes; this is approving editorial review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The icons used to represent the open and closed folders and a document in the declared properties example are broken, they work in the computed example.
- The documentation for the
space
key opening and closing a file folder is not documented in either example, and the APG guidance section only discusses thespace
key in the context of multi-selectable trees. It is also curious to note the behavior of thespace
andenter
keys is different when focus is on a folder node,space
opens and closes,enter
does not.
@jongund wrote:
@howard-e can you fix this this morning?
Behavior of space should be identical to Enter, which is that it should only select -- perform the default action. @howard-e can you change space key behavior so it does not open and close parent nodes? It should perform selection only, just like Enter. |
Sure, I'll take a look @mcking65 |
8c0e9fb
to
f623ddb
Compare
… RETURN and updated regression tests
'treeitem should have aria-selected="true" after selecting by sending key ENTER' | ||
); | ||
// move focus to the next item | ||
await items[i].sendKeys(Key.ARROW_DOWN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this line?
Addresses #1680.