diff --git a/projects/storefrontlib/shared/components/ng-select-a11y/ng-select-a11y.directive.spec.ts b/projects/storefrontlib/shared/components/ng-select-a11y/ng-select-a11y.directive.spec.ts
index 1701cee113e..7326e85acdb 100644
--- a/projects/storefrontlib/shared/components/ng-select-a11y/ng-select-a11y.directive.spec.ts
+++ b/projects/storefrontlib/shared/components/ng-select-a11y/ng-select-a11y.directive.spec.ts
@@ -6,22 +6,23 @@ import { FeatureConfigService, TranslationService } from '@spartacus/core';
import { of } from 'rxjs';
import { NgSelectA11yDirective } from './ng-select-a11y.directive';
import { NgSelectA11yModule } from './ng-select-a11y.module';
+import { BreakpointService } from '@spartacus/storefront';
@Component({
template: `
- {{
- val
- }}
`,
})
class MockComponent {
isSearchable: boolean = false;
+ selected = 1;
}
class MockFeatureConfigService {
@@ -39,6 +40,7 @@ class MockTranslationService {
describe('NgSelectA11yDirective', () => {
let component: MockComponent;
let fixture: ComponentFixture;
+ let breakpointService: BreakpointService;
beforeEach(() => {
TestBed.configureTestingModule({
@@ -51,8 +53,8 @@ describe('NgSelectA11yDirective', () => {
}).compileComponents();
fixture = TestBed.createComponent(MockComponent);
-
component = fixture.componentInstance;
+ breakpointService = TestBed.inject(BreakpointService);
});
function getNgSelect(): DebugElement {
@@ -89,4 +91,28 @@ describe('NgSelectA11yDirective', () => {
done();
});
});
+
+ it('should append value to aria-label and hide the value element from screen reader on mobile', (done) => {
+ const isDownSpy = spyOn(breakpointService, 'isDown').and.returnValue(
+ of(true)
+ );
+ fixture.detectChanges();
+ const ngSelectInstance = getNgSelect().componentInstance;
+ ngSelectInstance.writeValue(component.selected);
+ ngSelectInstance.detectChanges();
+
+ // Wait for the mutation observer to update the aria-label
+ setTimeout(() => {
+ const select = getNgSelect().nativeElement;
+ const valueElement = select.querySelector('.ng-value');
+ const divCombobox = select.querySelector("[role='combobox']");
+
+ expect(valueElement.getAttribute('aria-hidden')).toEqual('true');
+ expect(divCombobox.getAttribute('aria-label')).toContain(
+ `, ${component.selected}`
+ );
+ isDownSpy.and.callThrough();
+ done();
+ });
+ });
});
diff --git a/projects/storefrontlib/shared/components/ng-select-a11y/ng-select-a11y.directive.ts b/projects/storefrontlib/shared/components/ng-select-a11y/ng-select-a11y.directive.ts
index 570d0d4ceee..4c25b9a7a13 100644
--- a/projects/storefrontlib/shared/components/ng-select-a11y/ng-select-a11y.directive.ts
+++ b/projects/storefrontlib/shared/components/ng-select-a11y/ng-select-a11y.directive.ts
@@ -119,6 +119,10 @@ export class NgSelectA11yDirective implements AfterViewInit {
observerInstance.disconnect();
}
+ /**
+ * Hides the input value from the screen reader and provides it as part of the aria-label instead.
+ * This improves the screen reader output on mobile devices.
+ */
appendValueToAriaLabel(
_changes: any,
observer: MutationObserver,