UNPKG

element-plus

Version:

A Component Library for Vue3.0

165 lines (157 loc) 6.11 kB
import { inject, computed, ref, defineComponent, onMounted, getCurrentInstance, resolveDirective, withDirectives, openBlock, createBlock, withModifiers, renderSlot } from 'vue'; import { ClickOutside } from '../directives'; import { useGlobalConfig, generateId } from '../utils/util'; import { EVENT_CODE } from '../utils/aria'; import { addClass, on } from '../utils/dom'; const useDropdown = () => { const ELEMENT = useGlobalConfig(); const elDropdown = inject('elDropdown', {}); const _elDropdownSize = computed(() => elDropdown === null || elDropdown === void 0 ? void 0 : elDropdown.dropdownSize); return { ELEMENT, elDropdown, _elDropdownSize, }; }; const initDropdownDomEvent = (dropdownChildren, triggerElm, _instance) => { const menuItems = ref(null); const menuItemsArray = ref(null); const dropdownElm = ref(null); const listId = ref(`dropdown-menu-${generateId()}`); dropdownElm.value = dropdownChildren === null || dropdownChildren === void 0 ? void 0 : dropdownChildren.subTree.el; function removeTabindex() { var _a; triggerElm.setAttribute('tabindex', '-1'); (_a = menuItemsArray.value) === null || _a === void 0 ? void 0 : _a.forEach(item => { item.setAttribute('tabindex', '-1'); }); } function resetTabindex(ele) { removeTabindex(); ele === null || ele === void 0 ? void 0 : ele.setAttribute('tabindex', '0'); } function handleTriggerKeyDown(ev) { const code = ev.code; if ([EVENT_CODE.up, EVENT_CODE.down].includes(code)) { removeTabindex(); resetTabindex(menuItems.value[0]); menuItems.value[0].focus(); ev.preventDefault(); ev.stopPropagation(); } else if (code === EVENT_CODE.enter) { _instance.handleClick(); } else if ([EVENT_CODE.tab, EVENT_CODE.esc].includes(code)) { _instance.hide(); } } function handleItemKeyDown(ev) { const code = ev.code; const target = ev.target; const currentIndex = menuItemsArray.value.indexOf(target); const max = menuItemsArray.value.length - 1; let nextIndex; if ([EVENT_CODE.up, EVENT_CODE.down].includes(code)) { if (code === EVENT_CODE.up) { nextIndex = currentIndex !== 0 ? currentIndex - 1 : 0; } else { nextIndex = currentIndex < max ? currentIndex + 1 : max; } removeTabindex(); resetTabindex(menuItems.value[nextIndex]); menuItems.value[nextIndex].focus(); ev.preventDefault(); ev.stopPropagation(); } else if (code === EVENT_CODE.enter) { triggerElmFocus(); target.click(); if (_instance.props.hideOnClick) { _instance.hide(); } } else if ([EVENT_CODE.tab, EVENT_CODE.esc].includes(code)) { _instance.hide(); triggerElmFocus(); } } function initAria() { dropdownElm.value.setAttribute('id', listId.value); triggerElm.setAttribute('aria-haspopup', 'list'); triggerElm.setAttribute('aria-controls', listId.value); if (!_instance.props.splitButton) { triggerElm.setAttribute('role', 'button'); triggerElm.setAttribute('tabindex', _instance.props.tabindex); addClass(triggerElm, 'el-dropdown-selfdefine'); } } function initEvent() { on(triggerElm, 'keydown', handleTriggerKeyDown); on(dropdownElm.value, 'keydown', handleItemKeyDown, true); } function initDomOperation() { menuItems.value = dropdownElm.value.querySelectorAll("[tabindex='-1']"); menuItemsArray.value = [].slice.call(menuItems.value); initEvent(); initAria(); } function triggerElmFocus() { triggerElm.focus(); } initDomOperation(); }; var script = defineComponent({ name: 'ElDropdownMenu', directives: { ClickOutside, }, setup() { const { _elDropdownSize, elDropdown } = useDropdown(); const size = _elDropdownSize.value; function show() { var _a; (_a = elDropdown.show) === null || _a === void 0 ? void 0 : _a.call(elDropdown); } function hide() { if (['click', 'contextmenu'].includes(elDropdown.trigger.value)) return; _hide(); } function _hide() { var _a; (_a = elDropdown.hide) === null || _a === void 0 ? void 0 : _a.call(elDropdown); } onMounted(() => { const dropdownMenu = getCurrentInstance(); initDropdownDomEvent(dropdownMenu, elDropdown.triggerElm.value, elDropdown.instance); }); return { size, show, hide, innerHide: _hide, triggerElm: elDropdown.triggerElm, }; }, }); function render(_ctx, _cache, $props, $setup, $data, $options) { const _directive_clickOutside = resolveDirective("clickOutside"); return withDirectives((openBlock(), createBlock("ul", { class: [[_ctx.size && `el-dropdown-menu--${_ctx.size}`], "el-dropdown-menu"], onMouseenter: _cache[1] || (_cache[1] = withModifiers((...args) => (_ctx.show && _ctx.show(...args)), ["stop"])), onMouseleave: _cache[2] || (_cache[2] = withModifiers((...args) => (_ctx.hide && _ctx.hide(...args)), ["stop"])) }, [ renderSlot(_ctx.$slots, "default") ], 34 /* CLASS, HYDRATE_EVENTS */)), [ [_directive_clickOutside, _ctx.innerHide, _ctx.triggerElm] ]) } script.render = render; script.__file = "packages/dropdown/src/dropdown-menu.vue"; script.install = (app) => { app.component(script.name, script); }; const _DropdownMenu = script; export default _DropdownMenu;