npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@tippy.js/react

v3.1.1

Published

React component for Tippy.js

Downloads

190,349

Readme


Tippy.js is a highly customizable tooltip and popover library powered by Popper.js. This is a lightweight wrapper that lets you use it declaratively in React.

💎 Examples

Tooltips

Popovers

🚀 Installation

# npm
npm i @tippy.js/react

# Yarn
yarn add @tippy.js/react

CDN: https://unpkg.com/@tippy.js/react

Requires React 16.8+

🖲 Usage

Import the Tippy component and 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.

import React from 'react';
import Tippy from '@tippy.js/react';
import 'tippy.js/dist/tippy.css';

const StringContent = () => (
  <Tippy content="Hello">
    <button>My button</button>
  </Tippy>
);

const JSXContent = () => (
  <Tippy content={<span>Tooltip</span>}>
    <button>My button</button>
  </Tippy>
);

Component children

If you want to use a component element as a child, ensure you forward the ref to the DOM node:

import React, {forwardRef} from 'react';

function ThisWontWork() {
  return <button>Text</button>;
}

const ThisWillWork = forwardRef((props, ref) => {
  return <button ref={ref}>Text</button>;
});

function App() {
  return (
    <Tippy content="Tooltip">
      <ThisWillWork />
    </Tippy>
  );
}

styled-components v4 does this for you automatically, so it should be seamless when using the styled constructor.

If you're using a library that doesn't forwardRef for you, and doesn't give access to the ref via innerRef or similar, you can use a wrapper <span> element as a workaround.

<Tippy content="Tooltip">
  <span tabIndex="0">
    <LegacyComponent>Content</LegacyComponent>
  </span>
</Tippy>

🧬 Props

All of the native Tippy.js props can be passed to the component.

Visit All Props to view the complete table.

<Tippy
  content="Tooltip"
  arrow={true}
  animation="scale"
  duration={0}
  delay={[300, 0]}
  // ...and many more!
>
  <button>Text</button>
</Tippy>

In addition, there are 3 more props added specifically for the React component.

className?: string

A React alternative to the theme prop. The className gets added to the tooltip element's class list as expected, without adding -theme as a suffix.

<Tippy content="Tooltip" className="hello world">
  <button />
</Tippy>

If you're using styled-components, the className prop allows you to avoid global styles with the following technique:

const PurpleTippy = styled(Tippy)`
  background: purple;

  /* Styling the arrow for different placements */
  &[data-placement^='top'] {
    .tippy-arrow {
      border-top-color: purple;
    }
  }
`;

See themes for more information.

Note: the following examples are using the new React Hooks API. It isn't required to use this library – the props will work as expected in class components too.

enabled?: boolean

Prop to control the tippy.enable() / tippy.disable() instance methods. Use this when you want to temporarily disable a tippy from showing.

function App() {
  const [enabled, setEnabled] = useState(true);
  return (
    <Tippy content="Tooltip" enabled={enabled}>
      <button />
    </Tippy>
  );
}

visible?: boolean

Prop to control the tippy.show() / tippy.hide() instance methods. Use this when you want to programmatically show or hide the tippy instead of relying on UI events. This puts the tippy in controlled mode so it will only respond to state.

function App() {
  const [visible, setVisible] = useState(true);
  return (
    <Tippy content="Tooltip" visible={visible}>
      <button />
    </Tippy>
  );
}

Note: You should also set the hideOnClick prop to false if you don't want the tippy to hide when the user clicks on the document somewhere.

Plugins

Tippy.js splits certain props into separate pieces of code called plugins to enable treeshaking, so that users who don't need the prop's functionality are not burdened with the cost of it.

import Tippy from '@tippy.js/react';
import {followCursor} from 'tippy.js';
import 'tippy.js/dist/tippy.css';

function App() {
  return (
    <Tippy content="Tooltip" followCursor={true} plugins={[followCursor]}>
      <button />
    </Tippy>
  );
}

Read more about plugins here.

Performance

Props that the popperInstance depends on that aren't primitive values should be memoized or hoisted to a static constant, so that the popperInstance is not recreated on every render:

  • popperOptions
  • flipBehavior
// static constant if it doesn't change
const popperOptions = {};

function App() {
  const [placement, setPlacement] = useState('right');
  // memoized value if it's dynamic
  const flipBehavior = useMemo(() => [placement, 'bottom'], [placement]);

  return (
    <Tippy
      content="Tooltip"
      placement={placement}
      flipBehavior={flipBehavior}
      popperOptions={popperOptions}
    >
      <button />
    </Tippy>
  );
}

Default props

You can create a new component file that exports a wrapper component that has its own default props.

import Tippy from '@tippy.js/react';

// When importing Tippy from this file instead, it will have the fade animation
// by default
export default props => <Tippy animation="fade" {...props} />;

Proxy components

<Tippy />'s purpose is to be a useful generic component for all types of popper elements. This includes tooltips, popovers, dropdowns, etc. This means you can create proxy components that wrap the base <Tippy /> component with a new name and their own default props, to distinguish their functionality. For example:

export function Tooltip(props) {
  return (
    <Tippy
      animation="fade"
      theme="translucent"
      arrow={true}
      delay={150}
      {...props}
    />
  );
}

export function Popover(props) {
  return (
    <Tippy
      interactive={true}
      interactiveBorder={10}
      animation="scale"
      theme="light-border"
      trigger="click"
      {...props}
    />
  );
}

// In another file
import {Tooltip, Popover} from './Tippy';

🌈 Multiple tippys on a single element

You can nest the components like so:

<Tippy content="Tooltip" placement="bottom">
  <Tippy content="Tooltip" placement="left">
    <Tippy content="Tooltip" placement="right">
      <Tippy content="Tooltip">
        <button />
      </Tippy>
    </Tippy>
  </Tippy>
</Tippy>

📚 Singleton

Wraps the createSingleton() method.

Depending on your component tree, you can use one of the following:

<TippySingleton />

If each of your reference elements are adjacent to one another, with no nesting in the tree.

import Tippy, {TippySingleton} from '@tippy.js/react';

function App() {
  return (
    <TippySingleton delay={500}>
      <Tippy content="a">
        <button />
      </Tippy>
      <Tippy content="b">
        <button />
      </Tippy>
    </TippySingleton>
  );
}

useSingleton() (v3.1)

If each of your reference elements are not adjacent to one another, or there is nesting in the tree.

import Tippy, {useSingleton} from '@tippy.js/react';

function App() {
  const singleton = useSingleton({delay: 500});

  return (
    <>
      <Tippy content="a" singleton={singleton}>
        <button />
      </Tippy>
      <button />
      <div>
        <Tippy content="b" singleton={singleton}>
          <button />
        </Tippy>
      </div>
    </>
  );
}

📦 Bundle size

  • popper.js ≈ 7 kB
  • tippy.js ≈ 5.5 kB (including CSS)
  • @tippy.js/react ≈ 1 kB

If you're using Popper.js for other parts of your app, the added cost becomes much smaller!

⭐️ Comparison with other tooltip/popover libraries

Why should you use this library, and how does it compare to other ones?

Read all about it here!

📝 License

MIT