Official library to use Popper on React projects
npx @tessl/cli install tessl/npm-react-popper@2.3.0React Popper is the official React wrapper around Popper.js positioning engine. It provides React components and hooks for creating tooltips, popovers, dropdowns, and other floating elements with precise positioning. The library offers both component-based (Manager, Reference, Popper) and hook-based (usePopper) approaches for maximum flexibility.
npm install react-popper @popperjs/coreNote: @popperjs/core is a required peer dependency.
import { Manager, Reference, Popper, usePopper } from "react-popper";
import type {
ManagerProps,
ReferenceProps,
ReferenceChildrenProps,
PopperProps,
PopperChildrenProps,
PopperArrowProps
} from "react-popper";For CommonJS:
const { Manager, Reference, Popper, usePopper } = require("react-popper");import React from "react";
import { Manager, Reference, Popper } from "react-popper";
function Tooltip() {
const [showTooltip, setShowTooltip] = React.useState(false);
return (
<Manager>
<Reference>
{({ ref }) => (
<button
ref={ref}
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
>
Hover me
</button>
)}
</Reference>
{showTooltip && (
<Popper placement="top">
{({ ref, style, placement }) => (
<div ref={ref} style={style} data-placement={placement}>
Tooltip content
</div>
)}
</Popper>
)}
</Manager>
);
}import React from "react";
import { usePopper } from "react-popper";
function HookTooltip() {
const [referenceElement, setReferenceElement] = React.useState(null);
const [popperElement, setPopperElement] = React.useState(null);
const { styles, attributes } = usePopper(referenceElement, popperElement, {
placement: "top",
});
return (
<>
<button ref={setReferenceElement}>Reference element</button>
<div ref={setPopperElement} style={styles.popper} {...attributes.popper}>
Popper element
</div>
</>
);
}React Popper is built around several key components:
Provides context management for coordinating reference and popper elements in component-based usage patterns.
function Manager({ children }: ManagerProps): React.Node;
interface ManagerProps {
children: React.ReactNode;
}Handles reference element registration and provides render props for attaching refs to DOM elements.
function Reference({ children, innerRef }: ReferenceProps): React.Node;
interface ReferenceProps {
children: (props: ReferenceChildrenProps) => React.ReactNode;
innerRef?: React.Ref<any>;
}
interface ReferenceChildrenProps {
ref: React.Ref<any>;
}Creates positioned popper elements with comprehensive configuration options and render props providing positioning data.
function Popper<Modifiers>({
children,
innerRef,
modifiers,
placement,
strategy,
referenceElement,
onFirstUpdate,
}: PopperProps<Modifiers>): React.Node;
interface PopperProps<Modifiers> {
children: (props: PopperChildrenProps) => React.ReactNode;
innerRef?: React.Ref<any>;
modifiers?: ReadonlyArray<Modifier<Modifiers>>;
placement?: PopperJS.Placement;
strategy?: PopperJS.PositioningStrategy;
referenceElement?: HTMLElement | PopperJS.VirtualElement;
onFirstUpdate?: (state: Partial<PopperJS.State>) => void;
}
interface PopperChildrenProps {
ref: React.Ref<any>;
style: React.CSSProperties;
placement: PopperJS.Placement;
isReferenceHidden?: boolean;
hasPopperEscaped?: boolean;
update: () => Promise<null | Partial<PopperJS.State>>;
forceUpdate: () => Partial<PopperJS.State>;
arrowProps: PopperArrowProps;
}
interface PopperArrowProps {
ref: React.Ref<any>;
style: React.CSSProperties;
}Provides low-level programmatic control over Popper instances without component wrappers.
function usePopper<Modifiers>(
referenceElement?: Element | PopperJS.VirtualElement | null,
popperElement?: HTMLElement | null,
options?: Omit<Partial<PopperJS.Options>, 'modifiers'> & {
createPopper?: typeof PopperJS.createPopper;
modifiers?: ReadonlyArray<Modifier<Modifiers>>;
}
): {
styles: { [key: string]: React.CSSProperties };
attributes: { [key: string]: { [key: string]: string } | undefined };
state: PopperJS.State | null;
update: PopperJS.Instance['update'] | null;
forceUpdate: PopperJS.Instance['forceUpdate'] | null;
};// Utility type for union intersections
type UnionWhere<U, M> = U extends M ? U : never;
// Modifier types for configuration
type StrictModifierNames = NonNullable<PopperJS.StrictModifiers['name']>;
type StrictModifier<
Name extends StrictModifierNames = StrictModifierNames
> = UnionWhere<PopperJS.StrictModifiers, { name?: Name }>;
type Modifier<
Name,
Options extends object = object
> = Name extends StrictModifierNames
? StrictModifier<Name>
: Partial<PopperJS.Modifier<Name, Options>>;
// Ref handling types
type RefHandler = (ref: HTMLElement | null) => void;