UNPKG

winbox-ui-next

Version:

We Design Vue 2.0: A Vue.js 3 UI Library

172 lines (171 loc) 5.18 kB
import { defineComponent, computed, ref, createVNode } from "vue"; import { getChildrenComponents, getValueFromSlotsOrProps, getBooleanProp } from "../_utils/vue-utils.js"; import { getPrefixCls } from "../_utils/global-config.js"; import TabsNav from "./tabs-nav.js"; import usePickSlots from "../_hooks/use-pick-slots.js"; var _Tabs = defineComponent({ name: "Tabs", props: { activeKey: { type: String, default: void 0 }, defaultActiveKey: { type: String, default: "" }, tabPosition: { type: String, default: "top" }, size: { type: String, default: "default" }, type: { type: String, default: "line" }, direction: { type: String, default: "horizontal" }, editable: { type: Boolean, default: false }, showAddButton: { type: Boolean, default: false }, destroyOnHide: { type: Boolean, default: false }, lazyLoad: { type: Boolean, default: false }, justify: { type: Boolean, default: false }, animation: { type: Boolean, default: false }, headerPadding: { type: Boolean, default: true } }, emits: [ "update:activeKey", "change", "tabClick", "add", "delete" ], setup(props, { emit, slots }) { const prefixCls = getPrefixCls("tabs"); const mergedPosition = computed(() => props.direction === "vertical" ? "left" : props.tabPosition); const mergedDirection = computed(() => ["left", "right"].includes(mergedPosition.value) ? "vertical" : "horizontal"); const defaultSlot = usePickSlots(slots, "default"); const children = computed(() => { var _a, _b; return getChildrenComponents((_b = (_a = defaultSlot.value) == null ? void 0 : _a.call(defaultSlot)) != null ? _b : [], "TabPane"); }); const tabs = computed(() => children.value.map((vn) => { var _a, _b; return { title: getValueFromSlotsOrProps("title", vn.props, vn.children), key: String(vn.key), disabled: getBooleanProp((_a = vn.props) == null ? void 0 : _a.disabled), closable: ((_b = vn.props) == null ? void 0 : _b.closable) !== false }; })); const tabKeys = computed(() => tabs.value.map((item) => item.key)); const _activeTab = ref(props.defaultActiveKey); const computedActiveTab = computed(() => { var _a; const activeKey = (_a = props.activeKey) != null ? _a : _activeTab.value; if (tabKeys.value.includes(activeKey)) { return activeKey; } return tabKeys.value[0]; }); const activeIndex = computed(() => tabKeys.value.indexOf(computedActiveTab.value)); const loadedTabs = new Set([computedActiveTab.value]); const handleClick = (key, e) => { if (key !== computedActiveTab.value) { _activeTab.value = key; loadedTabs.add(key); emit("update:activeKey", key); emit("change", key); } emit("tabClick", key, e); }; const getIsRender = (isActive, key) => { if (isActive) { return true; } if (props.lazyLoad) { return loadedTabs.has(key); } return !props.destroyOnHide; }; const handleAdd = () => { emit("add"); }; const renderContent = () => { const list = children.value.map((vn, index) => { const key = String(vn.key); const isActive = index === activeIndex.value; return createVNode("div", { "key": key, "class": [`${prefixCls}-content-item`, { [`${prefixCls}-content-item-active`]: isActive }] }, [getIsRender(isActive, key) && vn]); }); return createVNode("div", { "class": `${prefixCls}-content` }, [createVNode("div", { "class": [`${prefixCls}-content-list`, { [`${prefixCls}-content-animation`]: props.animation }], "style": { marginLeft: `-${activeIndex.value * 100}%` } }, [list])]); }; const cls = computed(() => [prefixCls, `${prefixCls}-${mergedDirection.value}`, `${prefixCls}-${mergedPosition.value}`, `${prefixCls}-type-${props.type}`, `${prefixCls}-size-${props.size}`, { [`${prefixCls}-justify`]: props.justify }]); return () => createVNode("div", { "class": cls.value }, [mergedPosition.value === "bottom" && renderContent(), createVNode(TabsNav, { "tabs": tabs.value, "tabKeys": tabKeys.value, "activeTab": computedActiveTab.value, "activeIndex": activeIndex.value, "direction": mergedDirection.value, "tabPosition": mergedPosition.value, "editable": props.editable, "animation": props.animation, "showAddButton": props.showAddButton, "headerPadding": props.headerPadding, "size": props.size, "type": props.type, "onClick": handleClick, "onAdd": handleAdd, "onDelete": (key) => emit("delete", key) }, { extra: slots.extra }), mergedPosition.value !== "bottom" && renderContent()]); } }); export { _Tabs as default };