MIT License

项目介绍

atomiks/tippyjs-react 是一个托管在 GitHub 上的开源项目,主要使用 JavaScript 编写,采用 MIT License 许可证,目前获得 1.8k 个 Star、99 次 Fork。

仓库全名
atomiks/tippyjs-react
开源许可证
MIT License
Star 数
1.8k
Fork 数
99
未关闭 Issue
40

README 摘要

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…

完整内容见 GitHub 原始 README 或本页 。

常见问题

tippyjs-react 用什么语言开发?

主要使用 JavaScript 编写,采用 MIT License 许可证,目前有 1.8k 个 Star。

tippyjs-react 可以免费商用吗?

仓库采用 MIT License 许可证,可免费使用与修改,商业使用请遵守许可证条款(例如保留版权声明与许可声明)。

如何获取 tippyjs-react 的源码?

可以直接克隆仓库:git clone https://github.com/atomiks/tippyjs-react.git,默认分支为 master;安装与运行步骤见仓库 README。

tippyjs-react 最近还在维护吗?

仓库最近一次更新为 2024年5月28日,当前有 40 个未关闭 Issue;Star 数为 1.8k,可作为社区活跃度的参考。

简要分析

热度分
1999
价值分
1108
活跃状态
归档

语言占比

JavaScript

Release

README

Logo

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

# npm
npm i @tippyjs/react

# Yarn
yarn 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.

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

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

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

Default Tippy “just works” out of the box.

Headless Tippy

Render your own tippy element from scratch:

import React from 'react';
import Tippy from '@tippyjs/react/headless'; // different import path!

const HeadlessTippy = () => (
  <Tippy
    render={attrs => (
      <div className="box" tabIndex="-1" {...attrs}>
        My tippy box
      </div>
    )}
  >
    <button>My button</button>
  </Tippy>
);

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:

<Tippy
  render={attrs => (
    <Box {...attrs}>
      Hello
      <Arrow data-popper-arrow="" />
    </Box>
  )}
>
  <button>Reference</button>
</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:

function App() {
  const [arrow, setArrow] = useState(null);

  return (
    <Tippy
      render={attrs => (
        <Box {...attrs}>
          Content
          <Arrow ref={setArrow} />
        </Box>
      )}
      popperOptions={{
        modifiers: [
          {
            name: 'arrow',
            options: {
              element: arrow, // can be a CSS selector too
            },
          },
        ],
      }}
    >
      <button>Reference</button>
    </Tippy>
  );
}
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:

import React, {forwardRef} from 'react';

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

const ThisWillWork = forwardRef((props, ref) => {
  return <button ref={ref}>Reference</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.

Workaround for old libraries that don’t forward the ref is to use a <span> wrapper tag:

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

🧬 Props

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

Visit All Props to view the complete list.

<Tippy content="Tooltip" interactive={true} interactiveBorder={20} delay={100}>
  <button>Reference</button>
</Tippy>

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

className?: string

<Tippy content="Tooltip" className="hello world">
  <button>Reference</button>
</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

function App() {
  const [disabled, setDisabled] = useState(false);

  return (
    <Tippy content="Tooltip" disabled={disabled}>
      <button>Reference</button>
    </Tippy>
  );
}

visible?: boolean (controlled mode)

Use React’s state to fully control the tippy instead of relying on the native trigger and hideOnClick props:

function App() {
  const [visible, setVisible] = useState(true);
  const show = () => setVisible(true);
  const hide = () => setVisible(false);

  return (
    <Tippy content="Tooltip" visible={visible}
      <button ? hide : show}>Reference</button>
    </Tippy>
  );
}

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.

function App() {
  const ref = useRef();

  return (
    <>
      <button ref={ref} />
      <Tippy content="Tooltip" reference={ref} />
    </>
  );
}

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.

import Tippy from '@tippyjs/react';
// ⚠️ import from 'tippy.js/headless' if using Headless Tippy
import {followCursor} from 'tippy.js';

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

Read more about plugins here.

🌈 Multiple tippies 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>Reference</button>
      </Tippy>
    </Tippy>
  </Tippy>
</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.

View on CodeSandbox

import Tippy, {useSingleton} from '@tippyjs/react';

function App() {
  const [source, target] = useSingleton();

  return (
    <>
      {/* This is the tippy that gets used as the singleton */}
      <Tippy singleton={source} delay={500} />

      {/* These become "virtual" */}
      <Tippy content="Hello" singleton={target}>
        <button>Reference</button>
      </Tippy>
      <Tippy content="Bye" singleton={target}>
        <button>Reference</button>
      </Tippy>
    </>
  );
}

useSingleton() takes an optional props argument:

const [source, target] = useSingleton({
  disabled: true,
  overrides: ['placement'],
});

Headless singleton

The render prop takes the singleton content as a second parameter:

import Tippy, {useSingleton} from '@tippyjs/react/headless';

function App() {
  const [source, target] = useSingleton();

  return (
    <>
      <Tippy
        singleton={source}
        render={(attrs, content) => (
          <div className="box" tabIndex="-1" {...attrs}>
            {content}
          </div>
        )}
        delay={500}
      />

      <Tippy content="Hello" singleton={target}>
        <button>Reference</button>
      </Tippy>
      <Tippy content="Bye" singleton={target}>
        <button>Reference</button>
      </Tippy>
    </>
  );
}

📝 License

MIT

评论

暂无评论