diff --git a/iron-menu-behavior.html b/iron-menu-behavior.html
index a270301..662dc88 100644
--- a/iron-menu-behavior.html
+++ b/iron-menu-behavior.html
@@ -67,7 +67,7 @@
},
attached: function() {
- this._resetTabindices();
+ this._resetItemAttributes();
},
/**
@@ -90,16 +90,25 @@
},
/**
- * Resets all tabindex attributes to the appropriate value based on the
+ * Reset attributes of the menu's new/changed collection of items:
+ *
+ * Reset all tabindex attributes to the appropriate value based on the
* current selection state. The appropriate value is `0` (focusable) for
* the default selected item, and `-1` (not keyboard focusable) for all
* other items.
+ *
+ * Reset the aria-selected attribute based on the current selection state.
+ * As _applySelection notes, we need to set aria-selected to false for
+ * unselected items, even in their initial state, not just when they become
+ * deselected.
*/
- _resetTabindices: function() {
+ _resetItemAttributes: function() {
var selectedItem = this.multi ? (this.selectedItems && this.selectedItems[0]) : this.selectedItem;
this.items.forEach(function(item) {
- item.setAttribute('tabindex', item === selectedItem ? '0' : '-1');
+ var isSelected = item === selectedItem;
+ item.setAttribute('tabindex', isSelected ? '0' : '-1');
+ item.setAttribute('aria-selected', isSelected);
}, this);
},
@@ -193,11 +202,10 @@
* selected state, otherwise false.
*/
_applySelection: function(item, isSelected) {
- if (isSelected) {
- item.setAttribute('aria-selected', 'true');
- } else {
- item.removeAttribute('aria-selected');
- }
+ // Per the ARIA spec at https://www.w3.org/TR/wai-aria-1.1/#tab:
+ // "inactive tab elements [should] have their aria-selected attribute set
+ // to false".
+ item.setAttribute('aria-selected', isSelected);
Polymer.IronSelectableBehavior._applySelection.apply(this, arguments);
},
@@ -226,7 +234,8 @@
*/
_onIronItemsChanged: function(event) {
if (event.detail.addedNodes.length) {
- this._resetTabindices();
+ console.log('iron-menu-behavior: _onIronItemsChanged');
+ this._resetItemAttributes();
}
},
diff --git a/test/iron-menu-behavior.html b/test/iron-menu-behavior.html
index fa36c52..d9fea7c 100644
--- a/test/iron-menu-behavior.html
+++ b/test/iron-menu-behavior.html
@@ -497,6 +497,29 @@
done();
});
});
+
+ test('aria-selected attribute for items defaults to false', function() {
+ var menu = fixture('basic');
+ var selectedValues = menu.items.map(function(item) {
+ return item.getAttribute('aria-selected');
+ });
+ assert.deepEqual(selectedValues, ['false', 'false', 'false']);
+ });
+
+ test('aria-selected attribute reflects item selection state', function() {
+ var menu = fixture('basic');
+ var item0 = menu.items[0];
+ var item1 = menu.items[1];
+ assert.equal(item0.getAttribute('aria-selected'), 'false');
+ assert.equal(item1.getAttribute('aria-selected'), 'false');
+ menu.selected = 0;
+ assert.equal(item0.getAttribute('aria-selected'), 'true');
+ assert.equal(item1.getAttribute('aria-selected'), 'false');
+ menu.selected = 1;
+ assert.equal(item0.getAttribute('aria-selected'), 'false');
+ assert.equal(item1.getAttribute('aria-selected'), 'true');
+ });
+
});