UNPKG

element-plus

Version:

A Component Library for Vue 3

1 lines 10.4 kB
{"version":3,"file":"tabs.mjs","sources":["../../../../../../packages/components/tabs/src/tabs.ts"],"sourcesContent":["import {\n defineComponent,\n Fragment,\n getCurrentInstance,\n h,\n nextTick,\n onMounted,\n onUpdated,\n provide,\n ref,\n watch,\n} from 'vue'\nimport { isPromise } from '@vue/shared'\nimport { EVENT_CODE } from '@element-plus/utils/aria'\nimport ElIcon from '@element-plus/components/icon'\nimport { Plus } from '@element-plus/icons'\nimport TabNav from './tab-nav.vue'\n\nimport type { Component, ComponentInternalInstance, PropType, VNode } from 'vue'\nimport type {\n BeforeLeave,\n IElTabsProps,\n ITabType,\n ITabPosition,\n Pane,\n RootTabs,\n UpdatePaneStateCallback,\n} from './token'\n\nexport default defineComponent({\n name: 'ElTabs',\n components: { TabNav },\n props: {\n type: {\n type: String as PropType<ITabType>,\n default: '',\n },\n activeName: {\n type: String,\n default: '',\n },\n closable: Boolean,\n addable: Boolean,\n modelValue: {\n type: String,\n default: '',\n },\n editable: Boolean,\n tabPosition: {\n type: String as PropType<ITabPosition>,\n default: 'top',\n },\n beforeLeave: {\n type: Function as PropType<BeforeLeave>,\n default: null,\n },\n stretch: Boolean,\n },\n emits: [\n 'tab-click',\n 'edit',\n 'tab-remove',\n 'tab-add',\n 'input',\n 'update:modelValue',\n ],\n setup(props: IElTabsProps, ctx) {\n const nav$ = ref<typeof TabNav>(null)\n const currentName = ref(props.modelValue || props.activeName || '0')\n const panes = ref([])\n const instance = getCurrentInstance()\n const paneStatesMap = {}\n\n provide<RootTabs>('rootTabs', {\n props,\n currentName,\n })\n\n provide<UpdatePaneStateCallback>('updatePaneState', (pane: Pane) => {\n paneStatesMap[pane.uid] = pane\n })\n\n watch(\n () => props.activeName,\n (modelValue) => {\n setCurrentName(modelValue)\n }\n )\n\n watch(\n () => props.modelValue,\n (modelValue) => {\n setCurrentName(modelValue)\n }\n )\n\n watch(currentName, () => {\n nextTick(() => {\n nav$.value &&\n nav$.value.$nextTick(() => {\n nav$.value && nav$.value.scrollToActiveTab()\n })\n })\n setPaneInstances(true)\n })\n\n const getPaneInstanceFromSlot = (\n vnode: VNode,\n paneInstanceList: ComponentInternalInstance[] = []\n ) => {\n Array.from((vnode.children || []) as ArrayLike<VNode>).forEach((node) => {\n let type = node.type\n type = (type as Component).name || type\n if (type === 'ElTabPane' && node.component) {\n paneInstanceList.push(node.component)\n } else if (type === Fragment || type === 'template') {\n getPaneInstanceFromSlot(node, paneInstanceList)\n }\n })\n return paneInstanceList\n }\n\n const setPaneInstances = (isForceUpdate = false) => {\n if (ctx.slots.default) {\n const children = instance.subTree.children\n\n const content = Array.from(children as ArrayLike<VNode>).find(\n ({ props }) => {\n return props.class === 'el-tabs__content'\n }\n )\n\n if (!content) return\n\n const paneInstanceList: Pane[] = getPaneInstanceFromSlot(content).map(\n (paneComponent) => {\n return paneStatesMap[paneComponent.uid]\n }\n )\n const panesChanged = !(\n paneInstanceList.length === panes.value.length &&\n paneInstanceList.every(\n (pane, index) => pane.uid === panes.value[index].uid\n )\n )\n\n if (isForceUpdate || panesChanged) {\n panes.value = paneInstanceList\n }\n } else if (panes.value.length !== 0) {\n panes.value = []\n }\n }\n\n const changeCurrentName = (value) => {\n currentName.value = value\n ctx.emit('input', value)\n ctx.emit('update:modelValue', value)\n }\n\n const setCurrentName = (value) => {\n // should do nothing.\n if (currentName.value === value) return\n\n const beforeLeave = props.beforeLeave\n const before = beforeLeave && beforeLeave(value, currentName.value)\n if (before && isPromise(before)) {\n before.then(\n () => {\n changeCurrentName(value)\n nav$.value.removeFocus?.()\n },\n () => {\n // ignore promise rejection in `before-leave` hook\n }\n )\n } else if (before !== false) {\n changeCurrentName(value)\n }\n }\n\n const handleTabClick = (tab, tabName, event) => {\n if (tab.props.disabled) return\n setCurrentName(tabName)\n ctx.emit('tab-click', tab, event)\n }\n\n const handleTabRemove = (pane, ev) => {\n if (pane.props.disabled) return\n ev.stopPropagation()\n ctx.emit('edit', pane.props.name, 'remove')\n ctx.emit('tab-remove', pane.props.name)\n }\n\n const handleTabAdd = () => {\n ctx.emit('edit', null, 'add')\n ctx.emit('tab-add')\n }\n\n onUpdated(() => {\n setPaneInstances()\n })\n\n onMounted(() => {\n setPaneInstances()\n })\n\n return {\n nav$,\n handleTabClick,\n handleTabRemove,\n handleTabAdd,\n currentName,\n panes,\n }\n },\n\n render() {\n const {\n type,\n handleTabClick,\n handleTabRemove,\n handleTabAdd,\n currentName,\n panes,\n editable,\n addable,\n tabPosition,\n stretch,\n } = this\n\n const newButton =\n editable || addable\n ? h(\n 'span',\n {\n class: 'el-tabs__new-tab',\n tabindex: '0',\n onClick: handleTabAdd,\n onKeydown: (ev) => {\n if (ev.code === EVENT_CODE.enter) {\n handleTabAdd()\n }\n },\n },\n [h(ElIcon, { class: 'is-icon-plus' }, { default: () => h(Plus) })]\n )\n : null\n\n const header = h(\n 'div',\n {\n class: ['el-tabs__header', `is-${tabPosition}`],\n },\n [\n newButton,\n h(TabNav, {\n currentName,\n editable,\n type,\n panes,\n stretch,\n ref: 'nav$',\n onTabClick: handleTabClick,\n onTabRemove: handleTabRemove,\n }),\n ]\n )\n\n const panels = h(\n 'div',\n {\n class: 'el-tabs__content',\n },\n this.$slots?.default()\n )\n\n return h(\n 'div',\n {\n class: {\n 'el-tabs': true,\n 'el-tabs--card': type === 'card',\n [`el-tabs--${tabPosition}`]: true,\n 'el-tabs--border-card': type === 'border-card',\n },\n },\n tabPosition !== 'bottom' ? [header, panels] : [panels, header]\n )\n },\n})\n"],"names":["TabNav"],"mappings":"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"}