yuang-framework-ui-pc
Version:
yuang-framework-ui-pc Library
479 lines (478 loc) • 15.6 kB
JavaScript
;
const vue = require("vue");
const SortableJs = require("sortablejs");
const elementPlus = require("element-plus");
const icons = require("../icons");
const core = require("../utils/core");
const hook = require("../utils/hook");
const EleDropdown = require("../ele-dropdown/index");
const props = require("./props");
const _sfc_main = vue.defineComponent({
name: "EleTabs",
components: {
ElTabs: elementPlus.ElTabs,
ElTabPane: elementPlus.ElTabPane,
ElIcon: elementPlus.ElIcon,
EleDropdown,
CornerLeftFilled: icons.CornerLeftFilled,
CornerRightFilled: icons.CornerRightFilled
},
props: props.tabsProps,
emits: props.tabsEmits,
setup(props$1, { emit }) {
let sortableIns = null;
let currentSortItemId = null;
let contextMenuTabItem = null;
let contextMenuTabName = null;
const wrapProps = vue.inject(props.TAB_WRAP_KEY, null);
const [startScrollTimer, _stopScrollTimer, scrollWaiting] = hook.useTimer(320);
const { bindMousewheel, unbindMousewheel } = hook.useMousewheel((param) => {
const { e, direction } = param;
scrollTabs(direction === "up" ? "prev" : "next", () => {
e.preventDefault();
e.stopPropagation();
});
});
const { bindTouchEvent, unbindTouchEvent } = hook.useTouchEvent({
end: (param) => {
if (param.distanceX && param.distanceX > 80) {
scrollTabs("prev");
} else if (param.distanceX && param.distanceX < 80) {
scrollTabs("next");
}
}
});
const [startGhostTimer] = hook.useTimer(100);
const tabRef = vue.ref(null);
const isOnlyTab = vue.computed(() => wrapProps == null);
const tabSize = vue.computed(
() => wrapProps == null ? props$1.size : wrapProps.size
);
const tabType = vue.computed(
() => wrapProps == null ? props$1.type : wrapProps.type
);
const tabProps = vue.computed(() => {
return core.pick(props$1, props.tabPropKeys);
});
const ctxMenuDropdownRef = vue.ref(null);
const ctxMenuDropdownItems = vue.shallowRef([]);
const ctxMenuDropdownVirtualRef = vue.ref();
const updateModelValue = (name) => {
emit("update:modelValue", name);
};
const handleContextmenu = (e) => {
if (!props$1.contextMenu) {
return;
}
const el = e.target;
if (el && (el.classList.contains("is-icon-close") || el.classList.contains("el-tabs__nav") || el.classList.contains("el-tabs__item"))) {
e.preventDefault();
}
};
const handleTabClick = (pane, e) => {
emit("tabClick", pane, e);
};
const handleTabChange = (name) => {
emit("tabChange", name);
};
const handleTabRemove = (name) => {
emit("tabRemove", name);
};
const handleTabAdd = () => {
emit("tabAdd");
};
const handleEdit = (name, action) => {
emit("edit", name, action);
};
const handleItemClick = (item, tabName, e) => {
if (props$1.handleClick) {
e.stopPropagation();
}
emit("tabItemClick", {
item,
name: item ? item.name : tabName,
active: props$1.modelValue
});
};
const handleItemCtxMenuVisible = (visible) => {
if (visible) {
emit(
"tabContextOpen",
ctxMenuDropdownRef.value,
contextMenuTabItem,
contextMenuTabName
);
}
};
const handleItemCtxMenuClick = (command) => {
if (contextMenuTabItem != null || contextMenuTabName != null) {
emit("tabContextMenu", {
command,
item: contextMenuTabItem,
name: contextMenuTabItem ? contextMenuTabItem.name : contextMenuTabName,
active: props$1.modelValue
});
}
};
const getContextMenus = (item, tabName) => {
if (typeof props$1.contextMenus === "function") {
return props$1.contextMenus(item, tabName);
}
return props$1.contextMenus;
};
const hideAllDropdown = () => {
if (ctxMenuDropdownRef.value) {
ctxMenuDropdownRef.value.handleClose();
}
};
const showItemContextMenu = (item, tabName, itemEl) => {
if (contextMenuTabItem != null && contextMenuTabItem === item || contextMenuTabName != null && contextMenuTabName === tabName) {
return;
}
hideAllDropdown();
vue.nextTick(() => {
contextMenuTabItem = item;
contextMenuTabName = tabName;
ctxMenuDropdownItems.value = getContextMenus(item, tabName) || [];
ctxMenuDropdownVirtualRef.value = itemEl;
if (props$1.contextMenu && ctxMenuDropdownItems.value.length) {
vue.nextTick(() => {
ctxMenuDropdownRef.value && ctxMenuDropdownRef.value.handleOpen();
});
}
});
};
const handleItemContextmenu = (item, tabName, e) => {
const itemEl = e.currentTarget;
if (!props$1.contextMenu || ctxMenuDropdownVirtualRef.value === itemEl) {
return;
}
e.preventDefault();
showItemContextMenu(item, tabName, itemEl);
};
const getHeaderEl = () => {
const tabEl = tabRef.value ? tabRef.value.$el : void 0;
return tabEl ? tabEl.querySelector(".el-tabs__header") : void 0;
};
const getNavEl = () => {
const headerEl = getHeaderEl();
return headerEl ? headerEl.querySelector(".el-tabs__nav") : void 0;
};
const updateActiveBar = () => {
const el = getNavEl();
if (el) {
const bar = el.querySelector(".el-tabs__active-bar");
if (bar) {
bar.style.width = "0px";
}
}
};
const scrollTabs = (direction, done) => {
const tabEl = getHeaderEl();
if (tabEl && !scrollWaiting.value) {
const el = tabEl.querySelector(`.el-tabs__nav-${direction}`);
if (el && !el.classList.contains("is-disabled")) {
startScrollTimer();
done && done();
el.click();
}
}
};
const checkSortGhostTab = () => {
const navEl = getNavEl();
if (navEl == null) {
return;
}
if (currentSortItemId == null) {
const el2 = navEl.querySelector(".el-tabs__item.sortable-ghost");
if (el2 != null) {
el2.classList.remove("sortable-ghost");
}
return;
}
const el = navEl.querySelector(
`.el-tabs__item[id="${currentSortItemId}"]`
);
if (el != null) {
el.classList.add("sortable-ghost");
}
};
const bindDragSort = () => {
unbindDragSort();
const navEl = getNavEl();
if (!props$1.sortable || !navEl) {
return;
}
sortableIns = new SortableJs(navEl, {
draggable: ".el-tabs__item",
delay: 20,
onUpdate: ({ oldDraggableIndex, newDraggableIndex }) => {
if (typeof oldDraggableIndex === "number" && typeof newDraggableIndex === "number") {
const data = [...props$1.items];
data.splice(
newDraggableIndex,
0,
data.splice(oldDraggableIndex, 1)[0]
);
emit("tabSortChange", data);
}
},
onStart: (e) => {
currentSortItemId = e.item.getAttribute("id");
checkSortGhostTab();
startGhostTimer(() => {
checkSortGhostTab();
});
},
onEnd: () => {
currentSortItemId = null;
checkSortGhostTab();
},
onChange: () => {
checkSortGhostTab();
startGhostTimer(() => {
checkSortGhostTab();
});
},
onMove: () => {
checkSortGhostTab();
startGhostTimer(() => {
checkSortGhostTab();
});
},
setData: () => {
}
});
};
const unbindDragSort = () => {
sortableIns && sortableIns.destroy();
sortableIns = null;
currentSortItemId = null;
};
const initMousewheelEvent = () => {
const el = getHeaderEl();
if (el != null) {
unbindMousewheel(el);
if (props$1.mousewheel) {
bindMousewheel(el);
}
}
};
const initTouchEvent = () => {
const el = getHeaderEl();
if (el != null) {
unbindTouchEvent(el);
if (!props$1.sortable) {
bindTouchEvent(el);
}
}
};
if (wrapProps && wrapProps.setTabMethods) {
wrapProps.setTabMethods({
triggerTabItemClick: handleItemClick,
triggerItemContextMenu: handleItemContextmenu
});
}
vue.onMounted(() => {
initMousewheelEvent();
initTouchEvent();
bindDragSort();
});
vue.onBeforeUnmount(() => {
if (wrapProps && wrapProps.setTabMethods) {
wrapProps.setTabMethods({
triggerTabItemClick: void 0,
triggerItemContextMenu: void 0
});
}
contextMenuTabItem = null;
contextMenuTabName = null;
const el = getHeaderEl();
if (el != null) {
unbindMousewheel(el);
unbindTouchEvent(el);
}
unbindDragSort();
});
vue.watch(
() => props$1.sortable,
() => {
bindDragSort();
initTouchEvent();
}
);
vue.watch(
() => props$1.mousewheel,
() => {
initMousewheelEvent();
}
);
return {
omit: core.omit,
tabRef,
isOnlyTab,
tabSize,
tabType,
tabProps,
ctxMenuDropdownRef,
ctxMenuDropdownItems,
ctxMenuDropdownVirtualRef,
updateModelValue,
handleContextmenu,
handleTabClick,
handleTabChange,
handleTabRemove,
handleTabAdd,
handleEdit,
handleItemClick,
handleItemCtxMenuVisible,
handleItemCtxMenuClick,
handleItemContextmenu,
hideAllDropdown,
updateActiveBar,
scrollTabs
};
}
});
const _export_sfc = (sfc, props2) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props2) {
target[key] = val;
}
return target;
};
const _hoisted_1 = ["onClick", "onContextmenu"];
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_CornerLeftFilled = vue.resolveComponent("CornerLeftFilled");
const _component_ElIcon = vue.resolveComponent("ElIcon");
const _component_CornerRightFilled = vue.resolveComponent("CornerRightFilled");
const _component_ElTabPane = vue.resolveComponent("ElTabPane");
const _component_EleDropdown = vue.resolveComponent("EleDropdown");
const _component_ElTabs = vue.resolveComponent("ElTabs");
return vue.openBlock(), vue.createBlock(_component_ElTabs, vue.mergeProps(_ctx.tabProps, {
ref: "tabRef",
type: _ctx.tabType === "card" || _ctx.tabType === "border-card" ? _ctx.tabType : void 0,
class: [
"ele-tabs",
{ "ele-tabs-wrap": _ctx.isOnlyTab },
{ "is-small": _ctx.tabSize === "small" },
{ "is-large": _ctx.tabSize === "large" },
{ "is-default": !_ctx.tabType || _ctx.tabType === "default" },
{ "is-plain": _ctx.tabType === "plain" },
{ "is-simple": _ctx.tabType === "simple" },
{ "is-indicator": _ctx.tabType === "indicator" },
{ "is-button": _ctx.tabType === "button" },
{ "is-tag": _ctx.tabType === "tag" },
{ "is-center": _ctx.center },
{ "is-sortable": _ctx.sortable },
{ "is-flex-table": _ctx.flexTable }
],
"onUpdate:modelValue": _ctx.updateModelValue,
onTabClick: _ctx.handleTabClick,
onTabChange: _ctx.handleTabChange,
onTabRemove: _ctx.handleTabRemove,
onTabAdd: _ctx.handleTabAdd,
onEdit: _ctx.handleEdit,
onContextmenu: _ctx.handleContextmenu
}), vue.createSlots({
default: vue.withCtx(() => [
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.items, (item, index2) => {
return vue.openBlock(), vue.createBlock(_component_ElTabPane, vue.mergeProps({
key: [
index2,
item.name,
item.label,
!!item.closable,
!!item.disabled,
!!item.lazy
].join("-")
}, { ref_for: true }, _ctx.omit(item, ["slot", "meta"])), vue.createSlots({
label: vue.withCtx(() => [
vue.createElementVNode("div", {
class: "ele-tab-title",
onClick: (e) => _ctx.handleItemClick(item, void 0, e),
onContextmenu: (e) => _ctx.handleItemContextmenu(item, void 0, e)
}, [
vue.renderSlot(_ctx.$slots, "label", {
item,
label: item.label,
active: _ctx.modelValue
}, () => [
vue.createTextVNode(vue.toDisplayString(item.label), 1)
])
], 40, _hoisted_1),
_ctx.tabType === "simple" || _ctx.tabType === "indicator" ? (vue.openBlock(), vue.createBlock(_component_ElIcon, {
key: 0,
class: "ele-tab-corner-left"
}, {
default: vue.withCtx(() => [
vue.createVNode(_component_CornerLeftFilled)
]),
_: 1
})) : vue.createCommentVNode("", true),
_ctx.tabType === "simple" || _ctx.tabType === "indicator" ? (vue.openBlock(), vue.createBlock(_component_ElIcon, {
key: 1,
class: "ele-tab-corner-right"
}, {
default: vue.withCtx(() => [
vue.createVNode(_component_CornerRightFilled)
]),
_: 1
})) : vue.createCommentVNode("", true)
]),
_: 2
}, [
item.name && _ctx.$slots[item.slot || item.name] ? {
name: "default",
fn: vue.withCtx(() => [
vue.renderSlot(_ctx.$slots, item.slot || item.name, { item })
]),
key: "0"
} : void 0
]), 1040);
}), 128)),
_ctx.contextMenu ? (vue.openBlock(), vue.createBlock(_component_EleDropdown, vue.mergeProps(
{
key: 0,
triggerKeys: [],
persistent: false,
placement: "bottom-start",
popperClass: "ele-tab-popup",
popperOptions: {
modifiers: [{ name: "offset", options: { offset: [0, 8] } }]
}
},
!_ctx.contextMenu || typeof _ctx.contextMenu == "boolean" ? {} : _ctx.contextMenu,
{
ref: "ctxMenuDropdownRef",
componentType: "pro",
preventContextmenu: true,
trigger: "contextmenu",
virtualTriggering: true,
virtualRef: _ctx.ctxMenuDropdownVirtualRef,
disabled: !_ctx.ctxMenuDropdownItems.length,
items: _ctx.ctxMenuDropdownItems,
onCommand: _ctx.handleItemCtxMenuClick,
onVisibleChange: _ctx.handleItemCtxMenuVisible
}
), null, 16, ["virtualRef", "disabled", "items", "onCommand", "onVisibleChange"])) : vue.createCommentVNode("", true)
]),
_: 2
}, [
_ctx.$slots["add-icon"] ? {
name: "add-icon",
fn: vue.withCtx(() => [
vue.renderSlot(_ctx.$slots, "add-icon")
]),
key: "0"
} : _ctx.$slots.addIcon ? {
name: "addIcon",
fn: vue.withCtx(() => [
vue.renderSlot(_ctx.$slots, "addIcon")
]),
key: "1"
} : void 0
]), 1040, ["type", "class", "onUpdate:modelValue", "onTabClick", "onTabChange", "onTabRemove", "onTabAdd", "onEdit", "onContextmenu"]);
}
const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
module.exports = index;