The complete tooltip, popover, dropdown, and menu solution for the web
—
The core tooltip functionality provides the primary interface for creating and managing individual tooltip instances with comprehensive configuration and lifecycle management.
Creates tooltip instances for DOM elements with optional configuration properties.
/**
* Creates tooltip instances for given DOM elements or selectors
* @param targets - Element(s) or CSS selector for tooltip triggers
* @param optionalProps - Optional configuration properties
* @returns Single instance for single target, array for multiple targets
*/
function tippy<TProps = Props>(
targets: Element | Element[] | NodeList | string,
optionalProps?: Partial<TProps>
): Instance<TProps> | Instance<TProps>[];
// Target types
type SingleTarget = Element;
type MultipleTargets = string | Element[] | NodeList;
type Targets = SingleTarget | MultipleTargets;Usage Examples:
import tippy from "tippy.js";
// Single element
const button = document.querySelector('#myButton');
const instance = tippy(button, {
content: 'Click me!',
placement: 'top'
});
// Multiple elements by selector
const instances = tippy('.tooltip-trigger', {
content: 'Default content',
delay: [500, 100]
});
// Multiple elements by NodeList
const elements = document.querySelectorAll('.dynamic-tooltip');
const instances = tippy(elements, {
content(reference) {
return reference.getAttribute('data-title') || 'No title';
}
});
// Dynamic content function
tippy('#user-info', {
content(reference) {
const userId = reference.dataset.userId;
return `<div>Loading user ${userId}...</div>`;
},
allowHTML: true,
onShow(instance) {
// Fetch and update content asynchronously
fetchUserData(instance.reference.dataset.userId)
.then(data => instance.setContent(`<div>${data.name}</div>`));
}
});Core methods available on every tooltip instance for programmatic control.
interface Instance<TProps = Props> {
/** Unique identifier for this instance */
id: number;
/** Reference to the trigger element */
reference: ReferenceElement<TProps>;
/** Reference to the tooltip element (when mounted) */
popper: PopperElement<TProps>;
/** Popper.js instance for positioning (when mounted) */
popperInstance: Popper.Instance | null;
/** Current configuration properties */
props: TProps;
/** Active plugins for this instance */
plugins: Plugin<TProps>[];
/** Current state information */
state: {
isEnabled: boolean;
isVisible: boolean;
isDestroyed: boolean;
isMounted: boolean;
isShown: boolean;
};
/** Show the tooltip */
show(): void;
/** Hide the tooltip */
hide(): void;
/** Enable the tooltip (allow show/hide) */
enable(): void;
/** Disable the tooltip (prevent show/hide) */
disable(): void;
/** Update tooltip content */
setContent(content: Content): void;
/** Update configuration properties */
setProps(partialProps: Partial<TProps>): void;
/** Clear any pending delay timers */
clearDelayTimeouts(): void;
/** Hide with interactivity consideration */
hideWithInteractivity(event: MouseEvent): void;
/** Unmount tooltip from DOM (but keep instance) */
unmount(): void;
/** Destroy instance and remove all event listeners */
destroy(): void;
}Usage Examples:
const instance = tippy('#myButton', { content: 'Hello' });
// Programmatic control
instance.show();
setTimeout(() => instance.hide(), 2000);
// Dynamic updates
instance.setContent('Updated content');
instance.setProps({
placement: 'bottom',
delay: 1000
});
// State checking
if (instance.state.isVisible) {
instance.hide();
}
// Cleanup
instance.destroy();Flexible content system supporting multiple formats and dynamic generation.
type Content =
| string
| Element
| DocumentFragment
| ((ref: Element) => string | Element | DocumentFragment);Usage Examples:
// String content
tippy('#basic', { content: 'Simple text' });
// HTML string (requires allowHTML: true)
tippy('#html', {
content: '<strong>Bold</strong> text',
allowHTML: true
});
// DOM element
const div = document.createElement('div');
div.textContent = 'Element content';
tippy('#element', { content: div });
// Function returning string
tippy('.dynamic', {
content(reference) {
return `Tooltip for ${reference.textContent}`;
}
});
// Function returning element
tippy('.complex', {
content(reference) {
const container = document.createElement('div');
container.innerHTML = `
<h3>${reference.dataset.title}</h3>
<p>${reference.dataset.description}</p>
`;
return container;
}
});Comprehensive event system for customizing tooltip behavior at different stages.
interface LifecycleHooks<TProps = Props> {
/** Called after instance properties are updated */
onAfterUpdate(instance: Instance<TProps>, partialProps: Partial<TProps>): void;
/** Called before instance properties are updated */
onBeforeUpdate(instance: Instance<TProps>, partialProps: Partial<TProps>): void;
/** Called when instance is first created */
onCreate(instance: Instance<TProps>): void;
/** Called when instance is destroyed */
onDestroy(instance: Instance<TProps>): void;
/** Called after tooltip is fully hidden */
onHidden(instance: Instance<TProps>): void;
/** Called before tooltip starts hiding (can prevent with return false) */
onHide(instance: Instance<TProps>): void | false;
/** Called after tooltip is mounted to DOM */
onMount(instance: Instance<TProps>): void;
/** Called before tooltip starts showing (can prevent with return false) */
onShow(instance: Instance<TProps>): void | false;
/** Called after tooltip is fully shown */
onShown(instance: Instance<TProps>): void;
/** Called when trigger event occurs */
onTrigger(instance: Instance<TProps>, event: Event): void;
/** Called when untrigger event occurs */
onUntrigger(instance: Instance<TProps>, event: Event): void;
/** Called when clicking outside interactive tooltip */
onClickOutside(instance: Instance<TProps>, event: Event): void;
}Usage Examples:
tippy('#advanced', {
content: 'Loading...',
onShow(instance) {
// Prevent showing if data not ready
if (!instance.reference.dataset.ready) {
return false;
}
},
onMount(instance) {
// Fetch content after mounting
fetchTooltipContent(instance.reference.id)
.then(content => instance.setContent(content));
},
onHidden(instance) {
// Cleanup when hidden
instance.setContent('Loading...');
}
});Type-safe references to tooltip trigger and popup elements.
interface ReferenceElement<TProps = Props> extends Element {
/** Associated tippy instance (when created) */
_tippy?: Instance<TProps>;
}
interface PopperElement<TProps = Props> extends HTMLDivElement {
/** Associated tippy instance */
_tippy?: Instance<TProps>;
}Access and modification of global default properties.
interface DefaultProps extends Omit<Props, 'delay' | 'duration'> {
delay: number | [number, number];
duration: number | [number, number];
}
// Static properties on tippy function
interface TippyStatics {
readonly currentInput: { isTouch: boolean };
readonly defaultProps: DefaultProps;
setDefaultProps(partialProps: Partial<DefaultProps>): void;
}Usage Examples:
import tippy from "tippy.js";
// Check current input type
if (tippy.currentInput.isTouch) {
// Touch-specific behavior
}
// Update global defaults
tippy.setDefaultProps({
delay: 500,
duration: [200, 150],
theme: 'dark'
});
// Access current defaults
console.log(tippy.defaultProps.placement); // 'top'Install with Tessl CLI
npx tessl i tessl/npm-tippy-js