vue.jsvuetify.jstooltipv-tooltip

Vuetify - v-tooltip-Not displaying with keyboard tap button


I have a shared component using Vuetify's v-tooltip, and it works perfectly when hovering with the mouse. However, when I use the tap button to access a button that has the tooltip, it doesn't work. Can someone help me troubleshoot this issue?

I tried to add :open-on-focus="true"

in props but it didn't work


Solution

  • A regular div usually cannot be focused, so you'll never reach it through the keyboard and the handler won't be triggered.

    There are several ways around it:

    <template v-slot:activator="{ on, attrs }">
      <div v-bind="attrs" v-on="on" tabindex="0">
        <slot />
      </div>
    </template>
    

    const tooltip = {
      template: `
        <v-tooltip
          v-bind="$attrs"
          :open-on-focus="true"
          open-delay="250"
          max-width="288px"
        >
          <template v-slot:activator="{ on, attrs }">
            <div v-bind="attrs" v-on="on" tabindex="0">
              <slot />
            </div>
          </template>
          <span class="tooltip-text">getTooltipText()</span>
        </v-tooltip>
      `
    }
    
    new Vue({
      el: '#app',
      vuetify: new Vuetify(),
      components: {tooltip},
      template: `
        <v-app>
          <v-main>
            <v-container>
              <tooltip>
                <div style="background: pink;">activator content</div>
              </tooltip>
            
            </v-container>
          </v-main>
        </v-app>
      `,
      setup(){
      
      }
    })
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
    
    <div id="app"></div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>

    <template v-slot:activator="{ on, attrs }">
      <button v-bind="attrs" v-on="on">
        <slot />
      </button>
    </template>
    

    const tooltip = {
      template: `
        <v-tooltip
          v-bind="$attrs"
          :open-on-focus="true"
          open-delay="250"
          max-width="288px"
        >
          <template v-slot:activator="{ on, attrs }">
            <v-btn v-bind="attrs" v-on="on">
              <slot />
            </v-btn>
          </template>
          <span class="tooltip-text">getTooltipText()</span>
        </v-tooltip>
      `
    }
    
    new Vue({
      el: '#app',
      vuetify: new Vuetify(),
      components: {tooltip},
      template: `
        <v-app>
          <v-main>
            <v-container>
              <tooltip>
                <div style="background: pink;">activator content</div>
              </tooltip>
            
            </v-container>
          </v-main>
        </v-app>
      `,
      setup(){
      
      }
    })
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
    
    <div id="app"></div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>

    <template v-slot:activator="{ attrs, on: {mouseenter, mouseleave, focus, blur, keydown} }">
      <div v-bind="attrs" v-on="{mouseenter, mouseleave}">
        <slot :on="{focus, blur, keydown}"/>
      </div>
    </template>
    

    const tooltip = {
      template: `
        <v-tooltip
          v-bind="$attrs"
          :open-on-focus="true"
          open-delay="250"
          max-width="288px"
        >
          <template v-slot:activator="{ attrs, on: {mouseenter, mouseleave, focus, blur, keydown} }">
            <div v-bind="attrs" v-on="{mouseenter, mouseleave}">
              <slot :on="{focus, blur, keydown}"/>
            </div>
          </template>
          <span class="tooltip-text">getTooltipText()</span>
        </v-tooltip>
      `
    }
    
    new Vue({
      el: '#app',
      vuetify: new Vuetify(),
      components: {tooltip},
      template: `
        <v-app>
          <v-main>
            <v-container>
    
              <tooltip v-slot="{on}">
                <v-checkbox v-on="on"/>
              </tooltip>
          
            </v-container>
          </v-main>
        </v-app>
      `,
      setup(){
      
      }
    })
    <link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
    
    <div id="app"></div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>