Skip to content

Commit 1d8d796

Browse files
committed
feat(cdk/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 71b7b15 commit 1d8d796

File tree

3 files changed

+30
-10
lines changed

3 files changed

+30
-10
lines changed

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
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';
5-
import {A11yModule, AriaLivePoliteness} from '../index';
5+
import {A11yModule} from '../index';
66
import {LiveAnnouncer} from './live-announcer';
77
import {
88
LIVE_ANNOUNCER_ELEMENT_TOKEN,
@@ -288,7 +288,7 @@ describe('CdkAriaLive', () => {
288288
invokeMutationCallbacks();
289289
flush();
290290

291-
expect(announcer.announce).toHaveBeenCalledWith('New content', 'polite');
291+
expect(announcer.announce).toHaveBeenCalledWith('New content', 'polite', undefined);
292292
}));
293293

294294
it('should dynamically update the politeness', fakeAsync(() => {
@@ -297,7 +297,7 @@ describe('CdkAriaLive', () => {
297297
invokeMutationCallbacks();
298298
flush();
299299

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

302302
announcerSpy.calls.reset();
303303
fixture.componentInstance.politeness = 'off';
@@ -315,7 +315,7 @@ describe('CdkAriaLive', () => {
315315
invokeMutationCallbacks();
316316
flush();
317317

318-
expect(announcer.announce).toHaveBeenCalledWith('Newest content', 'assertive');
318+
expect(announcer.announce).toHaveBeenCalledWith('Newest content', 'assertive', undefined);
319319
}));
320320

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

336+
it('should be able to pass in a duration', fakeAsync(() => {
337+
fixture.componentInstance.content = 'New content';
338+
fixture.componentInstance.duration = 1337;
339+
fixture.detectChanges();
340+
invokeMutationCallbacks();
341+
flush();
342+
343+
expect(announcer.announce).toHaveBeenCalledWith('New content', 'polite', 1337);
344+
}));
345+
336346
});
337347

338348

@@ -349,8 +359,14 @@ class TestApp {
349359
}
350360
}
351361

352-
@Component({template: `<div [cdkAriaLive]="politeness ? politeness : null">{{content}}</div>`})
362+
@Component({
363+
template: `
364+
<div
365+
[cdkAriaLive]="politeness ? politeness : null"
366+
[cdkAriaLiveDuration]="duration">{{content}}</div>`
367+
})
353368
class DivWithCdkAriaLive {
354-
@Input() politeness: AriaLivePoliteness;
355-
@Input() content = 'Initial content';
369+
politeness = 'polite';
370+
content = 'Initial content';
371+
duration: number;
356372
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ export class CdkAriaLive implements OnDestroy {
203203
// The `MutationObserver` fires also for attribute
204204
// changes which we don't want to announce.
205205
if (elementText !== this._previousAnnouncedText) {
206-
this._liveAnnouncer.announce(elementText, this._politeness);
206+
this._liveAnnouncer.announce(elementText, this._politeness, this.duration);
207207
this._previousAnnouncedText = elementText;
208208
}
209209
});
@@ -212,6 +212,9 @@ export class CdkAriaLive implements OnDestroy {
212212
}
213213
private _politeness: AriaLivePoliteness = 'polite';
214214

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

tools/public_api_guard/cdk/a11y.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ export declare const CDK_DESCRIBEDBY_HOST_ATTRIBUTE = "cdk-describedby-host";
2727
export declare const CDK_DESCRIBEDBY_ID_PREFIX = "cdk-describedby-message";
2828

2929
export declare class CdkAriaLive implements OnDestroy {
30+
duration: number;
3031
get politeness(): AriaLivePoliteness;
3132
set politeness(value: AriaLivePoliteness);
3233
constructor(_elementRef: ElementRef, _liveAnnouncer: LiveAnnouncer, _contentObserver: ContentObserver, _ngZone: NgZone);
3334
ngOnDestroy(): void;
34-
static ɵdir: i0.ɵɵDirectiveDefWithMeta<CdkAriaLive, "[cdkAriaLive]", ["cdkAriaLive"], { "politeness": "cdkAriaLive"; }, {}, never>;
35+
static ɵdir: i0.ɵɵDirectiveDefWithMeta<CdkAriaLive, "[cdkAriaLive]", ["cdkAriaLive"], { "politeness": "cdkAriaLive"; "duration": "cdkAriaLiveDuration"; }, {}, never>;
3536
static ɵfac: i0.ɵɵFactoryDef<CdkAriaLive, never>;
3637
}
3738

0 commit comments

Comments
 (0)