UNPKG

bootstrap-vue

Version:

BootstrapVue, with over 40 plugins and more than 75 custom components, provides one of the most comprehensive implementations of Bootstrap v4 components and grid system for Vue.js. With extensive and automated WAI-ARIA accessibility markup.

999 lines (883 loc) 30.3 kB
"use strict"; exports.__esModule = true; exports.default = exports.BModal = exports.props = void 0; var _vue = _interopRequireDefault(require("../../utils/vue")); var _modalManager = _interopRequireDefault(require("./helpers/modal-manager")); var _bvModalEvent = _interopRequireDefault(require("./helpers/bv-modal-event.class")); var _id = _interopRequireDefault(require("../../mixins/id")); var _listenOnRoot = _interopRequireDefault(require("../../mixins/listen-on-root")); var _normalizeSlot = _interopRequireDefault(require("../../mixins/normalize-slot")); var _bvTransition = _interopRequireDefault(require("../../utils/bv-transition")); var _keyCodes = _interopRequireDefault(require("../../utils/key-codes")); var _observeDom = _interopRequireDefault(require("../../utils/observe-dom")); var _transporter = require("../../utils/transporter"); var _env = require("../../utils/env"); var _inspect = require("../../utils/inspect"); var _config = require("../../utils/config"); var _html = require("../../utils/html"); var _dom = require("../../utils/dom"); var _button = require("../button/button"); var _buttonClose = require("../button/button-close"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } // --- Constants --- var NAME = 'BModal'; // ObserveDom config to detect changes in modal content // so that we can adjust the modal padding if needed var OBSERVER_CONFIG = { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: ['style', 'class'] // Options for DOM event listeners }; var EVT_OPTIONS = { passive: true, capture: false }; var props = { title: { type: String, default: '' }, titleHtml: { type: String }, titleTag: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'titleTag'); } }, size: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'size'); } }, centered: { type: Boolean, default: false }, scrollable: { type: Boolean, default: false }, buttonSize: { type: String, default: '' }, noStacking: { type: Boolean, default: false }, noFade: { type: Boolean, default: false }, noCloseOnBackdrop: { type: Boolean, default: false }, noCloseOnEsc: { type: Boolean, default: false }, noEnforceFocus: { type: Boolean, default: false }, headerBgVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'headerBgVariant'); } }, headerBorderVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'headerBorderVariant'); } }, headerTextVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'headerTextVariant'); } }, headerCloseVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'headerCloseVariant'); } }, headerClass: { type: [String, Array], default: null }, bodyBgVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'bodyBgVariant'); } }, bodyTextVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'bodyTextVariant'); } }, modalClass: { type: [String, Array], default: null }, dialogClass: { type: [String, Array], default: null }, contentClass: { type: [String, Array], default: null }, bodyClass: { type: [String, Array], default: null }, footerBgVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'footerBgVariant'); } }, footerBorderVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'footerBorderVariant'); } }, footerTextVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'footerTextVariant'); } }, footerClass: { type: [String, Array], default: null }, hideHeader: { type: Boolean, default: false }, hideFooter: { type: Boolean, default: false }, hideHeaderClose: { type: Boolean, default: false }, hideBackdrop: { type: Boolean, default: false }, okOnly: { type: Boolean, default: false }, okDisabled: { type: Boolean, default: false }, cancelDisabled: { type: Boolean, default: false }, visible: { type: Boolean, default: false }, returnFocus: { // type: Object, default: null }, headerCloseLabel: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'headerCloseLabel'); } }, cancelTitle: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'cancelTitle'); } }, cancelTitleHtml: { type: String }, okTitle: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'okTitle'); } }, okTitleHtml: { type: String }, cancelVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'cancelVariant'); } }, okVariant: { type: String, default: function _default() { return (0, _config.getComponentConfig)(NAME, 'okVariant'); } }, lazy: { type: Boolean, default: false }, busy: { type: Boolean, default: false }, static: { type: Boolean, default: false } // @vue/component }; exports.props = props; var BModal = /*#__PURE__*/ _vue.default.extend({ name: NAME, mixins: [_id.default, _listenOnRoot.default, _normalizeSlot.default], model: { prop: 'visible', event: 'change' }, props: props, data: function data() { return { isHidden: true, // If modal should not be in document isVisible: false, // Controls modal visible state isTransitioning: false, // Used for style control isShow: false, // Used for style control isBlock: false, // Used for style control isOpening: false, // To signal that the modal is in the process of opening isClosing: false, // To signal that the modal is in the process of closing ignoreBackdropClick: false, // Used to signify if click out listener should ignore the click isModalOverflowing: false, return_focus: this.returnFocus || null, // The following items are controlled by the modalManager instance scrollbarWidth: 0, zIndex: _modalManager.default.getBaseZIndex(), isTop: true, isBodyOverflowing: false }; }, computed: { modalClasses: function modalClasses() { return [{ fade: !this.noFade, show: this.isShow }, this.modalClass]; }, modalStyles: function modalStyles() { var sbWidth = "".concat(this.scrollbarWidth, "px"); return { paddingLeft: !this.isBodyOverflowing && this.isModalOverflowing ? sbWidth : '', paddingRight: this.isBodyOverflowing && !this.isModalOverflowing ? sbWidth : '', // Needed to fix issue https://github.com/bootstrap-vue/bootstrap-vue/issues/3457 // Even though we are using v-show, we must ensure 'none' is restored in the styles display: this.isBlock ? 'block' : 'none' }; }, dialogClasses: function dialogClasses() { var _ref; return [(_ref = {}, _defineProperty(_ref, "modal-".concat(this.size), Boolean(this.size)), _defineProperty(_ref, 'modal-dialog-centered', this.centered), _defineProperty(_ref, 'modal-dialog-scrollable', this.scrollable), _ref), this.dialogClass]; }, headerClasses: function headerClasses() { var _ref2; return [(_ref2 = {}, _defineProperty(_ref2, "bg-".concat(this.headerBgVariant), Boolean(this.headerBgVariant)), _defineProperty(_ref2, "text-".concat(this.headerTextVariant), Boolean(this.headerTextVariant)), _defineProperty(_ref2, "border-".concat(this.headerBorderVariant), Boolean(this.headerBorderVariant)), _ref2), this.headerClass]; }, bodyClasses: function bodyClasses() { var _ref3; return [(_ref3 = {}, _defineProperty(_ref3, "bg-".concat(this.bodyBgVariant), Boolean(this.bodyBgVariant)), _defineProperty(_ref3, "text-".concat(this.bodyTextVariant), Boolean(this.bodyTextVariant)), _ref3), this.bodyClass]; }, footerClasses: function footerClasses() { var _ref4; return [(_ref4 = {}, _defineProperty(_ref4, "bg-".concat(this.footerBgVariant), Boolean(this.footerBgVariant)), _defineProperty(_ref4, "text-".concat(this.footerTextVariant), Boolean(this.footerTextVariant)), _defineProperty(_ref4, "border-".concat(this.footerBorderVariant), Boolean(this.footerBorderVariant)), _ref4), this.footerClass]; }, modalOuterStyle: function modalOuterStyle() { // Styles needed for proper stacking of modals return { position: 'absolute', zIndex: this.zIndex }; }, slotScope: function slotScope() { return { ok: this.onOk, cancel: this.onCancel, close: this.onClose, hide: this.hide, visible: this.isVisible }; } }, watch: { visible: function visible(newVal, oldVal) { if (newVal !== oldVal) { this[newVal ? 'show' : 'hide'](); } } }, created: function created() { // Define non-reactive properties this._observer = null; }, mounted: function mounted() { // Set initial z-index as queried from the DOM this.zIndex = _modalManager.default.getBaseZIndex(); // Listen for events from others to either open or close ourselves // and listen to all modals to enable/disable enforce focus this.listenOnRoot('bv::show::modal', this.showHandler); this.listenOnRoot('bv::hide::modal', this.hideHandler); this.listenOnRoot('bv::toggle::modal', this.toggleHandler); // Listen for `bv:modal::show events`, and close ourselves if the // opening modal not us this.listenOnRoot('bv::modal::show', this.modalListener); // Initially show modal? if (this.visible === true) { this.$nextTick(this.show); } }, beforeDestroy: function beforeDestroy() { // Ensure everything is back to normal if (this._observer) { this._observer.disconnect(); this._observer = null; } this.setEnforceFocus(false); this.setResizeEvent(false); if (this.isVisible) { this.isVisible = false; this.isShow = false; this.isTransitioning = false; } }, methods: { // Private method to update the v-model updateModel: function updateModel(val) { if (val !== this.visible) { this.$emit('change', val); } }, // Private method to create a BvModalEvent object buildEvent: function buildEvent(type) { var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return new _bvModalEvent.default(type, _objectSpread({ // Default options cancelable: false, target: this.$refs.modal || this.$el || null, relatedTarget: null, trigger: null }, opts, { // Options that can't be overridden vueTarget: this, componentId: this.safeId() })); }, // Public method to show modal show: function show() { if (this.isVisible || this.isOpening) { // If already open, on in the process of opening, do nothing /* istanbul ignore next */ return; } if (this.isClosing) { // If we are in the process of closing, wait until hidden before re-opening /* istanbul ignore next: very difficult to test */ this.$once('hidden', this.show); /* istanbul ignore next */ return; } this.isOpening = true; // Set the element to return focus to when closed this.return_focus = this.return_focus || this.getActiveElement(); var showEvt = this.buildEvent('show', { cancelable: true }); this.emitEvent(showEvt); // Don't show if canceled if (showEvt.defaultPrevented || this.isVisible) { this.isOpening = false; // Ensure the v-model reflects the current state this.updateModel(false); return; } // Show the modal this.doShow(); }, // Public method to hide modal hide: function hide() { var trigger = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; if (!this.isVisible || this.isClosing) { /* istanbul ignore next */ return; } this.isClosing = true; var hideEvt = this.buildEvent('hide', { cancelable: trigger !== 'FORCE', trigger: trigger || null }); // We emit specific event for one of the three built-in buttons if (trigger === 'ok') { this.$emit('ok', hideEvt); } else if (trigger === 'cancel') { this.$emit('cancel', hideEvt); } else if (trigger === 'headerclose') { this.$emit('close', hideEvt); } this.emitEvent(hideEvt); // Hide if not canceled if (hideEvt.defaultPrevented || !this.isVisible) { this.isClosing = false; // Ensure v-model reflects current state this.updateModel(true); return; } // Stop observing for content changes if (this._observer) { this._observer.disconnect(); this._observer = null; } // Trigger the hide transition this.isVisible = false; // Update the v-model this.updateModel(false); }, // Public method to toggle modal visibility toggle: function toggle(triggerEl) { if (triggerEl) { this.return_focus = triggerEl; } if (this.isVisible) { this.hide('toggle'); } else { this.show(); } }, // Private method to get the current document active element getActiveElement: function getActiveElement() { if (_env.isBrowser) { var activeElement = document.activeElement; // Note: On IE11, `document.activeElement` may be null. // So we test it for truthiness first. // https://github.com/bootstrap-vue/bootstrap-vue/issues/3206 // Returning focus to document.body may cause unwanted scrolls, so we // exclude setting focus on body if (activeElement && activeElement !== document.body && activeElement.focus) { // Preset the fallback return focus value if it is not set // `document.activeElement` should be the trigger element that was clicked or // in the case of using the v-model, which ever element has current focus // Will be overridden by some commands such as toggle, etc. return activeElement; } } return null; }, // Private method to finish showing modal doShow: function doShow() { var _this = this; /* istanbul ignore next: commenting out for now until we can test stacking */ if (_modalManager.default.modalsAreOpen && this.noStacking) { // If another modal(s) is already open, wait for it(them) to close this.listenOnRootOnce('bv::modal::hidden', this.doShow); return; } _modalManager.default.registerModal(this); // Place modal in DOM this.isHidden = false; this.$nextTick(function () { // We do this in `$nextTick()` to ensure the modal is in DOM first // before we show it _this.isVisible = true; _this.isOpening = false; // Update the v-model _this.updateModel(true); _this.$nextTick(function () { // In a nextTick in case modal content is lazy // Observe changes in modal content and adjust if necessary _this._observer = (0, _observeDom.default)(_this.$refs.content, _this.checkModalOverflow.bind(_this), OBSERVER_CONFIG); }); }); }, // Transition handlers onBeforeEnter: function onBeforeEnter() { this.isTransitioning = true; this.setResizeEvent(true); }, onEnter: function onEnter() { this.isBlock = true; }, onAfterEnter: function onAfterEnter() { var _this2 = this; this.checkModalOverflow(); this.isShow = true; this.isTransitioning = false; this.$nextTick(function () { _this2.emitEvent(_this2.buildEvent('shown')); _this2.focusFirst(); _this2.setEnforceFocus(true); }); }, onBeforeLeave: function onBeforeLeave() { this.isTransitioning = true; this.setResizeEvent(false); }, onLeave: function onLeave() { // Remove the 'show' class this.isShow = false; }, onAfterLeave: function onAfterLeave() { var _this3 = this; this.isBlock = false; this.isTransitioning = false; this.setEnforceFocus(false); this.isModalOverflowing = false; this.isHidden = true; this.$nextTick(function () { _this3.returnFocusTo(); _this3.isClosing = false; _this3.return_focus = null; _modalManager.default.unregisterModal(_this3); // TODO: Need to find a way to pass the `trigger` property // to the `hidden` event, not just only the `hide` event _this3.emitEvent(_this3.buildEvent('hidden')); }); }, // Event emitter emitEvent: function emitEvent(bvModalEvt) { var type = bvModalEvt.type; // We emit on root first incase a global listener wants to cancel // the event first before the instance emits it's event this.emitOnRoot("bv::modal::".concat(type), bvModalEvt, bvModalEvt.componentId); this.$emit(type, bvModalEvt); }, // UI event handlers onDialogMousedown: function onDialogMousedown() { var _this4 = this; // Watch to see if the matching mouseup event occurs outside the dialog // And if it does, cancel the clickOut handler var modal = this.$refs.modal; var onceModalMouseup = function onceModalMouseup(evt) { (0, _dom.eventOff)(modal, 'mouseup', onceModalMouseup, EVT_OPTIONS); if (evt.target === modal) { _this4.ignoreBackdropClick = true; } }; (0, _dom.eventOn)(modal, 'mouseup', onceModalMouseup, EVT_OPTIONS); }, onClickOut: function onClickOut(evt) { if (this.ignoreBackdropClick) { // Click was initiated inside the modal content, but finished outside. // Set by the above onDialogMousedown handler this.ignoreBackdropClick = false; return; } // Do nothing if not visible, backdrop click disabled, or element // that generated click event is no longer in document body if (!this.isVisible || this.noCloseOnBackdrop || !(0, _dom.contains)(document.body, evt.target)) { return; } // If backdrop clicked, hide modal if (!(0, _dom.contains)(this.$refs.content, evt.target)) { this.hide('backdrop'); } }, onOk: function onOk() { this.hide('ok'); }, onCancel: function onCancel() { this.hide('cancel'); }, onClose: function onClose() { this.hide('headerclose'); }, onEsc: function onEsc(evt) { // If ESC pressed, hide modal if (evt.keyCode === _keyCodes.default.ESC && this.isVisible && !this.noCloseOnEsc) { this.hide('esc'); } }, // Document focusin listener focusHandler: function focusHandler(evt) { // If focus leaves modal, bring it back var modal = this.$refs.modal; if (!this.noEnforceFocus && this.isTop && this.isVisible && modal && document !== evt.target && !(0, _dom.contains)(modal, evt.target)) { modal.focus({ preventScroll: true }); } }, // Turn on/off focusin listener setEnforceFocus: function setEnforceFocus(on) { var method = on ? _dom.eventOn : _dom.eventOff; method(document, 'focusin', this.focusHandler, EVT_OPTIONS); }, // Resize listener setResizeEvent: function setResizeEvent(on) { var method = on ? _dom.eventOn : _dom.eventOff; // These events should probably also check if // body is overflowing method(window, 'resize', this.checkModalOverflow, EVT_OPTIONS); method(window, 'orientationchange', this.checkModalOverflow, EVT_OPTIONS); }, // Root listener handlers showHandler: function showHandler(id, triggerEl) { if (id === this.safeId()) { this.return_focus = triggerEl || this.getActiveElement(); this.show(); } }, hideHandler: function hideHandler(id) { if (id === this.safeId()) { this.hide('event'); } }, toggleHandler: function toggleHandler(id, triggerEl) { if (id === this.safeId()) { this.toggle(triggerEl); } }, modalListener: function modalListener(bvEvt) { // If another modal opens, close this one if stacking not permitted if (this.noStacking && bvEvt.vueTarget !== this) { this.hide(); } }, // Focus control handlers focusFirst: function focusFirst() { // Don't try and focus if we are SSR if (_env.isBrowser) { var modal = this.$refs.modal; var activeElement = this.getActiveElement(); // If the modal contains the activeElement, we don't do anything if (modal && !(activeElement && (0, _dom.contains)(modal, activeElement))) { // Make sure top of modal is showing (if longer than the viewport) // and focus the modal content wrapper this.$nextTick(function () { modal.scrollTop = 0; modal.focus(); }); } } }, returnFocusTo: function returnFocusTo() { // Prefer `returnFocus` prop over event specified // `return_focus` value var el = this.returnFocus || this.return_focus || null; // Is el a string CSS selector? el = (0, _inspect.isString)(el) ? (0, _dom.select)(el) : el; if (el) { // Possibly could be a component reference el = el.$el || el; if ((0, _dom.isVisible)(el) && el.focus) { el.focus(); } } }, checkModalOverflow: function checkModalOverflow() { if (this.isVisible) { var modal = this.$refs.modal; this.isModalOverflowing = modal.scrollHeight > document.documentElement.clientHeight; } }, makeModal: function makeModal(h) { // Modal header var header = h(false); if (!this.hideHeader) { var modalHeader = this.normalizeSlot('modal-header', this.slotScope); if (!modalHeader) { var closeButton = h(false); if (!this.hideHeaderClose) { closeButton = h(_buttonClose.BButtonClose, { props: { disabled: this.isTransitioning, ariaLabel: this.headerCloseLabel, textVariant: this.headerCloseVariant || this.headerTextVariant }, on: { click: this.onClose } }, [this.normalizeSlot('modal-header-close', {})]); } var domProps = !this.hasNormalizedSlot('modal-title') && this.titleHtml ? { innerHTML: this.titleHtml } : {}; modalHeader = [h(this.titleTag, { class: ['modal-title'], domProps: domProps }, [this.normalizeSlot('modal-title', this.slotScope) || (0, _html.stripTags)(this.title)]), closeButton]; } header = h('header', { ref: 'header', staticClass: 'modal-header', class: this.headerClasses, attrs: { id: this.safeId('__BV_modal_header_') } }, [modalHeader]); } // Modal body var body = h('div', { ref: 'body', staticClass: 'modal-body', class: this.bodyClasses, attrs: { id: this.safeId('__BV_modal_body_') } }, this.normalizeSlot('default', this.slotScope)); // Modal footer var footer = h(false); if (!this.hideFooter) { var modalFooter = this.normalizeSlot('modal-footer', this.slotScope); if (!modalFooter) { var cancelButton = h(false); if (!this.okOnly) { var cancelHtml = this.cancelTitleHtml ? { innerHTML: this.cancelTitleHtml } : null; cancelButton = h(_button.BButton, { props: { variant: this.cancelVariant, size: this.buttonSize, disabled: this.cancelDisabled || this.busy || this.isTransitioning }, on: { click: this.onCancel } }, [this.normalizeSlot('modal-cancel', {}) || (cancelHtml ? h('span', { domProps: cancelHtml }) : (0, _html.stripTags)(this.cancelTitle))]); } var okHtml = this.okTitleHtml ? { innerHTML: this.okTitleHtml } : null; var okButton = h(_button.BButton, { props: { variant: this.okVariant, size: this.buttonSize, disabled: this.okDisabled || this.busy || this.isTransitioning }, on: { click: this.onOk } }, [this.normalizeSlot('modal-ok', {}) || (okHtml ? h('span', { domProps: okHtml }) : (0, _html.stripTags)(this.okTitle))]); modalFooter = [cancelButton, okButton]; } footer = h('footer', { ref: 'footer', staticClass: 'modal-footer', class: this.footerClasses, attrs: { id: this.safeId('__BV_modal_footer_') } }, [modalFooter]); } // Assemble modal content var modalContent = h('div', { ref: 'content', staticClass: 'modal-content', class: this.contentClass, attrs: { role: 'document', id: this.safeId('__BV_modal_content_'), 'aria-labelledby': this.hideHeader ? null : this.safeId('__BV_modal_header_'), 'aria-describedby': this.safeId('__BV_modal_body_') } }, [header, body, footer]); // Modal dialog wrapper var modalDialog = h('div', { staticClass: 'modal-dialog', class: this.dialogClasses, on: { mousedown: this.onDialogMousedown } }, [modalContent]); // Modal var modal = h('div', { ref: 'modal', staticClass: 'modal', class: this.modalClasses, style: this.modalStyles, directives: [{ name: 'show', rawName: 'v-show', value: this.isVisible, expression: 'isVisible' }], attrs: { id: this.safeId(), role: 'dialog', tabindex: '-1', 'aria-hidden': this.isVisible ? null : 'true', 'aria-modal': this.isVisible ? 'true' : null }, on: { keydown: this.onEsc, click: this.onClickOut } }, [modalDialog]); // Wrap modal in transition // Sadly, we can't use BVTransition here due to the differences in // transition durations for .modal and .modal-dialog. Not until // issue https://github.com/vuejs/vue/issues/9986 is resolved modal = h('transition', { props: { enterClass: '', enterToClass: '', enterActiveClass: '', leaveClass: '', leaveActiveClass: '', leaveToClass: '' }, on: { beforeEnter: this.onBeforeEnter, enter: this.onEnter, afterEnter: this.onAfterEnter, beforeLeave: this.onBeforeLeave, leave: this.onLeave, afterLeave: this.onAfterLeave } }, [modal]); // Modal backdrop var backdrop = h(false); if (!this.hideBackdrop && this.isVisible) { backdrop = h('div', { staticClass: 'modal-backdrop', attrs: { id: this.safeId('__BV_modal_backdrop_') } }, [this.normalizeSlot('modal-backdrop', {})]); } backdrop = h(_bvTransition.default, { props: { noFade: this.noFade } }, [backdrop]); // Tab trap to prevent page from scrolling to next element in // tab index during enforce focus tab cycle var tabTrap = h(false); if (this.isVisible && this.isTop && !this.noEnforceFocus) { tabTrap = h('div', { attrs: { tabindex: '0' } }); } // Assemble modal and backdrop in an outer <div> return h('div', { key: "modal-outer-".concat(this._uid), style: this.modalOuterStyle, attrs: { id: this.safeId('__BV_modal_outer_') } }, [modal, tabTrap, backdrop]); } }, render: function render(h) { if (this.static) { return this.lazy && this.isHidden ? h(false) : this.makeModal(h); } else { return this.isHidden ? h(false) : h(_transporter.BTransporterSingle, {}, [this.makeModal(h)]); } } }); exports.BModal = BModal; var _default2 = BModal; exports.default = _default2;