Skip to content Skip to sidebar Skip to footer

Keep V-tooltip Open When Hovering Over The Tooltip

First, the terms, 'link' is the area where the mouse enters. The 'tooltip' is the thing that pops up and shows extra information. --- above added 2020-04-29 I'm using Vuetify and t

Solution 1:

Instead of using v-tooltip, I suggest you use v-menu with the open-on-hover props set to true. If you have to nudge whatever you put in the menu, make sure to set an appropriate close-delay value, so the menu doesn't close before the user reaches it.

Example: https://codepen.io/stephane303/pen/WNwdNxY

<v-menu open-on-hover rightoffset-x nudge-right="20" close-delay="100">

Solution 2:

.v-tooltip__content has pointer-events:none set in vuetify.min.css. If you set it back to auto you allow it to be hovered.

When its hovered, its parent is hovered. And when its parent is hovered, it has a tooltip. So all you need is:

.v-tooltip__content {
  pointer-events: auto;
}

Solution 3:

I made extended version of VTooltip for this purpose. Just pass interactive prop. See working example here by hovering 'Creators' in list item: https://tzkt.io/KT1RJ6PbjHpwc3M5rw5s2Nbmefwbuwbdxton/tokens

<script>
/**
 * Extends VTooltip with interactivity
 * @see https://material-ui.com/components/tooltips/#interactive
 */import { VTooltip } from 'vuetify/lib';

export default {
    extends: VTooltip,
    props: {
        interactive: {
            type: Boolean,
            default: false,
        },
        closeDelay: {
            type: [Number, String],
            default: 50,
        },
    },
    computed: {
        // I'm not 100% sure in this, but it works
        calculatedLeft() {
            const originalValue = VTooltip.options.computed.calculatedLeft.call(this);
            if (!this.interactive) return originalValue;
            const { left, right } = this;
            let value = parseInt(originalValue);
            if (left || right) {
                value += right ? -10 : 10;
            }
            return `${value}px`;
        },
        calculatedTop() {
            const originalValue = VTooltip.options.computed.calculatedTop.call(this);
            if (!this.interactive) return originalValue;
            const { top, bottom } = this;
            let value = parseInt(originalValue);
            if (top || bottom) {
                value += bottom ? -10 : 10;
            }
            return `${value}px`;
        },
        styles() {
            const originalValue = VTooltip.options.computed.styles.call(this);
            if (!this.interactive) return originalValue;
            const {
                top, bottom, left, right,
            } = this;
            let paddingDirection;
            if (bottom) paddingDirection = 'top';
            elseif (top) paddingDirection = 'bottom';
            elseif (right) paddingDirection = 'left';
            elseif (left) paddingDirection = 'right';
            return {
                ...originalValue,
                [`padding-${paddingDirection}`]: `${10}px`,
            };
        },
    },
    methods: {
        onTooltipMouseenter(e) {
            if (this.interactive) {
                this.clearDelay();
                this.isActive = true;
            }
            this.$emit('tooltip:mouseenter', e);
        },
        onTooltipMouseleave(e) {
            if (this.interactive) {
                this.clearDelay();
                this.runDelay('close');
            }
            this.$emit('tooltip:mouseleave', e);
        },
        genContent() {
            const content = this.$createElement('div', this.setBackgroundColor(this.color, {
                style: this.contentStyles,
                staticClass: 'v-tooltip__content',
                class: {
                    [this.contentClass]: true,
                    menuable__content__active: this.isActive,
                },
            }), this.getContentSlot());
            returnthis.$createElement('div', {
                style: this.styles,
                attrs: this.getScopeIdAttrs(),
                class: {'v-tooltip__wrapper': true,
                    'v-tooltip__wrapper--fixed': this.activatorFixed,
                },
                directives: [{
                    name: 'show',
                    value: this.isContentActive,
                }],
                on: {
                    mouseenter: this.onTooltipMouseenter,
                    mouseleave: this.onTooltipMouseleave,
                },
                ref: 'content',
            }, [content]);
        },
        genActivatorListeners() {
            const listeners = VTooltip.options.methods.genActivatorListeners.call(this);

            if (this.interactive) {
                if (listeners.mouseenter) {
                    listeners.mouseenter = (e) => {
                        this.getActivator(e);
                        this.clearDelay();
                        if (!this.isActive) {
                            this.runDelay('open');
                        }
                    };
                }
            }

            return listeners;
        },
    },

};
</script>

<style lang="scss">
.v-tooltip__wrapper {
    position: absolute;
    &--fixed {
        position: fixed;
    }
    .v-tooltip__content {
        position: static;
    }
}
</style>

Post a Comment for "Keep V-tooltip Open When Hovering Over The Tooltip"