Directivas

Globos información

Comúnmente conocidos como Tooltips, estas directivas funcionan para cualquier elemento HTML o componente de Vue, agregando la directiva v-globo-informacion o v-globo-informacion-extendido.

Uso

Para usar un globo de información básico en un elemento HTML, agrega la directiva v-globo-informacion especificando la posición y el contenido u opciones.

Globo información:

html
<HTMLElement v-globo-informacion:[posicion]="contenido | opciones" />

Globo de información extendido (para contenido más largo):

html
<HTMLElement
  v-globo-informacion-extendido:[posicion].[interactivo]="contenido | opciones"
/>

Antes de usar

  • Dependencia: para el posicionamiento de los tooltips se utiliza la dependencia Popper js. No es necesario instalarla por separado, ya que se incluye con las dependencias de esta biblioteca.
  • Posicionamiento: la posición del tooltip es definida por el parámetro posicion (top, left, bottom, etc.). Sin embargo, la asignación final dependerá de la disponibilidad de espacio en pantalla y de la posición del scroll.
  • Compatibilidad con elementos deshabilitados: cuando un elemento de formulario, como un button, tiene activado el atributo disabled algunos eventos de tipo mouseenter y mouseleave dejan de ser detectados por JavaScript. Por tal motivo, la directiva podría no funcionar correctamente. Se recomienda no cambiar el atributo disabled mientras el tooltip esté pasando por el ciclo de aparecer/desaparecer.

Vista simplificada

En la vista simplificada el directiva v-globo-informacion o v-globo-informacion-extendido no se modifica en diseño ni en comportamiento.

API

Parámetros

La estructura de los parámetros es la siguiente:

v-globo-informacion:[posicion] = [contenido | opciones]

v-globo-informacion-extendido:[posicion].[interactivo] = [contenido | opciones]

Donde:

  • posicion: posición del globo de información respecto al elemento.
    • Valores aceptados: arriba-inicio | arriba | arriba-final | abajo-inicio | abajo | abajo-final | derecha-inicio | derecha | derecha-final | izquierda-inicio | izquierda | izquierda-final
    • Valor predeterminado: derecha
  • interactivo: indica si el globo de información tiene algún elemento para interactuar, útil cuando se agregan enlaces al globo de información.
    • Valores aceptados: Si existe es true, si no existe es false
    • Valor predeterminado: false
  • contenido: el contenido del globo de información, acepta html.
    • Tipo de dato: String
    • Valor predeterminado: ""
  • opciones: opciones que modifican al globo de información.
    • Tipo de dato: Object
    • Estructura:
    js
    {
      contenido: String,
      desfase: Array<Number>,
      asignadoAElemento: String
    }
    • Valor predeterminado:
    js
    {
      contenido: '',
      desfase: [0, 12],
      asignadoAElemento: undefined
    }

Descripción:

  • contenido: es el contenido del globo de información (acepta HTML).
  • desfase: es el desplazamiento que el globo de información puede tener respecto al elemento origen, siempre en valores positivos. Equivale a la propiedad offset en Popper js.
  • asignadoAElemento: es el selector CSS del elemento origen al que se le puede asignar el globo de información. Regularmente es un elemento padre del elemento al que se le aplica la directiva. Si no se especifica, usará de manera predeterminada el elemento al que se le aplicó la directiva.

Ejemplos de uso

Ejemplo básico

vue
<template>
  <div class="contenedor flex">
    <client-only>
      <!--Un globo de informacion basico -->
      <button
        class="boton-primario"
        v-globo-informacion="'Globo de información derecha (por defecto)'"
      >
        Globo de información derecha (por defecto)
      </button>

      <!--Un globo de informacion posicionado a la izquierda -->
      <button
        class="boton-primario"
        v-globo-informacion:izquierda="'Globo de información izquierda'"
      >
        Globo de información izquierda
      </button>

      <!--Un globo de informacion extendido  posicionado arriba -->
      <button
        class="boton-primario"
        v-globo-informacion-extendido:arriba="
          'Globo de información extendido arriba'
        "
      >
        Globo de información extendido arriba
      </button>

      <!--Un globo de informacion extendido  posicionado arriba -->
      <button
        class="boton-primario"
        v-globo-informacion-extendido:abajo="
          'Globo de información extendido abajo'
        "
      >
        Globo de información extendido abajo
      </button>
      <!--Un globo de informacion  posicionado abajo, con desplazamiento personalizado (50 pixeles abajo del elemento) -->
      <button
        class="boton-primario"
        v-globo-informacion:abajo="{
          contenido: 'Globo de información abajo trasladado 50px',
          desfase: [0, 50],
        }"
      >
        Globo de información abajo trasladado 50px
      </button>

      <!--Un globo de informacion extendido  posicionado arriba, con "interactable" activado, es decir que el globo de informacion se queda para interactuar (y tiene elementos para ello)-->
      <button
        class="boton-primario"
        v-globo-informacion-extendido:arriba.interactivo="{
          contenido: `Globo de información interactivo arriba <a href='#ejemplos'>con un enlace</a>`,
        }"
      >
        Globo de información interactivo arriba
      </button>
    </client-only>
  </div>
</template>
vue
<script setup>
import { ref } from 'vue'
const posicion = ref('arriba')

const posicionesDisponibles = [
  'arriba-inicio',
  'arriba',
  'arriba-final',
  'abajo-inicio',
  'abajo',
  'abajo-final',
  'derecha-inicio',
  'derecha',
  'derecha-final',
  'izquierda-inicio',
  'izquierda',
  'izquierda-final',
]
</script>
<template>
  <div>
    <client-only>
      <div
        class="elemento-padre"
        id="elementoPadre"
      >
        <div>
          Un tooltip que se posiciona a partir del elemento #ElementoPadre, pero
          que aparece/desaparece solo cuando el cursor esta en el botón
        </div>
        <button
          class="boton-primario m-y-1"
          v-globo-informacion:[posicion]="{
            contenido: `<b>soy un tooltip</b> de #ElementoPadre`,
            asignadoAElemento: '#elementoPadre',
          }"
        >
          Pasa el cursor o haz foco aquí
        </button>
        <div>
          Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nesciunt
          tenetur quo et ad explicabo
        </div>
      </div>
      <p>
        Posición del tooltip:
        <select v-model="posicion">
          <option
            v-for="posicion in posicionesDisponibles"
            :key="`id-${posicion}`"
            :value="posicion"
          >
            {{ posicion }}
          </option>
        </select>
      </p>
    </client-only>
  </div>
</template>

<style>
.elemento-padre {
  border: 1px solid red;
  max-width: 400px;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px;
}
</style>
vue
<script setup>
import { ref } from 'vue'

const contenido = ref('<b>Hola</b> edítame!')
</script>
<template>
  <div>
    <client-only>
      <p>Edita el texto para ver cómo se actualiza el globo de información</p>
      <button
        v-globo-informacion="contenido"
        class="boton-primario m-b-2"
      >
        pasa el cursor o haz foco aquí
      </button>
      <input
        type="text"
        v-model="contenido"
      />
    </client-only>
  </div>
</template>