From f5daadc3078d6be81c354de6646e392dd7bf6a41 Mon Sep 17 00:00:00 2001 From: Elizabeth Mitchell Date: Thu, 26 Oct 2023 14:08:23 -0700 Subject: [PATCH] chore: update components to use mixinFocusable PiperOrigin-RevId: 576982507 --- chips/internal/chip-set.ts | 4 +-- internal/aria/aria.ts | 53 -------------------------------------- list/internal/list.ts | 4 +-- menu/internal/menu.ts | 5 ++-- radio/internal/radio.ts | 12 ++++++--- tabs/internal/tab.ts | 10 ++++--- tabs/internal/tabs.ts | 4 +-- 7 files changed, 23 insertions(+), 69 deletions(-) diff --git a/chips/internal/chip-set.ts b/chips/internal/chip-set.ts index c7ac6eeb8..8fa151f43 100644 --- a/chips/internal/chip-set.ts +++ b/chips/internal/chip-set.ts @@ -8,8 +8,8 @@ import {html, isServer, LitElement} from 'lit'; import {queryAssignedElements} from 'lit/decorators.js'; import { + polyfillARIAMixin, polyfillElementInternalsAria, - setupHostAria, } from '../../internal/aria/aria.js'; import {Chip} from './chip.js'; @@ -19,7 +19,7 @@ import {Chip} from './chip.js'; */ export class ChipSet extends LitElement { static { - setupHostAria(ChipSet, {focusable: false}); + polyfillARIAMixin(ChipSet); } get chips() { diff --git a/internal/aria/aria.ts b/internal/aria/aria.ts index 8563aeb23..b5c1be454 100644 --- a/internal/aria/aria.ts +++ b/internal/aria/aria.ts @@ -315,59 +315,6 @@ export function polyfillARIAMixin(ctor: typeof ReactiveElement) { ctor.createProperty('role', {reflect: true}); } -/** - * Enables a host custom element to be the target for aria roles and attributes. - * Components should set the `elementInternals.role` property. - * - * By default, aria components are tab focusable. Provide a `focusable: false` - * option for components that should not be tab focusable, such as - * `role="listbox"`. - * - * This function will also polyfill aria `ElementInternals` properties for - * Firefox. - * - * @param ctor The `ReactiveElement` constructor to set up. - * @param options Options to configure the element's host aria. - * @deprecated use `mixinFocusable()` and `polyfillARIAMixin()` - * TODO(b/307785469): remove after updating components to use mixinFocusable - */ -export function setupHostAria( - ctor: typeof ReactiveElement, - {focusable}: SetupHostAriaOptions = {}, -) { - if (focusable !== false) { - ctor.addInitializer((host) => { - host.addController({ - hostConnected() { - if (host.hasAttribute('tabindex')) { - return; - } - - host.tabIndex = 0; - }, - }); - }); - } - - polyfillARIAMixin(ctor); -} - -/** - * Options for setting up a host element as an aria target. - * @deprecated use `mixinFocusable()` and `polyfillARIAMixin()` - * TODO(b/307785469): remove after updating components to use mixinFocusable - */ -export interface SetupHostAriaOptions { - /** - * Whether or not the element can be focused with the tab key. Defaults to - * true. - * - * Set this to false for aria roles that should not be tab focusable, such as - * `role="listbox"`. - */ - focusable?: boolean; -} - /** * Polyfills an element and its `ElementInternals` to support `ARIAMixin` * properties on internals. This is needed for Firefox. diff --git a/list/internal/list.ts b/list/internal/list.ts index 06338d105..bf0ce07c3 100644 --- a/list/internal/list.ts +++ b/list/internal/list.ts @@ -8,8 +8,8 @@ import {html, isServer, LitElement} from 'lit'; import {queryAssignedElements} from 'lit/decorators.js'; import { + polyfillARIAMixin, polyfillElementInternalsAria, - setupHostAria, } from '../../internal/aria/aria.js'; import {ListController, NavigableKeys} from './list-controller.js'; @@ -24,7 +24,7 @@ interface ListItem extends SharedListItem { // tslint:disable-next-line:enforce-comments-on-exported-symbols export class List extends LitElement { static { - setupHostAria(List, {focusable: false}); + polyfillARIAMixin(List); } /** diff --git a/menu/internal/menu.ts b/menu/internal/menu.ts index a50015f4d..0e300519f 100644 --- a/menu/internal/menu.ts +++ b/menu/internal/menu.ts @@ -13,8 +13,8 @@ import {classMap} from 'lit/directives/class-map.js'; import {styleMap} from 'lit/directives/style-map.js'; import { + polyfillARIAMixin, polyfillElementInternalsAria, - setupHostAria, } from '../../internal/aria/aria.js'; import {createAnimationSignal, EASING} from '../../internal/motion/animation.js'; import { @@ -91,8 +91,7 @@ function getFocusedElement( */ export abstract class Menu extends LitElement { static { - // We want to manage tabindex ourselves. - setupHostAria(Menu, {focusable: false}); + polyfillARIAMixin(Menu); } @query('.menu') private readonly surfaceEl!: HTMLElement | null; diff --git a/radio/internal/radio.ts b/radio/internal/radio.ts index 8a7e58161..dd7db1d33 100644 --- a/radio/internal/radio.ts +++ b/radio/internal/radio.ts @@ -12,16 +12,20 @@ import {property} from 'lit/decorators.js'; import {classMap} from 'lit/directives/class-map.js'; import { + polyfillARIAMixin, polyfillElementInternalsAria, - setupHostAria, } from '../../internal/aria/aria.js'; import {isActivationClick} from '../../internal/controller/events.js'; +import {mixinFocusable} from '../../labs/behaviors/focusable.js'; import {SingleSelectionController} from './single-selection-controller.js'; const CHECKED = Symbol('checked'); let maskId = 0; +// Separate variable needed for closure. +const radioBaseClass = mixinFocusable(LitElement); + /** * A radio component. * @@ -30,9 +34,9 @@ let maskId = 0; * @fires change Dispatched when the value changes from user interaction. * --bubbles --composed */ -export class Radio extends LitElement { +export class Radio extends radioBaseClass { static { - setupHostAria(Radio); + polyfillARIAMixin(Radio); } /** @nocollapse */ @@ -116,7 +120,7 @@ export class Radio extends LitElement { } protected override render() { - const classes = {checked: this.checked}; + const classes = {'checked': this.checked}; return html`