{"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":";;;;;;;;AA6BA,WAAe,gBAAgB;AAAA,EAC7B,MAAM;AAAA,EACN,YAAY,UAAEA;AAAA,EACd,OAAO;AAAA,IACL,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,SAAS;AAAA;AAAA,IAEX,YAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA;AAAA,IAEX,UAAU;AAAA,IACV,SAAS;AAAA,IACT,YAAY;AAAA,MACV,MAAM;AAAA,MACN,SAAS;AAAA;AAAA,IAEX,UAAU;AAAA,IACV,aAAa;AAAA,MACX,MAAM;AAAA,MACN,SAAS;AAAA;AAAA,IAEX,aAAa;AAAA,MACX,MAAM;AAAA,MACN,SAAS;AAAA;AAAA,IAEX,SAAS;AAAA;AAAA,EAEX,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,EAEF,MAAM,OAAqB,KAAK;AAC9B,UAAM,OAAO,IAAmB;AAChC,UAAM,cAAc,IAAI,MAAM,cAAc,MAAM,cAAc;AAChE,UAAM,QAAQ,IAAI;AAClB,UAAM,WAAW;AACjB,UAAM,gBAAgB;AAEtB,YAAkB,YAAY;AAAA,MAC5B;AAAA,MACA;AAAA;AAGF,YAAiC,mBAAmB,CAAC,SAAe;AAClE,oBAAc,KAAK,OAAO;AAAA;AAG5B,UACE,MAAM,MAAM,YACZ,CAAC,eAAe;AACd,qBAAe;AAAA;AAInB,UACE,MAAM,MAAM,YACZ,CAAC,eAAe;AACd,qBAAe;AAAA;AAInB,UAAM,aAAa,MAAM;AACvB,eAAS,MAAM;AACb,aAAK,SACH,KAAK,MAAM,UAAU,MAAM;AACzB,eAAK,SAAS,KAAK,MAAM;AAAA;AAAA;AAG/B,uBAAiB;AAAA;AAGnB,UAAM,0BAA0B,CAC9B,OACA,mBAAgD,OAC7C;AACH,YAAM,KAAM,MAAM,YAAY,IAAyB,QAAQ,CAAC,SAAS;AACvE,YAAI,OAAO,KAAK;AAChB,eAAQ,KAAmB,QAAQ;AACnC,YAAI,SAAS,eAAe,KAAK,WAAW;AAC1C,2BAAiB,KAAK,KAAK;AAAA,mBAClB,SAAS,YAAY,SAAS,YAAY;AACnD,kCAAwB,MAAM;AAAA;AAAA;AAGlC,aAAO;AAAA;AAGT,UAAM,mBAAmB,CAAC,gBAAgB,UAAU;AAClD,UAAI,IAAI,MAAM,SAAS;AACrB,cAAM,WAAW,SAAS,QAAQ;AAElC,cAAM,UAAU,MAAM,KAAK,UAA8B,KACvD,CAAC,EAAE,oBAAY;AACb,iBAAO,OAAM,UAAU;AAAA;AAI3B,YAAI,CAAC;AAAS;AAEd,cAAM,mBAA2B,wBAAwB,SAAS,IAChE,CAAC,kBAAkB;AACjB,iBAAO,cAAc,cAAc;AAAA;AAGvC,cAAM,eAAe,mBACF,WAAW,MAAM,MAAM,UACxC,iBAAiB,MACf,CAAC,MAAM,UAAU,KAAK,QAAQ,MAAM,MAAM,OAAO;AAIrD,YAAI,iBAAiB,cAAc;AACjC,gBAAM,QAAQ;AAAA;AAAA,iBAEP,MAAM,MAAM,WAAW,GAAG;AACnC,cAAM,QAAQ;AAAA;AAAA;AAIlB,UAAM,oBAAoB,CAAC,UAAU;AACnC,kBAAY,QAAQ;AACpB,UAAI,KAAK,SAAS;AAClB,UAAI,KAAK,qBAAqB;AAAA;AAGhC,UAAM,iBAAiB,CAAC,UAAU;AAEhC,UAAI,YAAY,UAAU;AAAO;AAEjC,YAAM,cAAc,MAAM;AAC1B,YAAM,SAAS,eAAe,YAAY,OAAO,YAAY;AAC7D,UAAI,UAAU,UAAU,SAAS;AAC/B,eAAO,KACL,MAAM;AAxKhB;AAyKY,4BAAkB;AAClB,2BAAK,OAAM,gBAAX;AAAA,WAEF,MAAM;AAAA;AAAA,iBAIC,WAAW,OAAO;AAC3B,0BAAkB;AAAA;AAAA;AAItB,UAAM,iBAAiB,CAAC,KAAK,SAAS,UAAU;AAC9C,UAAI,IAAI,MAAM;AAAU;AACxB,qBAAe;AACf,UAAI,KAAK,aAAa,KAAK;AAAA;AAG7B,UAAM,kBAAkB,CAAC,MAAM,OAAO;AACpC,UAAI,KAAK,MAAM;AAAU;AACzB,SAAG;AACH,UAAI,KAAK,QAAQ,KAAK,MAAM,MAAM;AAClC,UAAI,KAAK,cAAc,KAAK,MAAM;AAAA;AAGpC,UAAM,eAAe,MAAM;AACzB,UAAI,KAAK,QAAQ,MAAM;AACvB,UAAI,KAAK;AAAA;AAGX,cAAU,MAAM;AACd;AAAA;AAGF,cAAU,MAAM;AACd;AAAA;AAGF,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA,EAIJ,SAAS;AAzNX;AA0NI,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE;AAEJ,UAAM,YACJ,YAAY,UACR,EACE,QACA;AAAA,MACE,OAAO;AAAA,MACP,UAAU;AAAA,MACV,SAAS;AAAA,MACT,WAAW,CAAC,OAAO;AACjB,YAAI,GAAG,SAAS,WAAW,OAAO;AAChC;AAAA;AAAA;AAAA,OAIN,CAAC,EAAE,QAAQ,EAAE,OAAO,kBAAkB,EAAE,SAAS,MAAM,EAAE,aAE3D;AAEN,UAAM,SAAS,EACb,OACA;AAAA,MACE,OAAO,CAAC,mBAAmB,MAAM;AAAA,OAEnC;AAAA,MACE;AAAA,MACA,EAAEA,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK;AAAA,QACL,YAAY;AAAA,QACZ,aAAa;AAAA;AAAA;AAKnB,UAAM,SAAS,EACb,OACA;AAAA,MACE,OAAO;AAAA,OAET,WAAK,WAAL,mBAAa;AAGf,WAAO,EACL,OACA;AAAA,MACE,OAAO;AAAA,QACL,WAAW;AAAA,QACX,iBAAiB,SAAS;AAAA,SACzB,YAAY,gBAAgB;AAAA,QAC7B,wBAAwB,SAAS;AAAA;AAAA,OAGrC,gBAAgB,WAAW,CAAC,QAAQ,UAAU,CAAC,QAAQ;AAAA;AAAA;;;;"}