mirror of
https://github.com/material-components/material-web.git
synced 2026-01-14 17:02:14 +08:00
chore(aria): add separate setup function for polyfill and focusability
PiperOrigin-RevId: 576973090
This commit is contained in:
parent
e7bc633e18
commit
f94de5d302
@ -294,6 +294,27 @@ export type ARIARole =
|
||||
| 'doc-tip'
|
||||
| 'doc-toc';
|
||||
|
||||
/**
|
||||
* This function will polyfill `ARIAMixin` properties for Firefox.
|
||||
*
|
||||
* @param ctor The `ReactiveElement` constructor to set up.
|
||||
*/
|
||||
export function polyfillARIAMixin(ctor: typeof ReactiveElement) {
|
||||
if (isServer || 'role' in Element.prototype) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Polyfill reflective aria properties for Firefox
|
||||
for (const ariaProperty of ARIA_PROPERTIES) {
|
||||
ctor.createProperty(ariaProperty, {
|
||||
attribute: ariaPropertyToAttribute(ariaProperty),
|
||||
reflect: true,
|
||||
});
|
||||
}
|
||||
|
||||
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.
|
||||
@ -307,6 +328,8 @@ export type ARIARole =
|
||||
*
|
||||
* @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,
|
||||
@ -326,23 +349,13 @@ export function setupHostAria(
|
||||
});
|
||||
}
|
||||
|
||||
if (isServer || 'role' in Element.prototype) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Polyfill reflective aria properties for Firefox
|
||||
for (const ariaProperty of ARIA_PROPERTIES) {
|
||||
ctor.createProperty(ariaProperty, {
|
||||
attribute: ariaPropertyToAttribute(ariaProperty),
|
||||
reflect: true,
|
||||
});
|
||||
}
|
||||
|
||||
ctor.createProperty('role', {reflect: true});
|
||||
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 {
|
||||
/**
|
||||
|
||||
@ -13,8 +13,8 @@ import {
|
||||
ARIAProperty,
|
||||
ariaPropertyToAttribute,
|
||||
isAriaAttribute,
|
||||
polyfillARIAMixin,
|
||||
polyfillElementInternalsAria,
|
||||
setupHostAria,
|
||||
} from './aria.js';
|
||||
|
||||
describe('aria', () => {
|
||||
@ -52,11 +52,11 @@ describe('aria', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('setupHostAria()', () => {
|
||||
describe('polyfillARIAMixin()', () => {
|
||||
@customElement('test-setup-aria-host')
|
||||
class TestElement extends LitElement {
|
||||
static {
|
||||
setupHostAria(TestElement);
|
||||
polyfillARIAMixin(TestElement);
|
||||
}
|
||||
|
||||
override render() {
|
||||
@ -64,67 +64,28 @@ describe('aria', () => {
|
||||
}
|
||||
}
|
||||
|
||||
it('should not hydrate tabindex attribute on creation', () => {
|
||||
const element = new TestElement();
|
||||
expect(element.hasAttribute('tabindex'))
|
||||
.withContext('has tabindex attribute')
|
||||
.toBeFalse();
|
||||
});
|
||||
|
||||
it('should set tabindex="0" on element once connected', () => {
|
||||
it('should reflect ARIAMixin properties to attributes', async () => {
|
||||
const element = new TestElement();
|
||||
document.body.appendChild(element);
|
||||
expect(element.getAttribute('tabindex'))
|
||||
.withContext('tabindex attribute value')
|
||||
.toEqual('0');
|
||||
element.role = 'button';
|
||||
element.ariaLabel = 'Foo';
|
||||
await element.updateComplete;
|
||||
expect(element.getAttribute('role'))
|
||||
.withContext('role attribute value')
|
||||
.toEqual('button');
|
||||
|
||||
expect(element.getAttribute('aria-label'))
|
||||
.withContext('aria-label attribute value')
|
||||
.toEqual('Foo');
|
||||
element.remove();
|
||||
});
|
||||
|
||||
it('should not set tabindex on connected if one already exists', () => {
|
||||
const element = new TestElement();
|
||||
element.tabIndex = -1;
|
||||
document.body.appendChild(element);
|
||||
expect(element.getAttribute('tabindex'))
|
||||
.withContext('tabindex attribute value')
|
||||
.toEqual('-1');
|
||||
|
||||
element.remove();
|
||||
});
|
||||
|
||||
it('should not change tabindex if disconnected and reconnected', () => {
|
||||
const element = new TestElement();
|
||||
document.body.appendChild(element);
|
||||
element.tabIndex = -1;
|
||||
element.remove();
|
||||
document.body.appendChild(element);
|
||||
expect(element.getAttribute('tabindex'))
|
||||
.withContext('tabindex attribute value')
|
||||
.toEqual('-1');
|
||||
});
|
||||
|
||||
if (!('role' in Element.prototype)) {
|
||||
describe('polyfill', () => {
|
||||
it('should hydrate aria attributes when ARIAMixin is not supported', async () => {
|
||||
const element = new TestElement();
|
||||
document.body.appendChild(element);
|
||||
element.role = 'button';
|
||||
await element.updateComplete;
|
||||
expect(element.getAttribute('role'))
|
||||
.withContext('role attribute value')
|
||||
.toEqual('button');
|
||||
|
||||
element.remove();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('polyfillElementInternalsAria()', () => {
|
||||
@customElement('test-polyfill-element-internals-aria')
|
||||
class TestElement extends LitElement {
|
||||
static {
|
||||
setupHostAria(TestElement);
|
||||
polyfillARIAMixin(TestElement);
|
||||
}
|
||||
|
||||
internals = polyfillElementInternalsAria(this, this.attachInternals());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user