text: import Vue from '../../utils/vue';
  import getScopId from '../../utils/get-scope-id';
  import { isArray, arrayIncludes } from '../../utils/array';
  import { getComponentConfig } from '../../utils/config';
  import { isString, isUndefinedOrNull } from '../../utils/inspect';
  import { HTMLElement, SVGElement } from '../../utils/safe-types';
  import { BVTooltip } from './helpers/bv-tooltip';
  var NAME = 'BTooltip'; // @vue/component
  
  export var BTooltip = /*#__PURE__*/Vue.extend({
    name: NAME,
    props: {
      title: {
        type: String // default: undefined
  
      },
      // Added in by BPopover
      // content: {
      //   type: String,
      //   default: undefined
      // },
      target: {
        // String ID of element, or element/component reference
        // Or function that returns one of the above
        type: [String, HTMLElement, SVGElement, Function, Object],
        required: true
      },
      triggers: {
        type: [String, Array],
        default: 'hover focus'
      },
      placement: {
        type: String,
        default: 'top'
      },
      fallbackPlacement: {
        type: [String, Array],
        default: 'flip',
        validator: function validator(value) {
          return isArray(value) && value.every(function (v) {
            return isString(v);
          }) || arrayIncludes(['flip', 'clockwise', 'counterclockwise'], value);
        }
      },
      variant: {
        type: String,
        default: function _default() {
          return getComponentConfig(NAME, 'variant');
        }
      },
      customClass: {
        type: String,
        default: function _default() {
          return getComponentConfig(NAME, 'customClass');
        }
      },
      delay: {
        type: [Number, Object, String],
        default: function _default() {
          return getComponentConfig(NAME, 'delay');
        }
      },
      boundary: {
        // String: scrollParent, window, or viewport
        // Element: element reference
        // Object: Vue component
        type: [String, HTMLElement, Object],
        default: function _default() {
          return getComponentConfig(NAME, 'boundary');
        }
      },
      boundaryPadding: {
        type: [Number, String],
        default: function _default() {
          return getComponentConfig(NAME, 'boundaryPadding');
        }
      },
      offset: {
        type: [Number, String],
        default: 0
      },
      noFade: {
        type: Boolean,
        default: false
      },
      container: {
        // String: HTML ID of container, if null body is used (default)
        // HTMLElement: element reference reference
        // Object: Vue Component
        type: [String, HTMLElement, Object] // default: undefined
  
      },
      show: {
        type: Boolean,
        default: false
      },
      noninteractive: {
        type: Boolean,
        default: false
      },
      disabled: {
        type: Boolean,
        default: false
      },
      id: {
        // ID to use for tooltip element
        // If not provided on will automatically be generated
        type: String // default: null
  
      }
    },
    data: function data() {
      return {
        localShow: this.show,
        localTitle: '',
        localContent: ''
      };
    },
    computed: {
      templateData: function templateData() {
        // Data that will be passed to the template and popper
        return {
          // We use massaged versions of the title and content props/slots
          title: this.localTitle,
          content: this.localContent,
          // Pass these props as is
          target: this.target,
          triggers: this.triggers,
          placement: this.placement,
          fallbackPlacement: this.fallbackPlacement,
          variant: this.variant,
          customClass: this.customClass,
          container: this.container,
          boundary: this.boundary,
          boundaryPadding: this.boundaryPadding,
          delay: this.delay,
          offset: this.offset,
          noFade: this.noFade,
          interactive: !this.noninteractive,
          disabled: this.disabled,
          id: this.id
        };
      },
      templateTitleContent: function templateTitleContent() {
        // Used to watch for changes to the title and content props
        return {
          title: this.title,
          content: this.content
        };
      }
    },
    watch: {
      show: function show(_show, oldVal) {
        if (_show !== oldVal && _show !== this.localShow && this.$_bv_toolpop) {
          if (_show) {
            this.$_bv_toolpop.show();
          } else {
            // We use `forceHide()` to override any active triggers
            this.$_bv_toolpop.forceHide();
          }
        }
      },
      disabled: function disabled(newVal) {
        if (newVal) {
          this.doDisable();
        } else {
          this.doEnable();
        }
      },
      localShow: function localShow(newVal) {
        // TODO: May need to be done in a `$nextTick()`
        this.$emit('update:show', newVal);
      },
      templateData: function templateData() {
        var _this = this;
  
        this.$nextTick(function () {
          if (_this.$_bv_toolpop) {
            _this.$_bv_toolpop.updateData(_this.templateData);
          }
        });
      },
      // Watchers for title/content props (prop changes do not trigger the `updated()` hook)
      templateTitleContent: function templateTitleContent() {
        this.$nextTick(this.updateContent);
      }
    },
    created: function created() {
      // Non reactive properties
      this.$_bv_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('open', this.doOpen);
      this.$off('close', this.doClose);
      this.$off('disable', this.doDisable);
      this.$off('enable', this.doEnable); // Destroy the tip instance
  
      this.$_bv_toolpop && this.$_bv_toolpop.$destroy();
      this.$_bv_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 = getScopId(_this2) || getScopId(_this2.$parent); // Create the instance
  
        var $toolpop = _this2.$_bv_toolpop = new Component({
          parent: _this2,
          // Pass down the scoped style ID
          _scopeId: scopeId || undefined
        }); // Set the initial data
  
        $toolpop.updateData(_this2.templateData); // Set listeners
  
        $toolpop.$on('show', _this2.onShow);
        $toolpop.$on('shown', _this2.onShown);
        $toolpop.$on('hide', _this2.onHide);
        $toolpop.$on('hidden', _this2.onHidden);
        $toolpop.$on('disabled', _this2.onDisabled);
        $toolpop.$on('enabled', _this2.onEnabled); // Initially disabled?
  
        if (_this2.disabled) {
          // Initially disabled
          _this2.doDisable();
        } // Listen to open signals from others
  
  
        _this2.$on('open', _this2.doOpen); // Listen to close signals from others
  
  
        _this2.$on('close', _this2.doClose); // Listen to disable signals from others
  
  
        _this2.$on('disable', _this2.doDisable); // Listen to enable signals from others
  
  
        _this2.$on('enable', _this2.doEnable); // Initially show tooltip?
  
  
        if (_this2.localShow) {
          _this2.$_bv_toolpop && _this2.$_bv_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.$scopedSlots.default || this.title);
      },
      // Helper methods for `updateContent()`
      setTitle: function setTitle(val) {
        val = isUndefinedOrNull(val) ? '' : val; // We only update the value if it has changed
  
        if (this.localTitle !== val) {
          this.localTitle = val;
        }
      },
      setContent: function setContent(val) {
        val = isUndefinedOrNull(val) ? '' : val; // We only update the value if it has changed
  
        if (this.localContent !== val) {
          this.localContent = val;
        }
      },
      // --- Template event handlers ---
      onShow: function onShow(bvEvt) {
        // Placeholder
        this.$emit('show', bvEvt);
  
        if (bvEvt) {
          this.localShow = !bvEvt.defaultPrevented;
        }
      },
      onShown: function onShown(bvEvt) {
        // Tip is now showing
        this.localShow = true;
        this.$emit('shown', bvEvt);
      },
      onHide: function onHide(bvEvt) {
        this.$emit('hide', bvEvt);
      },
      onHidden: function onHidden(bvEvt) {
        // Tip is no longer showing
        this.$emit('hidden', bvEvt);
        this.localShow = false;
      },
      onDisabled: function onDisabled(bvEvt) {
        // Prevent possible endless loop if user mistakenly
        // fires `disabled` instead of `disable`
        if (bvEvt && bvEvt.type === 'disabled') {
          this.$emit('update:disabled', true);
          this.$emit('disabled', bvEvt);
        }
      },
      onEnabled: function onEnabled(bvEvt) {
        // Prevent possible endless loop if user mistakenly
        // fires `enabled` instead of `enable`
        if (bvEvt && bvEvt.type === 'enabled') {
          this.$emit('update:disabled', false);
          this.$emit('enabled', bvEvt);
        }
      },
      // --- Local event listeners ---
      doOpen: function doOpen() {
        !this.localShow && this.$_bv_toolpop && this.$_bv_toolpop.show();
      },
      doClose: function doClose() {
        this.localShow && this.$_bv_toolpop && this.$_bv_toolpop.hide();
      },
      doDisable: function doDisable() {
        this.$_bv_toolpop && this.$_bv_toolpop.disable();
      },
      doEnable: function doEnable() {
        this.$_bv_toolpop && this.$_bv_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();
    }
  });