feat(DropdownMenu): add role, aria and tabindex for a11y (#9893)

This commit is contained in:
neverland 2021-11-18 10:10:00 +08:00 committed by GitHub
parent 8214bf8d02
commit a055907b0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 128 additions and 67 deletions

View File

@ -58,7 +58,7 @@ export default defineComponent({
showWrapper: false,
});
const { parent } = useParent(DROPDOWN_KEY);
const { parent, index } = useParent(DROPDOWN_KEY);
if (!parent) {
if (process.env.NODE_ENV !== 'production') {
@ -142,14 +142,16 @@ export default defineComponent({
return (
<Cell
v-slots={{ value: renderIcon }}
clickable
role="menuitem"
key={option.value}
icon={option.icon}
title={option.text}
class={bem('option', { active })}
style={{ color: active ? activeColor : '' }}
tabindex={active ? 0 : -1}
clickable
onClick={onClick}
></Cell>
/>
);
};
@ -175,12 +177,14 @@ export default defineComponent({
>
<Popup
v-model:show={state.showPopup}
role="menu"
class={bem('content')}
overlay={overlay}
position={direction === 'down' ? 'top' : 'bottom'}
duration={state.transition ? duration : 0}
lazyRender={props.lazyRender}
overlayStyle={{ position: 'absolute' }}
aria-labelledby={`${parent.id}-${index.value}`}
closeOnClickOverlay={closeOnClickOverlay}
onOpen={onOpen}
onClose={onClose}

View File

@ -21,6 +21,7 @@ import {
} from '../utils';
// Composables
import { useId } from '../composables/use-id';
import {
useRect,
useChildren,
@ -54,6 +55,7 @@ export default defineComponent({
props: dropdownMenuProps,
setup(props, { slots }) {
const id = useId();
const root = ref<HTMLElement>();
const barRef = ref<HTMLElement>();
const offset = ref(0);
@ -115,6 +117,7 @@ export default defineComponent({
return (
<div
id={`${id}-${index}`}
role="button"
tabindex={disabled ? undefined : 0}
class={[bem('item', { disabled }), { [HAPTICS_FEEDBACK]: !disabled }]}
@ -140,7 +143,7 @@ export default defineComponent({
);
};
linkChildren({ props, offset });
linkChildren({ id, props, offset });
useClickAway(root, onClickAway);
useEventListener('scroll', onScroll, { target: scrollParent });

View File

@ -4,7 +4,8 @@ exports[`should render demo and match snapshot 1`] = `
<div>
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -14,7 +15,8 @@ exports[`should render demo and match snapshot 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -46,7 +48,8 @@ exports[`should render demo and match snapshot 1`] = `
<div>
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -56,7 +59,8 @@ exports[`should render demo and match snapshot 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -88,7 +92,8 @@ exports[`should render demo and match snapshot 1`] = `
<div>
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -98,7 +103,8 @@ exports[`should render demo and match snapshot 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -130,7 +136,8 @@ exports[`should render demo and match snapshot 1`] = `
<div>
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -140,7 +147,8 @@ exports[`should render demo and match snapshot 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -172,7 +180,8 @@ exports[`should render demo and match snapshot 1`] = `
<div>
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
class="van-dropdown-menu__item van-dropdown-menu__item--disabled"
>
<span class="van-dropdown-menu__title">
@ -181,7 +190,8 @@ exports[`should render demo and match snapshot 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
class="van-dropdown-menu__item van-dropdown-menu__item--disabled"
>
<span class="van-dropdown-menu__title">

View File

@ -3,7 +3,8 @@
exports[`click option 1`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar van-dropdown-menu__bar--opened">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -13,7 +14,8 @@ exports[`click option 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -36,9 +38,11 @@ exports[`click option 1`] = `
<transition-stub>
<div style="z-index: 2007; transition-duration: 0.2s; display: none;"
class="van-popup van-popup--top van-dropdown-item__content"
role="menu"
aria-labelledby="van-dropdown-menu-0"
>
<div class="van-cell van-cell--clickable van-dropdown-item__option van-dropdown-item__option--active"
role="button"
role="menuitem"
tabindex="0"
>
<div class="van-cell__title">
@ -52,8 +56,8 @@ exports[`click option 1`] = `
</div>
</div>
<div class="van-cell van-cell--clickable van-dropdown-item__option"
role="button"
tabindex="0"
role="menuitem"
tabindex="-1"
>
<div class="van-cell__title">
<span>
@ -80,7 +84,8 @@ exports[`click option 1`] = `
exports[`close-on-click-outside 1`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar van-dropdown-menu__bar--opened">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -90,7 +95,8 @@ exports[`close-on-click-outside 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -113,9 +119,11 @@ exports[`close-on-click-outside 1`] = `
<transition-stub>
<div style="z-index: 2004; transition-duration: 0.2s; display: none;"
class="van-popup van-popup--top van-dropdown-item__content"
role="menu"
aria-labelledby="van-dropdown-menu-0"
>
<div class="van-cell van-cell--clickable van-dropdown-item__option van-dropdown-item__option--active"
role="button"
role="menuitem"
tabindex="0"
>
<div class="van-cell__title">
@ -129,8 +137,8 @@ exports[`close-on-click-outside 1`] = `
</div>
</div>
<div class="van-cell van-cell--clickable van-dropdown-item__option"
role="button"
tabindex="0"
role="menuitem"
tabindex="-1"
>
<div class="van-cell__title">
<span>
@ -157,7 +165,8 @@ exports[`close-on-click-outside 1`] = `
exports[`destroy one item 1`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -182,7 +191,8 @@ exports[`destroy one item 1`] = `
exports[`direction up 1`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -192,7 +202,8 @@ exports[`direction up 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -225,7 +236,8 @@ exports[`direction up 1`] = `
exports[`direction up 2`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar van-dropdown-menu__bar--opened">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -235,7 +247,8 @@ exports[`direction up 2`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -258,9 +271,11 @@ exports[`direction up 2`] = `
<transition-stub>
<div style="z-index: 2006; transition-duration: 0.2s;"
class="van-popup van-popup--bottom van-dropdown-item__content"
role="menu"
aria-labelledby="van-dropdown-menu-0"
>
<div class="van-cell van-cell--clickable van-dropdown-item__option van-dropdown-item__option--active"
role="button"
role="menuitem"
tabindex="0"
>
<div class="van-cell__title">
@ -274,8 +289,8 @@ exports[`direction up 2`] = `
</div>
</div>
<div class="van-cell van-cell--clickable van-dropdown-item__option"
role="button"
tabindex="0"
role="menuitem"
tabindex="-1"
>
<div class="van-cell__title">
<span>
@ -302,7 +317,8 @@ exports[`direction up 2`] = `
exports[`disable close-on-click-outside 1`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar van-dropdown-menu__bar--opened">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -312,7 +328,8 @@ exports[`disable close-on-click-outside 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -335,9 +352,11 @@ exports[`disable close-on-click-outside 1`] = `
<transition-stub>
<div style="z-index: 2005; transition-duration: 0.2s;"
class="van-popup van-popup--top van-dropdown-item__content"
role="menu"
aria-labelledby="van-dropdown-menu-0"
>
<div class="van-cell van-cell--clickable van-dropdown-item__option van-dropdown-item__option--active"
role="button"
role="menuitem"
tabindex="0"
>
<div class="van-cell__title">
@ -351,8 +370,8 @@ exports[`disable close-on-click-outside 1`] = `
</div>
</div>
<div class="van-cell van-cell--clickable van-dropdown-item__option"
role="button"
tabindex="0"
role="menuitem"
tabindex="-1"
>
<div class="van-cell__title">
<span>
@ -379,7 +398,8 @@ exports[`disable close-on-click-outside 1`] = `
exports[`disable dropdown item 1`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
class="van-dropdown-menu__item van-dropdown-menu__item--disabled"
>
<span class="van-dropdown-menu__title">
@ -403,7 +423,8 @@ exports[`disable dropdown item 1`] = `
exports[`render option icon 1`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar van-dropdown-menu__bar--opened">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -413,7 +434,8 @@ exports[`render option icon 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -436,9 +458,11 @@ exports[`render option icon 1`] = `
<transition-stub>
<div style="z-index: 2003; transition-duration: 0.2s;"
class="van-popup van-popup--top van-dropdown-item__content"
role="menu"
aria-labelledby="van-dropdown-menu-0"
>
<div class="van-cell van-cell--clickable van-dropdown-item__option van-dropdown-item__option--active"
role="button"
role="menuitem"
tabindex="0"
>
<i class="van-badge__wrapper van-icon van-icon-success van-cell__left-icon">
@ -454,8 +478,8 @@ exports[`render option icon 1`] = `
</div>
</div>
<div class="van-cell van-cell--clickable van-dropdown-item__option"
role="button"
tabindex="0"
role="menuitem"
tabindex="-1"
>
<i class="van-badge__wrapper van-icon van-icon-success van-cell__left-icon">
</i>
@ -484,7 +508,8 @@ exports[`render option icon 1`] = `
exports[`show dropdown item 1`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar van-dropdown-menu__bar--opened">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -494,7 +519,8 @@ exports[`show dropdown item 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -517,9 +543,11 @@ exports[`show dropdown item 1`] = `
<transition-stub>
<div style="z-index: 2001; transition-duration: 0.2s;"
class="van-popup van-popup--top van-dropdown-item__content"
role="menu"
aria-labelledby="van-dropdown-menu-0"
>
<div class="van-cell van-cell--clickable van-dropdown-item__option van-dropdown-item__option--active"
role="button"
role="menuitem"
tabindex="0"
>
<div class="van-cell__title">
@ -533,8 +561,8 @@ exports[`show dropdown item 1`] = `
</div>
</div>
<div class="van-cell van-cell--clickable van-dropdown-item__option"
role="button"
tabindex="0"
role="menuitem"
tabindex="-1"
>
<div class="van-cell__title">
<span>
@ -561,7 +589,8 @@ exports[`show dropdown item 1`] = `
exports[`show dropdown item 2`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar van-dropdown-menu__bar--opened">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -571,7 +600,8 @@ exports[`show dropdown item 2`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -594,9 +624,11 @@ exports[`show dropdown item 2`] = `
<transition-stub>
<div style="z-index: 2001; transition-duration: 0s; display: none;"
class="van-popup van-popup--top van-dropdown-item__content"
role="menu"
aria-labelledby="van-dropdown-menu-0"
>
<div class="van-cell van-cell--clickable van-dropdown-item__option van-dropdown-item__option--active"
role="button"
role="menuitem"
tabindex="0"
>
<div class="van-cell__title">
@ -610,8 +642,8 @@ exports[`show dropdown item 2`] = `
</div>
</div>
<div class="van-cell van-cell--clickable van-dropdown-item__option"
role="button"
tabindex="0"
role="menuitem"
tabindex="-1"
>
<div class="van-cell__title">
<span>
@ -636,9 +668,11 @@ exports[`show dropdown item 2`] = `
<transition-stub>
<div style="z-index: 2002; transition-duration: 0.2s;"
class="van-popup van-popup--top van-dropdown-item__content"
role="menu"
aria-labelledby="van-dropdown-menu-1"
>
<div class="van-cell van-cell--clickable van-dropdown-item__option van-dropdown-item__option--active"
role="button"
role="menuitem"
tabindex="0"
>
<div class="van-cell__title">
@ -652,8 +686,8 @@ exports[`show dropdown item 2`] = `
</div>
</div>
<div class="van-cell van-cell--clickable van-dropdown-item__option"
role="button"
tabindex="0"
role="menuitem"
tabindex="-1"
>
<div class="van-cell__title">
<span>
@ -672,7 +706,8 @@ exports[`show dropdown item 2`] = `
exports[`show dropdown item 3`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar van-dropdown-menu__bar--opened">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -682,7 +717,8 @@ exports[`show dropdown item 3`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -705,9 +741,11 @@ exports[`show dropdown item 3`] = `
<transition-stub>
<div style="z-index: 2001; transition-duration: 0s; display: none;"
class="van-popup van-popup--top van-dropdown-item__content"
role="menu"
aria-labelledby="van-dropdown-menu-0"
>
<div class="van-cell van-cell--clickable van-dropdown-item__option van-dropdown-item__option--active"
role="button"
role="menuitem"
tabindex="0"
>
<div class="van-cell__title">
@ -721,8 +759,8 @@ exports[`show dropdown item 3`] = `
</div>
</div>
<div class="van-cell van-cell--clickable van-dropdown-item__option"
role="button"
tabindex="0"
role="menuitem"
tabindex="-1"
>
<div class="van-cell__title">
<span>
@ -747,9 +785,11 @@ exports[`show dropdown item 3`] = `
<transition-stub>
<div style="z-index: 2002; transition-duration: 0.2s; display: none;"
class="van-popup van-popup--top van-dropdown-item__content"
role="menu"
aria-labelledby="van-dropdown-menu-1"
>
<div class="van-cell van-cell--clickable van-dropdown-item__option van-dropdown-item__option--active"
role="button"
role="menuitem"
tabindex="0"
>
<div class="van-cell__title">
@ -763,8 +803,8 @@ exports[`show dropdown item 3`] = `
</div>
</div>
<div class="van-cell van-cell--clickable van-dropdown-item__option"
role="button"
tabindex="0"
role="menuitem"
tabindex="-1"
>
<div class="van-cell__title">
<span>
@ -783,7 +823,8 @@ exports[`show dropdown item 3`] = `
exports[`title prop 1`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -793,7 +834,8 @@ exports[`title prop 1`] = `
</div>
</span>
</div>
<div role="button"
<div id="van-dropdown-menu-1"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>
@ -826,7 +868,8 @@ exports[`title prop 1`] = `
exports[`title slot 1`] = `
<div class="van-dropdown-menu">
<div class="van-dropdown-menu__bar">
<div role="button"
<div id="van-dropdown-menu-0"
role="button"
tabindex="0"
class="van-dropdown-menu__item van-haptics-feedback"
>

View File

@ -4,6 +4,7 @@ import type { DropdownMenuProps } from './DropdownMenu';
export type DropdownMenuDirection = 'up' | 'down';
export type DropdownMenuProvide = {
id: string;
props: DropdownMenuProps;
offset: Ref<number>;
};