From d5197be9fad56cd22572b52e65cd824c06e367fa Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Tue, 4 Nov 2025 12:07:36 -0800 Subject: [PATCH 1/4] fix(select): add aria-selected to button option --- core/src/components/select/select.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index ac2fbb6d89f..10d6836c262 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -548,6 +548,7 @@ export class Select implements ComponentInterface { } private createActionSheetButtons(data: HTMLIonSelectOptionElement[], selectValue: any): ActionSheetButton[] { + console.log('createActionSheetButtons', data, selectValue); const actionSheetButtons = data.map((option) => { const value = getOptionValue(option); @@ -556,14 +557,18 @@ export class Select implements ComponentInterface { .filter((cls) => cls !== 'hydrated') .join(' '); const optClass = `${OPTION_CLASS} ${copyClasses}`; + const isSelected = isOptionSelected(selectValue, value, this.compareWith); return { - role: isOptionSelected(selectValue, value, this.compareWith) ? 'selected' : '', + role: isSelected ? 'selected' : '', text: option.textContent, cssClass: optClass, handler: () => { this.setValue(value); }, + htmlAttributes: { + 'aria-selected': isSelected ? 'true' : undefined, + }, } as ActionSheetButton; }); From 8df50f4a9fd66e2fff6a7a79baba6e30a2fe5c32 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Tue, 4 Nov 2025 15:58:28 -0800 Subject: [PATCH 2/4] fix(select): use aria description for selected option --- core/src/components/select/select.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index 10d6836c262..ddc95af0293 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -566,9 +566,7 @@ export class Select implements ComponentInterface { handler: () => { this.setValue(value); }, - htmlAttributes: { - 'aria-selected': isSelected ? 'true' : undefined, - }, + ...(isSelected ? { htmlAttributes: { 'aria-description': 'selected' } } : {}), } as ActionSheetButton; }); From 398ae6d8cdd2016cbb4cda831ccc604269c41dd4 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Wed, 5 Nov 2025 10:17:44 -0800 Subject: [PATCH 3/4] docs(select): remove comment --- core/src/components/select/select.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index ddc95af0293..2b12082c505 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -548,7 +548,6 @@ export class Select implements ComponentInterface { } private createActionSheetButtons(data: HTMLIonSelectOptionElement[], selectValue: any): ActionSheetButton[] { - console.log('createActionSheetButtons', data, selectValue); const actionSheetButtons = data.map((option) => { const value = getOptionValue(option); From 3f3ffaec1d9dfa7ac3ff08d455dd527d8ab5e8d3 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Wed, 5 Nov 2025 12:41:32 -0800 Subject: [PATCH 4/4] test(select): check for aria description --- .../components/select/test/a11y/select.e2e.ts | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/core/src/components/select/test/a11y/select.e2e.ts b/core/src/components/select/test/a11y/select.e2e.ts index 063add891dc..55416a982c4 100644 --- a/core/src/components/select/test/a11y/select.e2e.ts +++ b/core/src/components/select/test/a11y/select.e2e.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test'; import { configs, test } from '@utils/test/playwright'; configs({ directions: ['ltr'], palettes: ['light', 'dark'] }).forEach(({ title, config }) => { - test.describe(title('textarea: a11y'), () => { + test.describe(title('select: a11y'), () => { test('default layout should not have accessibility violations', async ({ page }) => { await page.setContent( ` @@ -111,3 +111,39 @@ configs({ directions: ['ltr'] }).forEach(({ title, config, screenshot }) => { }); }); }); + +/** + * This behavior does not vary across modes/directions. + */ +configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => { + test.describe(title('select: aria attributes'), () => { + test('should have a aria-description on the selected option when action sheet interface is open', async ({ + page, + }) => { + await page.setContent( + ` + + Apple + Banana + Orange + + `, + config + ); + + const ionActionSheetDidPresent = await page.spyOnEvent('ionActionSheetDidPresent'); + + const select = page.locator('ion-select'); + + await select.click(); + await ionActionSheetDidPresent.next(); + + const selectedOption = page.locator('.action-sheet-selected'); + await expect(selectedOption).toHaveAttribute('aria-description', 'selected'); + + // Check that the attribut is not added to non-selected option + const nonSelectedOption = page.locator('.select-interface-option:not(.action-sheet-selected)').first(); + await expect(nonSelectedOption).not.toHaveAttribute('aria-description'); + }); + }); +});