UNPKG

bootstrap-vue-next

Version:

BootstrapVueNext is an early and lovely component library for Vue 3 & Nuxt 3 based on Bootstrap 5 and Typescript.

313 lines (312 loc) 14.1 kB
import { defineComponent, mergeModels, useSlots, useModel, useTemplateRef, ref, onMounted, computed, watch, createBlock, openBlock, unref, withCtx, createCommentVNode, renderSlot, Transition, mergeProps, withDirectives, createElementVNode, createElementBlock, Fragment, normalizeClass, normalizeProps, guardReactiveProps, createTextVNode, toDisplayString, vShow, nextTick } from "vue"; import { l as useBreakpoints, o as onKeyStroke, f as unrefElement, m as breakpointsBootstrapV5 } from "./index-CMqRvrZx.mjs"; import { a as useSafeScrollLock, u as useActivatedFocusTrap } from "./useSafeScrollLock-DX55jDcC.mjs"; import { u as useDefaults } from "./useDefaults-CzkRF2AY.mjs"; import { u as useId } from "./useId-BmZnPXsS.mjs"; import { _ as _sfc_main$2 } from "./BButton.vue_vue_type_script_setup_true_lang-CywtlN38.mjs"; import { _ as _sfc_main$3 } from "./BCloseButton.vue_vue_type_script_setup_true_lang-DjJD_nYp.mjs"; import { _ as _sfc_main$1 } from "./ConditionalTeleport.vue_vue_type_script_lang-BCI6afpC.mjs"; import { i as isEmptySlot } from "./dom-BK2w00Ec.mjs"; import { u as useShowHide } from "./useShowHide-CguGFDSN.mjs"; import { g as getElement } from "./getElement-WfnRgCbF.mjs"; import { _ as _export_sfc } from "./_plugin-vue_export-helper-1tPrXgE0.mjs"; const _hoisted_1 = ["id", "aria-labelledby"]; const _hoisted_2 = ["id"]; const fallbackClassSelector = "offcanvas-fallback-focus"; const _sfc_main = /* @__PURE__ */ defineComponent({ ...{ inheritAttrs: false }, __name: "BOffcanvas", props: /* @__PURE__ */ 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 }, 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__ */ 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(_props, "BOffcanvas"); const emit = __emit; const slots = useSlots(); const modelValue = useModel(__props, "modelValue"); const computedId = useId(() => props.id, "offcanvas"); const element = useTemplateRef("_element"); const fallbackFocusElement = useTemplateRef("_fallbackFocusElement"); const closeButton = useTemplateRef("_close"); const pickFocusItem = () => { if (props.focus && typeof props.focus !== "boolean") { if (props.focus === "close") { return closeButton; } return getElement(props.focus, element.value ?? void 0); } return element; }; const onAfterEnter = () => { nextTick(() => { if (props.focus !== false && !isOpenByBreakpoint.value && props.noTrap) { const focusElement = unrefElement(pickFocusItem()); focusElement == null ? void 0 : focusElement.focus(); } }); }; const { showRef, renderRef, renderBackdropRef, hide, show, toggle, computedNoAnimation, contentShowing, transitionProps, backdropReady, backdropTransitionProps, backdropVisible, isVisible, buildTriggerableEvent, localNoAnimation, isLeaving, trapActive } = useShowHide(modelValue, props, emit, element, computedId, { transitionProps: { onAfterEnter, enterToClass: "showing", leaveToClass: "hiding", enterActiveClass: "", leaveActiveClass: "", enterFromClass: "", leaveFromClass: "" } }); const breakpoints = useBreakpoints(breakpointsBootstrapV5); const smallerOrEqualToBreakpoint = breakpoints.smallerOrEqual(() => props.responsive ?? "xs"); const isOpenByBreakpoint = ref(props.responsive !== void 0 && !smallerOrEqualToBreakpoint.value); onMounted(() => { if (props.responsive !== void 0) emit("breakpoint", buildTriggerableEvent("breakpoint"), isOpenByBreakpoint.value); }); useSafeScrollLock(showRef, () => props.bodyScrolling || isOpenByBreakpoint.value); onKeyStroke( "Escape", () => { hide("esc"); }, { target: element } ); const { needsFallback } = useActivatedFocusTrap({ element, isActive: trapActive, noTrap: () => props.noTrap || isOpenByBreakpoint.value, fallbackFocus: { classSelector: fallbackClassSelector, ref: fallbackFocusElement }, focus: () => props.focus === false || isOpenByBreakpoint.value ? false : unrefElement(pickFocusItem()) ?? void 0 }); const showBackdrop = computed( () => (props.responsive === void 0 || !isOpenByBreakpoint.value) && props.noBackdrop === false && (showRef.value === true || isLeaving.value && props.backdropFirst && !computedNoAnimation.value) ); const hasHeaderCloseSlot = computed(() => !isEmptySlot(slots["header-close"])); const headerCloseClasses = computed(() => [ { "text-reset": !hasHeaderCloseSlot.value }, props.headerCloseClass ]); const headerCloseAttrs = computed(() => ({ variant: hasHeaderCloseSlot.value ? props.headerCloseVariant : void 0, class: headerCloseClasses.value })); const hasFooterSlot = computed(() => !isEmptySlot(slots.footer)); const computedClasses = 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 = computed(() => ({ width: props.width })); const sharedSlots = computed(() => ({ visible: isVisible.value, placement: props.placement, hide, show, toggle, id: computedId.value, active: trapActive.value })); watch(smallerOrEqualToBreakpoint, (newValue) => { if (props.responsive === void 0) return; if (newValue === true) { const opened = false; localNoAnimation.value = true; requestAnimationFrame(() => { isOpenByBreakpoint.value = opened; }); emit("breakpoint", buildTriggerableEvent("breakpoint"), opened); emit("hide", buildTriggerableEvent("hide")); } else { const opened = true; localNoAnimation.value = true; requestAnimationFrame(() => { isOpenByBreakpoint.value = opened; }); emit("breakpoint", buildTriggerableEvent("breakpoint"), opened); emit("show", buildTriggerableEvent("show")); } }); __expose({ hide, show, toggle, isOpenByBreakpoint }); return (_ctx, _cache) => { return openBlock(), createBlock(_sfc_main$1, { to: unref(props).teleportTo, disabled: unref(props).teleportDisabled || isOpenByBreakpoint.value }, { default: withCtx(() => [ unref(renderRef) || unref(contentShowing) || isOpenByBreakpoint.value ? (openBlock(), createBlock(Transition, mergeProps({ key: 0 }, unref(transitionProps), { appear: modelValue.value || unref(props).visible }), { default: withCtx(() => [ withDirectives(createElementVNode("div", mergeProps({ id: unref(computedId), ref: "_element", "aria-modal": "true", role: "dialog", class: computedClasses.value, style: computedStyles.value, tabindex: "-1", "aria-labelledby": `${unref(computedId)}-offcanvas-label`, "data-bs-backdrop": "false" }, _ctx.$attrs), [ unref(contentShowing) || isOpenByBreakpoint.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [ !unref(props).noHeader ? (openBlock(), createElementBlock("div", { key: 0, class: normalizeClass(["offcanvas-header", unref(props).headerClass]) }, [ renderSlot(_ctx.$slots, "header", normalizeProps(guardReactiveProps(sharedSlots.value)), () => [ createElementVNode("h5", { id: `${unref(computedId)}-offcanvas-label`, class: "offcanvas-title" }, [ renderSlot(_ctx.$slots, "title", normalizeProps(guardReactiveProps(sharedSlots.value)), () => [ createTextVNode(toDisplayString(unref(props).title), 1) ], true) ], 8, _hoisted_2), !unref(props).noHeaderClose ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [ hasHeaderCloseSlot.value ? (openBlock(), createBlock(_sfc_main$2, mergeProps({ key: 0, ref: "_close" }, headerCloseAttrs.value, { onClick: _cache[0] || (_cache[0] = ($event) => unref(hide)("close")) }), { default: withCtx(() => [ renderSlot(_ctx.$slots, "header-close", normalizeProps(guardReactiveProps(sharedSlots.value)), void 0, true) ]), _: 3 }, 16)) : (openBlock(), createBlock(_sfc_main$3, mergeProps({ key: 1, ref: "_close", "aria-label": unref(props).headerCloseLabel }, headerCloseAttrs.value, { onClick: _cache[1] || (_cache[1] = ($event) => unref(hide)("close")) }), null, 16, ["aria-label"])) ], 64)) : createCommentVNode("", true) ], true) ], 2)) : createCommentVNode("", true), createElementVNode("div", mergeProps({ class: ["offcanvas-body", unref(props).bodyClass] }, unref(props).bodyAttrs), [ renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(sharedSlots.value)), void 0, true) ], 16), hasFooterSlot.value ? (openBlock(), createElementBlock("div", { key: 1, class: normalizeClass(unref(props).footerClass) }, [ renderSlot(_ctx.$slots, "footer", normalizeProps(guardReactiveProps(sharedSlots.value)), void 0, true) ], 2)) : createCommentVNode("", true) ], 64)) : createCommentVNode("", true), unref(needsFallback) ? (openBlock(), createElementBlock("div", { key: 1, ref: "_fallbackFocusElement", class: normalizeClass(fallbackClassSelector), tabindex: "0", style: { "width": "0", "height": "0", "overflow": "hidden" } }, null, 512)) : createCommentVNode("", true) ], 16, _hoisted_1), [ [ vShow, unref(showRef) && (unref(backdropReady) && unref(props).backdropFirst || !unref(props).backdropFirst) || isOpenByBreakpoint.value ] ]) ]), _: 3 }, 16, ["appear"])) : createCommentVNode("", true), !unref(props).noBackdrop ? renderSlot(_ctx.$slots, "backdrop", normalizeProps(mergeProps({ key: 1 }, sharedSlots.value)), () => [ unref(renderBackdropRef) ? (openBlock(), createBlock(Transition, normalizeProps(mergeProps({ key: 0 }, unref(backdropTransitionProps))), { default: withCtx(() => [ withDirectives(createElementVNode("div", { class: normalizeClass(["offcanvas-backdrop", { fade: !unref(computedNoAnimation), show: unref(backdropVisible) || unref(computedNoAnimation) }]), onClick: _cache[2] || (_cache[2] = ($event) => unref(hide)("backdrop")) }, null, 2), [ [vShow, showBackdrop.value] ]) ]), _: 1 }, 16)) : createCommentVNode("", true) ], true) : createCommentVNode("", true) ]), _: 3 }, 8, ["to", "disabled"]); }; } }); const BOffcanvas = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-d3f94528"]]); export { BOffcanvas as B }; //# sourceMappingURL=BOffcanvas-DH1MW9Or.mjs.map