From 9447ec7d72999f5e6bcef91baf803d51d0d0e442 Mon Sep 17 00:00:00 2001 From: Elliott Marquez Date: Fri, 15 Sep 2023 13:44:49 -0700 Subject: [PATCH] refactor(list)!: move list aria to host BREAKING CHANGE: Aria and roles on List have been moved to the host element. list-tabindex attribute should be migrated to tabindex attribute. type attribute should be migrated to role attribute. PiperOrigin-RevId: 565767899 --- catalog/site/_includes/default.html | 2 +- docs/components/list.md | 16 +++++++----- list/demo/demo.ts | 3 +-- list/demo/stories.ts | 7 +---- list/internal/list.ts | 40 ++++++++++++----------------- list/list_test.ts | 28 ++++++++++++++++++++ menu/internal/menu.ts | 4 +-- 7 files changed, 59 insertions(+), 41 deletions(-) diff --git a/catalog/site/_includes/default.html b/catalog/site/_includes/default.html index f5e341ebd5..94f6ef316c 100644 --- a/catalog/site/_includes/default.html +++ b/catalog/site/_includes/default.html @@ -56,7 +56,7 @@ {% block content %}{{ content | safe }}{% endblock %} - + {% for component in collections.component|filtersort('data.name') %}
  • -and[ `'listitem'`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listitem_role) -respectively. +List can have its `role` and `tabindex` set via the `role` and `tabindex` +attributes, and list items can have their internal `role` and `tabindex` set via +the `type` and `item-tabindex` attributes respectively. + +By default these values are set to +[`role="list"`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/list_role) +and `tabindex="-1"` for list, and +[`role="listitem"`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listitem_role) +and `tabindex="0"` for list items. The following example sets [`role="listbox"`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role) @@ -246,7 +250,7 @@ on the internal list and on the internal list item nodes. ```html - + account_circle diff --git a/list/demo/demo.ts b/list/demo/demo.ts index 895f711544..13712b376d 100644 --- a/list/demo/demo.ts +++ b/list/demo/demo.ts @@ -8,7 +8,7 @@ import './index.js'; import './material-collection.js'; import {KnobTypesToKnobs, MaterialCollection, materialInitsToStoryInits, setUpDemo, title} from './material-collection.js'; -import {boolInput, Knob, numberInput, textInput} from './index.js'; +import {boolInput, Knob, textInput} from './index.js'; import {stories, StoryKnobs} from './stories.js'; @@ -36,7 +36,6 @@ export const VIDEO_URL = const collection = new MaterialCollection>('List', [ - new Knob('listTabIndex', {ui: numberInput(), defaultValue: -1}), new Knob('md-list-item', {ui: title()}), new Knob('disabled', {ui: boolInput(), defaultValue: false}), new Knob('noninteractive', {ui: boolInput(), defaultValue: false}), diff --git a/list/demo/stories.ts b/list/demo/stories.ts index 264fc8516c..d8a0bc4b57 100644 --- a/list/demo/stories.ts +++ b/list/demo/stories.ts @@ -14,8 +14,6 @@ import {css, html} from 'lit'; /** Knob types for list stories. */ export interface StoryKnobs { - listTabIndex: number; - 'md-list-item': void; disabled: boolean; noninteractive: boolean; @@ -59,7 +57,6 @@ const standard: MaterialStoryInit = { }`, render(knobs) { const { - listTabIndex, disabled, noninteractive, multiLineSupportingText, @@ -72,9 +69,7 @@ const standard: MaterialStoryInit = { } = knobs; return html`
    - + + `; diff --git a/list/list_test.ts b/list/list_test.ts index c386134f6d..6bd988eeb1 100644 --- a/list/list_test.ts +++ b/list/list_test.ts @@ -937,6 +937,34 @@ describe('', () => { expect(document.activeElement).toEqual(first); }); }); + + describe('aria', () => { + it('Sets default role to list', async () => { + const root = env.render(html``); + const listEl = root.querySelector('md-list')!; + await env.waitForStability(); + const internals = + (listEl as unknown as {internals: {role: string | null}}).internals; + + expect(internals.role).toEqual('list'); + }); + + it('Does not override user given role attribute', async () => { + const root = env.render(html``); + const listEl = root.querySelector('md-list')!; + await env.waitForStability(); + + expect(listEl.getAttribute('role')).toBe('listbox'); + }); + + it('Does not override user given role property', async () => { + const root = env.render(html``); + const listEl = root.querySelector('md-list')!; + await env.waitForStability(); + + expect(listEl.role).toBe('listbox'); + }); + }); }); describe('', () => { diff --git a/menu/internal/menu.ts b/menu/internal/menu.ts index 19b4aac492..3e620ae8ec 100644 --- a/menu/internal/menu.ts +++ b/menu/internal/menu.ts @@ -306,8 +306,8 @@ export abstract class Menu extends LitElement { part="list" id="list" aria-label=${ariaLabel || nothing} - type=${this.type} - listTabIndex=${this.listTabIndex} + role=${this.type} + tabindex=${this.listTabIndex} @keydown=${this.handleListKeydown}> ${this.renderMenuItems()} `;