Flexible, customizable, and accessible tooltips, popovers, and guided hints for React.
Maintenance Mode: This library is built on Popper.js v2, which is no longer actively maintained. For new projects, we recommend using Floating UI directly.
Highlights
- 🏖 Easy to use: Just set the
content - 🛠 Flexible: Personalize the options to fit your needs
- 🟦 Type-safe: Full TypeScript support
Usage
npm install react-floater
Import it into your app:
import Floater from 'react-floater'; <Floater content="This is the Floater content"> <span>click me</span> </Floater>;
Voilà! A tooltip will appear on click!
Customization & Styling
React Floater is highly customizable. You can:
- Use a custom component for the content via the
componentprop
(seeWithStyledComponents.tsin the demo). - Pass a custom arrow using the
arrowprop. - Customize the UI appearance using the
stylesprop.
You only need to provide the keys you want to override—defaults will be merged automatically.
<Floater content={<div>Custom content <b>with bold!</b></div>} placement="right" arrow={<MyCustomArrow />} styles={{ container: { backgroundColor: "#222", color: "#fff" }, arrow: { color: "#222", size: 16, base: 24 }, }} > <button>Hover or click me</button> </Floater>
For all available style keys and their default values, see the styles.ts source.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| arrow ✨ | ReactNode | – | Custom arrow for the floater. See styles.arrow |
| autoOpen | boolean | false | Open the Floater automatically. |
| callback | (action: ‘open’ | ‘close’, props: Props) => void | – | Called when the Floater opens or closes. |
| children | ReactNode | – | Element to trigger the Floater. |
| component | ComponentType | ReactElement | – | Custom component UI for the Floater. Has access to closeFn. |
| content | ReactNode | – | The content of the Floater. (Required unless you pass a component.) |
| debug | boolean | false | Log basic actions. |
| disableFlip | boolean | false | Disable changes in position on scroll/resize. |
| disableHoverToClick | boolean | false | Don’t convert hover to click on mobile. |
| event | 'hover' | 'click' | 'click' | Event that triggers the Floater.Not used in controlled mode. |
| eventDelay | number | 0.4 | Time in seconds before hiding on mouseLeave (only for hover). |
| footer | ReactNode | – | Footer area content. |
| getPopper | (popper: PopperInstance, origin: ‘floater’ | ‘wrapper’) => void | – | Get the popper.js instance. |
| hideArrow | boolean | false | Hide the arrow (good for centered/modal). |
| offset | number | 15 | Distance (px) between Floater and target. |
| open | boolean | – | Switch to controlled mode. Disables normal event triggers. |
| modifiers | PopperModifiers | – | Customize popper.js modifiers. |
| placement | Placement | 'bottom' | Floater’s position. |
| portalElement | string | HTMLElement | – | Selector or element for rendering. |
| showCloseButton | boolean | false | Shows a close (×) button. |
| styles | Styles | – | Customize UI styles. |
| target | string | HTMLElement | – | Target element for position. Defaults to children. |
| title | ReactNode | – | Floater title. |
| wrapperOptions | WrapperOptions | – | Options for positioning the wrapper. Requires a target. |
interface PopperModifiers { applyStyles?: Partial<ApplyStylesModifier>; arrow?: Partial<ArrowModifier>; computeStyles?: Partial<ComputeStylesModifier>; eventListeners?: Partial<EventListenersModifier>; flip?: Partial<FlipModifier>; hide?: Partial<HideModifier>; offset?: Partial<OffsetModifier>; popperOffsets?: Partial<PopperOffsetsModifier>; preventOverflow?: Partial<PreventOverflowModifier>; }
Placement Type DefinitionIntended for advanced customization—use with caution.
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" | "center"
interface Styles { arrow: CSSProperties & { size: number; base: number; }; close: CSSProperties; container: CSSProperties; content: CSSProperties; floater: CSSProperties; floaterCentered: CSSProperties; floaterClosing: CSSProperties; floaterOpening: CSSProperties; floaterWithAnimation: CSSProperties; floaterWithComponent: CSSProperties; footer: CSSProperties; options: { zIndex: number; }; title: CSSProperties; wrapper: CSSProperties; wrapperPosition: CSSProperties; }
interface WrapperOptions { offset: number; // The distance between the wrapper and the target. It can be a negative value. placement: string; // the same options as above, except center position: boolean; // Set to true to position the wrapper }
Modes
React Floater supports several modes for flexible positioning and control:
Default
The Floater is anchored to its child and triggers on event.
<Floater content="This is the Floater content"> <span>click me</span> </Floater>
Proxy
The Floater is triggered by the child, but positioned relative to the target.
<div className="App"> <img src="some-path" /> <Floater content="This is the Floater content" target=".App img"> <span>click me</span> </Floater> </div>
Beacon
The Floater wrapper is positioned relative to the target (useful for guided tours or beacons).
<div className="App"> <img src="https://upload.wikimedia.org/wikipedia/commons/2/2d/Google-favicon-2015.png" width="100" className="my-super-image" /> <Floater content="This is the Floater content" target=".my-super-image" wrapperOptions={{ offset: -22, placement: 'top', position: true, }} > <span style={{ color: '#f04', fontSize: 34 }}>◉</span> </Floater> </div>
Controlled
You manage the Floater’s visibility with the open prop - no trigger events are needed.
In this mode, you don't even need to have children
<div className="App"> <img src="some-path" /> <Floater content="This is the Floater content" open={true} target=".App img" /> </div>