"use strict";
const vue = require("vue");
const classes = require("./classes-DA6TfAZg.js");
const useAlignment = require("./useAlignment-BKpl8Nif.js");
const useId = require("./useId-Dl8Hi5_U.js");
const index = require("./index-C_bsiScj.js");
const keys = require("./keys-D70E9HED.js");
const useDefaults = require("./useDefaults-YXpmugKp.js");
const dom = require("./dom-BgEUZpKg.js");
const flattenFragments = require("./flattenFragments-C5j6tfjr.js");
const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
  ...{
    inheritAttrs: false
  },
  __name: "BTab",
  props: /* @__PURE__ */ vue.mergeModels({
    buttonId: { default: void 0 },
    disabled: { type: Boolean, default: false },
    id: { default: void 0 },
    lazy: { type: Boolean, default: void 0 },
    unmountLazy: { type: Boolean, default: void 0 },
    noBody: { type: Boolean, default: false },
    tag: { default: "div" },
    title: { default: void 0 },
    titleItemClass: { default: void 0 },
    titleLinkAttrs: { default: void 0 },
    titleLinkClass: { default: void 0 }
  }, {
    "active": { type: Boolean, ...{
      default: false
    } },
    "activeModifiers": {}
  }),
  emits: ["update:active"],
  setup(__props, { expose: __expose }) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BTab");
    const slots = vue.useSlots();
    const attrs = vue.useAttrs();
    const activeModel = vue.useModel(__props, "active");
    const parentData = vue.inject(keys.tabsInjectionKey, null);
    const localId = vue.ref(props.id);
    const internalId = useId.useId("", "tabpane");
    const computedId = vue.computed(() => props.id ?? localId.value ?? internalId.value);
    const computedButtonId = useId.useId(() => props.buttonId, "tab");
    const lazyRenderCompleted = vue.ref(false);
    const el = vue.useTemplateRef("_el");
    const processedAttrs = vue.computed(() => {
      const { onClick: _, ...tabAttrs } = attrs;
      return tabAttrs;
    });
    function updateTab() {
      if (!parentData) return;
      const newId = parentData.registerTab(
        vue.computed(
          () => ({
            internalId: internalId.value,
            id: computedId.value,
            active: activeModel.value,
            buttonId: computedButtonId.value,
            disabled: props.disabled,
            title: props.title,
            titleComponent: slots.title,
            titleItemClass: props.titleItemClass,
            titleLinkAttrs: props.titleLinkAttrs,
            titleLinkClass: props.titleLinkClass,
            onClick: attrs.onClick,
            el
          })
        )
      );
      if (newId !== localId.value) {
        localId.value = newId;
      }
    }
    if (parentData) {
      updateTab();
      if (activeModel.value) {
        parentData.activateTab(internalId.value);
      }
    }
    vue.onUnmounted(() => {
      if (!parentData) return;
      parentData.unregisterTab(internalId.value);
    });
    const isActive = vue.computed(() => parentData?.activeId.value === computedId.value);
    const show = vue.ref(isActive.value);
    const computedLazy = vue.computed(() => !!(parentData?.lazy.value || props.lazy));
    const computedActive = vue.computed(() => isActive.value && !props.disabled);
    const showSlot = vue.computed(
      () => computedActive.value || !computedLazy.value || computedLazy.value && !props.unmountLazy && lazyRenderCompleted.value
    );
    vue.watch(showSlot, (shown) => {
      if (shown && !lazyRenderCompleted.value) lazyRenderCompleted.value = true;
    });
    vue.watch(isActive, (active) => {
      if (active) {
        activeModel.value = true;
        setTimeout(() => {
          show.value = true;
        }, 0);
        return;
      }
      show.value = false;
      activeModel.value = false;
    });
    vue.watch(activeModel, (active) => {
      if (props.disabled) {
        activeModel.value = false;
        return;
      }
      if (!parentData) return;
      if (!active) {
        if (isActive.value) {
          parentData.activateTab(void 0);
        }
        return;
      }
      if (!isActive.value) {
        parentData.activateTab(internalId.value);
      }
    });
    const computedClasses = vue.computed(() => [
      {
        "active": isActive.value,
        "show": show.value,
        "card-body": parentData?.card.value && props.noBody === false,
        "fade": !parentData?.noFade.value
      },
      show.value ? parentData?.activeTabClass.value : parentData?.inactiveTabClass.value,
      parentData?.tabClass.value
    ]);
    __expose({
      activate: () => {
        activeModel.value = true;
      },
      deactivate: () => {
        activeModel.value = false;
      }
    });
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.unref(props).tag), vue.mergeProps({
        id: computedId.value,
        ref: "_el",
        class: ["tab-pane", computedClasses.value],
        role: "tabpanel",
        "aria-labelledby": vue.unref(computedButtonId)
      }, processedAttrs.value), {
        default: vue.withCtx(() => [
          showSlot.value ? vue.renderSlot(_ctx.$slots, "default", { key: 0 }) : vue.createCommentVNode("", true)
        ]),
        _: 3
      }, 16, ["id", "class", "aria-labelledby"]);
    };
  }
});
const _hoisted_1 = ["aria-orientation"];
const _hoisted_2 = ["id", "aria-controls", "aria-selected", "disabled", "tabindex", "onClick"];
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  __name: "BTabs",
  props: /* @__PURE__ */ vue.mergeModels({
    activeNavItemClass: { default: void 0 },
    activeTabClass: { default: void 0 },
    align: { default: void 0 },
    card: { type: Boolean, default: false },
    contentClass: { default: void 0 },
    end: { type: Boolean, default: false },
    fill: { type: Boolean, default: false },
    id: { default: void 0 },
    index: {},
    inactiveNavItemClass: { default: void 0 },
    inactiveTabClass: { default: void 0 },
    justified: { type: Boolean, default: false },
    lazy: { type: Boolean, default: false },
    navClass: { default: void 0 },
    navItemClass: { default: void 0 },
    navWrapperClass: { default: void 0 },
    noFade: { type: Boolean, default: false },
    noKeyNav: { type: Boolean, default: false },
    noNavStyle: { type: Boolean, default: false },
    pills: { type: Boolean, default: false },
    small: { type: Boolean, default: false },
    tag: { default: "div" },
    tabClass: { default: void 0 },
    underline: { type: Boolean, default: false },
    vertical: { type: Boolean, default: false }
  }, {
    "index": {
      default: -1
    },
    "indexModifiers": {},
    "modelValue": {
      default: void 0
    },
    "modelModifiers": {}
  }),
  emits: /* @__PURE__ */ vue.mergeModels(["activate-tab"], ["update:index", "update:modelValue"]),
  setup(__props, { emit: __emit }) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BTabs");
    const emit = __emit;
    const slots = vue.useSlots();
    const activeIndex = vue.useModel(__props, "index");
    const activeId = vue.useModel(__props, "modelValue");
    const ReusableEmptyTab = index.createReusableTemplate();
    const tabsInternal = vue.ref([]);
    const tabElementsArray = vue.ref([]);
    const isChildActive = vue.ref(false);
    const initialIds = vue.ref([]);
    const hasExplicitIds = vue.ref(false);
    const updateTabElementsArray = () => {
      const tabElements = flattenFragments.flattenFragments(slots.default?.({}) ?? []);
      tabElementsArray.value = (Array.isArray(tabElements) ? tabElements : [tabElements]).filter(
        (tab) => tab.type === _sfc_main$1
      );
      if (initialIds.value.length === 0) {
        initialIds.value = tabElementsArray.value.map(
          (tab) => vue.unref(useId.useId(() => tab.props?.id, "tabpane"))
        );
        hasExplicitIds.value = tabElementsArray.value.some((tab) => tab.props?.id !== void 0);
      }
      isChildActive.value = tabElementsArray.value.some(
        (tab) => tab.props?.active !== void 0 && tab.props?.active !== false
      );
    };
    updateTabElementsArray();
    vue.watch(
      () => slots.default?.({}),
      () => {
        updateTabElementsArray();
        vue.nextTick(() => {
          sortTabs();
        });
      }
    );
    const tabs = vue.computed(() => {
      if (tabsInternal.value.length === 0) {
        const _activeIndex = tabElementsArray.value.findIndex(
          (tab) => tab.props?.active !== void 0 && (tab.props.disabled === false || tab.props.disabled === void 0) || activeId.value && tab.props?.id === activeId.value
        );
        return tabElementsArray.value.map((tab, index2) => {
          const active = _activeIndex !== -1 ? index2 === _activeIndex : activeIndex.value > -1 ? index2 === activeIndex.value : index2 === 0;
          return {
            id: tab.props?.id ?? initialIds.value[index2],
            internalId: `premount-${index2}`,
            // temporary id for the tab
            buttonId: tab.props?.buttonId,
            disabled: tab.props?.disabled,
            title: tab.props?.title,
            titleComponent: tab.children?.title,
            titleItemClass: tab.props?.titleItemClass,
            titleLinkAttrs: tab.props?.titleLinkAttrs,
            titleLinkClass: tab.props?.titleLinkClass,
            onClick: tab.props?.onClick,
            active,
            navItemClasses: [
              {
                active,
                disabled: !(tab.props?.disabled === false || tab.props?.disabled === void 0)
              },
              active ? props.activeNavItemClass : props.inactiveNavItemClass,
              props.navItemClass
            ]
          };
        });
      }
      return tabsInternal.value.map((_tab) => {
        const tab = vue.unref(_tab);
        const active = tab.id === activeId.value;
        return {
          ...tab,
          active,
          navItemClasses: [
            {
              active,
              disabled: tab.disabled
            },
            active ? props.activeNavItemClass : props.inactiveNavItemClass,
            props.navItemClass
          ]
        };
      });
    });
    let initialized = false;
    let updateInitialActiveIndex = false;
    let updateInitialActiveId = false;
    let delayedTabSelection = false;
    const needsDelayedSelection = activeIndex.value > -1 && !activeId.value && !hasExplicitIds.value && tabElementsArray.value.length > 0;
    if (needsDelayedSelection) {
      delayedTabSelection = true;
      updateInitialActiveId = true;
    } else if (activeIndex.value === -1 && activeId.value) {
      if (tabs.value.findIndex((t) => t.id === activeId.value) !== -1) {
        activeIndex.value = tabs.value.findIndex((t) => t.id === activeId.value);
      } else {
        updateInitialActiveIndex = true;
      }
    } else if (activeIndex.value > -1 && !activeId.value) {
      if (tabs.value[activeIndex.value]?.id) {
        activeId.value = tabs.value[activeIndex.value]?.id;
      } else {
        updateInitialActiveId = true;
      }
    } else if (activeIndex.value === -1 && !activeId.value && !isChildActive.value) {
      activeIndex.value = tabs.value.findIndex((t) => t.disabled === void 0 || t.disabled === false);
      activeId.value = tabs.value[activeIndex.value]?.id;
    } else if (activeIndex.value === -1 && !activeId.value && isChildActive.value) {
      activeIndex.value = tabs.value.findIndex(
        (t) => t.active !== void 0 && t.active !== false && (t.disabled === void 0 || t.disabled === false)
      );
      activeId.value = tabs.value[activeIndex.value]?.id;
    }
    function updateInitialIndexAndId() {
      if (updateInitialActiveIndex) {
        const index2 = tabs.value.findIndex((t) => t.id === activeId.value);
        if (index2 !== -1) {
          vue.nextTick(() => {
            activeIndex.value = index2;
            updateInitialActiveIndex = false;
          });
        }
      }
      if (updateInitialActiveId) {
        if (delayedTabSelection && tabsInternal.value.length === 0) {
          return;
        }
        if (activeIndex.value > -1 && tabs.value[activeIndex.value]?.id) {
          vue.nextTick(() => {
            activeId.value = tabs.value[activeIndex.value]?.id;
            updateInitialActiveId = false;
            delayedTabSelection = false;
          });
        }
      }
    }
    updateInitialIndexAndId();
    const showEmpty = vue.computed(() => !(tabs?.value && tabs.value.length > 0));
    const computedClasses = vue.computed(() => ({
      "d-flex": props.vertical,
      "align-items-start": props.vertical
    }));
    const alignment = useAlignment.useAlignment(() => props.align);
    const navTabsClasses = vue.computed(() => ({
      "nav-pills": props.pills,
      "nav-underline": props.underline,
      "flex-column me-3": props.vertical,
      [alignment.value]: props.align !== void 0,
      "nav-fill": props.fill,
      "card-header-tabs": props.card && !props.pills && !props.underline,
      "card-header-pills": props.card && props.pills,
      "nav-justified": props.justified,
      "nav-tabs": !props.noNavStyle && !props.pills && !props.underline,
      "small": props.small
    }));
    const handleClick = (event, index2) => {
      if (index2 >= 0 && !tabs.value[index2].disabled && tabs.value[index2]?.onClick && typeof tabs.value[index2].onClick === "function") {
        tabs.value[index2].onClick?.(event);
        if (event.defaultPrevented) {
          document.getElementById(tabs.value[index2].buttonId)?.blur();
          return;
        }
      }
      activeIndex.value = index2;
    };
    const keynav = (e, direction) => {
      if (tabs.value.length <= 0 || props.noKeyNav) return;
      e.preventDefault();
      e.stopPropagation();
      activeIndex.value = nextIndex(activeIndex.value + direction, direction);
      vue.nextTick(() => {
        if (activeIndex.value >= 0) {
          document.getElementById(tabs.value[activeIndex.value]?.buttonId)?.focus();
        }
      });
    };
    const nextIndex = (start, direction) => {
      let index2 = start;
      let minIdx = -1;
      let maxIdx = -1;
      for (let i = 0; i < tabs.value.length; i++) {
        if (!tabs.value[i].disabled) {
          if (minIdx === -1) minIdx = i;
          maxIdx = i;
        }
      }
      while (index2 >= minIdx && index2 <= maxIdx && tabs.value[index2].disabled) {
        index2 += direction;
      }
      if (index2 < minIdx) index2 = minIdx;
      if (index2 > maxIdx) index2 = maxIdx;
      return index2;
    };
    let previousIndex;
    let isReverting = false;
    vue.watch(activeIndex, (newValue, oldValue) => {
      if (tabs.value.length <= 0 || tabs.value.filter((t) => !t.disabled).length <= 0) {
        return;
      }
      if (isReverting) {
        isReverting = false;
        return;
      }
      const index2 = nextIndex(newValue, newValue > oldValue ? 1 : -1);
      if (index2 !== newValue) {
        previousIndex = oldValue;
        activeIndex.value = index2;
        return;
      }
      const tabEvent = new classes.BvEvent("activate-tab", { cancelable: true });
      emit("activate-tab", {
        newTabId: tabs.value[index2]?.id,
        prevTabId: tabs.value[previousIndex ?? oldValue]?.id,
        newTabIndex: index2,
        prevTabIndex: previousIndex ?? oldValue,
        event: tabEvent
      });
      if (tabEvent.defaultPrevented) {
        isReverting = true;
        const prev = previousIndex ?? oldValue ?? nextIndex(0, 1);
        previousIndex = void 0;
        if (activeId.value !== tabs.value[prev]?.id) {
          activeId.value = tabs.value[prev]?.id;
        }
        vue.nextTick(() => {
          if (prev >= 0) {
            document.getElementById(tabs.value[prev]?.buttonId)?.focus();
          }
        });
        return;
      }
      if (activeId.value !== tabs.value[index2]?.id) {
        activeId.value = tabs.value[index2]?.id;
      }
      previousIndex = void 0;
    });
    vue.watch(activeId, (newValue, oldValue) => {
      if (tabs.value.length <= 0 || tabs.value.filter((t) => !t.disabled).length <= 0) {
        return;
      }
      const index2 = tabs.value.findIndex((t) => t.id === newValue);
      if (index2 === activeIndex.value) return;
      const oldIndex = tabs.value.findIndex((t) => t.id === oldValue);
      if (tabs.value[index2]?.disabled) {
        activeIndex.value = nextIndex(index2, index2 > oldIndex ? 1 : -1);
        return;
      }
      if (index2 === -1) {
        activeIndex.value = nextIndex(0, 1);
        vue.nextTick(() => {
          activeId.value = tabs.value[activeIndex.value]?.id;
        });
        return;
      }
      activeIndex.value = index2;
    });
    const registerTab = (tab) => {
      const idx = tabsInternal.value.findIndex((t) => t.value.internalId === tab.value.internalId);
      if (idx === -1) {
        tabsInternal.value.push(tab);
        if (initialized) {
          vue.nextTick(() => {
            sortTabs();
          });
        } else {
          if (delayedTabSelection) {
            vue.nextTick(() => {
              updateInitialIndexAndId();
            });
          }
        }
      } else {
        tabsInternal.value[idx] = tab;
        if (initialized) {
          sortTabs();
        }
      }
      const idx2 = tabsInternal.value.findIndex((t) => t.value.internalId === tab.value.internalId);
      return tab.value.id ?? (!initialized ? initialIds.value[idx2] : tab.value.internalId);
    };
    vue.onMounted(() => {
      updateInitialIndexAndId();
      sortTabs();
      initialized = true;
    });
    const sortTabs = () => {
      tabsInternal.value.sort((a, b) => dom.sortSlotElementsByPosition(a.value.el.value, b.value.el.value));
      if (activeId.value && activeIndex.value !== tabs.value.findIndex((t) => t.id === activeId.value)) {
        activeIndex.value = tabs.value.findIndex((t) => t.id === activeId.value);
      }
    };
    const unregisterTab = (id) => {
      tabsInternal.value = tabsInternal.value.filter((t) => t.value.internalId !== id);
    };
    vue.provide(keys.tabsInjectionKey, {
      lazy: vue.toRef(() => props.lazy),
      card: vue.toRef(() => props.card),
      noFade: vue.toRef(() => props.noFade),
      activeTabClass: vue.toRef(() => props.activeTabClass),
      inactiveTabClass: vue.toRef(() => props.inactiveTabClass),
      tabClass: vue.toRef(() => props.tabClass),
      registerTab,
      unregisterTab,
      activeId,
      activateTab: (internalId) => {
        const idx = tabs.value.findIndex((t) => t.internalId === internalId);
        if (internalId === void 0 || idx === -1) {
          activeIndex.value = nextIndex(0, 1);
          return;
        }
        activeIndex.value = idx;
      }
    });
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.unref(props).tag), {
        id: vue.unref(props).id,
        class: vue.normalizeClass(["tabs", computedClasses.value])
      }, {
        default: vue.withCtx(() => [
          vue.createVNode(vue.unref(ReusableEmptyTab).define, null, {
            default: vue.withCtx(() => [
              vue.createElementVNode("div", {
                class: vue.normalizeClass(["tab-content", vue.unref(props).contentClass])
              }, [
                vue.renderSlot(_ctx.$slots, "default"),
                showEmpty.value ? (vue.openBlock(), vue.createElementBlock("div", {
                  key: "bv-empty-tab",
                  class: vue.normalizeClass(["tab-pane active", { "card-body": vue.unref(props).card }])
                }, [
                  vue.renderSlot(_ctx.$slots, "empty")
                ], 2)) : vue.createCommentVNode("", true)
              ], 2)
            ]),
            _: 3
          }),
          vue.unref(props).end ? (vue.openBlock(), vue.createBlock(vue.unref(ReusableEmptyTab).reuse, { key: 0 })) : vue.createCommentVNode("", true),
          vue.createElementVNode("div", {
            class: vue.normalizeClass([
              vue.unref(props).navWrapperClass,
              { "card-header": vue.unref(props).card, "ms-auto": __props.vertical && vue.unref(props).end }
            ])
          }, [
            vue.createElementVNode("ul", {
              class: vue.normalizeClass(["nav", [navTabsClasses.value, vue.unref(props).navClass]]),
              role: "tablist",
              "aria-orientation": vue.unref(props).vertical ? "vertical" : "horizontal"
            }, [
              vue.renderSlot(_ctx.$slots, "tabs-start"),
              (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(tabs.value, (tab, idx) => {
                return vue.openBlock(), vue.createElementBlock("li", {
                  key: tab.id ?? tab.internalId,
                  class: vue.normalizeClass(["nav-item", tab.titleItemClass]),
                  role: "presentation"
                }, [
                  vue.createElementVNode("button", vue.mergeProps({
                    id: tab.buttonId,
                    class: ["nav-link", [tab.navItemClasses, tab.titleLinkClass]],
                    role: "tab",
                    "aria-controls": tab.id,
                    "aria-selected": tab.active,
                    disabled: tab.disabled,
                    tabindex: vue.unref(props).noKeyNav ? void 0 : tab.active ? void 0 : -1,
                    type: "button"
                  }, { ref_for: true }, tab.titleLinkAttrs, {
                    onKeydown: [
                      _cache[0] || (_cache[0] = vue.withKeys(vue.withModifiers(($event) => !vue.unref(props).vertical && keynav($event, -1), ["exact"]), ["left"])),
                      _cache[1] || (_cache[1] = vue.withKeys(vue.withModifiers(($event) => !vue.unref(props).vertical && keynav($event, -999), ["shift"]), ["left"])),
                      _cache[2] || (_cache[2] = vue.withKeys(vue.withModifiers(($event) => vue.unref(props).vertical && keynav($event, -1), ["exact"]), ["up"])),
                      _cache[3] || (_cache[3] = vue.withKeys(vue.withModifiers(($event) => vue.unref(props).vertical && keynav($event, -999), ["shift"]), ["up"])),
                      _cache[4] || (_cache[4] = vue.withKeys(vue.withModifiers(($event) => !vue.unref(props).vertical && keynav($event, 1), ["exact"]), ["right"])),
                      _cache[5] || (_cache[5] = vue.withKeys(vue.withModifiers(($event) => !vue.unref(props).vertical && keynav($event, 999), ["shift"]), ["right"])),
                      _cache[6] || (_cache[6] = vue.withKeys(vue.withModifiers(($event) => vue.unref(props).vertical && keynav($event, 1), ["exact"]), ["down"])),
                      _cache[7] || (_cache[7] = vue.withKeys(vue.withModifiers(($event) => vue.unref(props).vertical && keynav($event, 999), ["shift"]), ["down"])),
                      _cache[8] || (_cache[8] = vue.withKeys(($event) => keynav($event, -999), ["page-up"])),
                      _cache[9] || (_cache[9] = vue.withKeys(($event) => keynav($event, 999), ["page-down"])),
                      _cache[10] || (_cache[10] = vue.withKeys(($event) => keynav($event, -999), ["home"])),
                      _cache[11] || (_cache[11] = vue.withKeys(($event) => keynav($event, 999), ["end"]))
                    ],
                    onClick: vue.withModifiers((e) => handleClick(e, idx), ["stop"])
                  }), [
                    tab.titleComponent ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(tab.titleComponent), { key: 0 })) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
                      vue.createTextVNode(vue.toDisplayString(tab.title), 1)
                    ], 64))
                  ], 16, _hoisted_2)
                ], 2);
              }), 128)),
              vue.renderSlot(_ctx.$slots, "tabs-end")
            ], 10, _hoisted_1)
          ], 2),
          !vue.unref(props).end ? (vue.openBlock(), vue.createBlock(vue.unref(ReusableEmptyTab).reuse, { key: 1 })) : vue.createCommentVNode("", true)
        ]),
        _: 3
      }, 8, ["id", "class"]);
    };
  }
});
exports._sfc_main = _sfc_main$1;
exports._sfc_main$1 = _sfc_main;
//# sourceMappingURL=BTabs.vue_vue_type_script_setup_true_lang-lZyOHmrQ.js.map
