UNPKG

bootstrap-vue

Version:

With more than 85 components, over 45 available plugins, several directives, and 1000+ icons, BootstrapVue provides one of the most comprehensive implementations of the Bootstrap v4 component and grid system available for Vue.js v2.6, complete with extens

264 lines (233 loc) 11.9 kB
var _makePropsConfigurabl, _watch; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(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; } import { extend } from '../../vue'; import { NAME_TOOLTIP } from '../../constants/components'; import { EVENT_NAME_CLOSE, EVENT_NAME_DISABLE, EVENT_NAME_DISABLED, EVENT_NAME_ENABLE, EVENT_NAME_ENABLED, EVENT_NAME_HIDDEN, EVENT_NAME_HIDE, EVENT_NAME_OPEN, EVENT_NAME_SHOW, EVENT_NAME_SHOWN, MODEL_EVENT_NAME_PREFIX } from '../../constants/events'; import { PROP_TYPE_ARRAY_STRING, PROP_TYPE_BOOLEAN, PROP_TYPE_FUNCTION, PROP_TYPE_NUMBER_OBJECT_STRING, PROP_TYPE_NUMBER_STRING, PROP_TYPE_OBJECT, PROP_TYPE_STRING } from '../../constants/props'; import { HTMLElement, SVGElement } from '../../constants/safe-types'; import { useParentMixin } from '../../mixins/use-parent'; import { getScopeId } from '../../utils/get-scope-id'; import { isUndefinedOrNull } from '../../utils/inspect'; import { pick } from '../../utils/object'; import { makeProp, makePropsConfigurable } from '../../utils/props'; import { createNewChildComponent } from '../../utils/create-new-child-component'; import { normalizeSlotMixin } from '../../mixins/normalize-slot'; import { BVTooltip } from './helpers/bv-tooltip'; // --- Constants --- var MODEL_PROP_NAME_ENABLED = 'disabled'; var MODEL_EVENT_NAME_ENABLED = MODEL_EVENT_NAME_PREFIX + MODEL_PROP_NAME_ENABLED; var MODEL_PROP_NAME_SHOW = 'show'; var MODEL_EVENT_NAME_SHOW = MODEL_EVENT_NAME_PREFIX + MODEL_PROP_NAME_SHOW; // --- Props --- export var props = makePropsConfigurable((_makePropsConfigurabl = { // String: scrollParent, window, or viewport // Element: element reference // Object: Vue component boundary: makeProp([HTMLElement, PROP_TYPE_OBJECT, PROP_TYPE_STRING], 'scrollParent'), boundaryPadding: makeProp(PROP_TYPE_NUMBER_STRING, 50), // String: HTML ID of container, if null body is used (default) // HTMLElement: element reference reference // Object: Vue Component container: makeProp([HTMLElement, PROP_TYPE_OBJECT, PROP_TYPE_STRING]), customClass: makeProp(PROP_TYPE_STRING), delay: makeProp(PROP_TYPE_NUMBER_OBJECT_STRING, 50) }, _defineProperty(_makePropsConfigurabl, MODEL_PROP_NAME_ENABLED, makeProp(PROP_TYPE_BOOLEAN, false)), _defineProperty(_makePropsConfigurabl, "fallbackPlacement", makeProp(PROP_TYPE_ARRAY_STRING, 'flip')), _defineProperty(_makePropsConfigurabl, "id", makeProp(PROP_TYPE_STRING)), _defineProperty(_makePropsConfigurabl, "noFade", makeProp(PROP_TYPE_BOOLEAN, false)), _defineProperty(_makePropsConfigurabl, "noninteractive", makeProp(PROP_TYPE_BOOLEAN, false)), _defineProperty(_makePropsConfigurabl, "offset", makeProp(PROP_TYPE_NUMBER_STRING, 0)), _defineProperty(_makePropsConfigurabl, "placement", makeProp(PROP_TYPE_STRING, 'top')), _defineProperty(_makePropsConfigurabl, MODEL_PROP_NAME_SHOW, makeProp(PROP_TYPE_BOOLEAN, false)), _defineProperty(_makePropsConfigurabl, "target", makeProp([HTMLElement, SVGElement, PROP_TYPE_FUNCTION, PROP_TYPE_OBJECT, PROP_TYPE_STRING], undefined, true)), _defineProperty(_makePropsConfigurabl, "title", makeProp(PROP_TYPE_STRING)), _defineProperty(_makePropsConfigurabl, "triggers", makeProp(PROP_TYPE_ARRAY_STRING, 'hover focus')), _defineProperty(_makePropsConfigurabl, "variant", makeProp(PROP_TYPE_STRING)), _makePropsConfigurabl), NAME_TOOLTIP); // --- Main component --- // @vue/component export var BTooltip = /*#__PURE__*/extend({ name: NAME_TOOLTIP, mixins: [normalizeSlotMixin, useParentMixin], inheritAttrs: false, props: props, data: function data() { return { localShow: this[MODEL_PROP_NAME_SHOW], localTitle: '', localContent: '' }; }, computed: { // Data that will be passed to the template and popper templateData: function templateData() { return _objectSpread({ title: this.localTitle, content: this.localContent, interactive: !this.noninteractive }, pick(this.$props, ['boundary', 'boundaryPadding', 'container', 'customClass', 'delay', 'fallbackPlacement', 'id', 'noFade', 'offset', 'placement', 'target', 'target', 'triggers', 'variant', MODEL_PROP_NAME_ENABLED])); }, // Used to watch for changes to the title and content props templateTitleContent: function templateTitleContent() { var title = this.title, content = this.content; return { title: title, content: content }; } }, watch: (_watch = {}, _defineProperty(_watch, MODEL_PROP_NAME_SHOW, function (newValue, oldValue) { if (newValue !== oldValue && newValue !== this.localShow && this.$_toolpop) { if (newValue) { this.$_toolpop.show(); } else { // We use `forceHide()` to override any active triggers this.$_toolpop.forceHide(); } } }), _defineProperty(_watch, MODEL_PROP_NAME_ENABLED, function (newValue) { if (newValue) { this.doDisable(); } else { this.doEnable(); } }), _defineProperty(_watch, "localShow", function localShow(newValue) { // TODO: May need to be done in a `$nextTick()` this.$emit(MODEL_EVENT_NAME_SHOW, newValue); }), _defineProperty(_watch, "templateData", function templateData() { var _this = this; this.$nextTick(function () { if (_this.$_toolpop) { _this.$_toolpop.updateData(_this.templateData); } }); }), _defineProperty(_watch, "templateTitleContent", function templateTitleContent() { this.$nextTick(this.updateContent); }), _watch), created: function created() { // Create private non-reactive props this.$_toolpop = null; }, updated: function updated() { // Update the `propData` object // Done in a `$nextTick()` to ensure slot(s) have updated this.$nextTick(this.updateContent); }, beforeDestroy: function beforeDestroy() { // Shutdown our local event listeners this.$off(EVENT_NAME_OPEN, this.doOpen); this.$off(EVENT_NAME_CLOSE, this.doClose); this.$off(EVENT_NAME_DISABLE, this.doDisable); this.$off(EVENT_NAME_ENABLE, this.doEnable); // Destroy the tip instance if (this.$_toolpop) { this.$_toolpop.$destroy(); this.$_toolpop = null; } }, mounted: function mounted() { var _this2 = this; // Instantiate a new BVTooltip instance // Done in a `$nextTick()` to ensure DOM has completed rendering // so that target can be found this.$nextTick(function () { // Load the on demand child instance var Component = _this2.getComponent(); // Ensure we have initial content _this2.updateContent(); // Pass down the scoped style attribute if available var scopeId = getScopeId(_this2) || getScopeId(_this2.bvParent); // Create the instance var $toolpop = _this2.$_toolpop = createNewChildComponent(_this2, Component, { // Pass down the scoped style ID _scopeId: scopeId || undefined }); // Set the initial data $toolpop.updateData(_this2.templateData); // Set listeners $toolpop.$on(EVENT_NAME_SHOW, _this2.onShow); $toolpop.$on(EVENT_NAME_SHOWN, _this2.onShown); $toolpop.$on(EVENT_NAME_HIDE, _this2.onHide); $toolpop.$on(EVENT_NAME_HIDDEN, _this2.onHidden); $toolpop.$on(EVENT_NAME_DISABLED, _this2.onDisabled); $toolpop.$on(EVENT_NAME_ENABLED, _this2.onEnabled); // Initially disabled? if (_this2[MODEL_PROP_NAME_ENABLED]) { // Initially disabled _this2.doDisable(); } // Listen to open signals from others _this2.$on(EVENT_NAME_OPEN, _this2.doOpen); // Listen to close signals from others _this2.$on(EVENT_NAME_CLOSE, _this2.doClose); // Listen to disable signals from others _this2.$on(EVENT_NAME_DISABLE, _this2.doDisable); // Listen to enable signals from others _this2.$on(EVENT_NAME_ENABLE, _this2.doEnable); // Initially show tooltip? if (_this2.localShow) { $toolpop.show(); } }); }, methods: { getComponent: function getComponent() { // Overridden by BPopover return BVTooltip; }, updateContent: function updateContent() { // Overridden by BPopover // Tooltip: Default slot is `title` // Popover: Default slot is `content`, `title` slot is title // We pass a scoped slot function reference by default (Vue v2.6x) // And pass the title prop as a fallback this.setTitle(this.normalizeSlot() || this.title); }, // Helper methods for `updateContent()` setTitle: function setTitle(value) { value = isUndefinedOrNull(value) ? '' : value; // We only update the value if it has changed if (this.localTitle !== value) { this.localTitle = value; } }, setContent: function setContent(value) { value = isUndefinedOrNull(value) ? '' : value; // We only update the value if it has changed if (this.localContent !== value) { this.localContent = value; } }, // --- Template event handlers --- onShow: function onShow(bvEvent) { // Placeholder this.$emit(EVENT_NAME_SHOW, bvEvent); if (bvEvent) { this.localShow = !bvEvent.defaultPrevented; } }, onShown: function onShown(bvEvent) { // Tip is now showing this.localShow = true; this.$emit(EVENT_NAME_SHOWN, bvEvent); }, onHide: function onHide(bvEvent) { this.$emit(EVENT_NAME_HIDE, bvEvent); }, onHidden: function onHidden(bvEvent) { // Tip is no longer showing this.$emit(EVENT_NAME_HIDDEN, bvEvent); this.localShow = false; }, onDisabled: function onDisabled(bvEvent) { // Prevent possible endless loop if user mistakenly // fires `disabled` instead of `disable` if (bvEvent && bvEvent.type === EVENT_NAME_DISABLED) { this.$emit(MODEL_EVENT_NAME_ENABLED, true); this.$emit(EVENT_NAME_DISABLED, bvEvent); } }, onEnabled: function onEnabled(bvEvent) { // Prevent possible endless loop if user mistakenly // fires `enabled` instead of `enable` if (bvEvent && bvEvent.type === EVENT_NAME_ENABLED) { this.$emit(MODEL_EVENT_NAME_ENABLED, false); this.$emit(EVENT_NAME_ENABLED, bvEvent); } }, // --- Local event listeners --- doOpen: function doOpen() { !this.localShow && this.$_toolpop && this.$_toolpop.show(); }, doClose: function doClose() { this.localShow && this.$_toolpop && this.$_toolpop.hide(); }, doDisable: function doDisable() { this.$_toolpop && this.$_toolpop.disable(); }, doEnable: function doEnable() { this.$_toolpop && this.$_toolpop.enable(); } }, render: function render(h) { // Always renders a comment node // TODO: // Future: Possibly render a target slot (single root element) // which we can apply the listeners to (pass `this.$el` to BVTooltip) return h(); } });