fix: add aria-hidden="true" to ripple, focus ring, and elevation

PiperOrigin-RevId: 562075778
This commit is contained in:
Elizabeth Mitchell 2023-09-01 16:32:52 -07:00 committed by Copybara-Service
parent cdd2ea6c1d
commit 2295f12e71
7 changed files with 32 additions and 11 deletions

View File

@ -56,15 +56,12 @@ export abstract class Chip extends LitElement {
} }
protected renderContainerContent() { protected renderContainerContent() {
// Note: add aria-hidden="true" to focus ring and ripple. For some reason
// they cause VoiceOver to get stuck inside filter chip sets without it.
// TODO(b/297428579): investigate and file VoiceOver bug
return html` return html`
${this.renderOutline()} ${this.renderOutline()}
<md-focus-ring part="focus-ring" for=${this.primaryId} <md-focus-ring part="focus-ring"
aria-hidden="true"></md-focus-ring> for=${this.primaryId}></md-focus-ring>
<md-ripple for=${this.primaryId} ?disabled=${this.rippleDisabled} <md-ripple for=${this.primaryId}
aria-hidden="true"></md-ripple> ?disabled=${this.rippleDisabled}></md-ripple>
${this.renderPrimaryAction(this.renderPrimaryContent())} ${this.renderPrimaryAction(this.renderPrimaryContent())}
`; `;
} }

View File

@ -8,7 +8,7 @@
<div> <div>
<div class="fab-wrapper"> <div class="fab-wrapper">
<md-fab label="navigate" variant="primary"> <md-fab label="navigate" variant="primary">
<md-icon slot="icon" aria-hidden="true">navigation</md-icon> <md-icon slot="icon">navigation</md-icon>
</md-fab> </md-fab>
</div> </div>
<span>1</span> <span>1</span>
@ -22,4 +22,4 @@
</div> </div>
</div> </div>
</figure> </figure>
</div> </div>

View File

@ -10,6 +10,13 @@ import {html, LitElement} from 'lit';
* A component for elevation. * A component for elevation.
*/ */
export class Elevation extends LitElement { export class Elevation extends LitElement {
override connectedCallback() {
super.connectedCallback();
// Needed for VoiceOver, which will create a "group" if the element is a
// sibling to other content.
this.setAttribute('aria-hidden', 'true');
}
protected override render() { protected override render() {
return html`<span class="shadow"></span>`; return html`<span class="shadow"></span>`;
} }

View File

@ -56,6 +56,13 @@ export class FocusRing extends LitElement implements Attachable {
this.attachableController.detach(); this.attachableController.detach();
} }
override connectedCallback() {
super.connectedCallback();
// Needed for VoiceOver, which will create a "group" if the element is a
// sibling to other content.
this.setAttribute('aria-hidden', 'true');
}
/** @private */ /** @private */
handleEvent(event: FocusRingEvent) { handleEvent(event: FocusRingEvent) {
if (event[HANDLED_BY_FOCUS_RING]) { if (event[HANDLED_BY_FOCUS_RING]) {

View File

@ -18,10 +18,14 @@ export class Icon extends LitElement {
super.connectedCallback(); super.connectedCallback();
const ariaHidden = this.getAttribute('aria-hidden'); const ariaHidden = this.getAttribute('aria-hidden');
if (ariaHidden === 'false') { if (ariaHidden === 'false') {
// Allow the user to set `aria-hidden="false"` to create an icon that is
// announced by screenreaders.
this.removeAttribute('aria-hidden'); this.removeAttribute('aria-hidden');
return; return;
} }
// Needed for VoiceOver, which will create a "group" if the element is a
// sibling to other content.
this.setAttribute('aria-hidden', 'true'); this.setAttribute('aria-hidden', 'true');
} }
} }

View File

@ -126,6 +126,13 @@ export class Ripple extends LitElement implements Attachable {
this.attachableController.detach(); this.attachableController.detach();
} }
override connectedCallback() {
super.connectedCallback();
// Needed for VoiceOver, which will create a "group" if the element is a
// sibling to other content.
this.setAttribute('aria-hidden', 'true');
}
protected override render() { protected override render() {
const classes = { const classes = {
'hovered': this.hovered, 'hovered': this.hovered,

View File

@ -367,8 +367,7 @@ function getTabContentGenerator(knobs: StoryKnobs) {
const useIcon = contentKnob !== 'label'; const useIcon = contentKnob !== 'label';
const useLabel = contentKnob !== 'icon'; const useLabel = contentKnob !== 'icon';
return (icon: string, label: string) => { return (icon: string, label: string) => {
const iconTemplate = const iconTemplate = html`<md-icon slot="icon">${icon}</md-icon>`;
html`<md-icon aria-hidden="true" slot="icon">${icon}</md-icon>`;
return html` return html`
${useIcon ? iconTemplate : nothing} ${useIcon ? iconTemplate : nothing}
${useLabel ? html`${label}` : nothing} ${useLabel ? html`${label}` : nothing}