'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var vue = require('vue');
var shared = require('@vue/shared');
var core = require('@vueuse/core');
var props = require('../../../utils/props.js');
var aria = require('../../../utils/aria.js');
var error = require('../../../utils/error.js');
var index = require('../../icon/index.js');
var icons = require('@element-plus/icons');
require('../../../tokens/index.js');
require('./tab-bar.js');
var tabs = require('../../../tokens/tabs.js');
var tabBar_vue_vue_type_script_lang = require('./tab-bar.vue_vue_type_script_lang.js');

const tabNavProps = props.buildProps({
  panes: {
    type: props.definePropType(Array),
    default: () => props.mutable([])
  },
  currentName: {
    type: String,
    default: ""
  },
  editable: Boolean,
  onTabClick: {
    type: props.definePropType(Function),
    default: shared.NOOP
  },
  onTabRemove: {
    type: props.definePropType(Function),
    default: shared.NOOP
  },
  type: {
    type: String,
    values: ["card", "border-card", ""],
    default: ""
  },
  stretch: Boolean
});
const COMPONENT_NAME = "ElTabNav";
var TabNav = vue.defineComponent({
  name: COMPONENT_NAME,
  props: tabNavProps,
  setup(props, { expose }) {
    const visibility = core.useDocumentVisibility();
    const focused = core.useWindowFocus();
    const rootTabs = vue.inject(tabs.tabsRootContextKey);
    if (!rootTabs)
      error.throwError(COMPONENT_NAME, `ElTabNav must be nested inside ElTabs`);
    const scrollable = vue.ref(false);
    const navOffset = vue.ref(0);
    const isFocus = vue.ref(false);
    const focusable = vue.ref(true);
    const navScroll$ = vue.ref();
    const nav$ = vue.ref();
    const el$ = vue.ref();
    const sizeName = vue.computed(() => ["top", "bottom"].includes(rootTabs.props.tabPosition) ? "width" : "height");
    const navStyle = vue.computed(() => {
      const dir = sizeName.value === "width" ? "X" : "Y";
      return {
        transform: `translate${dir}(-${navOffset.value}px)`
      };
    });
    const scrollPrev = () => {
      if (!navScroll$.value)
        return;
      const containerSize = navScroll$.value[`offset${shared.capitalize(sizeName.value)}`];
      const currentOffset = navOffset.value;
      if (!currentOffset)
        return;
      const newOffset = currentOffset > containerSize ? currentOffset - containerSize : 0;
      navOffset.value = newOffset;
    };
    const scrollNext = () => {
      if (!navScroll$.value || !nav$.value)
        return;
      const navSize = nav$.value[`offset${shared.capitalize(sizeName.value)}`];
      const containerSize = navScroll$.value[`offset${shared.capitalize(sizeName.value)}`];
      const currentOffset = navOffset.value;
      if (navSize - currentOffset <= containerSize)
        return;
      const newOffset = navSize - currentOffset > containerSize * 2 ? currentOffset + containerSize : navSize - containerSize;
      navOffset.value = newOffset;
    };
    const scrollToActiveTab = () => {
      const nav = nav$.value;
      if (!scrollable.value || !el$.value || !navScroll$.value || !nav)
        return;
      const activeTab = el$.value.querySelector(".is-active");
      if (!activeTab)
        return;
      const navScroll = navScroll$.value;
      const isHorizontal = ["top", "bottom"].includes(rootTabs.props.tabPosition);
      const activeTabBounding = activeTab.getBoundingClientRect();
      const navScrollBounding = navScroll.getBoundingClientRect();
      const maxOffset = isHorizontal ? nav.offsetWidth - navScrollBounding.width : nav.offsetHeight - navScrollBounding.height;
      const currentOffset = navOffset.value;
      let newOffset = currentOffset;
      if (isHorizontal) {
        if (activeTabBounding.left < navScrollBounding.left) {
          newOffset = currentOffset - (navScrollBounding.left - activeTabBounding.left);
        }
        if (activeTabBounding.right > navScrollBounding.right) {
          newOffset = currentOffset + activeTabBounding.right - navScrollBounding.right;
        }
      } else {
        if (activeTabBounding.top < navScrollBounding.top) {
          newOffset = currentOffset - (navScrollBounding.top - activeTabBounding.top);
        }
        if (activeTabBounding.bottom > navScrollBounding.bottom) {
          newOffset = currentOffset + (activeTabBounding.bottom - navScrollBounding.bottom);
        }
      }
      newOffset = Math.max(newOffset, 0);
      navOffset.value = Math.min(newOffset, maxOffset);
    };
    const update = () => {
      if (!nav$.value || !navScroll$.value)
        return;
      const navSize = nav$.value[`offset${shared.capitalize(sizeName.value)}`];
      const containerSize = navScroll$.value[`offset${shared.capitalize(sizeName.value)}`];
      const currentOffset = navOffset.value;
      if (containerSize < navSize) {
        const currentOffset2 = navOffset.value;
        scrollable.value = scrollable.value || {};
        scrollable.value.prev = currentOffset2;
        scrollable.value.next = currentOffset2 + containerSize < navSize;
        if (navSize - currentOffset2 < containerSize) {
          navOffset.value = navSize - containerSize;
        }
      } else {
        scrollable.value = false;
        if (currentOffset > 0) {
          navOffset.value = 0;
        }
      }
    };
    const changeTab = (e) => {
      const code = e.code;
      const { up, down, left, right } = aria.EVENT_CODE;
      if (![up, down, left, right].includes(code))
        return;
      const tabList = Array.from(e.currentTarget.querySelectorAll("[role=tab]"));
      const currentIndex = tabList.indexOf(e.target);
      let nextIndex;
      if (code === left || code === up) {
        if (currentIndex === 0) {
          nextIndex = tabList.length - 1;
        } else {
          nextIndex = currentIndex - 1;
        }
      } else {
        if (currentIndex < tabList.length - 1) {
          nextIndex = currentIndex + 1;
        } else {
          nextIndex = 0;
        }
      }
      tabList[nextIndex].focus();
      tabList[nextIndex].click();
      setFocus();
    };
    const setFocus = () => {
      if (focusable.value)
        isFocus.value = true;
    };
    const removeFocus = () => isFocus.value = false;
    vue.watch(visibility, (visibility2) => {
      if (visibility2 === "hidden") {
        focusable.value = false;
      } else if (visibility2 === "visible") {
        setTimeout(() => focusable.value = true, 50);
      }
    });
    vue.watch(focused, (focused2) => {
      if (focused2) {
        setTimeout(() => focusable.value = true, 50);
      } else {
        focusable.value = false;
      }
    });
    core.useResizeObserver(el$, update);
    vue.onMounted(() => setTimeout(() => scrollToActiveTab(), 0));
    vue.onUpdated(() => update());
    expose({
      scrollToActiveTab,
      removeFocus
    });
    return () => {
      const scrollBtn = scrollable.value ? [
        vue.h("span", {
          class: [
            "el-tabs__nav-prev",
            scrollable.value.prev ? "" : "is-disabled"
          ],
          onClick: scrollPrev
        }, [vue.h(index.ElIcon, {}, { default: () => vue.h(icons.ArrowLeft) })]),
        vue.h("span", {
          class: [
            "el-tabs__nav-next",
            scrollable.value.next ? "" : "is-disabled"
          ],
          onClick: scrollNext
        }, [vue.h(index.ElIcon, {}, { default: () => vue.h(icons.ArrowRight) })])
      ] : null;
      const tabs = props.panes.map((pane, index$1) => {
        var _a, _b;
        const tabName = pane.props.name || pane.index || `${index$1}`;
        const closable = pane.isClosable || props.editable;
        pane.index = `${index$1}`;
        const btnClose = closable ? vue.h(index.ElIcon, {
          class: "is-icon-close",
          onClick: (ev) => props.onTabRemove(pane, ev)
        }, { default: () => vue.h(icons.Close) }) : null;
        const tabLabelContent = ((_b = (_a = pane.instance.slots).label) == null ? void 0 : _b.call(_a)) || pane.props.label;
        const tabindex = pane.active ? 0 : -1;
        return vue.h("div", {
          class: {
            "el-tabs__item": true,
            [`is-${rootTabs.props.tabPosition}`]: true,
            "is-active": pane.active,
            "is-disabled": pane.props.disabled,
            "is-closable": closable,
            "is-focus": isFocus
          },
          id: `tab-${tabName}`,
          key: `tab-${tabName}`,
          "aria-controls": `pane-${tabName}`,
          role: "tab",
          "aria-selected": pane.active,
          ref: `tab-${tabName}`,
          tabindex,
          onFocus: () => setFocus(),
          onBlur: () => removeFocus(),
          onClick: (ev) => {
            removeFocus();
            props.onTabClick(pane, tabName, ev);
          },
          onKeydown: (ev) => {
            if (closable && (ev.code === aria.EVENT_CODE.delete || ev.code === aria.EVENT_CODE.backspace)) {
              props.onTabRemove(pane, ev);
            }
          }
        }, [tabLabelContent, btnClose]);
      });
      return vue.h("div", {
        ref: el$,
        class: [
          "el-tabs__nav-wrap",
          scrollable.value ? "is-scrollable" : "",
          `is-${rootTabs.props.tabPosition}`
        ]
      }, [
        scrollBtn,
        vue.h("div", {
          class: "el-tabs__nav-scroll",
          ref: navScroll$
        }, [
          vue.h("div", {
            class: [
              "el-tabs__nav",
              `is-${rootTabs.props.tabPosition}`,
              props.stretch && ["top", "bottom"].includes(rootTabs.props.tabPosition) ? "is-stretch" : ""
            ],
            ref: nav$,
            style: navStyle.value,
            role: "tablist",
            onKeydown: changeTab
          }, [
            !props.type ? vue.h(tabBar_vue_vue_type_script_lang["default"], {
              tabs: [...props.panes]
            }) : null,
            tabs
          ])
        ])
      ]);
    };
  }
});

exports["default"] = TabNav;
exports.tabNavProps = tabNavProps;
//# sourceMappingURL=tab-nav.js.map
