Skip to content

Commit f94de5d

Browse files
asyncLizcopybara-github
authored andcommitted
chore(aria): add separate setup function for polyfill and focusability
PiperOrigin-RevId: 576973090
1 parent e7bc633 commit f94de5d

File tree

2 files changed

+41
-67
lines changed

2 files changed

+41
-67
lines changed

internal/aria/aria.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,27 @@ export type ARIARole =
294294
| 'doc-tip'
295295
| 'doc-toc';
296296

297+
/**
298+
* This function will polyfill `ARIAMixin` properties for Firefox.
299+
*
300+
* @param ctor The `ReactiveElement` constructor to set up.
301+
*/
302+
export function polyfillARIAMixin(ctor: typeof ReactiveElement) {
303+
if (isServer || 'role' in Element.prototype) {
304+
return;
305+
}
306+
307+
// Polyfill reflective aria properties for Firefox
308+
for (const ariaProperty of ARIA_PROPERTIES) {
309+
ctor.createProperty(ariaProperty, {
310+
attribute: ariaPropertyToAttribute(ariaProperty),
311+
reflect: true,
312+
});
313+
}
314+
315+
ctor.createProperty('role', {reflect: true});
316+
}
317+
297318
/**
298319
* Enables a host custom element to be the target for aria roles and attributes.
299320
* Components should set the `elementInternals.role` property.
@@ -307,6 +328,8 @@ export type ARIARole =
307328
*
308329
* @param ctor The `ReactiveElement` constructor to set up.
309330
* @param options Options to configure the element's host aria.
331+
* @deprecated use `mixinFocusable()` and `polyfillARIAMixin()`
332+
* TODO(b/307785469): remove after updating components to use mixinFocusable
310333
*/
311334
export function setupHostAria(
312335
ctor: typeof ReactiveElement,
@@ -326,23 +349,13 @@ export function setupHostAria(
326349
});
327350
}
328351

329-
if (isServer || 'role' in Element.prototype) {
330-
return;
331-
}
332-
333-
// Polyfill reflective aria properties for Firefox
334-
for (const ariaProperty of ARIA_PROPERTIES) {
335-
ctor.createProperty(ariaProperty, {
336-
attribute: ariaPropertyToAttribute(ariaProperty),
337-
reflect: true,
338-
});
339-
}
340-
341-
ctor.createProperty('role', {reflect: true});
352+
polyfillARIAMixin(ctor);
342353
}
343354

344355
/**
345356
* Options for setting up a host element as an aria target.
357+
* @deprecated use `mixinFocusable()` and `polyfillARIAMixin()`
358+
* TODO(b/307785469): remove after updating components to use mixinFocusable
346359
*/
347360
export interface SetupHostAriaOptions {
348361
/**

internal/aria/aria_test.ts

Lines changed: 15 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import {
1313
ARIAProperty,
1414
ariaPropertyToAttribute,
1515
isAriaAttribute,
16+
polyfillARIAMixin,
1617
polyfillElementInternalsAria,
17-
setupHostAria,
1818
} from './aria.js';
1919

2020
describe('aria', () => {
@@ -52,79 +52,40 @@ describe('aria', () => {
5252
});
5353
});
5454

55-
describe('setupHostAria()', () => {
55+
describe('polyfillARIAMixin()', () => {
5656
@customElement('test-setup-aria-host')
5757
class TestElement extends LitElement {
5858
static {
59-
setupHostAria(TestElement);
59+
polyfillARIAMixin(TestElement);
6060
}
6161

6262
override render() {
6363
return html`<slot></slot>`;
6464
}
6565
}
6666

67-
it('should not hydrate tabindex attribute on creation', () => {
67+
it('should reflect ARIAMixin properties to attributes', async () => {
6868
const element = new TestElement();
69-
expect(element.hasAttribute('tabindex'))
70-
.withContext('has tabindex attribute')
71-
.toBeFalse();
72-
});
73-
74-
it('should set tabindex="0" on element once connected', () => {
75-
const element = new TestElement();
76-
document.body.appendChild(element);
77-
expect(element.getAttribute('tabindex'))
78-
.withContext('tabindex attribute value')
79-
.toEqual('0');
80-
81-
element.remove();
82-
});
83-
84-
it('should not set tabindex on connected if one already exists', () => {
85-
const element = new TestElement();
86-
element.tabIndex = -1;
8769
document.body.appendChild(element);
88-
expect(element.getAttribute('tabindex'))
89-
.withContext('tabindex attribute value')
90-
.toEqual('-1');
91-
70+
element.role = 'button';
71+
element.ariaLabel = 'Foo';
72+
await element.updateComplete;
73+
expect(element.getAttribute('role'))
74+
.withContext('role attribute value')
75+
.toEqual('button');
76+
77+
expect(element.getAttribute('aria-label'))
78+
.withContext('aria-label attribute value')
79+
.toEqual('Foo');
9280
element.remove();
9381
});
94-
95-
it('should not change tabindex if disconnected and reconnected', () => {
96-
const element = new TestElement();
97-
document.body.appendChild(element);
98-
element.tabIndex = -1;
99-
element.remove();
100-
document.body.appendChild(element);
101-
expect(element.getAttribute('tabindex'))
102-
.withContext('tabindex attribute value')
103-
.toEqual('-1');
104-
});
105-
106-
if (!('role' in Element.prototype)) {
107-
describe('polyfill', () => {
108-
it('should hydrate aria attributes when ARIAMixin is not supported', async () => {
109-
const element = new TestElement();
110-
document.body.appendChild(element);
111-
element.role = 'button';
112-
await element.updateComplete;
113-
expect(element.getAttribute('role'))
114-
.withContext('role attribute value')
115-
.toEqual('button');
116-
117-
element.remove();
118-
});
119-
});
120-
}
12182
});
12283

12384
describe('polyfillElementInternalsAria()', () => {
12485
@customElement('test-polyfill-element-internals-aria')
12586
class TestElement extends LitElement {
12687
static {
127-
setupHostAria(TestElement);
88+
polyfillARIAMixin(TestElement);
12889
}
12990

13091
internals = polyfillElementInternalsAria(this, this.attachInternals());

0 commit comments

Comments
 (0)