Skip to content
Devix Open Source

Reference

Options and methods

createPopover(element, {
  content: 'Removes this row for good',
  html: false,
  placement: 'bottom',
  offset: 8,
  arrow: true,
  trigger: 'hover',
  delay: 120,
  role: 'tooltip',
  focusTrap: false,
  maxWidth: undefined,
  theme: 'auto',
  classNames: {},
  onOpen: (instance) => {},
  onClose: (instance) => {},
});
Option Default
content — Text, a Node, or a function called each time it opens.
html false Treat a string as markup. Off, because most content is not.
placement 'bottom' top bottom left right, each with -start / -end.
offset 8 Between the anchor and the panel.
arrow tooltips only
trigger by role 'hover', 'click', 'focus' or 'manual'.
delay 120 / 0 A number, or [in, out].
role 'tooltip' 'dialog' for a popover. Changes the ARIA, not the look.
focusTrap false Move focus in on open and back on close. Dialogs only.
maxWidth 260 / 320 In pixels.
theme 'auto' 'light', 'dark', or follow the page.
classNames panel, arrow, open.

Methods

const tip = createTooltip(el, { content: 'Hello' });

tip.open;                 // boolean
tip.show();
tip.hide();
tip.toggle();
tip.update();             // re-measure and re-place
tip.setContent('Changed');
tip.panel;                // the element, if you want to style or query it
tip.destroy();

update() is for when the content or the page changed under it — a lazily loaded preview, a row that grew. Scrolling and resizing are handled already.

destroy() removes the panel and puts every attribute back.

The positioning on its own

place() is pure arithmetic with no DOM in it — 590 bytes, and useful anywhere you need to put a box next to another box:

import { place } from '@devix-labs/popover/core';

place(
  { x: 930, y: 400, width: 100, height: 40 },   // the anchor
  { x: 0, y: 0, width: 200, height: 100 },      // the panel
  { x: 0, y: 0, width: 1000, height: 800 },     // the viewport
  { placement: 'bottom' },
);
// { x: 792, y: 448, placement: 'bottom', side: 'bottom', arrow: 188, shifted: true }

arrow is how far along the panel's edge the arrow goes, measured so that it still points at the anchor after the panel has slid to stay on screen.

Styling

Every colour and size is a custom property, and there is no z-index — the top layer does that job.

.dxp {
  --dxp-bg: #1e293b;
  --dxp-fg: #f8fafc;
  --dxp-radius: 10px;
  --dxp-pad: 8px 12px;
  --dxp-size: 13px;
  --dxp-arrow: 6px;
  --dxp-max: 280px;
  --dxp-shadow: 0 4px 16px rgb(0 0 0 / .18);
}

[data-side] on the panel tells you which way it ended up, for an animation that comes from the right direction. classNames puts your own class on the panel, the arrow, or the anchor while it is open — which is tippy.js #1115, still open.

Updated 15 Sep 2026