Installations
npm install @tippyjs/react
Score
85.2
Supply Chain
93
Quality
75.9
Maintenance
100
Vulnerability
100
License
Releases
Contributors
Developer
atomiks
Developer Guide
Module System
CommonJS
Min. Node Version
Typescript Support
Yes
Node Version
14.17.6
NPM Version
6.14.15
Statistics
1,800 Stars
289 Commits
94 Forks
12 Watching
17 Branches
14 Contributors
Updated on 19 Nov 2024
Bundle Size
42.43 kB
Minified
13.87 kB
Minified + Gzipped
Languages
JavaScript (100%)
Total Downloads
Cumulative downloads
Total Downloads
88,933,963
Last day
-24.1%
89,697
Compared to previous day
Last week
-2.4%
547,704
Compared to previous week
Last month
2.9%
2,345,043
Compared to previous month
Last year
7.4%
28,407,588
Compared to previous year
Daily Downloads
Weekly Downloads
Monthly Downloads
Yearly Downloads
Dependencies
1
Dev Dependencies
29
Tippy.js for React
⚠️⚠️⚠️
If you're new here, we recommend using Floating UI's React DOM Interactions package instead of this library. It offers a first class React experience rather than being a wrapper around a vanilla library and encourages much better accessibility practices with more flexibility.
If you want some out-of-the-box styling and animations, and are adding simple tooltips/popovers to your app, Tippy will still work fine. For more advanced/headless solutions, it's best to use Floating UI!
⚠️⚠️⚠️
Tippy.js is the complete tooltip, popover, dropdown, and menu solution for the web, powered by Popper.
Tippy is an abstraction over Popper that provides common logic involved in all types of elements that pop out on top of the UI, positioned next to a target or reference element. This is a React wrapper for the core library, providing full integration including headless rendering abilities.
🚀 Installation
1# npm 2npm i @tippyjs/react 3 4# Yarn 5yarn add @tippyjs/react
CDN: https://unpkg.com/@tippyjs/react
🖲 Usage
There are two ways to use this component:
- Default: With the built-in DOM rendering and optionally the default CSS. This is complete "out of the box" behavior and requires no setup. If you want something that just works, this is for you.
- Headless: With React's DOM rendering for improved usage with CSS-in-JS and spring libraries. If you want greater control over your poppers to integrate fully with design systems, this is for you.
Both may be used in conjunction.
Default Tippy
Import the Tippy
component and (optionally) the core CSS. Wrap the <Tippy />
component around the element, supplying the tooltip's content as the content
prop. It can take a string or a tree of React elements.
1import React from 'react'; 2import Tippy from '@tippyjs/react'; 3import 'tippy.js/dist/tippy.css'; // optional 4 5const StringContent = () => ( 6 <Tippy content="Hello"> 7 <button>My button</button> 8 </Tippy> 9); 10 11const JSXContent = () => ( 12 <Tippy content={<span>Tooltip</span>}> 13 <button>My button</button> 14 </Tippy> 15);
Default Tippy "just works" out of the box.
Headless Tippy
Render your own tippy element from scratch:
1import React from 'react'; 2import Tippy from '@tippyjs/react/headless'; // different import path! 3 4const HeadlessTippy = () => ( 5 <Tippy 6 render={attrs => ( 7 <div className="box" tabIndex="-1" {...attrs}> 8 My tippy box 9 </div> 10 )} 11 > 12 <button>My button</button> 13 </Tippy> 14);
attrs
is an object containing data-placement
, data-reference-hidden
, and
data-escaped
attributes. This allows you to conditionally style your tippy.
Headless animation
Headless arrow
To make Popper position your custom arrow, set a data-popper-arrow
attribute
on it:
1<Tippy 2 render={attrs => ( 3 <Box {...attrs}> 4 Hello 5 <Arrow data-popper-arrow="" /> 6 </Box> 7 )} 8> 9 <button>Reference</button> 10</Tippy>
For details on styling the arrow from scratch, take a look at the Popper tutorial.
Note: your arrow must be an HTMLElement
(not an SVGElement
). To use an SVG
arrow, wrap it in a <div>
tag with the data-popper-arrow
attribute.
You may also pass a ref to the element directly without the attribute using a callback ref:
1function App() { 2 const [arrow, setArrow] = useState(null); 3 4 return ( 5 <Tippy 6 render={attrs => ( 7 <Box {...attrs}> 8 Content 9 <Arrow ref={setArrow} /> 10 </Box> 11 )} 12 popperOptions={{ 13 modifiers: [ 14 { 15 name: 'arrow', 16 options: { 17 element: arrow, // can be a CSS selector too 18 }, 19 }, 20 ], 21 }} 22 > 23 <button>Reference</button> 24 </Tippy> 25 ); 26}
Headless root element
When rendering an element with the render
prop, you're rendering the inner
element that the root popper (positioned) node wraps.
For advanced cases you can access the root element via instance.popper
.
Here's moveTransition
with Framer Motion.
Component children
If you want to use a component element as a child of the component, ensure you forward the ref to the DOM node:
1import React, {forwardRef} from 'react'; 2 3function ThisWontWork() { 4 return <button>Reference</button>; 5} 6 7const ThisWillWork = forwardRef((props, ref) => { 8 return <button ref={ref}>Reference</button>; 9}); 10 11function App() { 12 return ( 13 <Tippy content="Tooltip"> 14 <ThisWillWork /> 15 </Tippy> 16 ); 17}
styled-components
v4+ does this for you automatically, so it should be
seamless when using the styled
constructor.
Workaround for old libraries that don't forward the ref is to use a <span>
wrapper tag:
1<Tippy content="Tooltip"> 2 <span tabIndex="0"> 3 <LegacyComponent>Reference</LegacyComponent> 4 </span> 5</Tippy>
🧬 Props
All of the native Tippy.js props can be passed to the component.
Visit All Props to view the complete list.
1<Tippy content="Tooltip" interactive={true} interactiveBorder={20} delay={100}> 2 <button>Reference</button> 3</Tippy>
In addition, there are 3 more props added specifically for the React component.
className?: string
1<Tippy content="Tooltip" className="hello world"> 2 <button>Reference</button> 3</Tippy>
This allows you to use styled(Tippy)
or the css
prop in styled-components
or emotion
.
Note: Does not apply if using Headless Tippy.
disabled?: boolean
1function App() { 2 const [disabled, setDisabled] = useState(false); 3 4 return ( 5 <Tippy content="Tooltip" disabled={disabled}> 6 <button>Reference</button> 7 </Tippy> 8 ); 9}
visible?: boolean
(controlled mode)
Use React's state to fully control the tippy instead of relying on the native
trigger
and hideOnClick
props:
1function App() { 2 const [visible, setVisible] = useState(true); 3 const show = () => setVisible(true); 4 const hide = () => setVisible(false); 5 6 return ( 7 <Tippy content="Tooltip" visible={visible} onClickOutside={hide}> 8 <button onClick={visible ? hide : show}>Reference</button> 9 </Tippy> 10 ); 11}
reference?: React.RefObject | Element
Available from
v4.1.0
If you can't place your reference element as a child inside <Tippy />
, you can
use this prop instead. It accepts a React RefObject
(.current
property) or a
plain Element
.
1function App() { 2 const ref = useRef(); 3 4 return ( 5 <> 6 <button ref={ref} /> 7 <Tippy content="Tooltip" reference={ref} /> 8 </> 9 ); 10}
Plugins
Tippy.js splits certain props into separate pieces of code called plugins to enable tree-shaking, so that components or routes that don't need the prop's functionality are not burdened with the bundle size cost of it. In addition, they enable a neat way to extend the functionality of tippy instances.
1import Tippy from '@tippyjs/react'; 2// ⚠️ import from 'tippy.js/headless' if using Headless Tippy 3import {followCursor} from 'tippy.js'; 4 5function App() { 6 return ( 7 <Tippy content="Tooltip" followCursor={true} plugins={[followCursor]}> 8 <button>Reference</button> 9 </Tippy> 10 ); 11}
🌈 Multiple tippies on a single element
You can nest the components like so:
1<Tippy content="Tooltip" placement="bottom"> 2 <Tippy content="Tooltip" placement="left"> 3 <Tippy content="Tooltip" placement="right"> 4 <Tippy content="Tooltip"> 5 <button>Reference</button> 6 </Tippy> 7 </Tippy> 8 </Tippy> 9</Tippy>
Lazy mounting
By default, Tippy mounts your content
or render
elements into a container
element once created, even if the tippy isn't mounted on the DOM. In most cases,
this is fine, but in performance-sensitive scenarios or cases where mounting the
component should fire effects only when the tippy mounted, you can lazify the
component.
View the following gists to optimize your <Tippy />
if needed.
📚 useSingleton
A Hook for the
createSingleton()
addon to re-use a single tippy element for many different reference element
targets.
1import Tippy, {useSingleton} from '@tippyjs/react'; 2 3function App() { 4 const [source, target] = useSingleton(); 5 6 return ( 7 <> 8 {/* This is the tippy that gets used as the singleton */} 9 <Tippy singleton={source} delay={500} /> 10 11 {/* These become "virtual" */} 12 <Tippy content="Hello" singleton={target}> 13 <button>Reference</button> 14 </Tippy> 15 <Tippy content="Bye" singleton={target}> 16 <button>Reference</button> 17 </Tippy> 18 </> 19 ); 20}
useSingleton()
takes an optional props argument:
1const [source, target] = useSingleton({ 2 disabled: true, 3 overrides: ['placement'], 4});
Headless singleton
The render
prop takes the singleton content as a second parameter:
1import Tippy, {useSingleton} from '@tippyjs/react/headless'; 2 3function App() { 4 const [source, target] = useSingleton(); 5 6 return ( 7 <> 8 <Tippy 9 singleton={source} 10 render={(attrs, content) => ( 11 <div className="box" tabIndex="-1" {...attrs}> 12 {content} 13 </div> 14 )} 15 delay={500} 16 /> 17 18 <Tippy content="Hello" singleton={target}> 19 <button>Reference</button> 20 </Tippy> 21 <Tippy content="Bye" singleton={target}> 22 <button>Reference</button> 23 </Tippy> 24 </> 25 ); 26}
📝 License
MIT
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
- Info: project has a license file: LICENSE:0
- Info: FSF or OSI recognized license: MIT License: LICENSE:0
Reason
Found 4/30 approved changesets -- score normalized to 1
Reason
project is archived
Details
- Warn: Repository is archived.
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
- Warn: no security policy file detected
- Warn: no security file to analyze
- Warn: no security file to analyze
- Warn: no security file to analyze
Reason
project is not fuzzed
Details
- Warn: no fuzzer integrations found
Reason
branch protection not enabled on development/release branches
Details
- Warn: branch protection not enabled for branch 'master'
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
- Warn: 0 commits out of 9 are checked with a SAST tool
Reason
60 existing vulnerabilities detected
Details
- Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92
- Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw
- Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw
- Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg
- Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw
- Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5
- Warn: Project is vulnerable to: GHSA-257v-vj4p-3w2h
- Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275
- Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c
- Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq
- Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w
- Warn: Project is vulnerable to: GHSA-434g-2637-qmqr
- Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m
- Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw
- Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p
- Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747
- Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj
- Warn: Project is vulnerable to: GHSA-7r28-3m3f-r2pr
- Warn: Project is vulnerable to: GHSA-r8j5-h5cx-65gg
- Warn: Project is vulnerable to: GHSA-896r-f27r-55mw
- Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h
- Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw
- Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9
- Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm
- Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv
- Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3
- Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h
- Warn: Project is vulnerable to: GHSA-92xj-mqp7-vmcj
- Warn: Project is vulnerable to: GHSA-wxgw-qj99-44c2
- Warn: Project is vulnerable to: GHSA-5rrq-pxf6-6jx5
- Warn: Project is vulnerable to: GHSA-8fr3-hfg3-gpgp
- Warn: Project is vulnerable to: GHSA-gf8q-jrpm-jvxq
- Warn: Project is vulnerable to: GHSA-2r2c-g63r-vccr
- Warn: Project is vulnerable to: GHSA-cfm4-qjh2-4765
- Warn: Project is vulnerable to: GHSA-x4jg-mjrx-434g
- Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p
- Warn: Project is vulnerable to: GHSA-rp65-9cf3-cjxr
- Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9
- Warn: Project is vulnerable to: GHSA-566m-qj78-rww5
- Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j
- Warn: Project is vulnerable to: GHSA-hwj9-h5mp-3pm3
- Warn: Project is vulnerable to: GHSA-6fw4-hr69-g3rv
- Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp
- Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6
- Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm
- Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw
- Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg
- Warn: Project is vulnerable to: GHSA-hxcc-f52p-wc94
- Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p
- Warn: Project is vulnerable to: GHSA-3f95-r44v-8mrg
- Warn: Project is vulnerable to: GHSA-28xr-mwxg-3qc8
- Warn: Project is vulnerable to: GHSA-9p95-fxvg-qgq2
- Warn: Project is vulnerable to: GHSA-9w5j-4mwv-2wj8
- Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc
- Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v
- Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3
- Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7
- Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693
- Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q
- Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh
Score
1.9
/10
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More