Skip to content

Commit 2b708cf

Browse files
committed
feat(a11y): add input to control the duration of the aria live directive
Adds an input that allows the consumer to control how long it takes before the messages that are announced by `CdkAriaLive` to be cleared from the DOM.
1 parent 5d3f515 commit 2b708cf

File tree

3 files changed

+24
-7
lines changed

3 files changed

+24
-7
lines changed

src/cdk/a11y/live-announcer/live-announcer.spec.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {MutationObserverFactory} from '@angular/cdk/observers';
2-
import {Component, Input} from '@angular/core';
2+
import {Component} from '@angular/core';
33
import {ComponentFixture, fakeAsync, flush, inject, TestBed, tick} from '@angular/core/testing';
44
import {By} from '@angular/platform-browser';
55
import {A11yModule} from '../index';
@@ -284,7 +284,7 @@ describe('CdkAriaLive', () => {
284284
invokeMutationCallbacks();
285285
flush();
286286

287-
expect(announcer.announce).toHaveBeenCalledWith('New content', 'polite');
287+
expect(announcer.announce).toHaveBeenCalledWith('New content', 'polite', undefined);
288288

289289
announcerSpy.calls.reset();
290290
fixture.componentInstance.politeness = 'off';
@@ -302,7 +302,7 @@ describe('CdkAriaLive', () => {
302302
invokeMutationCallbacks();
303303
flush();
304304

305-
expect(announcer.announce).toHaveBeenCalledWith('Newest content', 'assertive');
305+
expect(announcer.announce).toHaveBeenCalledWith('Newest content', 'assertive', undefined);
306306
}));
307307

308308
it('should not announce the same text multiple times', fakeAsync(() => {
@@ -320,6 +320,16 @@ describe('CdkAriaLive', () => {
320320
expect(announcer.announce).toHaveBeenCalledTimes(1);
321321
}));
322322

323+
it('should be able to pass in a duration', fakeAsync(() => {
324+
fixture.componentInstance.content = 'New content';
325+
fixture.componentInstance.duration = 1337;
326+
fixture.detectChanges();
327+
invokeMutationCallbacks();
328+
flush();
329+
330+
expect(announcer.announce).toHaveBeenCalledWith('New content', 'polite', 1337);
331+
}));
332+
323333
});
324334

325335

@@ -336,8 +346,11 @@ class TestApp {
336346
}
337347
}
338348

339-
@Component({template: `<div [cdkAriaLive]="politeness">{{content}}</div>`})
349+
@Component({
350+
template: `<div [cdkAriaLive]="politeness" [cdkAriaLiveDuration]="duration">{{content}}</div>`
351+
})
340352
class DivWithCdkAriaLive {
341-
@Input() politeness = 'polite';
342-
@Input() content = 'Initial content';
353+
politeness = 'polite';
354+
content = 'Initial content';
355+
duration: number;
343356
}

src/cdk/a11y/live-announcer/live-announcer.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export class CdkAriaLive implements OnDestroy {
205205
// The `MutationObserver` fires also for attribute
206206
// changes which we don't want to announce.
207207
if (elementText !== this._previousAnnouncedText) {
208-
this._liveAnnouncer.announce(elementText, this._politeness);
208+
this._liveAnnouncer.announce(elementText, this._politeness, this.duration);
209209
this._previousAnnouncedText = elementText;
210210
}
211211
});
@@ -214,6 +214,9 @@ export class CdkAriaLive implements OnDestroy {
214214
}
215215
private _politeness: AriaLivePoliteness = 'off';
216216

217+
/** Time in milliseconds after which to clear out the announcer element. */
218+
@Input('cdkAriaLiveDuration') duration: number;
219+
217220
private _previousAnnouncedText?: string;
218221
private _subscription: Subscription | null;
219222

tools/public_api_guard/cdk/a11y.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export declare const CDK_DESCRIBEDBY_HOST_ATTRIBUTE = "cdk-describedby-host";
2828
export declare const CDK_DESCRIBEDBY_ID_PREFIX = "cdk-describedby-message";
2929

3030
export declare class CdkAriaLive implements OnDestroy {
31+
duration: number;
3132
politeness: AriaLivePoliteness;
3233
constructor(_elementRef: ElementRef, _liveAnnouncer: LiveAnnouncer, _contentObserver: ContentObserver, _ngZone: NgZone);
3334
ngOnDestroy(): void;

0 commit comments

Comments
 (0)