"use strict";
const vue = require("vue");
const index = require("./index-C_bsiScj.js");
const useSafeScrollLock = require("./useSafeScrollLock-ov0LQtXv.js");
const useDefaults = require("./useDefaults-YXpmugKp.js");
const useId = require("./useId-Dl8Hi5_U.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 ConditionalTeleport_vue_vue_type_script_lang = require("./ConditionalTeleport.vue_vue_type_script_lang-BL9AAILt.js");
const dom = require("./dom-BgEUZpKg.js");
const useShowHide = require("./useShowHide-b1MKf6Ye.js");
const getElement = require("./getElement-CodzX3WA.js");
const _hoisted_1 = ["id", "aria-labelledby"];
const _hoisted_2 = ["id"];
const fallbackClassSelector = "offcanvas-fallback-focus";
const _sfc_main = /* @__PURE__ */ vue.defineComponent({
  ...{
    inheritAttrs: false
  },
  __name: "BOffcanvas",
  props: /* @__PURE__ */ vue.mergeModels({
    noBackdrop: { type: Boolean, default: false },
    backdropFirst: { type: Boolean, default: false },
    bodyAttrs: { default: void 0 },
    bodyClass: { default: void 0 },
    bodyScrolling: { type: Boolean, default: false },
    focus: { type: [String, Boolean, Object, null], default: void 0 },
    footerClass: { default: void 0 },
    headerAttrs: { default: void 0 },
    headerClass: { default: void 0 },
    headerCloseClass: { default: void 0 },
    headerCloseLabel: { default: "Close" },
    headerCloseVariant: { default: "secondary" },
    id: { default: void 0 },
    noCloseOnBackdrop: { type: Boolean, default: false },
    noCloseOnEsc: { type: Boolean, default: false },
    noHeader: { type: Boolean, default: false },
    noTrap: { type: Boolean, default: false },
    noHeaderClose: { type: Boolean, default: false },
    placement: { default: "start" },
    shadow: { type: [String, Boolean], default: false },
    title: { default: void 0 },
    responsive: {},
    width: { default: void 0 },
    teleportDisabled: { type: Boolean, default: false },
    teleportTo: { default: "body" },
    initialAnimation: { type: Boolean, default: false },
    noAnimation: { type: Boolean, default: false },
    noFade: { type: Boolean },
    lazy: { type: Boolean, default: false },
    unmountLazy: { type: Boolean, default: false },
    show: { type: Boolean, default: false },
    transProps: {},
    visible: { type: Boolean, default: false }
  }, {
    "modelValue": { type: Boolean, ...{
      default: false
    } },
    "modelModifiers": {}
  }),
  emits: /* @__PURE__ */ vue.mergeModels(["close", "esc", "backdrop", "breakpoint", "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, "BOffcanvas");
    const emit = __emit;
    const slots = vue.useSlots();
    const modelValue = vue.useModel(__props, "modelValue");
    const computedId = useId.useId(() => props.id, "offcanvas");
    const element = vue.useTemplateRef("_element");
    const fallbackFocusElement = vue.useTemplateRef("_fallbackFocusElement");
    const closeButton = vue.useTemplateRef("_close");
    const pickFocusItem = () => {
      if (props.focus && typeof props.focus !== "boolean") {
        if (props.focus === "close") {
          return closeButton;
        }
        return getElement.getElement(props.focus, element.value ?? void 0);
      }
      return element;
    };
    const onAfterEnter = () => {
      vue.nextTick(() => {
        if (props.focus !== false && !isOpenByBreakpoint.value && props.noTrap) {
          const focusElement = index.unrefElement(pickFocusItem());
          focusElement?.focus();
        }
      });
    };
    const {
      showRef,
      renderRef,
      renderBackdropRef,
      hide,
      show,
      toggle,
      computedNoAnimation,
      contentShowing,
      transitionProps,
      backdropReady,
      backdropTransitionProps,
      backdropVisible,
      isVisible,
      buildTriggerableEvent,
      isLeaving,
      trapActive,
      setLocalNoAnimation
    } = useShowHide.useShowHide(modelValue, props, emit, element, computedId, {
      transitionProps: {
        onAfterEnter,
        enterToClass: "showing",
        leaveToClass: "hiding",
        enterActiveClass: "",
        leaveActiveClass: "",
        enterFromClass: "",
        leaveFromClass: ""
      }
    });
    const breakpoints = index.useBreakpoints(index.breakpointsBootstrapV5);
    const smallerOrEqualToBreakpoint = breakpoints.smallerOrEqual(() => props.responsive ?? "xs");
    const isOpenByBreakpoint = vue.ref(false);
    vue.onMounted(() => {
      if (props.responsive !== void 0) {
        isOpenByBreakpoint.value = !smallerOrEqualToBreakpoint.value;
        emit("breakpoint", buildTriggerableEvent("breakpoint"), isOpenByBreakpoint.value);
      }
    });
    useSafeScrollLock.useSafeScrollLock(showRef, () => props.bodyScrolling || isOpenByBreakpoint.value);
    index.onKeyStroke(
      "Escape",
      () => {
        hide("esc");
      },
      { target: element }
    );
    const { needsFallback } = useSafeScrollLock.useActivatedFocusTrap({
      element,
      isActive: trapActive,
      noTrap: () => props.noTrap || isOpenByBreakpoint.value,
      fallbackFocus: {
        classSelector: fallbackClassSelector,
        ref: fallbackFocusElement
      },
      focus: () => props.focus === false || isOpenByBreakpoint.value ? false : index.unrefElement(pickFocusItem()) ?? void 0
    });
    const showBackdrop = vue.computed(
      () => (props.responsive === void 0 || !isOpenByBreakpoint.value) && props.noBackdrop === false && (showRef.value === true || isLeaving.value && props.backdropFirst && !computedNoAnimation.value)
    );
    const hasHeaderCloseSlot = vue.computed(() => !dom.isEmptySlot(slots["header-close"]));
    const headerCloseClasses = vue.computed(() => [
      { "text-reset": !hasHeaderCloseSlot.value },
      props.headerCloseClass
    ]);
    const headerCloseAttrs = vue.computed(() => ({
      variant: hasHeaderCloseSlot.value ? props.headerCloseVariant : void 0,
      class: headerCloseClasses.value
    }));
    const hasFooterSlot = vue.computed(() => !dom.isEmptySlot(slots.footer));
    const computedClasses = vue.computed(() => [
      props.responsive === void 0 ? "offcanvas" : `offcanvas-${props.responsive}`,
      `offcanvas-${props.placement}`,
      {
        "show": isVisible.value,
        [`shadow-${props.shadow}`]: !!props.shadow,
        "no-transition": computedNoAnimation.value
      }
    ]);
    const computedStyles = vue.computed(() => ({
      width: props.width
    }));
    const sharedSlots = vue.computed(() => ({
      visible: isVisible.value,
      placement: props.placement,
      hide,
      show,
      toggle,
      id: computedId.value,
      active: trapActive.value
    }));
    vue.watch(smallerOrEqualToBreakpoint, (newValue) => {
      if (props.responsive === void 0) return;
      if (newValue === true) {
        const opened = false;
        setLocalNoAnimation(true);
        requestAnimationFrame(() => {
          isOpenByBreakpoint.value = opened;
        });
        emit("breakpoint", buildTriggerableEvent("breakpoint"), opened);
        emit("hide", buildTriggerableEvent("hide"));
      } else {
        const opened = true;
        setLocalNoAnimation(true);
        requestAnimationFrame(() => {
          isOpenByBreakpoint.value = opened;
        });
        emit("breakpoint", buildTriggerableEvent("breakpoint"), opened);
        emit("show", buildTriggerableEvent("show"));
      }
    });
    __expose({
      hide,
      show,
      toggle,
      isOpenByBreakpoint
    });
    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 || isOpenByBreakpoint.value
      }, {
        default: vue.withCtx(() => [
          vue.unref(renderRef) || vue.unref(contentShowing) || isOpenByBreakpoint.value ? (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",
                "aria-modal": "true",
                role: "dialog",
                class: computedClasses.value,
                style: computedStyles.value,
                tabindex: "-1",
                "aria-labelledby": `${vue.unref(computedId)}-offcanvas-label`,
                "data-bs-backdrop": "false"
              }, _ctx.$attrs), [
                vue.unref(contentShowing) || isOpenByBreakpoint.value ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
                  !vue.unref(props).noHeader ? (vue.openBlock(), vue.createElementBlock("div", vue.mergeProps({
                    key: 0,
                    class: ["offcanvas-header", vue.unref(props).headerClass]
                  }, vue.unref(props).headerAttrs), [
                    vue.renderSlot(_ctx.$slots, "header", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)), () => [
                      vue.createElementVNode("h5", {
                        id: `${vue.unref(computedId)}-offcanvas-label`,
                        class: "offcanvas-title"
                      }, [
                        vue.renderSlot(_ctx.$slots, "title", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)), () => [
                          vue.createTextVNode(vue.toDisplayString(vue.unref(props).title), 1)
                        ])
                      ], 8, _hoisted_2),
                      !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: "_close"
                        }, 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: "_close",
                          "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({
                    class: ["offcanvas-body", vue.unref(props).bodyClass]
                  }, vue.unref(props).bodyAttrs), [
                    vue.renderSlot(_ctx.$slots, "default", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)))
                  ], 16),
                  hasFooterSlot.value ? (vue.openBlock(), vue.createElementBlock("div", {
                    key: 1,
                    class: vue.normalizeClass(vue.unref(props).footerClass)
                  }, [
                    vue.renderSlot(_ctx.$slots, "footer", vue.normalizeProps(vue.guardReactiveProps(sharedSlots.value)))
                  ], 2)) : vue.createCommentVNode("", true)
                ], 64)) : vue.createCommentVNode("", true),
                vue.unref(needsFallback) ? (vue.openBlock(), vue.createElementBlock("div", {
                  key: 1,
                  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) || isOpenByBreakpoint.value
                ]
              ])
            ]),
            _: 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(["offcanvas-backdrop", {
                    fade: !vue.unref(computedNoAnimation),
                    show: vue.unref(backdropVisible) || vue.unref(computedNoAnimation)
                  }]),
                  onClick: _cache[2] || (_cache[2] = ($event) => vue.unref(hide)("backdrop"))
                }, null, 2), [
                  [vue.vShow, showBackdrop.value]
                ])
              ]),
              _: 1
            }, 16)) : vue.createCommentVNode("", true)
          ]) : vue.createCommentVNode("", true)
        ]),
        _: 3
      }, 8, ["to", "disabled"]);
    };
  }
});
exports._sfc_main = _sfc_main;
//# sourceMappingURL=BOffcanvas.vue_vue_type_script_setup_true_lang-C8cdZALa.js.map
