UNPKG

bootstrap-vue-next

Version:

Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development

518 lines (517 loc) 21.4 kB
require("./chunk-CoQrYLCe.js"); const require_keys = require("./keys-durSVUrO.js"); const require_dist = require("./dist-B_c893QG.js"); const require_dom = require("./dom-Bs6DzM72.js"); const require_useDefaults = require("./useDefaults-DsLf4iRY.js"); const require_useId = require("./useId-DHrBgM7P.js"); const require_useShowHide = require("./useShowHide-sLzwukNm.js"); const require_useColorVariantClasses = require("./useColorVariantClasses-CEfOwjPv.js"); const require_BButton = require("./BButton-sb1cBCIb.js"); const require_BCloseButton = require("./BCloseButton-CN__Jjcj.js"); const require_ConditionalTeleport = require("./ConditionalTeleport-BJZk6HAx.js"); const require_getElement = require("./getElement-BPm7tpe2.js"); const require_useSafeScrollLock = require("./useSafeScrollLock-xJBEvCQ7.js"); let vue = require("vue"); //#region src/composables/useModalManager.ts var modalOpenClassName = "modal-open"; var useSharedModalStack = () => { const modalManagerPlugin = (0, vue.inject)(require_keys.modalManagerKey, null); /** * Removes an item from both the stack and registry */ const dispose = (modal) => { modalManagerPlugin?.removeStack(modal); modalManagerPlugin?.removeRegistry(modal); }; const updateHTMLAttrs = require_dist.getSSRHandler("updateHTMLAttrs", (selector, attribute, value) => { const el = typeof selector !== "string" ? require_dist.unrefElement(selector) : selector ? require_dom.getSafeDocument()?.querySelector(selector) : void 0; if (!el) return; if (attribute === "class") el.classList.toggle(modalOpenClassName, value === modalOpenClassName); else el.setAttribute(attribute, value); }); require_dist.tryOnScopeDispose(() => { if (modalManagerPlugin?.countStack.value === 0) updateHTMLAttrs("body", "class", ""); }); (0, vue.watch)(() => modalManagerPlugin?.countStack.value, (newValue) => { if (newValue === void 0) return; updateHTMLAttrs("body", "class", newValue > 0 ? modalOpenClassName : ""); }); return { ...modalManagerPlugin, dispose }; }; var useModalManager = (modalOpen, initialValue) => { const { pushRegistry, pushStack, removeStack, stack, dispose, countStack } = useSharedModalStack(); const currentModal = (0, vue.getCurrentInstance)(); if (!currentModal || currentModal.type.__name !== "BModal") throw new Error("useModalManager must only use in BModal component"); pushRegistry?.(currentModal); require_dist.tryOnScopeDispose(() => { dispose(currentModal); }); const setInStack = (newValue, oldValue) => { if (newValue) pushStack?.(currentModal); else if (oldValue && !newValue) removeStack?.(currentModal); }; setInStack(initialValue, initialValue); (0, vue.watch)(modalOpen, setInStack); return { activePosition: (0, vue.computed)(() => stack?.value.findIndex((el) => (0, vue.toValue)(el.exposed?.id) === (0, vue.toValue)(currentModal.exposed?.id))), activeModalCount: countStack, stackWithoutSelf: (0, vue.computed)(() => stack?.value.filter((el) => (0, vue.toValue)(el.exposed?.id) !== (0, vue.toValue)(currentModal.exposed?.id)) ?? []) }; }; //#endregion //#region src/components/BModal/BModal.vue?vue&type=script&setup=true&lang.ts var _hoisted_1 = [ "id", "aria-labelledby", "aria-describedby" ]; var _hoisted_2 = ["id"]; var fallbackClassSelector = "modal-fallback-focus"; //#endregion //#region src/components/BModal/BModal.vue var BModal_default = /* @__PURE__ */ (0, vue.defineComponent)({ inheritAttrs: false, __name: "BModal", props: /* @__PURE__ */ (0, 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__ */ (0, 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 = require_useDefaults.useDefaults(__props, "BModal"); const emit = __emit; const slots = (0, vue.useSlots)(); const computedId = require_useId.useId(() => props.id, "modal"); const modelValue = (0, vue.useModel)(__props, "modelValue"); const element = (0, vue.useTemplateRef)("_element"); const fallbackFocusElement = (0, vue.useTemplateRef)("_fallbackFocusElement"); const okButton = (0, vue.useTemplateRef)("_okButton"); const cancelButton = (0, vue.useTemplateRef)("_cancelButton"); const closeButton = (0, 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 require_getElement.getElement(props.focus, element.value ?? void 0) ?? element.value; } return element; }; let activeElement = null; const onAfterEnter = () => { const doc = require_dom.getSafeDocument(); if (props.noTrap && props.focus !== false && doc) { activeElement = doc.activeElement; if (activeElement === element.value) activeElement = null; const el = require_dist.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 } = require_useShowHide.useShowHide(modelValue, props, emit, element, computedId, { transitionProps: { onAfterEnter, onAfterLeave } }); const { needsFallback } = require_useSafeScrollLock.useActivatedFocusTrap({ element, isActive: trapActive, noTrap: () => props.noTrap, fallbackFocus: { ref: fallbackFocusElement, classSelector: fallbackClassSelector }, focus: () => props.focus === false ? false : require_dist.unrefElement(pickFocusItem()) ?? void 0 }); require_dist.onKeyStroke("Escape", () => { hide("esc"); }, { target: element }); require_useSafeScrollLock.useSafeScrollLock(showRef, () => props.bodyScrolling); const hasHeaderCloseSlot = (0, vue.computed)(() => !require_dom.isEmptySlot(slots["header-close"])); const modalDialogClasses = (0, 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 = require_useColorVariantClasses.useColorVariantClasses(() => ({ bgVariant: props.bodyBgVariant, textVariant: props.bodyTextVariant, variant: props.bodyVariant })); const bodyClasses = (0, vue.computed)(() => [props.bodyClass, bodyColorClasses.value]); const headerColorClasses = require_useColorVariantClasses.useColorVariantClasses(() => ({ bgVariant: props.headerBgVariant, textVariant: props.headerTextVariant, variant: props.headerVariant, borderVariant: props.headerBorderVariant })); const headerClasses = (0, vue.computed)(() => [props.headerClass, headerColorClasses.value]); const headerCloseAttrs = (0, vue.computed)(() => ({ variant: hasHeaderCloseSlot.value ? props.headerCloseVariant : void 0, class: props.headerCloseClass })); const footerColorClasses = require_useColorVariantClasses.useColorVariantClasses(() => ({ bgVariant: props.footerBgVariant, textVariant: props.footerTextVariant, variant: props.footerVariant, borderVariant: props.footerBorderVariant })); const footerClasses = (0, vue.computed)(() => [props.footerClass, footerColorClasses.value]); const titleClasses = (0, vue.computed)(() => [props.titleClass, { ["visually-hidden"]: props.titleVisuallyHidden }]); const disableCancel = (0, vue.computed)(() => props.cancelDisabled || props.busy); const disableOk = (0, vue.computed)(() => props.okDisabled || props.busy); const { activePosition, activeModalCount, stackWithoutSelf } = useModalManager(showRef, modelValue.value); const sharedClasses = (0, vue.computed)(() => ({ [`stack-position-${activePosition?.value ?? 0}`]: true, [`stack-inverse-position-${(activeModalCount?.value ?? 1) - 1 - (activePosition?.value ?? 0)}`]: true })); (0, vue.watch)(stackWithoutSelf, (newValue, oldValue) => { if (newValue.length > oldValue.length && showRef.value === true && props.noStacking) hide(); }); const defaultModalDialogZIndex = (0, vue.ref)(require_dom.getModalZIndex(element.value ?? require_dom.getSafeDocument()?.body)); (0, vue.onMounted)(() => { (0, vue.watch)(renderRef, (v) => { if (!v) return; (0, vue.nextTick)(() => { if (!element.value) return; defaultModalDialogZIndex.value = require_dom.getModalZIndex(element.value); }); }, { immediate: true }); }); const computedZIndexNumber = (0, vue.computed)(() => showRef.value || isLeaving.value ? defaultModalDialogZIndex.value - ((activeModalCount?.value ?? 0) * 2 - (activePosition?.value ?? 0) * 2) : defaultModalDialogZIndex.value); const computedZIndex = (0, 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 = (0, 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 = (0, 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 (0, vue.openBlock)(), (0, vue.createBlock)(require_ConditionalTeleport.ConditionalTeleport_default, { to: (0, vue.unref)(props).teleportTo, disabled: (0, vue.unref)(props).teleportDisabled }, { default: (0, vue.withCtx)(() => [(0, vue.unref)(renderRef) || (0, vue.unref)(contentShowing) ? ((0, vue.openBlock)(), (0, vue.createBlock)(vue.Transition, (0, vue.mergeProps)({ key: 0 }, (0, vue.unref)(transitionProps), { appear: modelValue.value || (0, vue.unref)(props).visible }), { default: (0, vue.withCtx)(() => [(0, vue.withDirectives)((0, vue.createElementVNode)("div", (0, vue.mergeProps)({ id: (0, vue.unref)(computedId), ref: "_element", class: ["modal", [(0, vue.unref)(props).modalClass, { fade: !(0, vue.unref)(computedNoAnimation), show: (0, vue.unref)(isVisible), ...sharedClasses.value }]], role: "dialog", "aria-labelledby": !(0, vue.unref)(props).noHeader ? `${(0, vue.unref)(computedId)}-label` : void 0, "aria-describedby": `${(0, vue.unref)(computedId)}-body`, tabindex: "-1" }, _ctx.$attrs, { style: [computedZIndex.value, { "display": "block" }], onMousedown: _cache[4] || (_cache[4] = (0, vue.withModifiers)(($event) => (0, vue.unref)(hide)("backdrop"), ["left", "self"])) }), [(0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["modal-dialog", modalDialogClasses.value]) }, [(0, vue.unref)(contentShowing) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 0, class: (0, vue.normalizeClass)(["modal-content", (0, vue.unref)(props).contentClass]) }, [ !(0, vue.unref)(props).noHeader ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", (0, vue.mergeProps)({ key: 0, class: ["modal-header", headerClasses.value] }, (0, vue.unref)(props).headerAttrs), [(0, vue.renderSlot)(_ctx.$slots, "header", (0, vue.normalizeProps)((0, vue.guardReactiveProps)(sharedSlots.value)), () => [((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(props).titleTag), { id: `${(0, vue.unref)(computedId)}-label`, class: (0, vue.normalizeClass)(["modal-title", titleClasses.value]) }, { default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "title", (0, vue.normalizeProps)((0, vue.guardReactiveProps)(sharedSlots.value)), () => [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(props).title), 1)])]), _: 3 }, 8, ["id", "class"])), !(0, vue.unref)(props).noHeaderClose ? ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 0 }, [hasHeaderCloseSlot.value ? ((0, vue.openBlock)(), (0, vue.createBlock)(require_BButton.BButton_default, (0, vue.mergeProps)({ key: 0, ref: "_closeButton" }, headerCloseAttrs.value, { onClick: _cache[0] || (_cache[0] = ($event) => (0, vue.unref)(hide)("close")) }), { default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "header-close", (0, vue.normalizeProps)((0, vue.guardReactiveProps)(sharedSlots.value)))]), _: 3 }, 16)) : ((0, vue.openBlock)(), (0, vue.createBlock)(require_BCloseButton.BCloseButton_default, (0, vue.mergeProps)({ key: 1, ref: "_closeButton", "aria-label": (0, vue.unref)(props).headerCloseLabel }, headerCloseAttrs.value, { onClick: _cache[1] || (_cache[1] = ($event) => (0, vue.unref)(hide)("close")) }), null, 16, ["aria-label"]))], 64)) : (0, vue.createCommentVNode)("", true)])], 16)) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("div", (0, vue.mergeProps)({ id: `${(0, vue.unref)(computedId)}-body`, class: ["modal-body", bodyClasses.value] }, (0, vue.unref)(props).bodyAttrs), [(0, vue.renderSlot)(_ctx.$slots, "default", (0, vue.normalizeProps)((0, vue.guardReactiveProps)(sharedSlots.value)), () => [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(props).body), 1)])], 16, _hoisted_2), !(0, vue.unref)(props).noFooter ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 1, class: (0, vue.normalizeClass)(["modal-footer", footerClasses.value]) }, [(0, vue.renderSlot)(_ctx.$slots, "footer", (0, vue.normalizeProps)((0, vue.guardReactiveProps)(sharedSlots.value)), () => [(0, vue.renderSlot)(_ctx.$slots, "cancel", (0, vue.normalizeProps)((0, vue.guardReactiveProps)(sharedSlots.value)), () => [!(0, vue.unref)(props).okOnly ? ((0, vue.openBlock)(), (0, vue.createBlock)(require_BButton.BButton_default, { key: 0, ref: "_cancelButton", disabled: disableCancel.value, size: (0, vue.unref)(props).buttonSize, variant: (0, vue.unref)(props).cancelVariant, class: (0, vue.normalizeClass)((0, vue.unref)(props).cancelClass), onClick: _cache[2] || (_cache[2] = ($event) => (0, vue.unref)(hide)("cancel")) }, { default: (0, vue.withCtx)(() => [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(props).cancelTitle), 1)]), _: 1 }, 8, [ "disabled", "size", "variant", "class" ])) : (0, vue.createCommentVNode)("", true)]), (0, vue.renderSlot)(_ctx.$slots, "ok", (0, vue.normalizeProps)((0, vue.guardReactiveProps)(sharedSlots.value)), () => [(0, vue.createVNode)(require_BButton.BButton_default, { ref: "_okButton", disabled: disableOk.value, size: (0, vue.unref)(props).buttonSize, variant: (0, vue.unref)(props).okVariant, class: (0, vue.normalizeClass)((0, vue.unref)(props).okClass), onClick: _cache[3] || (_cache[3] = ($event) => (0, vue.unref)(hide)("ok")) }, { default: (0, vue.withCtx)(() => [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(props).okTitle), 1)]), _: 1 }, 8, [ "disabled", "size", "variant", "class" ])])])], 2)) : (0, vue.createCommentVNode)("", true) ], 2)) : (0, vue.createCommentVNode)("", true)], 2), (0, vue.unref)(needsFallback) ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: 0, ref: "_fallbackFocusElement", class: (0, vue.normalizeClass)(fallbackClassSelector), tabindex: "0", style: { "width": "0", "height": "0", "overflow": "hidden" } }, null, 512)) : (0, vue.createCommentVNode)("", true)], 16, _hoisted_1), [[vue.vShow, (0, vue.unref)(showRef) && ((0, vue.unref)(backdropReady) && (0, vue.unref)(props).backdropFirst || !(0, vue.unref)(props).backdropFirst)]])]), _: 3 }, 16, ["appear"])) : (0, vue.createCommentVNode)("", true), !(0, vue.unref)(props).noBackdrop ? (0, vue.renderSlot)(_ctx.$slots, "backdrop", (0, vue.normalizeProps)((0, vue.mergeProps)({ key: 1 }, sharedSlots.value)), () => [(0, vue.unref)(renderBackdropRef) ? ((0, vue.openBlock)(), (0, vue.createBlock)(vue.Transition, (0, vue.normalizeProps)((0, vue.mergeProps)({ key: 0 }, (0, vue.unref)(backdropTransitionProps))), { default: (0, vue.withCtx)(() => [(0, vue.withDirectives)((0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["modal-backdrop", { fade: !(0, vue.unref)(computedNoAnimation), show: (0, vue.unref)(backdropVisible) || (0, vue.unref)(computedNoAnimation), ...sharedClasses.value }]), style: (0, vue.normalizeStyle)(computedZIndexBackdrop.value), onClick: _cache[5] || (_cache[5] = ($event) => (0, vue.unref)(hide)("backdrop")) }, null, 6), [[vue.vShow, (0, vue.unref)(showRef) || (0, vue.unref)(isLeaving) && (0, vue.unref)(props).backdropFirst && !(0, vue.unref)(computedNoAnimation)]])]), _: 1 }, 16)) : (0, vue.createCommentVNode)("", true)]) : (0, vue.createCommentVNode)("", true)]), _: 3 }, 8, ["to", "disabled"]); }; } }); //#endregion Object.defineProperty(exports, "BModal_default", { enumerable: true, get: function() { return BModal_default; } }); Object.defineProperty(exports, "useSharedModalStack", { enumerable: true, get: function() { return useSharedModalStack; } }); //# sourceMappingURL=BModal-CVf686JS.js.map