UNPKG

@aplus-frontend/antdv

Version:

Vue basic component library maintained based on ant-design-vue

243 lines 7.48 kB
import { createVNode as _createVNode } from "vue"; import Menu, { MenuItem } from '../../../menu'; import Dropdown from '../../../vc-dropdown'; import AddButton from './AddButton'; import { functionType } from '../../../_util/type'; import KeyCode from '../../../_util/KeyCode'; import classNames from '../../../_util/classNames'; import { defineComponent, watch, computed, onMounted } from 'vue'; import PropTypes from '../../../_util/vue-types'; import useState from '../../../_util/hooks/useState'; import EllipsisOutlined from "@ant-design/icons-vue/es/icons/EllipsisOutlined"; import { useProvideOverride } from '../../../menu/src/OverrideContext'; export const operationNodeProps = { prefixCls: { type: String }, id: { type: String }, tabs: { type: Object }, rtl: { type: Boolean }, tabBarGutter: { type: Number }, activeKey: { type: [String, Number] }, mobile: { type: Boolean }, moreIcon: PropTypes.any, moreTransitionName: { type: String }, editable: { type: Object }, locale: { type: Object, default: undefined }, removeAriaLabel: String, onTabClick: { type: Function }, popupClassName: String, getPopupContainer: functionType() }; export default defineComponent({ compatConfig: { MODE: 3 }, name: 'OperationNode', inheritAttrs: false, props: operationNodeProps, emits: ['tabClick'], slots: Object, setup(props, _ref) { let { attrs, slots } = _ref; // ======================== Dropdown ======================== const [open, setOpen] = useState(false); const [selectedKey, setSelectedKey] = useState(null); const selectOffset = offset => { const enabledTabs = props.tabs.filter(tab => !tab.disabled); let selectedIndex = enabledTabs.findIndex(tab => tab.key === selectedKey.value) || 0; const len = enabledTabs.length; for (let i = 0; i < len; i += 1) { selectedIndex = (selectedIndex + offset + len) % len; const tab = enabledTabs[selectedIndex]; if (!tab.disabled) { setSelectedKey(tab.key); return; } } }; const onKeyDown = e => { const { which } = e; if (!open.value) { if ([KeyCode.DOWN, KeyCode.SPACE, KeyCode.ENTER].includes(which)) { setOpen(true); e.preventDefault(); } return; } switch (which) { case KeyCode.UP: selectOffset(-1); e.preventDefault(); break; case KeyCode.DOWN: selectOffset(1); e.preventDefault(); break; case KeyCode.ESC: setOpen(false); break; case KeyCode.SPACE: case KeyCode.ENTER: if (selectedKey.value !== null) props.onTabClick(selectedKey.value, e); break; } }; const popupId = computed(() => `${props.id}-more-popup`); const selectedItemId = computed(() => selectedKey.value !== null ? `${popupId.value}-${selectedKey.value}` : null); const onRemoveTab = (event, key) => { event.preventDefault(); event.stopPropagation(); props.editable.onEdit('remove', { key, event }); }; onMounted(() => { watch(selectedKey, () => { const ele = document.getElementById(selectedItemId.value); if (ele && ele.scrollIntoView) { ele.scrollIntoView(false); } }, { flush: 'post', immediate: true }); }); watch(open, () => { if (!open.value) { setSelectedKey(null); } }); useProvideOverride({}); return () => { var _a; const { prefixCls, id, tabs, locale, mobile, moreIcon = ((_a = slots.moreIcon) === null || _a === void 0 ? void 0 : _a.call(slots)) || _createVNode(EllipsisOutlined, null, null), moreTransitionName, editable, tabBarGutter, rtl, onTabClick, popupClassName } = props; if (!tabs.length) return null; const dropdownPrefix = `${prefixCls}-dropdown`; const dropdownAriaLabel = locale === null || locale === void 0 ? void 0 : locale.dropdownAriaLabel; // ========================= Render ========================= const moreStyle = { [rtl ? 'marginRight' : 'marginLeft']: tabBarGutter }; if (!tabs.length) { moreStyle.visibility = 'hidden'; moreStyle.order = 1; } const overlayClassName = classNames({ [`${dropdownPrefix}-rtl`]: rtl, [`${popupClassName}`]: true }); const moreNode = mobile ? null : _createVNode(Dropdown, { "prefixCls": dropdownPrefix, "trigger": ['hover'], "visible": open.value, "transitionName": moreTransitionName, "onVisibleChange": setOpen, "overlayClassName": overlayClassName, "mouseEnterDelay": 0.1, "mouseLeaveDelay": 0.1, "getPopupContainer": props.getPopupContainer }, { overlay: () => _createVNode(Menu, { "onClick": _ref2 => { let { key, domEvent } = _ref2; onTabClick(key, domEvent); setOpen(false); }, "id": popupId.value, "tabindex": -1, "role": "listbox", "aria-activedescendant": selectedItemId.value, "selectedKeys": [selectedKey.value], "aria-label": dropdownAriaLabel !== undefined ? dropdownAriaLabel : 'expanded dropdown' }, { default: () => [tabs.map(tab => { var _a, _b; const removable = editable && tab.closable !== false && !tab.disabled; return _createVNode(MenuItem, { "key": tab.key, "id": `${popupId.value}-${tab.key}`, "role": "option", "aria-controls": id && `${id}-panel-${tab.key}`, "disabled": tab.disabled }, { default: () => [_createVNode("span", null, [typeof tab.tab === 'function' ? tab.tab() : tab.tab]), removable && _createVNode("button", { "type": "button", "aria-label": props.removeAriaLabel || 'remove', "tabindex": 0, "class": `${dropdownPrefix}-menu-item-remove`, "onClick": e => { e.stopPropagation(); onRemoveTab(e, tab.key); } }, [((_a = tab.closeIcon) === null || _a === void 0 ? void 0 : _a.call(tab)) || ((_b = editable.removeIcon) === null || _b === void 0 ? void 0 : _b.call(editable)) || '×'])] }); })] }), default: () => _createVNode("button", { "type": "button", "class": `${prefixCls}-nav-more`, "style": moreStyle, "tabindex": -1, "aria-hidden": "true", "aria-haspopup": "listbox", "aria-controls": popupId.value, "id": `${id}-more`, "aria-expanded": open.value, "onKeydown": onKeyDown }, [moreIcon]) }); return _createVNode("div", { "class": classNames(`${prefixCls}-nav-operations`, attrs.class), "style": attrs.style }, [moreNode, _createVNode(AddButton, { "prefixCls": prefixCls, "locale": locale, "editable": editable }, null)]); }; } });