layui-vue/es/tab/index.js

366 lines
21 KiB
JavaScript
Raw Normal View History

2022-12-12 01:08:28 +00:00
import { b as isArrayChildren, w as withInstall } from "../badge/index2.js";
import { defineComponent, useSlots, reactive, ref, computed, provide, shallowRef, watch, nextTick, onMounted, openBlock, createElementBlock, normalizeClass, createElementVNode, normalizeStyle, unref, createCommentVNode, Fragment, renderList, withModifiers, createBlock, createVNode, renderSlot, h, createTextVNode } from "vue";
2022-11-14 03:59:26 +00:00
import { _ as _sfc_main$2E } from "../checkbox/index2.js";
import { T as TabInjectKey, _ as _sfc_main$1 } from "../tabItem/index2.js";
import { R as RenderFunction } from "../dropdown/index2.js";
import { a as useResizeObserver } from "../_chunks/@vueuse/index.js";
var index = /* @__PURE__ */ (() => '.layui-tab{display:flex;margin:10px 0;text-align:left!important}.layui-tab[overflow]>.layui-tab-head>.layui-tab-title{overflow:hidden}.layui-tab.is-left{flex-direction:row}.layui-tab.is-right{flex-direction:row-reverse;justify-content:space-between}.layui-tab.is-top{flex-direction:column}.layui-tab.is-bottom{flex-direction:column-reverse}.layui-tab-head{display:inline-block;overflow:hidden}.layui-tab-card .layui-tab-head{background-color:var(--global-neutral-color-1)}.layui-tab-title{position:relative;left:0;height:40px;white-space:nowrap;font-size:0;border-bottom-width:1px;border-bottom-style:solid;transition:all .2s;-webkit-transition:all .2s}.layui-tab-title li{display:inline-block;vertical-align:middle;font-size:14px;transition:all .2s;-webkit-transition:all .2s;position:relative;line-height:40px;min-width:65px;padding:0 15px;text-align:center;cursor:pointer;user-select:none}.layui-tab-title li a{display:block;padding:0 15px;margin:0 -15px}.layui-tab-head.is-top,.layui-tab-head.is-bottom,.layui-tab-title.is-top,.layui-tab-title.is-bottom{width:100%;position:relative}.layui-tab-title.is-right,.layui-tab-title.is-left{height:100%;min-width:60px;border-bottom-width:0px;border-bottom-style:none}.layui-tab-title.is-left li{display:list-item;margin-right:-1px}.layui-tab-title.is-right li{display:list-item;margin-left:-1px}.layui-tab-title.is-top li,.layui-tab-title.is-bottom li{border-bottom:1px solid #eeeeee}.layui-tab-title.is-right{border-left:1px solid var(--global-neutral-color-3)}.layui-tab-title.is-left{border-right:1px solid var(--global-neutral-color-3)}.layui-tab-title .layui-this{color:#000;background-color:#fff}.layui-tab-title .layui-this:after{position:absolute;left:0;top:0;content:"";width:100%;height:41px;border-width:1px;border-style:solid;border-bottom-color:#fff;border-radius:2px 2px 0 0;box-sizing:border-box;pointer-events:none}.layui-tab-title.is-left .layui-this:after{border:1px solid var(--global-neutral-color-3);border-right-color:#fff}.layui-tab-title.is-right .layui-this:after{border:1px solid var(--global-neutral-color-3);border-left-color:#fff}.layui-tab-brief>.layui-tab-head{background-color:transparent}.layui-tab-brief>.layui-tab-head>.layui-tab-title .layui-this{color:var(--global-primary-color)}.layui-tab-brief>.layui-tab-head>.layui-tab-more li.layui-this:after,.layui-tab-brief>.layui-tab-head>.layui-tab-title .layui-this:after{border:none;border-radius:0}.layui-tab-brief>.layui-tab-head.is-right>.layui-tab-title{border-left:1px solid var(--global-neutral-color-3)}.layui-tab-brief>.layui-tab-head.is-left>.layui-tab-title{border-right:1px solid var(--global-neutral-color-3)}.layui-tab-brief[overflow]>.layui-tab-head>.layui-tab-title .layui-this:after{top:-1px}.layui-tab-brief>.layui-tab-head.is-right>.layui-tab-title li,.layui-tab-brief>.layui-tab-head.is-left>.layui-tab-title li{margin-right:0}.layui-tab-brief>.layui-tab-head.is-top>.layui-tab-title li,.layui-tab-brief>.layui-tab-head.is-top>.layui-tab-title li{margin-top:0;margin-bottom:0}.layui-tab-card{border-width:1px;border-style:solid;border-radius:2px;box-shadow:0 2px 5px #0000001a}.layui-tab-card>.layui-tab-head>.layui-tab-title.is-top{margin-top:-1px;margin-left:-1px}.layui-tab-card>.layui-tab-head>.layui-tab-title.is-right,.layui-tab-card>.layui-tab-head>.layui-tab-title.is-left{margin-right:-1px;margin-left:-1px}.layui-tab-card>.layui-tab-head>.layui-tab-title.is-bottom li{margin-top:-1px}.layui-tab-card>.layui-tab-head>.layui-tab-title .layui-this:after{border-radius:0}.layui-tab-card>.layui-tab-head>.layui-tab-title.is-bottom{border-top:1px solid var(--global-neutral-color-3);margin-bottom:-2px;margin-left:-1px}.layui-tab-card>.layui-tab-head>.layui-tab-title.is-left li,.layui-tab-card>.layui-tab-head>.layui-tab-title.is-right li{margin-top:-1px;margin-bottom:-1px}.layui-tab-card>.layui-tab-head>.layui-tab-title.is-top .layui-this:after{border:1px solid var(--global-neutral-color-3);border-bottom-color:#fff}.layui-tab-card>.layui-tab-head>.layui-tab-title.is-bottom .layui-this:after{border:1
const _hoisted_1 = ["onClick"];
const _hoisted_2 = ["onClick"];
const _hoisted_3 = { class: "layui-tab-content" };
const __default__ = {
name: "LayTab"
};
const _sfc_main = defineComponent({
...__default__,
props: {
type: null,
modelValue: null,
allowClose: { type: Boolean },
tabPosition: { default: "top" },
beforeClose: null,
beforeLeave: null,
activeBarTransition: { type: Boolean }
},
emits: ["update:modelValue", "change", "close"],
setup(__props, { emit }) {
const props = __props;
const slot = useSlots();
const tabMap = reactive(/* @__PURE__ */ new Map());
2022-12-12 01:08:28 +00:00
const childrens = ref([]);
2022-11-14 03:59:26 +00:00
const setItemInstanceBySlot = function(nodes) {
nodes == null ? void 0 : nodes.map((item) => {
2022-12-12 01:08:28 +00:00
if (isArrayChildren(item, item.children)) {
2022-11-14 03:59:26 +00:00
setItemInstanceBySlot(item.children);
} else {
2022-12-12 01:08:28 +00:00
if (item.type.name == _sfc_main$1.name) {
2022-11-14 03:59:26 +00:00
childrens.value.push(item);
}
}
});
};
const active = computed({
get() {
return props.modelValue;
},
set(val) {
emit("update:modelValue", val);
}
});
const tabItems = computed(() => {
const tabData = [];
childrens.value.forEach((item) => {
var _a;
const tab = tabMap.get((_a = item.props) == null ? void 0 : _a.id);
if (tab)
tabData.push(tab);
});
return tabData;
});
const addItem = (id, data) => {
tabMap.set(id, data);
};
const removeItem = (id) => {
tabMap.delete(id);
};
provide(TabInjectKey, reactive({
active,
addItem,
removeItem
}));
const change = function(id) {
if (props.beforeLeave && props.beforeLeave(id) === false) {
return;
}
emit("update:modelValue", id);
emit("change", id);
};
const close = function(index2, id) {
if (props.beforeClose && props.beforeClose(id) === false) {
return;
}
childrens.value.splice(index2, 1);
if (active.value === id) {
const nextChildren = childrens.value[index2 === childrens.value.length ? 0 : index2];
change(nextChildren && nextChildren.props ? nextChildren.props.id : "");
}
emit("close", id);
};
const activeBarRef = shallowRef(void 0);
const activeEl = shallowRef(void 0);
const tabBarStyle = ref();
const getBarStyle = () => {
let offset = 0;
let tabSize = 0;
const sizeName2 = props.tabPosition === "top" || props.tabPosition === "bottom" ? "width" : "height";
const axis = sizeName2 === "width" ? "X" : "Y";
const position = axis === "X" ? "left" : "top";
const el = activeEl.value;
const activeElParentElement = navRef.value;
if (!el || !activeElParentElement)
return;
const rect = el == null ? void 0 : el.getBoundingClientRect();
const parentRect = activeElParentElement == null ? void 0 : activeElParentElement.getBoundingClientRect();
offset = rect[position] - parentRect[position];
tabSize = el.getBoundingClientRect()[sizeName2];
return {
[sizeName2]: `${tabSize}px`,
transform: `translate${axis}(${offset}px)`,
transition: props.activeBarTransition ? `transform .3s` : ""
};
};
const navRef = shallowRef(void 0);
const scrollable = ref(false);
const navOffset = ref(0);
const navStyle = computed(() => {
var _a, _b;
const axis = props.tabPosition === "top" || props.tabPosition === "bottom" ? "X" : "Y";
const position = axis === "X" ? "left" : "top";
const scrollPrevSize = (_b = (_a = scrollPrevRef.value) == null ? void 0 : _a[`offset${sizeName.value}`]) != null ? _b : 0;
return {
transform: `translate${axis}(-${navOffset.value}px)`,
[position]: scrollable.value ? `${scrollPrevSize}px` : 0
};
});
const sizeName = computed(() => {
return props.tabPosition === "top" || props.tabPosition === "bottom" ? "Width" : "Height";
});
const getNavSize = function() {
var _a;
let size = 0;
const nodeList = (_a = navRef.value) == null ? void 0 : _a.querySelectorAll("li");
nodeList == null ? void 0 : nodeList.forEach((item) => {
size += item[`offset${sizeName.value}`];
});
return size;
};
const scrollPrev = function() {
if (!navRef.value)
return;
const containerSize = navRef.value[`offset${sizeName.value}`];
const currentOffset = navOffset.value;
if (!currentOffset)
return;
let newOffset = currentOffset > containerSize ? currentOffset - containerSize : 0;
navOffset.value = newOffset;
};
const scrollNextRef = shallowRef(void 0);
const scrollPrevRef = shallowRef(void 0);
const scrollNext = function() {
var _a, _b, _c, _d;
if (!navRef.value)
return;
const navSize = getNavSize();
const containerSize = navRef.value[`offset${sizeName.value}`];
const currentOffset = navOffset.value;
const scrollNextSize = (_b = (_a = scrollNextRef.value) == null ? void 0 : _a[`offset${sizeName.value}`]) != null ? _b : 0;
const scrollPrevSize = (_d = (_c = scrollPrevRef.value) == null ? void 0 : _c[`offset${sizeName.value}`]) != null ? _d : 0;
if (navSize - currentOffset <= containerSize)
return;
let newOffset = navSize - currentOffset > containerSize * 2 ? currentOffset + containerSize : navSize - containerSize + scrollNextSize + scrollPrevSize;
navOffset.value = newOffset;
};
const headRef = shallowRef(void 0);
const scrollToActiveTab = function() {
var _a, _b, _c, _d;
if (!scrollable.value)
return;
const activeTab = activeEl.value;
const container = headRef.value;
if (!activeTab || !container)
return;
const activeTabRect = activeTab == null ? void 0 : activeTab.getBoundingClientRect();
const containerRect = container == null ? void 0 : container.getBoundingClientRect();
const isHorizontal = ["top", "bottom"].includes(props.tabPosition);
const currentOffset = navOffset.value;
let newOffset = currentOffset;
const navSize = getNavSize();
const scrollNextSize = (_b = (_a = scrollNextRef.value) == null ? void 0 : _a[`offset${sizeName.value}`]) != null ? _b : 0;
const scrollPrevSize = (_d = (_c = scrollPrevRef.value) == null ? void 0 : _c[`offset${sizeName.value}`]) != null ? _d : 0;
const maxOffset = isHorizontal ? navSize - containerRect.width + scrollNextSize + scrollPrevSize : navSize - containerRect.height + scrollNextSize + scrollPrevSize;
if (isHorizontal) {
if (activeTabRect.left < containerRect.left) {
newOffset = currentOffset - (containerRect.left - activeTabRect.left);
newOffset -= scrollPrevSize;
}
if (activeTabRect.right > containerRect.right) {
newOffset = currentOffset + activeTabRect.right - containerRect.right;
newOffset += scrollNextSize;
}
} else {
if (activeTabRect.top < containerRect.top) {
newOffset = currentOffset - (containerRect.top - activeTabRect.top);
}
if (activeTabRect.bottom > containerRect.bottom) {
newOffset = currentOffset + (activeTabRect.bottom - containerRect.bottom);
}
}
newOffset = Math.max(newOffset, 0);
navOffset.value = Math.min(newOffset, maxOffset);
};
const update = () => {
var _a, _b, _c, _d, _e;
if (!navRef.value)
return;
activeEl.value = (_a = navRef.value) == null ? void 0 : _a.querySelector(".layui-this");
tabBarStyle.value = getBarStyle();
if (props.tabPosition !== "top" && props.tabPosition !== "bottom")
return;
const navSize = getNavSize();
const containerSize = navRef.value[`offset${sizeName.value}`];
const currentOffset = navOffset.value;
const scrollNextSize = (_c = (_b = scrollNextRef.value) == null ? void 0 : _b[`offset${sizeName.value}`]) != null ? _c : 0;
const scrollPrevSize = (_e = (_d = scrollPrevRef.value) == null ? void 0 : _d[`offset${sizeName.value}`]) != null ? _e : 0;
if (containerSize < navSize) {
const currentOffset2 = navOffset.value;
scrollable.value = true;
if (navSize - currentOffset2 < containerSize) {
navOffset.value = navSize - containerSize + scrollNextSize + scrollPrevSize;
}
scrollToActiveTab();
} else {
scrollable.value = false;
if (currentOffset > 0) {
navOffset.value = 0;
}
}
};
2022-12-12 01:08:28 +00:00
const horizontalScroll = (e) => {
var _a, _b;
e.preventDefault();
const navSize = getNavSize();
const containerSize = navRef.value[`offset${sizeName.value}`];
const currentOffset = navOffset.value;
const scrollNextSize = (_b = (_a = scrollNextRef.value) == null ? void 0 : _a[`offset${sizeName.value}`]) != null ? _b : 0;
const direction = Math.abs(e.deltaX) >= Math.abs(e.deltaY) ? e.deltaX : e.deltaY;
const distance = 50 * (direction > 0 ? 1 : -1);
const newOffset = Math.max(currentOffset + distance, 0);
if (navSize - currentOffset <= containerSize - scrollNextSize && direction > 0)
return;
navOffset.value = newOffset;
};
2022-11-14 03:59:26 +00:00
const renderTabIcon = (attrs) => {
const tab = attrs.tabData;
if (typeof tab.icon === "function") {
return tab.icon();
} else if (typeof tab.icon === "string") {
return h(_sfc_main$2E, {
type: tab.icon,
style: "margin-right: 8px;"
});
}
};
const renderTabTitle = (attrs) => {
var _a, _b;
const tab = attrs.tabData;
if ((_a = tab.slots) == null ? void 0 : _a.title) {
return h(Fragment, ((_b = tab.slots) == null ? void 0 : _b.title) && tab.slots.title());
}
if (typeof tab.title === "function") {
return tab.title();
} else if (typeof tab.title === "string") {
return createTextVNode(tab.title);
}
};
useResizeObserver(navRef, update);
2022-12-12 01:08:28 +00:00
watch(tabMap, () => {
2022-11-14 03:59:26 +00:00
childrens.value = [];
setItemInstanceBySlot(slot.default && slot.default());
}, { immediate: true });
watch(() => [
props.modelValue,
props.tabPosition,
props.type,
childrens.value.length
], async () => {
await nextTick();
update();
});
onMounted(() => {
update();
scrollToActiveTab();
});
provide("active", active);
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
class: normalizeClass(["layui-tab", [
__props.type ? "layui-tab-" + __props.type : "",
props.tabPosition ? `is-${__props.tabPosition}` : ""
]])
}, [
createElementVNode("div", {
ref_key: "headRef",
ref: headRef,
class: normalizeClass(["layui-tab-head", props.tabPosition ? `is-${__props.tabPosition}` : ""])
}, [
createElementVNode("ul", {
ref_key: "navRef",
ref: navRef,
2022-12-12 01:08:28 +00:00
onWheel: horizontalScroll,
2022-11-14 03:59:26 +00:00
class: normalizeClass([
"layui-tab-title",
props.tabPosition ? `is-${__props.tabPosition}` : ""
]),
style: normalizeStyle(unref(navStyle))
}, [
__props.type === "brief" ? (openBlock(), createElementBlock("div", {
key: 0,
ref_key: "activeBarRef",
ref: activeBarRef,
class: "layui-tab-active-bar",
style: normalizeStyle(tabBarStyle.value)
}, null, 4)) : createCommentVNode("", true),
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(tabItems), (child, index2) => {
return openBlock(), createElementBlock("li", {
key: child.id,
class: normalizeClass([child.id === unref(active) ? "layui-this" : ""]),
onClick: withModifiers(($event) => change(child.id), ["stop"])
}, [
createElementVNode("span", null, [
child["icon"] ? (openBlock(), createBlock(unref(RenderFunction), {
key: 0,
renderFunc: renderTabIcon,
tabData: child
}, null, 8, ["tabData"])) : createCommentVNode("", true),
createVNode(unref(RenderFunction), {
renderFunc: renderTabTitle,
tabData: child
}, null, 8, ["tabData"])
]),
__props.allowClose && child.closable != false ? (openBlock(), createElementBlock("i", {
key: 0,
class: "layui-icon layui-icon-close layui-unselect layui-tab-close",
onClick: withModifiers(($event) => close(index2, child.id), ["stop"])
}, null, 8, _hoisted_2)) : createCommentVNode("", true)
], 10, _hoisted_1);
}), 128))
2022-12-12 01:08:28 +00:00
], 38),
2022-11-14 03:59:26 +00:00
scrollable.value ? (openBlock(), createElementBlock("span", {
key: 0,
ref_key: "scrollPrevRef",
ref: scrollPrevRef,
class: "layui-unselect layui-tab-bar prev",
onClick: scrollPrev
}, [
createVNode(unref(_sfc_main$2E), { type: "layui-icon-left" })
], 512)) : createCommentVNode("", true),
scrollable.value ? (openBlock(), createElementBlock("span", {
key: 1,
ref_key: "scrollNextRef",
ref: scrollNextRef,
class: "layui-unselect layui-tab-bar",
onClick: scrollNext
}, [
createVNode(unref(_sfc_main$2E), { type: "layui-icon-right" })
], 512)) : createCommentVNode("", true)
], 2),
createElementVNode("div", _hoisted_3, [
renderSlot(_ctx.$slots, "default")
])
], 2);
};
}
});
const component = withInstall(_sfc_main);
export { component as default };