Skip to content
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

Merged

Conversation

kdoberst
Copy link
Contributor

@kdoberst kdoberst commented Apr 23, 2021

Address: w3c#1680

When an item receives a tab index of 0, then the aria-selected flag also turns to true.
@a11ydoer
Copy link
Contributor

a11ydoer commented Jun 21, 2021

@kdoberst Thanks for your PR as well as your patience.
We will discuss this PR at ARIA APG meeting on June 22 and update the issue.

@a11ydoer a11ydoer requested a review from mcking65 June 22, 2021 18:54
Copy link
Contributor

@smhigley smhigley left a 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;
Copy link
Contributor

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.

Copy link
Member

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?

@mcking65 mcking65 added this to the 1.2 Release 1 milestone Oct 18, 2021
@mcking65
Copy link
Contributor

Added to November 2, 2021 Agenda · w3c/aria-practices Wiki

@a11ydoer
Copy link
Contributor

a11ydoer commented Nov 2, 2021

I don't see any aria-selected attribute from current treview example.

@jongund or @zcorpan any idea?

@zcorpan
Copy link
Member

zcorpan commented Nov 2, 2021

@a11ydoer right, this PRs adds it. But I guess it should also include aria-selected="false" in markup on each item, as it's a required state.

Edit: added in e93dbfd

@jongund
Copy link
Contributor

jongund commented Nov 2, 2021

@zcorpan The roles, properties and states table needs to be updated and also the regression tests for the additional aria-selected attribute to be documented and tested in the example.

@a11ydoer
Copy link
Contributor

a11ydoer commented Nov 2, 2021

@jongund I agree with you.
Can you point where the roles, properties and states table is? It has been a while to see that table and I will make sure whether we have updated every attribute in the table.

@zcorpan
Copy link
Member

zcorpan commented Nov 3, 2021

The implementation at first was setting aria-selected="true" to the currently focused item. Since the example doesn't change which file is "selected" (as shown in the "File or Folder Selected" box) when moving focus, only when clicking or pressing enter, I changed the implementation to set aria-selected="true" in onClick.

I've also written regression tests.

@zcorpan zcorpan force-pushed the Issue-1680-add-aria-selected-to-treeview-items branch from 00cb024 to fbaacd6 Compare November 3, 2021 15:49
Copy link
Contributor

@mzgoddard mzgoddard left a 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) {
Copy link
Contributor

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;
Copy link
Contributor

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()).

);

ariaTest(
'aria-selected attribute on treeitem on down arrow and enter',
Copy link
Contributor

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"'
      );
    }
  }
);

@mcking65
Copy link
Contributor

mcking65 commented Nov 8, 2021

@mzgoddard

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.

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.

@mcking65
Copy link
Contributor

mcking65 commented Nov 8, 2021

@mzgoddard pointed out this aspect of the pattern:

  • 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.

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.

@mcking65
Copy link
Contributor

mcking65 commented Nov 8, 2021

The example might be more clear if:

  1. The label on the tree were "Select folder or file to view". Currently, the tree is labeled "File viewer", but the tree is not a viewer; it is a chooser.
  2. The label on the read-only edit field were "Selected folder or file:" Putting the word "selected" first may improve clarity.

@mcking65
Copy link
Contributor

mcking65 commented Nov 8, 2021

I noticed that enter both expands and selects a parent node. Shouldn't Enter only select?

@mcking65 mcking65 changed the title Set aria selected to active tree view item File Viewer Tree Examples: Add aria-selected Nov 8, 2021
@mcking65
Copy link
Contributor

mcking65 commented Nov 8, 2021

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.

@a11ydoer
Copy link
Contributor

a11ydoer commented Nov 9, 2021

APG meeting on Nov 9, 2021 (Note: plan to merge this tomorrow morning.)

  • change label on tree to be "My Documents", not "File viewer" The heading of "File Viewer" can stay.
  • add a visual selection state - refer the visual example of navigation tree
  • remove expanding/collapsing behavior from enter key(make it consistent with other APG patterns)

@mcking65
Copy link
Contributor

@howard-e

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:

<h3 id="tree1" aria-label="My Documents">File Viewer</h3>

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.

@mcking65
Copy link
Contributor

@jongund or @smhigley
I think I have this in a good place to ship. Would be nice if either of you could take a look and change to approving review.

Copy link
Contributor

@mcking65 mcking65 left a 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.

Copy link
Contributor

@jongund jongund left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 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.
  2. 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 the space key in the context of multi-selectable trees. It is also curious to note the behavior of the space and enter keys is different when focus is on a folder node, space opens and closes, enter does not.

@jongund
Copy link
Contributor

jongund commented Nov 15, 2021

@mcking65 @howard-e I added a review, a few more things I think need to be addressed.

@mcking65
Copy link
Contributor

@jongund wrote:

  1. 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.

@howard-e can you fix this this morning?

  1. 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 the space key in the context of multi-selectable trees. It is also curious to note the behavior of the space and enter keys is different when focus is on a folder node, space opens and closes, enter does not.

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.

@howard-e
Copy link
Contributor

Sure, I'll take a look @mcking65

@howard-e howard-e force-pushed the Issue-1680-add-aria-selected-to-treeview-items branch from 8c0e9fb to f623ddb Compare November 15, 2021 16:12
@jongund
Copy link
Contributor

jongund commented Nov 15, 2021

@mcking65 @howard-e
Approved this pull request

@howard-e
Copy link
Contributor

Approved this pull request

Thanks @jongund.

can you change space key behavior so it does not open and close parent nodes? It should perform selection only, just like Enter

Also just pushed the final change to account for @mcking65's request and updated the relevant 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this line?

@mcking65 mcking65 merged commit 1c89267 into w3c:main Nov 15, 2021
@mcking65 mcking65 added editorial Changes to prose that don't alter intended meaning, e.g., phrasing, grammar. May fix inaccuracies. enhancement Any addition or improvement that doesn't fix a code bug or prose inaccuracy Example Page Related to a page containing an example implementation of a pattern QA for APG Examples Related to improve the quality and the acceptance of APG examples labels Nov 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
editorial Changes to prose that don't alter intended meaning, e.g., phrasing, grammar. May fix inaccuracies. enhancement Any addition or improvement that doesn't fix a code bug or prose inaccuracy Example Page Related to a page containing an example implementation of a pattern QA for APG Examples Related to improve the quality and the acceptance of APG examples
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants