0

I used this reference: https://stackoverflow.com/a/53108600 to close an outer v-tooltip on an inner v-tooltip hover.
The problem is that this approach is only elegant when there is one container to deal with.
When you start to have many containers then you have to create a data variable in vue for each one.
Code sample: https://jsfiddle.net/jyts1fug/6/
As shown in the fiddle I now have 2 variables, isOpen and isOpen2.
I would like to find a more elegant solution for this.

yuval
  • 2,848
  • 4
  • 31
  • 51

1 Answers1

1

You need something to track which elements are open and which isn't. This will rely heavily on the existing data structure you are using.

In the case, in your code sample, I would do something like the following:

Note: index+'inner' is not a very clean way, it's just for demonstration. You can choose whatever variable inside the loop to track by. like user Id and user posts Ids for example.

console.clear()

new Vue({
  el: '#app',
  data: {
    openId: null,
    message: 'Outer Tooltip'
  },
})
body {
  font-family: sans-serif;
  margin: 42px;
}

.tooltip {
  display: block !important;
  z-index: 10000;
}

.tooltip .tooltip-inner {
  background: black;
  color: white;
  border-radius: 16px;
  padding: 5px 10px 4px;
}

.tooltip .tooltip-arrow {
  width: 0;
  height: 0;
  border-style: solid;
  position: absolute;
  margin: 5px;
  border-color: black;
}

.tooltip[x-placement^="top"] {
  margin-bottom: 5px;
}

.tooltip[x-placement^="top"] .tooltip-arrow {
  border-width: 5px 5px 0 5px;
  border-left-color: transparent !important;
  border-right-color: transparent !important;
  border-bottom-color: transparent !important;
  bottom: -5px;
  left: calc(50% - 5px);
  margin-top: 0;
  margin-bottom: 0;
}

.tooltip[x-placement^="bottom"] {
  margin-top: 5px;
}

.tooltip[x-placement^="bottom"] .tooltip-arrow {
  border-width: 0 5px 5px 5px;
  border-left-color: transparent !important;
  border-right-color: transparent !important;
  border-top-color: transparent !important;
  top: -5px;
  left: calc(50% - 5px);
  margin-top: 0;
  margin-bottom: 0;
}

.tooltip[x-placement^="right"] {
  margin-left: 5px;
}

.tooltip[x-placement^="right"] .tooltip-arrow {
  border-width: 5px 5px 5px 0;
  border-left-color: transparent !important;
  border-top-color: transparent !important;
  border-bottom-color: transparent !important;
  left: -5px;
  top: calc(50% - 5px);
  margin-left: 0;
  margin-right: 0;
}

.tooltip[x-placement^="left"] {
  margin-right: 5px;
}

.tooltip[x-placement^="left"] .tooltip-arrow {
  border-width: 5px 0 5px 5px;
  border-top-color: transparent !important;
  border-right-color: transparent !important;
  border-bottom-color: transparent !important;
  right: -5px;
  top: calc(50% - 5px);
  margin-left: 0;
  margin-right: 0;
}

.tooltip[aria-hidden='true'] {
  visibility: hidden;
  opacity: 0;
  transition: opacity .15s, visibility .15s;
}

.tooltip[aria-hidden='false'] {
  visibility: visible;
  opacity: 1;
  transition: opacity .15s;
}

.box{
  border: 1px solid red;
  border-radius: 2px;
  padding: 15px;
  margin: 20px;
  text-align: center;
  cursor: pointer;
}
.box:hover{
  box-shadow: 0 0 4px;
}
<script src="https://unpkg.com/popper.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/v-tooltip"></script>

<div id="app">
  <div v-for="index in 2" 
       v-tooltip="{content: message, show: openId === index}" 
       class="box" 
       @mouseover.stop="openId=index"
  >
    
    {{ message }}
    
    <div v-tooltip="{content: 'Inner',
    show: openId === index+'inner'}" @mouseover.stop="openId=index+'inner'" class="box">
      okokok
    </div>
    
  </div>
</div>
Omar Atta
  • 11
  • 1
  • 4