React Hook to add tooltip to any element
React Popper is a low level react hook (along with a provider) to add all kinds of absolutely positioned poppers which are added to the target element via React.createPortal
.
It identifies the target element (the one to which popper gets appended to), via the event.currentTarget
(in case, it's not provided in the options
to the usePopper
) and calculates the positioning of the popper internally using a few inline styles, hence, does not have any dependency on any other styling library.
UsePopper Hook exposes togglePopper
, showPopper
and hidePopper
callbacks to the consume/client which can be called in response to different MouseEvent
s. The Hook manages the open/close
state of the popper internally, and therefore, togglePopper
is the recommend way to use, and should be enough for most of the use cases. But if the consumer really wants to manage the open/close
manually, then he may use a combination of showPopper
and hidePopper
callbacks.
npm install --save react-use-popper
Wrap your root component with PopperProvider
// app.jsx
import { PopperProvider } from 'react-use-popper'
const App = () => {
return (
<PopperProvider>
<RootComponent />
</PopperProvider>
)
}
import React, { Component } from 'react'
import { usePopper } from 'react-use-popper'
const ChidlComponent = () => {
const { togglePopper } = usePopper('Popper 1')
const handleClick = (e: React.MouseEvent) => {
togglePopper(e)
}
return (
<>
<button onClick={handleClick}>Button</button>
</>
)
}
If you want to have multiple poppers open at same time, it's recommended to use multiple hooks, e.g:
import React, { Component } from 'react'
import { usePopper } from 'react-use-popper'
const ChidlComponent = () => {
const popper1 = usePopper('Popper 1')
const popper2 = usePopper('Popper 2')
const handleClick = (e: React.MouseEvent) => {
popper1.togglePopper(e)
}
const handleAnotherClick = (e: React.MouseEvent) => {
popper2.togglePopper(e)
}
return (
<>
<button onClick={handleClick}>Button</button>
<button onClick={handleAnotherClick}>Another Button</button>
</>
)
}
((popper: Popper) => React.ReactNode) | React.ReactNode
| optional |default value: "Default Content"
The react element you want to render in the popper
string
| optional
An ID to avoid duplicate poppers. generated randomly by default, if no id is provided
Element
| optional
A DOM node in which to render the popper
gets extracted from the event.currentTarget
, in case not provided.
() => void
| optional
A callback that's fired when the popper gets closed.
Easiest and Recommended to use, manages popper's open/close state internally.
event: React.MouseEvent
| required
content : ((popper: Popper) => React.ReactNode) | React.ReactNode
| optional | defaults tousePopper
'sdefaultContent
options: PopperOptions
| optional | defaults tousePopper
'sdefaultContent
Useful in case you want to manage popper's state manually, takes similar args as togglePopper
returns, Popper object containing id
which will be needed to pass to hidePopper
event: React.MouseEvent
| required
content : ((popper: Popper) => React.ReactNode) | React.ReactNode
| optional | defaults tousePopper
'sdefaultContent
options: PopperOptions
| optional | defaults tousePopper
'sdefaultContent
popper: PrivatePopper
Closes Popper by ID.
popperId: string
| required
interface PopperArgs {
/**
* The react element you want to render in the popper
*/
defaultContent?: ((popper: Popper) => React.ReactNode) | React.ReactNode
defaultOptions?: PopperOptions
}
interface PopperOptions {
/**
* An ID to avoid duplicate poppers
* generates randomly by default, if no id is provided
*/
id?: string
/**
* A DOM node in which to render the popper
* gets extracted by the `event`, in case not provided
*/
appendTo?: Element
/**
* A callback that is fired when the popper closes
*/
onClose?: () => void
}
interface PrivatePopper {
/**
* Popper Content Element
*/
element: React.ReactNode
/**
* Popper ID, need to pass this id while closing
*/
id: string
/**
* Popper Container Element to which Popper is appended to
*/
appendTo: Element
}
MIT © WaleedAli070