Skip to content
Devix Open Source

Guide

React, Vue, Svelte and a plain page

React

import { Tooltip } from '@devix-labs/popover/react';
import '@devix-labs/popover/styles.css';

<Tooltip content="Removes this row for good" placement="right">
  <button onClick={remove}>Delete</button>
</Tooltip>

No portal, no z-index prop and nothing corresponding to tippy's appendTo: the browser's top layer puts the panel above everything, so there is nothing for React to move.

A controlled tooltip takes open and onOpenChange.

This works on React 19, which tippy does not — its #1183 is "Accessing element.ref was removed in React 19", against an archived repository.

Vue

A directive, because a tooltip belongs to an element rather than wrapping one:

import { tooltip } from '@devix-labs/popover/vue';

app.directive('tooltip', tooltip);
<button v-tooltip="'Removes this row for good'">Delete</button>
<button v-tooltip="{ content: 'On the right', placement: 'right' }">Info</button>

Svelte

<script>
  import { popover } from '@devix-labs/popover/svelte';
</script>

<button use:popover={{ content: 'Removes this row for good' }}>Delete</button>

A web component

<script type="module" src="https://devix.pk/cdn/oss/popover@1.0.0/element.js"></script>

<dx-tooltip content="Removes this row for good" placement="right">
  <button>Delete</button>
</dx-tooltip>

It wraps whatever is inside it, so the anchor keeps its own attributes and its place in the tab order. trigger="click" makes it a popover.

A plain page, or Laravel

The most useful form is one line that adopts every element already marked up for it:

<button data-tip="Removes this row for good">Delete</button>
<a data-tip="Opens in a new window" data-tip-placement="top" href="/report">Report</a>
import { createTooltip } from '/cdn/oss/popover@1.0.0/index.js';

for (const el of document.querySelectorAll('[data-tip]')) {
  createTooltip(el, { content: el.dataset.tip, placement: el.dataset.tipPlacement });
}

In Blade that is a component:

{{-- resources/views/components/tip.blade.php --}}
<span data-tip="{{ $text }}">{{ $slot }}</span>
<x-tip text="Removes this row for good"><button>Delete</button></x-tip>

The title attribute

If all you need is a plain label with no styling, the browser's own title is still the most accessible thing available and costs nothing. Reach for this when you need it to look like your product, to hold markup, to stay open long enough to read, or to be dismissible with Escape — which title is not.

Updated 15 Sep 2026