@arco-design/web-vue
Version:
Arco Design Vue 2.0: A Vue.js 3 UI Library
215 lines (214 loc) • 5.82 kB
JavaScript
import { defineComponent, toRefs, computed, reactive, ref, provide, createVNode, nextTick } from "vue";
import { getPrefixCls } from "../_utils/global-config.js";
import TabsNav from "./tabs-nav.js";
import { tabsInjectionKey } from "./context.js";
import { isUndefined } from "../_utils/is.js";
import { useSize } from "../_hooks/use-size.js";
import { useChildrenComponents } from "../_hooks/use-children-components.js";
var _Tabs = defineComponent({
name: "Tabs",
props: {
activeKey: {
type: [String, Number],
default: void 0
},
defaultActiveKey: {
type: [String, Number],
default: void 0
},
position: {
type: String,
default: "top"
},
size: {
type: String
},
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
},
autoSwitch: {
type: Boolean,
default: false
},
hideContent: {
type: Boolean,
default: false
},
trigger: {
type: String,
default: "click"
},
scrollPosition: {
type: [String, Number],
default: "auto"
}
},
emits: {
"update:activeKey": (key) => true,
"change": (key) => true,
"tabClick": (key, ev) => true,
"add": (ev) => true,
"delete": (key, ev) => true
},
setup(props, {
emit,
slots
}) {
const {
size,
lazyLoad,
destroyOnHide,
trigger
} = toRefs(props);
const prefixCls = getPrefixCls("tabs");
const {
mergedSize
} = useSize(size);
const mergedPosition = computed(() => props.direction === "vertical" ? "left" : props.position);
const mergedDirection = computed(() => ["left", "right"].includes(mergedPosition.value) ? "vertical" : "horizontal");
const {
children,
components
} = useChildrenComponents("TabPane");
const tabMap = reactive(/* @__PURE__ */ new Map());
const sortedTabs = computed(() => {
const tabData = [];
components.value.forEach((id) => {
const tab = tabMap.get(id);
if (tab)
tabData.push(tab);
});
return tabData;
});
const tabKeys = computed(() => sortedTabs.value.map((item) => item.key));
const addItem = (id, data) => {
tabMap.set(id, data);
};
const removeItem = (id) => {
tabMap.delete(id);
};
const _activeKey = ref(props.defaultActiveKey);
const computedActiveKey = computed(() => {
var _a;
const activeKey = (_a = props.activeKey) != null ? _a : _activeKey.value;
if (isUndefined(activeKey)) {
return tabKeys.value[0];
}
return activeKey;
});
const activeIndex = computed(() => {
const index = tabKeys.value.indexOf(computedActiveKey.value);
if (index === -1) {
return 0;
}
return index;
});
provide(tabsInjectionKey, reactive({
lazyLoad,
destroyOnHide,
activeKey: computedActiveKey,
addItem,
removeItem,
trigger
}));
const handleChange = (key) => {
if (key !== computedActiveKey.value) {
_activeKey.value = key;
emit("update:activeKey", key);
emit("change", key);
}
};
const handleClick = (key, e) => {
handleChange(key);
emit("tabClick", key, e);
};
const handleAdd = (ev) => {
emit("add", ev);
if (props.autoSwitch) {
nextTick(() => {
const lastKey = tabKeys.value[tabKeys.value.length - 1];
handleChange(lastKey);
});
}
};
const handleDelete = (key, ev) => {
emit("delete", key, ev);
};
const renderContent = () => {
return createVNode("div", {
"class": [`${prefixCls}-content`, {
[`${prefixCls}-content-hide`]: props.hideContent
}]
}, [createVNode("div", {
"class": [`${prefixCls}-content-list`, {
[`${prefixCls}-content-animation`]: props.animation
}],
"style": {
marginLeft: `-${activeIndex.value * 100}%`
}
}, [children.value])]);
};
const cls = computed(() => [prefixCls, `${prefixCls}-${mergedDirection.value}`, `${prefixCls}-${mergedPosition.value}`, `${prefixCls}-type-${props.type}`, `${prefixCls}-size-${mergedSize.value}`, {
[`${prefixCls}-justify`]: props.justify
}]);
return () => {
var _a;
children.value = (_a = slots.default) == null ? void 0 : _a.call(slots);
return createVNode("div", {
"class": cls.value
}, [mergedPosition.value === "bottom" && renderContent(), createVNode(TabsNav, {
"tabs": sortedTabs.value,
"activeKey": computedActiveKey.value,
"activeIndex": activeIndex.value,
"direction": mergedDirection.value,
"position": mergedPosition.value,
"editable": props.editable,
"animation": props.animation,
"showAddButton": props.showAddButton,
"headerPadding": props.headerPadding,
"scrollPosition": props.scrollPosition,
"size": mergedSize.value,
"type": props.type,
"onClick": handleClick,
"onAdd": handleAdd,
"onDelete": handleDelete
}, {
extra: slots.extra
}), mergedPosition.value !== "bottom" && renderContent()]);
};
}
});
export { _Tabs as default };