UNPKG

react-floater

Version:
231 lines (186 loc) 10.5 kB
# React Floater [![NPM version](https://badge.fury.io/js/react-floater.svg)](https://www.npmjs.com/package/react-floater) [![CI](https://github.com/gilbarbara/react-floater/actions/workflows/ci.yml/badge.svg)](https://github.com/gilbarbara/react-floater/actions/workflows/ci.yml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=gilbarbara_react-floater&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=gilbarbara_react-floater) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=gilbarbara_react-floater&metric=coverage)](https://sonarcloud.io/summary/new_code?id=gilbarbara_react-floater) **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](https://floating-ui.com/) directly. [**View the live demo →**](https://codesandbox.io/s/github/gilbarbara/react-floater/tree/main/demo) ## Highlights - 🏖 **Easy to use:** Just set the `content` - 🛠 **Flexible:** Personalize the options to fit your needs - 🟦 **Type-safe:** Full TypeScript support ## Usage ```shell npm install react-floater ``` Import it into your app: ```tsx 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 `component` prop (see `WithStyledComponents.ts` in the [demo](https://codesandbox.io/s/github/gilbarbara/react-floater/tree/main/demo)). - Pass a custom arrow using the `arrow` prop. - Customize the UI appearance using the `styles` prop. You only need to provide the keys you want to override—defaults will be merged automatically. ```tsx <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](src/modules/styles.ts) source. ## Props | **Prop** | **Type** | **Default** | **Description** | |---------------------|------------------------------------------------------------------|-------------|---------------------------------------------------------------------------| | arrow ✨ | ReactNode | – | Custom arrow for the floater. [See styles.arrow](#styles-type-definition) | | 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](#poppermodifiers-type-definition) | – | Customize popper.js modifiers. | | placement | [Placement](#placement-type-definition) | 'bottom' | Floater’s position. | | portalElement | string \| HTMLElement | – | Selector or element for rendering. | | showCloseButton | boolean | false | Shows a close (×) button. | | styles | [Styles](#styles-type-definition) | – | Customize UI styles. | | target | string \| HTMLElement | – | Target element for position. Defaults to children. | | title | ReactNode | – | Floater title. | | wrapperOptions | [WrapperOptions](#wrapperoptions-type-definition) | – | Options for positioning the wrapper. Requires a target. | <details> <summary><b id="poppermodifiers-type-definition">PopperModifiers Type Definition</b></summary> ```typescript 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>; } ``` </details> > **Intended for advanced customization—use with caution.** <details> <summary><b id="placement-type-definition">Placement Type Definition</b></summary> ```typescript 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" ``` </details> <details> <summary><b id="styles-type-definition">Styles Type Definition</b></summary> ```typescript 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; } ``` </details> <details> <summary><b id="wrapperoptions-type-definition">WrapperOptions Type Definition</b></summary> ```typescript 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 } ``` </details> ## Modes React Floater supports several modes for flexible positioning and control: **Default** The Floater is anchored to its child and triggers on event. ```tsx <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`. ```tsx <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). ```tsx <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` ```tsx <div className="App"> <img src="some-path" /> <Floater content="This is the Floater content" open={true} target=".App img" /> </div> ```