Tooltip and popover positioning engine that automatically calculates optimal placement for UI elements with advanced positioning logic and overflow prevention
npx @tessl/cli install tessl/npm-popperjs--core@2.11.0Popper.js Core is a lightweight (~3 kB) tooltip and popover positioning engine that automatically calculates optimal placement for UI elements. It provides advanced positioning logic with automatic flip detection, overflow prevention, and virtual positioning capabilities that pure CSS solutions cannot achieve.
npm install @popperjs/coreimport { createPopper } from '@popperjs/core';For specific modifiers or lite version:
import { createPopperLite, flip, preventOverflow } from '@popperjs/core';For constants and advanced use:
import { createPopper, top, bottom, placements, modifierPhases } from '@popperjs/core';CommonJS:
const { createPopper } = require('@popperjs/core');UMD (via CDN):
<script src="https://unpkg.com/@popperjs/core@2"></script>
<!-- Access via Popper.createPopper -->import { createPopper } from '@popperjs/core';
const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');
// Create popper instance
const popperInstance = createPopper(button, tooltip, {
placement: 'top',
modifiers: [
{
name: 'offset',
options: {
offset: [0, 8],
},
},
],
});
// Update positioning
popperInstance.update();
// Cleanup when done
popperInstance.destroy();Popper.js is built around several key components:
Main createPopper function and instance management for tooltip and popover positioning.
function createPopper(
reference: Element | VirtualElement,
popper: HTMLElement,
options?: Partial<Options>
): Instance;
interface Instance {
state: State;
destroy(): void;
forceUpdate(): void;
update(): Promise<Partial<State>>;
setOptions(setOptionsAction: SetAction<Partial<Options>>): Promise<Partial<State>>;
}Nine built-in modifiers that control positioning behavior including flip, preventOverflow, offset, arrow, and more.
// Key modifiers for positioning control
const flip: Modifier<'flip', FlipOptions>;
const preventOverflow: Modifier<'preventOverflow', PreventOverflowOptions>;
const offset: Modifier<'offset', OffsetOptions>;
const arrow: Modifier<'arrow', ArrowOptions>;Three different builds for various bundle size requirements and tree-shaking optimization.
// Full version with all modifiers
function createPopper(reference, popper, options?): Instance;
// Lite version with minimal modifiers
function createPopperLite(reference, popper, options?): Instance;
// Base version with no default modifiers
function createPopperBase(reference, popper, options?): Instance;
// Factory function for custom builds
function popperGenerator(generatorOptions?): typeof createPopper;Support for positioning relative to virtual coordinates for context menus and mouse-following tooltips.
interface VirtualElement {
getBoundingClientRect(): ClientRect | DOMRect;
contextElement?: Element;
}Core utility functions for advanced use cases and custom modifier development.
// Detect overflow conditions for positioning logic
function detectOverflow(
state: State,
options?: {
boundary?: Boundary;
rootBoundary?: RootBoundary;
padding?: Padding;
altBoundary?: boolean;
}
): SideObject;
type SideObject = {
top: number;
right: number;
bottom: number;
left: number;
};Useful constants for advanced positioning logic and custom modifier development.
// Placement constants
const placements: Array<Placement>;
const basePlacements: Array<BasePlacement>;
const variationPlacements: Array<VariationPlacement>;
// Direction constants
const top: 'top';
const bottom: 'bottom';
const left: 'left';
const right: 'right';
const start: 'start';
const end: 'end';
const auto: 'auto';
// Boundary constants
const clippingParents: 'clippingParents';
const viewport: 'viewport';
// Context constants
const popper: 'popper';
const reference: 'reference';
// Modifier execution phases
const modifierPhases: Array<ModifierPhases>;interface Options {
placement: Placement;
modifiers: Array<Partial<Modifier<any, any>>>;
strategy: PositioningStrategy;
onFirstUpdate?: (state: Partial<State>) => void;
}
interface State {
elements: {
reference: Element | VirtualElement;
popper: HTMLElement;
arrow?: HTMLElement;
};
options: Options;
placement: Placement;
strategy: PositioningStrategy;
orderedModifiers: Array<Modifier<any, any>>;
rects: StateRects;
scrollParents: {
reference: Array<Element | Window | VisualViewport>;
popper: Array<Element | Window | VisualViewport>;
};
styles: { [key: string]: Partial<CSSStyleDeclaration> };
attributes: { [key: string]: { [key: string]: string | boolean } };
modifiersData: { [key: string]: any };
reset: boolean;
}
type Placement =
| 'auto' | 'auto-start' | 'auto-end'
| 'top' | 'top-start' | 'top-end'
| 'bottom' | 'bottom-start' | 'bottom-end'
| 'right' | 'right-start' | 'right-end'
| 'left' | 'left-start' | 'left-end';
type PositioningStrategy = 'absolute' | 'fixed';
interface Rect {
width: number;
height: number;
x: number;
y: number;
}
interface Offsets {
x: number;
y: number;
}
type Boundary = Element | Array<Element> | 'clippingParents';
type RootBoundary = 'viewport' | 'document';