Skip to content

Commit bdbb27b

Browse files
feat(suggest): announce status of current item
1 parent 7962bc1 commit bdbb27b

File tree

3 files changed

+96
-9
lines changed

3 files changed

+96
-9
lines changed

projects/angular/components/ui-suggest/src/ui-suggest.component.spec.ts

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,57 @@ const sharedSpecifications = (
11951195
fixture.detectChanges();
11961196
expect(spy).toHaveBeenCalledWith(`${component.items[0].text} item 1 out of ${component.items.length}`);
11971197
});
1198+
1199+
it(`should announce as highlighted and selected for first time`, () => {
1200+
component.items = generateSuggetionItemList('random');
1201+
component.value = [component.items[0]];
1202+
fixture.detectChanges();
1203+
1204+
const spy = spyOn((uiSuggest as any)._liveAnnouncer, 'announce');
1205+
const display = fixture.debugElement.query(By.css('.mat-chip-list'));
1206+
display.nativeElement.dispatchEvent(EventGenerator.click);
1207+
1208+
fixture.detectChanges();
1209+
1210+
expect(spy).toHaveBeenCalledWith(`${component.items[0].text} (selected) item 1 out of ${component.items.length}`);
1211+
});
1212+
1213+
it(`should announce status of item`, () => {
1214+
component.items = generateSuggetionItemList('random');
1215+
fixture.detectChanges();
1216+
1217+
const spy = spyOn((uiSuggest as any)._liveAnnouncer, 'announce');
1218+
const display = fixture.debugElement.query(By.css('.mat-chip-list'));
1219+
display.nativeElement.dispatchEvent(EventGenerator.click);
1220+
1221+
fixture.detectChanges();
1222+
1223+
const itemContainer = fixture.debugElement.query(By.css('.ui-suggest-dropdown-item-list-container'));
1224+
itemContainer.nativeElement.dispatchEvent(
1225+
EventGenerator.keyDown(Key.Enter),
1226+
);
1227+
itemContainer.nativeElement.dispatchEvent(
1228+
EventGenerator.keyDown(Key.ArrowDown),
1229+
);
1230+
itemContainer.nativeElement.dispatchEvent(
1231+
EventGenerator.keyDown(Key.Enter),
1232+
);
1233+
itemContainer.nativeElement.dispatchEvent(
1234+
EventGenerator.keyDown(Key.Enter),
1235+
);
1236+
itemContainer.nativeElement.dispatchEvent(
1237+
EventGenerator.keyDown(Key.ArrowUp),
1238+
);
1239+
1240+
expect(spy.calls.allArgs()).toEqual([
1241+
[`${component.items[0].text} item 1 out of ${component.items.length}`],
1242+
[`${component.items[0].text} item is selected`],
1243+
[`${component.items[1].text} item 2 out of ${component.items.length}`],
1244+
[`${component.items[1].text} item is selected`],
1245+
[`${component.items[1].text} item is removed from selection`],
1246+
[`${component.items[0].text} (selected) item 1 out of ${component.items.length}`],
1247+
]);
1248+
});
11981249
});
11991250

12001251
describe('With custom', () => {
@@ -1252,6 +1303,7 @@ const sharedSpecifications = (
12521303

12531304
expect(fixture.debugElement.query(By.css('.mat-chip.mat-standard-chip span'))).toBeFalsy();
12541305

1306+
flush();
12551307
discardPeriodicTasks();
12561308
}));
12571309

@@ -2295,20 +2347,20 @@ const sharedSpecifications = (
22952347
}));
22962348

22972349
it('should load more data at bottom of the list', waitForAsync(async () => {
2350+
fixture.detectChanges();
22982351
const display = fixture.debugElement.query(By.css('.display'));
22992352
display.nativeElement.dispatchEvent(EventGenerator.click);
2300-
fixture.detectChanges();
23012353

2354+
fixture.detectChanges();
23022355
await fixture.whenStable();
23032356

23042357
expect(uiSuggest.items.length).toBe(NUMBER_OF_ITEMS_PER_VIEW + 1);
23052358

23062359
const itemContainer = fixture.debugElement.query(By.css('.ui-suggest-dropdown-item-list-container'));
2307-
for (let i = 0; i <= uiSuggest.items.length; i++) {
2360+
for (let i = 0; i <= uiSuggest.items.length + 1; i++) {
23082361
itemContainer.nativeElement.dispatchEvent(
23092362
EventGenerator.keyDown(Key.ArrowUp),
23102363
);
2311-
23122364
}
23132365
fixture.detectChanges();
23142366
await fixture.whenStable();
@@ -2321,9 +2373,10 @@ const sharedSpecifications = (
23212373

23222374
const display = fixture.debugElement.query(By.css('.display'));
23232375
display.nativeElement.dispatchEvent(EventGenerator.click);
2324-
fixture.detectChanges();
23252376

2377+
fixture.detectChanges();
23262378
await fixture.whenStable();
2379+
23272380
expect(spy).toHaveBeenCalledTimes(1);
23282381

23292382
const itemContainer = fixture.debugElement.query(By.css('.ui-suggest-dropdown-item-list-container'));
@@ -2335,6 +2388,8 @@ const sharedSpecifications = (
23352388
}
23362389
fixture.detectChanges();
23372390
await fixture.whenStable();
2391+
fixture.detectChanges();
2392+
await fixture.whenStable();
23382393
expect(spy).toHaveBeenCalledTimes(2);
23392394
}));
23402395
});

projects/angular/components/ui-suggest/src/ui-suggest.component.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,6 +1214,8 @@ export class UiSuggestComponent extends UiSuggestMatFormFieldDirective
12141214
this._focusChipInput();
12151215
}
12161216
this._pushEntry(value);
1217+
1218+
this._announceSelectStatus(value.text, true);
12171219
}
12181220

12191221
const alreadySelectedNormalValue = this.multiple &&
@@ -1223,6 +1225,8 @@ export class UiSuggestComponent extends UiSuggestMatFormFieldDirective
12231225

12241226
if (alreadySelectedNormalValue) {
12251227
this._removeEntry(value);
1228+
1229+
this._announceSelectStatus(value.text, false);
12261230
}
12271231

12281232
if (closeAfterSelect) {
@@ -1471,14 +1475,26 @@ export class UiSuggestComponent extends UiSuggestMatFormFieldDirective
14711475
this._liveAnnouncer.announce(this.intl.noResultsLabel);
14721476
return;
14731477
}
1478+
1479+
const item = this.activeIndex < this.headerItems!.length
1480+
? this.headerItems![this.activeIndex]
1481+
: this.items[this.activeIndex - this.headerItems!.length];
1482+
1483+
const isCurrentItemSelected = !this._isOnCustomValueIndex
1484+
? this.isItemSelected(item)
1485+
: undefined;
1486+
14741487
const textToAnnounce = !this._isOnCustomValueIndex
1475-
? this.activeIndex < this.headerItems!.length
1476-
? this.headerItems![this.activeIndex].text
1477-
: this.items[this.activeIndex - this.headerItems!.length].text
1488+
? item.text
14781489
: `${this.intl.customValueLiveLabel} ${this.customValueLabelTranslator(this.inputControl.value)}`;
14791490

14801491
this._liveAnnouncer.announce(
1481-
this.intl.currentItemLabel(textToAnnounce, this.activeIndex + 1, this.headerItems!.length + this._items.length),
1492+
this.intl.currentItemLabel(
1493+
textToAnnounce,
1494+
this.activeIndex + 1,
1495+
this.headerItems!.length + this._items.length,
1496+
isCurrentItemSelected,
1497+
),
14821498
);
14831499
}
14841500

@@ -1748,4 +1764,10 @@ export class UiSuggestComponent extends UiSuggestMatFormFieldDirective
17481764
end: this._items.length - 1,
17491765
});
17501766
}
1767+
1768+
private _announceSelectStatus(text: string, status: boolean) {
1769+
if (text) {
1770+
this._liveAnnouncer.announce(this.intl.currentItemSelectionStatus(text, status));
1771+
}
1772+
}
17511773
}

projects/angular/components/ui-suggest/src/ui-suggest.intl.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ export class UiSuggestIntl implements OnDestroy {
5454
* @param itemNo The current item index.
5555
* @param itemCount The total item count.
5656
*/
57-
currentItemLabel = (text: string, itemNo: number, itemCount: number) => `${text} item ${itemNo} out of ${itemCount}`;
57+
currentItemLabel = (text: string, itemNo: number, itemCount: number, selectedStatus?: boolean) => `${text}${this._selectedStatusText(selectedStatus)} item ${itemNo} out of ${itemCount}`;
58+
59+
currentItemSelectionStatus = (text: string, isItemSelected: boolean) => `${text} item is ${isItemSelected ? 'selected' : 'removed from selection'}`;
5860

5961
/**
6062
* Custom value label generator function.
@@ -86,4 +88,12 @@ export class UiSuggestIntl implements OnDestroy {
8688
this._destroyed$.complete();
8789
this.changes.complete();
8890
}
91+
92+
private _selectedStatusText(selectedStatus?: boolean) {
93+
if (selectedStatus) {
94+
return ' (selected)';
95+
}
96+
97+
return '';
98+
}
8999
}

0 commit comments

Comments
 (0)