Skip to content

Commit 127b0d2

Browse files
feat(suggest): announce status of current item
1 parent bf46c3a commit 127b0d2

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
@@ -1152,6 +1152,57 @@ const sharedSpecifications = (
11521152
fixture.detectChanges();
11531153
expect(spy).toHaveBeenCalledWith(`${component.items[0].text} item 1 out of ${component.items.length}`);
11541154
});
1155+
1156+
it(`should announce as highlighted and selected for first time`, () => {
1157+
component.items = generateSuggetionItemList('random');
1158+
component.value = [component.items[0]];
1159+
fixture.detectChanges();
1160+
1161+
const spy = spyOn((uiSuggest as any)._liveAnnouncer, 'announce');
1162+
const display = fixture.debugElement.query(By.css('.mat-chip-list'));
1163+
display.nativeElement.dispatchEvent(EventGenerator.click);
1164+
1165+
fixture.detectChanges();
1166+
1167+
expect(spy).toHaveBeenCalledWith(`${component.items[0].text} (selected) item 1 out of ${component.items.length}`);
1168+
});
1169+
1170+
it(`should announce status of item`, () => {
1171+
component.items = generateSuggetionItemList('random');
1172+
fixture.detectChanges();
1173+
1174+
const spy = spyOn((uiSuggest as any)._liveAnnouncer, 'announce');
1175+
const display = fixture.debugElement.query(By.css('.mat-chip-list'));
1176+
display.nativeElement.dispatchEvent(EventGenerator.click);
1177+
1178+
fixture.detectChanges();
1179+
1180+
const itemContainer = fixture.debugElement.query(By.css('.item-list-container'));
1181+
itemContainer.nativeElement.dispatchEvent(
1182+
EventGenerator.keyDown(Key.Enter),
1183+
);
1184+
itemContainer.nativeElement.dispatchEvent(
1185+
EventGenerator.keyDown(Key.ArrowDown),
1186+
);
1187+
itemContainer.nativeElement.dispatchEvent(
1188+
EventGenerator.keyDown(Key.Enter),
1189+
);
1190+
itemContainer.nativeElement.dispatchEvent(
1191+
EventGenerator.keyDown(Key.Enter),
1192+
);
1193+
itemContainer.nativeElement.dispatchEvent(
1194+
EventGenerator.keyDown(Key.ArrowUp),
1195+
);
1196+
1197+
expect(spy.calls.allArgs()).toEqual([
1198+
[`${component.items[0].text} item 1 out of ${component.items.length}`],
1199+
[`${component.items[0].text} item is selected`],
1200+
[`${component.items[1].text} item 2 out of ${component.items.length}`],
1201+
[`${component.items[1].text} item is selected`],
1202+
[`${component.items[1].text} item is removed from selection`],
1203+
[`${component.items[0].text} (selected) item 1 out of ${component.items.length}`],
1204+
]);
1205+
});
11551206
});
11561207

11571208
describe('With custom', () => {
@@ -1209,6 +1260,7 @@ const sharedSpecifications = (
12091260

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

1263+
flush();
12121264
discardPeriodicTasks();
12131265
}));
12141266

@@ -2251,20 +2303,20 @@ const sharedSpecifications = (
22512303
}));
22522304

22532305
it('should load more data at bottom of the list', waitForAsync(async () => {
2306+
fixture.detectChanges();
22542307
const display = fixture.debugElement.query(By.css('.display'));
22552308
display.nativeElement.dispatchEvent(EventGenerator.click);
2256-
fixture.detectChanges();
22572309

2310+
fixture.detectChanges();
22582311
await fixture.whenStable();
22592312

22602313
expect(uiSuggest.items.length).toBe(NUMBER_OF_ITEMS_PER_VIEW + 1);
22612314

22622315
const itemContainer = fixture.debugElement.query(By.css('.item-list-container'));
2263-
for (let i = 0; i <= uiSuggest.items.length; i++) {
2316+
for (let i = 0; i <= uiSuggest.items.length + 1; i++) {
22642317
itemContainer.nativeElement.dispatchEvent(
22652318
EventGenerator.keyDown(Key.ArrowUp),
22662319
);
2267-
22682320
}
22692321
fixture.detectChanges();
22702322
await fixture.whenStable();
@@ -2277,9 +2329,10 @@ const sharedSpecifications = (
22772329

22782330
const display = fixture.debugElement.query(By.css('.display'));
22792331
display.nativeElement.dispatchEvent(EventGenerator.click);
2280-
fixture.detectChanges();
22812332

2333+
fixture.detectChanges();
22822334
await fixture.whenStable();
2335+
22832336
expect(spy).toHaveBeenCalledTimes(1);
22842337

22852338
const itemContainer = fixture.debugElement.query(By.css('.item-list-container'));
@@ -2291,6 +2344,8 @@ const sharedSpecifications = (
22912344
}
22922345
fixture.detectChanges();
22932346
await fixture.whenStable();
2347+
fixture.detectChanges();
2348+
await fixture.whenStable();
22942349
expect(spy).toHaveBeenCalledTimes(2);
22952350
}));
22962351
});

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

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,8 @@ export class UiSuggestComponent extends UiSuggestMatFormFieldDirective
11521152
this._focusChipInput();
11531153
}
11541154
this._pushEntry(value);
1155+
1156+
this._announceSelectStatus(value.text, true);
11551157
}
11561158

11571159
const alreadySelectedNormalValue = this.multiple &&
@@ -1161,6 +1163,8 @@ export class UiSuggestComponent extends UiSuggestMatFormFieldDirective
11611163

11621164
if (alreadySelectedNormalValue) {
11631165
this._removeEntry(value);
1166+
1167+
this._announceSelectStatus(value.text, false);
11641168
}
11651169

11661170
if (closeAfterSelect) {
@@ -1353,14 +1357,26 @@ export class UiSuggestComponent extends UiSuggestMatFormFieldDirective
13531357
this._liveAnnouncer.announce(this.intl.noResultsLabel);
13541358
return;
13551359
}
1360+
1361+
const item = this.activeIndex < this.headerItems!.length
1362+
? this.headerItems![this.activeIndex]
1363+
: this.items[this.activeIndex - this.headerItems!.length];
1364+
1365+
const isCurrentItemSelected = !this._isOnCustomValueIndex
1366+
? this.isItemSelected(item)
1367+
: undefined;
1368+
13561369
const textToAnnounce = !this._isOnCustomValueIndex
1357-
? this.activeIndex < this.headerItems!.length
1358-
? this.headerItems![this.activeIndex].text
1359-
: this.items[this.activeIndex - this.headerItems!.length].text
1370+
? item.text
13601371
: `${this.intl.customValueLiveLabel} ${this.customValueLabelTranslator(this.inputControl.value)}`;
13611372

13621373
this._liveAnnouncer.announce(
1363-
this.intl.currentItemLabel(textToAnnounce, this.activeIndex + 1, this.headerItems!.length + this._items.length),
1374+
this.intl.currentItemLabel(
1375+
textToAnnounce,
1376+
this.activeIndex + 1,
1377+
this.headerItems!.length + this._items.length,
1378+
isCurrentItemSelected,
1379+
),
13641380
);
13651381
}
13661382

@@ -1630,4 +1646,10 @@ export class UiSuggestComponent extends UiSuggestMatFormFieldDirective
16301646
end: this._items.length - 1,
16311647
});
16321648
}
1649+
1650+
private _announceSelectStatus(text: string, status: boolean) {
1651+
if (text) {
1652+
this._liveAnnouncer.announce(this.intl.currentItemSelectionStatus(text, status));
1653+
}
1654+
}
16331655
}

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)