"use strict";
const vue = require("vue");
const index$1 = require("./index-C_bsiScj.js");
const useSafeScrollLock = require("./useSafeScrollLock-ov0LQtXv.js");
const BButton_vue_vue_type_script_setup_true_lang = require("./BButton.vue_vue_type_script_setup_true_lang-CXQy0Rf_.js");
const BCloseButton_vue_vue_type_script_setup_true_lang = require("./BCloseButton.vue_vue_type_script_setup_true_lang-CbUMoMu7.js");
const useDefaults = require("./useDefaults-YXpmugKp.js");
const useId = require("./useId-Dl8Hi5_U.js");
const dom = require("./dom-BgEUZpKg.js");
const useColorVariantClasses = require("./useColorVariantClasses-BjkZZDqD.js");
const keys = require("./keys-D70E9HED.js");
const index = require("./index-JJEBhaXq.js");
const useShowHide = require("./useShowHide-b1MKf6Ye.js");
const ConditionalTeleport_vue_vue_type_script_lang = require("./ConditionalTeleport.vue_vue_type_script_lang-BL9AAILt.js");
const getElement = require("./getElement-CodzX3WA.js");
const modalOpenClassName = "modal-open";
const useSharedModalStack = () => {
  const modalManagerPlugin = vue.inject(keys.modalManagerKey, null);
  const dispose = (modal) => {
    modalManagerPlugin?.removeStack(modal);
    modalManagerPlugin?.removeRegistry(modal);
  };
  const updateHTMLAttrs = index$1.getSSRHandler("updateHTMLAttrs", (selector, attribute, value) => {
    const el = typeof selector === "string" ? window?.document.querySelector(selector) : index$1.unrefElement(selector);
    if (!el) return;
    if (attribute === "class") {
      el.classList.toggle(modalOpenClassName, value === modalOpenClassName);
    } else {
      el.setAttribute(attribute, value);
    }
  });
  index.tryOnScopeDispose(() => {
    if (modalManagerPlugin?.countStack.value === 0) {
      updateHTMLAttrs("body", "class", "");
    }
  });
  vue.watch(
    () => modalManagerPlugin?.countStack.value,
    (newValue) => {
      if (newValue === void 0) return;
      updateHTMLAttrs("body", "class", newValue > 0 ? modalOpenClassName : "");
    }
  );
  return {
    ...modalManagerPlugin,
    dispose
  };
};
const useModalManager = (modalOpen, initialValue) => {
  const { pushRegistry, pushStack, removeStack, stack, dispose, countStack } = useSharedModalStack();
  const currentModal = vue.getCurrentInstance();
  if (!currentModal || currentModal.type.__name !== "BModal") {
    throw new Error("useModalManager must only use in BModal component");
  }
  pushRegistry?.(currentModal);
  index.tryOnScopeDispose(() => {
    dispose(currentModal);
  });
  const setInStack = (newValue, oldValue) => {
    if (newValue) {
      pushStack?.(currentModal);
    } else if (oldValue && !newValue) {
      removeStack?.(currentModal);
    }
  };
  setInStack(initialValue, initialValue);
  vue.watch(modalOpen, setInStack);
  return {
    activePosition: vue.computed(
      () => stack?.value.findIndex((el) => vue.toValue(el.exposed?.id) === vue.toValue(currentModal.exposed?.id))
    ),
    activeModalCount: countStack,
    stackWithoutSelf: vue.computed(
      () => stack?.value.filter(
        (el) => vue.toValue(el.exposed?.id) !== vue.toValue(currentModal.exposed?.id)
      ) ?? []
    )
  };
};
const _hoisted_1 = ["id", "aria-labelledby", "aria-describedby"];
const _hoisted_2 = ["id"];
const fallbackClassSelector = "modal-fallback-focus";
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  ...{
    inheritAttrs: false
  },
  __name: "BModal",
  props: /* @__PURE__ */ vue.mergeModels({
    focus: { type: [String, Boolean, Object, null], default: void 0 },
    backdropFirst: { type: Boolean, default: false },
    body: { default: void 0 },
    bodyAttrs: { default: void 0 },
    bodyBgVariant: { default: null },
    bodyClass: { default: null },
    bodyScrolling: { type: Boolean, default: false },
    bodyTextVariant: { default: null },
    bodyVariant: { default: null },
    busy: { type: Boolean, default: false },
    buttonSize: { default: "md" },
    cancelClass: { default: void 0 },
    cancelDisabled: { type: Boolean, default: false },
    cancelTitle: { default: "Cancel" },
    cancelVariant: { default: "secondary" },
    centered: { type: Boolean, default: false },
    contentClass: { default: void 0 },
    dialogClass: { default: void 0 },
    footerBgVariant: { default: null },
    footerBorderVariant: { default: null },
    footerClass: { default: void 0 },
    footerTextVariant: { default: null },
    footerVariant: { default: null },
    fullscreen: { type: [Boolean, String], default: false },
    headerAttrs: { default: void 0 },
    headerBgVariant: { default: null },
    headerBorderVariant: { default: null },
    headerClass: { default: void 0 },
    headerCloseClass: { default: void 0 },
    headerCloseLabel: { default: "Close" },
    headerCloseVariant: { default: "secondary" },
    headerTextVariant: { default: null },
    headerVariant: { default: null },
    noBackdrop: { type: Boolean, default: false },
    noFooter: { type: Boolean, default: false },
    noHeader: { type: Boolean, default: false },
    noHeaderClose: { type: Boolean, default: false },
    id: { default: void 0 },
    modalClass: { default: void 0 },
    noCloseOnBackdrop: { type: Boolean, default: false },
    noCloseOnEsc: { type: Boolean, default: false },
    noTrap: { type: Boolean, default: false },
    noStacking: { type: Boolean },
    okClass: { default: void 0 },
    okDisabled: { type: Boolean, default: false },
    okOnly: { type: Boolean, default: false },
    okTitle: { default: "OK" },
    okVariant: { default: "primary" },
    scrollable: { type: Boolean, default: false },
    size: { default: "md" },
    title: { default: void 0 },
    titleClass: { default: void 0 },
    titleVisuallyHidden: { type: Boolean, default: false },
    titleTag: { default: "h5" },
    teleportDisabled: { type: Boolean, default: false },
    teleportTo: { default: "body" },
    initialAnimation: { type: Boolean, default: false },
    noAnimation: { type: Boolean },
    noFade: { type: Boolean, default: false },
    lazy: { type: Boolean, default: false },
    unmountLazy: { type: Boolean, default: false },
    show: { type: Boolean, default: false },
    transProps: { default: void 0 },
    visible: { type: Boolean, default: false }
  }, {
    "modelValue": { type: Boolean, ...{ default: false } },
    "modelModifiers": {}
  }),
  emits: /* @__PURE__ */ vue.mergeModels(["backdrop", "cancel", "close", "esc", "ok", "hide", "hide-prevented", "hidden", "show", "show-prevented", "shown", "toggle", "toggle-prevented"], ["update:modelValue"]),
  setup(__props, { expose: __expose, emit: __emit }) {
    const _props = __props;
    const props = useDefaults.useDefaults(_props, "BModal");
    const emit = __emit;
    const slots = vue.useSlots();
    const computedId = useId.useId(() => props.id, "modal");
    const modelValue = vue.useModel(__props, "modelValue");
    const element = vue.useTemplateRef("_element");
    const fallbackFocusElement = vue.useTemplateRef("_fallbackFocusElement");
    const okButton = vue.useTemplateRef("_okButton");
    const cancelButton = vue.useTemplateRef("_cancelButton");
    const closeButton = vue.useTemplateRef("_closeButton");
    const pickFocusItem = () => {
      if (props.focus && typeof props.focus !== "boolean") {
        if (props.focus === "ok") {
          return okButton;
        } else if (props.focus === "close") {
          return closeButton;
        } else if (props.focus === "cancel") {
          return cancelButton;
        }
        return getElement.getElement(props.focus, element.value ?? void 0) ?? element.value;
      }
      return element;
    };
    let activeElement = null;
    const onAfterEnter = () => {
      if (props.noTrap && props.focus !== false) {
        activeElement = document.activeElement;
        if (activeElement === element.value) {
          activeElement = null;
        }
        const el = index$1.unrefElement(pickFocusItem());
        if (!el) return;
        el?.focus();
        if (el.tagName && el.tagName.toLowerCase() === "input" && typeof el.select === "function") {
          el.select();
        }
      }
    };
    const onAfterLeave = () => {
      if (props.noTrap && props.focus !== false && activeElement) {
        activeElement?.focus();
        activeElement = null;
      }
    };
    const {
      showRef,
      renderRef,
      renderBackdropRef,
      hide,
      show,
      toggle,
      computedNoAnimation,
      transitionProps,
      backdropTransitionProps,
      isLeaving,
      isVisible,
      trapActive,
      contentShowing,
      backdropReady,
      backdropVisible
    } = useShowHide.useShowHide(modelValue, props, emit, element, computedId, {
      // addShowClass: false,
      transitionProps: {
        onAfterEnter,
        onAfterLeave
      }
    });
    const { needsFallback } = useSafeScrollLock.useActivatedFocusTrap({
      element,
      isActive: trapActive,
      noTrap: () => props.noTrap,
      fallbackFocus: {
        ref: fallbackFocusElement,
        classSelector: fallbackClassSelector
      },
      focus: () => props.focus === false ? false : index$1.unrefElement(pickFocusItem()) ?? void 0
      // () => (typeof focus === 'boolean' ? focus : (unrefElement(focus) ?? undefined)),
    });
    index$1.onKeyStroke(
      "Escape",
      () => {
        hide("esc");
      },
      { target: element }
    );
    useSafeScrollLock.useSafeScrollLock(showRef, () => props.bodyScrolling);
    const hasHeaderCloseSlot = vue.computed(() => !dom.isEmptySlot(slots["header-close"]));
    const modalDialogClasses = vue.computed(() => [
      props.dialogClass,
      {
        "modal-fullscreen": props.fullscreen === true,
        [`modal-fullscreen-${props.fullscreen}-down`]: typeof props.fullscreen === "string",
        [`modal-${props.size}`]: props.size !== "md",
        "modal-dialog-centered": props.centered,
        "modal-dialog-scrollable": props.scrollable
      }
    ]);
    const bodyColorClasses = useColorVariantClasses.useColorVariantClasses(() => ({
      bgVariant: props.bodyBgVariant,
      textVariant: props.bodyTextVariant,
      variant: props.bodyVariant
    }));
    const bodyClasses = vue.computed(() => [props.bodyClass, bodyColorClasses.value]);
    const headerColorClasses = useColorVariantClasses.useColorVariantClasses(() => ({
      bgVariant: props.headerBgVariant,
      textVariant: props.headerTextVariant,
      variant: props.headerVariant,
      borderVariant: props.headerBorderVariant
    }));
    const headerClasses = vue.computed(() => [props.headerClass, headerColorClasses.value]);
    const headerCloseAttrs = vue.computed(() => ({
      variant: hasHeaderCloseSlot.value ? props.headerCloseVariant : void 0,
      class: props.headerCloseClass
    }));
    const footerColorClasses = useColorVariantClasses.useColorVariantClasses(() => ({
      bgVariant: props.footerBgVariant,
      textVariant: props.footerTextVariant,
      variant: props.footerVariant,
      borderVariant: props.footerBorderVariant
    }));
    const footerClasses = vue.computed(() => [props.footerClass, footerColorClasses.value]);
    const titleClasses = vue.computed(() => [
      props.titleClass,
      {
        ["visually-hidden"]: props.titleVisuallyHidden
      }
    ]);
    const disableCancel = vue.computed(() => props.cancelDisabled || props.busy);
    const disableOk = vue.computed(() => props.okDisabled || props.busy);
    const { activePosition, activeModalCount, stackWithoutSelf } = useModalManager(
      showRef,
      modelValue.value
    );
    const sharedClasses = vue.computed(() => ({
      [`stack-position-${activePosition?.value ?? 0}`]: true,
      [`stack-inverse-position-${(activeModalCount?.value ?? 1) - 1 - (activePosition?.value ?? 0)}`]: true
    }));
    vue.watch(stackWithoutSelf, (newValue, oldValue) => {
      if (newValue.length > oldValue.length && showRef.value === true && props.noStacking === true)
        hide();
    });
    const defaultModalDialogZIndex = vue.ref(
      dom.getModalZIndex(element.value ?? (typeof document !== "undefined" ? document.body : void 0))
    );
    vue.onMounted(() => {
      vue.watch(
        renderRef,
        (v) => {
          if (!v) return;
          vue.nextTick(() => {
            if (!element.value) return;
            defaultModalDialogZIndex.value = dom.getModalZIndex(element.value);
          });
        },
        { immediate: true }
      );
    });
    const computedZIndexNumber = vue.computed(
      () => (
        // Make sure that newly opened modals have a higher z-index than currently active ones.
        // All active modals have a z-index of ('defaultZIndex' - 'stackSize' - 'positionInStack').
        //
        // This means inactive modals will already be higher than active ones when opened.
        showRef.value || isLeaving.value ? (
          // Just for reference there is a single frame in which the modal is not active but still has a higher z-index than the active ones due to _when_ it calculates its position. It's a small visual effect
          defaultModalDialogZIndex.value - ((activeModalCount?.value ?? 0) * 2 - (activePosition?.value ?? 0) * 2)
        ) : defaultModalDialogZIndex.value
      )
    );
    const computedZIndex = vue.computed(() => ({
      "z-index": computedZIndexNumber.value,
      "--b-position": activePosition?.value ?? 0,
      "--b-inverse-position": (activeModalCount?.value ?? 1) - 1 - (activePosition?.value ?? 0),
      "--b-count": activeModalCount?.value ?? 0
    }));
    const computedZIndexBackdrop = vue.computed(() => ({
      "z-index": computedZIndexNumber.value - 1,
      "--b-position": activePosition?.value ?? 0,
      "--b-inverse-position": (activeModalCount?.value ?? 1) - 1 - (activePosition?.value ?? 0),
      "--b-count": activeModalCount?.value ?? 0
    }));
    const sharedSlots = vue.computed(() => ({
      id: computedId.value,
      cancel: () => {
        hide("cancel");
      },
      close: () => {
        hide("close");
      },
      hide,
      show,
      toggle,
      ok: () => {
        hide("ok");
      },
      active: showRef.value,
      visible: showRef.value
    }));
    __expose({
      hide,
      id: computedId,
      show,
      toggle,
      visible: showRef
    });
    return (_ctx, _cache) => {
      return vue.openBlock(), vue.createBlock(ConditionalTeleport_vue_vue_type_script_lang._sfc_main, {
        to: vue.unref(props).teleportTo,
        disabled: vue.unref(props).teleportDisabled
      }, {
        default: vue.withCtx(() => [
          vue.unref(renderRef) || vue.unref(contentShowing) ? (vue.openBlock(), vue.createBlock(vue.Transition, vue.mergeProps({ key: 0 }, vue.unref(transitionProps), {
            appear: modelValue.value || vue.unref(props).visible
          }), {
            default: vue.withCtx(() => [
              vue.withDirectives(vue.createElementVNode("div", vue.mergeProps({
                id: vue.unref(computedId),
                ref: "_element",
                class: ["modal", [
                  vue.unref(props).modalClass,
                  {
                    fade: !vue.unref(computedNoAnimation),
                    show: vue.unref(isVisible),
                    ...sharedClasses.value
                  }
                ]],
                role: "dialog",
                "aria-labelledby": !vue.unref(props).noHeader ? `${vue.unref(computedId)}-label` : void 0,
                "aria-describedby": `${vue.unref(computedId)}-body`,
                tabindex: "-1"
              }, _ctx.$attrs, {
                style: [computedZIndex.value, { "display": "block" }],
                onMousedown: _cache[4] || (_cache[4] = vue.withModifiers(($event) => vue.unref(hide)("backdrop"), ["left", "self"]))
              }), [
                vue.createElementVNode("div", {
                  class: vue.normalizeClass(["modal-dialog", modalDialogClasses.value])
                }, [
                  vue.unref(contentShowing) ? (vue.openBlock(), vue.createElementBlock("div", {
                    key: 0,
                    class: vue.normalizeClass(["modal-content", vue.unref(props).contentClass])
                  }, [
                    !vue.unref(props).noHeader ? (vue.openBlock(), vue.createElementBlock("div", vue.mergeProps({
                      key: 0,
                      class: ["modal-header", headerClasses.value]
                    }, vue.unref(props).headerAttrs), [
                      vue.renderSlot(_ctx.$slots, "header", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)), () => [
                        (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(vue.unref(props).titleTag), {
                          id: `${vue.unref(computedId)}-label`,
                          class: vue.normalizeClass(["modal-title", titleClasses.value])
                        }, {
                          default: vue.withCtx(() => [
                            vue.renderSlot(_ctx.$slots, "title", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)), () => [
                              vue.createTextVNode(vue.toDisplayString(vue.unref(props).title), 1)
                            ])
                          ]),
                          _: 3
                        }, 8, ["id", "class"])),
                        !vue.unref(props).noHeaderClose ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
                          hasHeaderCloseSlot.value ? (vue.openBlock(), vue.createBlock(BButton_vue_vue_type_script_setup_true_lang._sfc_main, vue.mergeProps({
                            key: 0,
                            ref: "_closeButton"
                          }, headerCloseAttrs.value, {
                            onClick: _cache[0] || (_cache[0] = ($event) => vue.unref(hide)("close"))
                          }), {
                            default: vue.withCtx(() => [
                              vue.renderSlot(_ctx.$slots, "header-close", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)))
                            ]),
                            _: 3
                          }, 16)) : (vue.openBlock(), vue.createBlock(BCloseButton_vue_vue_type_script_setup_true_lang._sfc_main, vue.mergeProps({
                            key: 1,
                            ref: "_closeButton",
                            "aria-label": vue.unref(props).headerCloseLabel
                          }, headerCloseAttrs.value, {
                            onClick: _cache[1] || (_cache[1] = ($event) => vue.unref(hide)("close"))
                          }), null, 16, ["aria-label"]))
                        ], 64)) : vue.createCommentVNode("", true)
                      ])
                    ], 16)) : vue.createCommentVNode("", true),
                    vue.createElementVNode("div", vue.mergeProps({
                      id: `${vue.unref(computedId)}-body`,
                      class: ["modal-body", bodyClasses.value]
                    }, vue.unref(props).bodyAttrs), [
                      vue.renderSlot(_ctx.$slots, "default", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)), () => [
                        vue.createTextVNode(vue.toDisplayString(vue.unref(props).body), 1)
                      ])
                    ], 16, _hoisted_2),
                    !vue.unref(props).noFooter ? (vue.openBlock(), vue.createElementBlock("div", {
                      key: 1,
                      class: vue.normalizeClass(["modal-footer", footerClasses.value])
                    }, [
                      vue.renderSlot(_ctx.$slots, "footer", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)), () => [
                        vue.renderSlot(_ctx.$slots, "cancel", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)), () => [
                          !vue.unref(props).okOnly ? (vue.openBlock(), vue.createBlock(BButton_vue_vue_type_script_setup_true_lang._sfc_main, {
                            key: 0,
                            ref: "_cancelButton",
                            disabled: disableCancel.value,
                            size: vue.unref(props).buttonSize,
                            variant: vue.unref(props).cancelVariant,
                            class: vue.normalizeClass(vue.unref(props).cancelClass),
                            onClick: _cache[2] || (_cache[2] = ($event) => vue.unref(hide)("cancel"))
                          }, {
                            default: vue.withCtx(() => [
                              vue.createTextVNode(vue.toDisplayString(vue.unref(props).cancelTitle), 1)
                            ]),
                            _: 1
                          }, 8, ["disabled", "size", "variant", "class"])) : vue.createCommentVNode("", true)
                        ]),
                        vue.renderSlot(_ctx.$slots, "ok", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)), () => [
                          vue.createVNode(BButton_vue_vue_type_script_setup_true_lang._sfc_main, {
                            ref: "_okButton",
                            disabled: disableOk.value,
                            size: vue.unref(props).buttonSize,
                            variant: vue.unref(props).okVariant,
                            class: vue.normalizeClass(vue.unref(props).okClass),
                            onClick: _cache[3] || (_cache[3] = ($event) => vue.unref(hide)("ok"))
                          }, {
                            default: vue.withCtx(() => [
                              vue.createTextVNode(vue.toDisplayString(vue.unref(props).okTitle), 1)
                            ]),
                            _: 1
                          }, 8, ["disabled", "size", "variant", "class"])
                        ])
                      ])
                    ], 2)) : vue.createCommentVNode("", true)
                  ], 2)) : vue.createCommentVNode("", true)
                ], 2),
                vue.unref(needsFallback) ? (vue.openBlock(), vue.createElementBlock("div", {
                  key: 0,
                  ref: "_fallbackFocusElement",
                  class: vue.normalizeClass(fallbackClassSelector),
                  tabindex: "0",
                  style: { "width": "0", "height": "0", "overflow": "hidden" }
                }, null, 512)) : vue.createCommentVNode("", true)
              ], 16, _hoisted_1), [
                [vue.vShow, vue.unref(showRef) && (vue.unref(backdropReady) && vue.unref(props).backdropFirst || !vue.unref(props).backdropFirst)]
              ])
            ]),
            _: 3
          }, 16, ["appear"])) : vue.createCommentVNode("", true),
          !vue.unref(props).noBackdrop ? vue.renderSlot(_ctx.$slots, "backdrop", vue.normalizeProps(vue.mergeProps({ key: 1 }, sharedSlots.value)), () => [
            vue.unref(renderBackdropRef) ? (vue.openBlock(), vue.createBlock(vue.Transition, vue.normalizeProps(vue.mergeProps({ key: 0 }, vue.unref(backdropTransitionProps))), {
              default: vue.withCtx(() => [
                vue.withDirectives(vue.createElementVNode("div", {
                  class: vue.normalizeClass(["modal-backdrop", {
                    fade: !vue.unref(computedNoAnimation),
                    show: vue.unref(backdropVisible) || vue.unref(computedNoAnimation),
                    ...sharedClasses.value
                  }]),
                  style: vue.normalizeStyle(computedZIndexBackdrop.value),
                  onClick: _cache[5] || (_cache[5] = ($event) => vue.unref(hide)("backdrop"))
                }, null, 6), [
                  [vue.vShow, vue.unref(showRef) || vue.unref(isLeaving) && vue.unref(props).backdropFirst && !vue.unref(computedNoAnimation)]
                ])
              ]),
              _: 1
            }, 16)) : vue.createCommentVNode("", true)
          ]) : vue.createCommentVNode("", true)
        ]),
        _: 3
      }, 8, ["to", "disabled"]);
    };
  }
});
exports._sfc_main = _sfc_main;
exports.useSharedModalStack = useSharedModalStack;
//# sourceMappingURL=BModal.vue_vue_type_script_setup_true_lang-ePg_le3O.js.map
