Andre12
Andre12

Reputation: 564

Using Vuetify tooltip (v-tooltip) component with an external activator (i.e. not wrapped)

I understand how to use Vuetify's v-tooltip with the tooltip wrapping the component. However, I'm not quite sure how to have the activator button outside.

e.g. I have this (non-working code):

<v-tooltip bottom
  :activator="$refs.filterBtn"
>
  Filter displayed items
</v-tooltip>
<v-btn
  ref="filterBtn"
  icon
  @click="isFilter = !isFilter"
>
  <v-icon>fa-filter</v-icon>
</v-btn>

I also tried using prop activator without the v-bind:, same result

Idea: I want the button to be placed separately from tooltip in order to run unit tests. When testing, shallowMount strips anything inside <v-tooltip> so I can't test the button. The problem is I don't know how to make tooltip show up on hover (just like it does when wrapped), I do not want to trigger it with @click.

EDIT: here's codepen

Upvotes: 7

Views: 26243

Answers (4)

Vadim Demchenko
Vadim Demchenko

Reputation: 1

In my case, it was necessary to place the tooltip together with the button in one component (a custom button with a tooltip function). Therefore, I used a prop activator and added the tooltip itself directly to the button:

<template>
  <v-btn
  :id="id"
  >
    <span>
      <slot></slot>
      <v-tooltip
      v-if="tooltipText"
      :activator="`#${id}`"
      top
      >
        {{ tooltipText }}
      </v-tooltip>  
    </span>
  </v-btn>
</template>

<script>
  let id = 0;

  export default {
    data() {
      return {
        id: `custom-button-${id++}`, //This is how we get a unique id for each created button
      }
    }
  }
</script>

According to the same scheme, you can place v-tooltip anywhere, the main thing is that at the time of mounting the "activator" already exists.

Upvotes: 0

user15392697
user15392697

Reputation:

  <v-app>
        <v-tooltip bottom>
            <template v-slot:activator="{ on }">
                <v-btn
                 v-on="on"
                >
                Your button
                </v-btn>
            </template>
            <span> Your hover message </span>
       </v-tooltip>
  </v-app>

Upvotes: 0

Dylan Zgorski Dykes
Dylan Zgorski Dykes

Reputation: 151

How about using the v-hover UI Component. Wrap it around your button. Bind a boolean variable to the v-hover using v-model, call it buttonHovering. Then bind a boolean variable to the v-tooltip using v-model, call it showToolTip. Then use a watcher to toggle showToolTip true and false based on the value of buttonHovering. Or you can make showToolTip a computed property that always returns the value of buttonHovering. Lastly, bind the disabled attribute of the v-tooltip to the !buttonHovering property to ensure that the tooltip only displays when hovering over the button and not the tooltip's activator.

new Vue({
  el: '#app',
  data () {       
    return {
      buttonHovering: false,
      showToolTip: false
    }
  },
  watch: {
    buttonHovering (newVal) {
      this.showToolTip = newVal
    }
  }
})
<link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons' rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>


<div id="app">
  <v-app>
    <v-card>
      <v-card-title>
        <v-hover v-model="buttonHovering">
          <v-btn large>
            Hello
          </v-btn>
        </v-hover>
        <v-spacer></v-spacer>
        <v-tooltip left v-model="showToolTip" :disabled="!buttonHovering">
          <span>Hi from over here!</span>
        </v-tooltip>
      </v-card-title>
    </v-card>
  </v-app>
</div>

Upvotes: 4

Vladislav Ladicky
Vladislav Ladicky

Reputation: 2489

Try this:

<v-tooltip bottom
  v-model="filterBtnTTip"
>
  Filter displayed items
</v-tooltip>

<v-btn
  icon
  @click="isFilter = !isFilter"
  @mouseover="filterBtnTTip = true"
  @mouseleave="filterBtnTTip = false"
>
  <v-icon>fa-filter</v-icon>
</v-btn>

...
data () {
  return {
    ...
    filterBtnTTip: false
  }
}

Upvotes: 3

Related Questions