{"version":3,"file":"tabs.mjs","names":["computed","createVNode","defineComponent","getCurrentInstance","nextTick","provide","ref","renderSlot","watch","_createVNode","omit","buildProps","definePropType","getEventCode","isNumber","isString","isUndefined","EVENT_CODE","UPDATE_MODEL_EVENT","ElIcon","Plus","useNamespace","useOrderedChildren","tabsRootContextKey","TabNav","tabsProps","type","String","values","default","closable","Boolean","addable","modelValue","Number","defaultValue","editable","tabPosition","beforeLeave","Function","stretch","tabindex","isPaneName","value","tabsEmits","name","tabClick","pane","ev","Event","tabChange","edit","paneName","action","includes","tabRemove","tabAdd","Tabs","props","emits","setup","emit","slots","expose","ns","isVertical","children","panes","addChild","registerPane","removeChild","unregisterPane","ChildrenSorter","PanesSorter","nav$","currentName","setCurrentName","trigger","canLeave","result","Promise","isFocusInsidePane","find","item","removeFocus","focusActiveTab","handleTabClick","tab","tabName","event","disabled","handleTabRemove","stopPropagation","handleTabAdd","undefined","handleKeydown","code","enter","numpadEnter","swapChildren","vnode","actualFirstChild","el","firstChild","before","scrollToActiveTab","tabNavRef","addSlot","newButton","e","is","tabNav","header","$stable","panels","b","m"],"sources":["../../../../../../packages/components/tabs/src/tabs.tsx"],"sourcesContent":["import {\n  computed,\n  createVNode,\n  defineComponent,\n  getCurrentInstance,\n  nextTick,\n  provide,\n  ref,\n  renderSlot,\n  watch,\n} from 'vue'\nimport { omit } from 'lodash-unified'\nimport {\n  buildProps,\n  definePropType,\n  getEventCode,\n  isNumber,\n  isString,\n  isUndefined,\n} from '@element-plus/utils'\nimport { EVENT_CODE, UPDATE_MODEL_EVENT } from '@element-plus/constants'\nimport ElIcon from '@element-plus/components/icon'\nimport { Plus } from '@element-plus/icons-vue'\nimport { useNamespace, useOrderedChildren } from '@element-plus/hooks'\nimport { tabsRootContextKey } from './constants'\nimport TabNav from './tab-nav'\n\nimport type { ExtractPropTypes, ExtractPublicPropTypes, VNode } from 'vue'\nimport type { Awaitable } from '@element-plus/utils'\nimport type { TabNavInstance } from './tab-nav'\nimport type { TabPaneName, TabsPaneContext } from './constants'\n\nexport const tabsProps = buildProps({\n  /**\n   * @description type of Tab\n   */\n  type: {\n    type: String,\n    values: ['card', 'border-card', ''],\n    default: '',\n  },\n  /**\n   * @description whether Tab is closable\n   */\n  closable: Boolean,\n  /**\n   * @description whether Tab is addable\n   */\n  addable: Boolean,\n  /**\n   * @description binding value, name of the selected tab\n   */\n  modelValue: {\n    type: [String, Number],\n  },\n  /**\n   * @description initial value when `model-value` is not set\n   */\n  defaultValue: {\n    type: [String, Number],\n  },\n  /**\n   * @description whether Tab is addable and closable\n   */\n  editable: Boolean,\n  /**\n   * @description position of tabs\n   */\n  tabPosition: {\n    type: String,\n    values: ['top', 'right', 'bottom', 'left'],\n    default: 'top',\n  },\n  /**\n   * @description hook function before switching tab. If `false` is returned or a `Promise` is returned and then is rejected, switching will be prevented\n   */\n  beforeLeave: {\n    type: definePropType<\n      (newName: TabPaneName, oldName: TabPaneName) => Awaitable<void | boolean>\n    >(Function),\n    default: () => true,\n  },\n  /**\n   * @description whether width of tab automatically fits its container\n   */\n  stretch: Boolean,\n  /**\n   * @description tabs tabindex\n   */\n  tabindex: {\n    type: [String, Number],\n    default: 0,\n  },\n} as const)\nexport type TabsProps = ExtractPropTypes<typeof tabsProps>\nexport type TabsPropsPublic = ExtractPublicPropTypes<typeof tabsProps>\n\nconst isPaneName = (value: unknown): value is string | number =>\n  isString(value) || isNumber(value)\n\nexport const tabsEmits = {\n  [UPDATE_MODEL_EVENT]: (name: TabPaneName) => isPaneName(name),\n  tabClick: (pane: TabsPaneContext, ev: Event) => ev instanceof Event,\n  tabChange: (name: TabPaneName) => isPaneName(name),\n  edit: (paneName: TabPaneName | undefined, action: 'remove' | 'add') =>\n    ['remove', 'add'].includes(action),\n  tabRemove: (name: TabPaneName) => isPaneName(name),\n  tabAdd: () => true,\n}\nexport type TabsEmits = typeof tabsEmits\n\nexport type TabsPanes = Record<number, TabsPaneContext>\n\nconst Tabs = defineComponent({\n  name: 'ElTabs',\n\n  props: tabsProps,\n  emits: tabsEmits,\n\n  setup(props, { emit, slots, expose }) {\n    const ns = useNamespace('tabs')\n\n    const isVertical = computed(() =>\n      ['left', 'right'].includes(props.tabPosition)\n    )\n\n    const {\n      children: panes,\n      addChild: registerPane,\n      removeChild: unregisterPane,\n      ChildrenSorter: PanesSorter,\n    } = useOrderedChildren<TabsPaneContext>(getCurrentInstance()!, 'ElTabPane')\n\n    const nav$ = ref<TabNavInstance>()\n    const currentName = ref<TabPaneName>(\n      (isUndefined(props.modelValue) ? props.defaultValue : props.modelValue) ??\n        '0'\n    )\n\n    const setCurrentName = async (value?: TabPaneName, trigger = false) => {\n      // should do nothing.\n      if (currentName.value === value || isUndefined(value)) return\n\n      try {\n        let canLeave\n        if (props.beforeLeave) {\n          const result = props.beforeLeave(value, currentName.value)\n          canLeave = result instanceof Promise ? await result : result\n        } else {\n          canLeave = true\n        }\n\n        if (canLeave !== false) {\n          const isFocusInsidePane = panes.value\n            .find((item) => item.paneName === currentName.value)\n            ?.isFocusInsidePane()\n\n          currentName.value = value\n          if (trigger) {\n            emit(UPDATE_MODEL_EVENT, value)\n            emit('tabChange', value)\n          }\n\n          nav$.value?.removeFocus?.()\n          if (isFocusInsidePane) {\n            nav$.value?.focusActiveTab()\n          }\n        }\n      } catch {}\n    }\n\n    const handleTabClick = (\n      tab: TabsPaneContext,\n      tabName: TabPaneName,\n      event: Event\n    ) => {\n      if (tab.props.disabled) return\n      emit('tabClick', tab, event)\n      setCurrentName(tabName, true)\n    }\n\n    const handleTabRemove = (pane: TabsPaneContext, ev: Event) => {\n      if (pane.props.disabled || isUndefined(pane.props.name)) return\n      ev.stopPropagation()\n      emit('edit', pane.props.name, 'remove')\n      emit('tabRemove', pane.props.name)\n    }\n\n    const handleTabAdd = () => {\n      emit('edit', undefined, 'add')\n      emit('tabAdd')\n    }\n\n    const handleKeydown = (event: KeyboardEvent) => {\n      const code = getEventCode(event)\n      if ([EVENT_CODE.enter, EVENT_CODE.numpadEnter].includes(code))\n        handleTabAdd()\n    }\n\n    const swapChildren = (\n      vnode: VNode & {\n        el: HTMLDivElement\n        children: VNode<HTMLDivElement>[]\n      }\n    ) => {\n      const actualFirstChild = vnode.el.firstChild!\n      const firstChild = ['bottom', 'right'].includes(props.tabPosition)\n        ? vnode.children[0].el!\n        : vnode.children[1].el!\n\n      if (actualFirstChild !== firstChild) {\n        actualFirstChild.before(firstChild)\n      }\n    }\n\n    watch(\n      () => props.modelValue,\n      (modelValue) => setCurrentName(modelValue)\n    )\n\n    watch(currentName, async () => {\n      await nextTick()\n      nav$.value?.scrollToActiveTab()\n    })\n\n    provide(tabsRootContextKey, {\n      props,\n      currentName,\n      registerPane,\n      unregisterPane,\n      nav$,\n    })\n\n    expose({\n      currentName,\n      get tabNavRef() {\n        return omit(nav$.value, ['scheduleRender'])\n      },\n    })\n\n    return () => {\n      const addSlot = slots['add-icon']\n      const newButton =\n        props.editable || props.addable ? (\n          <div\n            class={[\n              ns.e('new-tab'),\n              isVertical.value && ns.e('new-tab-vertical'),\n            ]}\n            tabindex={props.tabindex}\n            onClick={handleTabAdd}\n            onKeydown={handleKeydown}\n          >\n            {addSlot ? (\n              renderSlot(slots, 'add-icon')\n            ) : (\n              <ElIcon class={ns.is('icon-plus')}>\n                <Plus />\n              </ElIcon>\n            )}\n          </div>\n        ) : null\n\n      const tabNav = () => (\n        <TabNav\n          ref={nav$}\n          currentName={currentName.value}\n          editable={props.editable}\n          type={props.type}\n          panes={panes.value}\n          stretch={props.stretch}\n          onTabClick={handleTabClick}\n          onTabRemove={handleTabRemove}\n        />\n      )\n\n      const header = (\n        <div\n          class={[\n            ns.e('header'),\n            isVertical.value && ns.e('header-vertical'),\n            ns.is(props.tabPosition),\n          ]}\n        >\n          {createVNode(PanesSorter, null, {\n            default: tabNav,\n            $stable: true,\n          })}\n          {newButton}\n        </div>\n      )\n\n      const panels = (\n        <div class={ns.e('content')}>{renderSlot(slots, 'default')}</div>\n      )\n\n      return (\n        <div\n          class={[\n            ns.b(),\n            ns.m(props.tabPosition),\n            {\n              [ns.m('card')]: props.type === 'card',\n              [ns.m('border-card')]: props.type === 'border-card',\n            },\n          ]}\n          // @ts-ignore\n          onVnodeMounted={swapChildren}\n          onVnodeUpdated={swapChildren}\n        >\n          {panels}\n          {header}\n        </div>\n      )\n    }\n  },\n})\n\nexport type TabsInstance = InstanceType<typeof Tabs> & {\n  currentName: TabPaneName\n  tabNavRef: TabNavInstance | undefined\n}\n\nexport default Tabs\n"],"mappings":"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"}