diff --git a/packages/components/mention/__tests__/mention.test.tsx b/packages/components/mention/__tests__/mention.test.tsx index d37686856f..321a3420fb 100644 --- a/packages/components/mention/__tests__/mention.test.tsx +++ b/packages/components/mention/__tests__/mention.test.tsx @@ -86,4 +86,35 @@ describe('Mention.vue', () => { 4 ) }) + + test('It should generate accessible attributes', async () => { + const wrapper = mount(Mention, { + attachTo: document.body, + props: { options }, + }) + + const input = wrapper.find('input') + expect(input.attributes('role')).toBe(undefined) + expect(input.attributes('aria-autocomplete')).toBe(undefined) + expect(input.attributes('aria-controls')).toBe(undefined) + expect(input.attributes('aria-expanded')).toBe(undefined) + expect(input.attributes('aria-haspopup')).toBe(undefined) + expect(input.attributes('aria-activedescendant')).toBe(undefined) + + wrapper.find('input').trigger('focus') + input.element.value = '@' + wrapper.find('input').trigger('input') + await sleep(150) + const dropdown = wrapper.findComponent({ name: 'ElMentionDropdown' }) + const list = dropdown.find('.el-mention-dropdown__list') + const option = dropdown.find('.el-mention-dropdown__item') + + expect(list.attributes('id')).toBeTruthy() + expect(list.attributes('role')).toBe('listbox') + expect(list.attributes('aria-orientation')).toBe('vertical') + expect(option.attributes('id')).toBeTruthy() + expect(option.attributes('role')).toBe('option') + expect(option.attributes('aria-disabled')).toBe(undefined) + expect(option.attributes('aria-selected')).toBe('true') + }) }) diff --git a/packages/components/mention/src/mention-dropdown.ts b/packages/components/mention/src/mention-dropdown.ts index 7135015559..3dcaa8ec22 100644 --- a/packages/components/mention/src/mention-dropdown.ts +++ b/packages/components/mention/src/mention-dropdown.ts @@ -9,6 +9,8 @@ export const mentionDropdownProps = buildProps({ }, loading: Boolean, disabled: Boolean, + contentId: String, + ariaLabel: String, }) export const mentionDropdownEmits = { diff --git a/packages/components/mention/src/mention-dropdown.vue b/packages/components/mention/src/mention-dropdown.vue index 28db2ecc0a..7f7a3209e7 100644 --- a/packages/components/mention/src/mention-dropdown.vue +++ b/packages/components/mention/src/mention-dropdown.vue @@ -5,16 +5,24 @@
  • @@ -134,6 +142,7 @@ watch(() => props.options, resetHoveringIndex, { }) defineExpose({ + hoveringIndex, navigateOptions, selectHoverOption, hoverOption, diff --git a/packages/components/mention/src/mention.vue b/packages/components/mention/src/mention.vue index 3c47659825..b2a96300a0 100644 --- a/packages/components/mention/src/mention.vue +++ b/packages/components/mention/src/mention.vue @@ -4,6 +4,13 @@ v-bind="mergeProps(passInputProps, $attrs)" ref="elInputRef" :model-value="modelValue" + :role="dropdownVisible ? 'combobox' : undefined" + :aria-activedescendant="dropdownVisible ? hoveringId || '' : undefined" + :aria-controls="dropdownVisible ? contentId : undefined" + :aria-expanded="dropdownVisible || undefined" + :aria-label="ariaLabel" + :aria-autocomplete="dropdownVisible ? 'none' : undefined" + :aria-haspopup="dropdownVisible ? 'listbox' : undefined" @input="handleInputChange" @keydown="handleInputKeyDown" @mousedown="handleInputMouseDown" @@ -14,7 +21,7 @@ @@ -48,7 +57,7 @@