{"id":13517466,"url":"https://github.com/atomiks/tippyjs-react","last_synced_at":"2025-04-09T02:10:49.016Z","repository":{"id":39829849,"uuid":"145971204","full_name":"atomiks/tippyjs-react","owner":"atomiks","description":"React component for Tippy.js (official)","archived":false,"fork":false,"pushed_at":"2024-05-28T10:36:58.000Z","size":1852,"stargazers_count":1797,"open_issues_count":58,"forks_count":92,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-10-29T15:10:50.155Z","etag":null,"topics":["combobox","dropdown","menu","popover","popper","react","reactjs","tooltip"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atomiks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["atomiks"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2018-08-24T09:23:47.000Z","updated_at":"2024-10-25T13:11:29.000Z","dependencies_parsed_at":"2024-06-02T04:44:50.248Z","dependency_job_id":"bf8d387e-a89b-4526-b5b4-37378dcdf31a","html_url":"https://github.com/atomiks/tippyjs-react","commit_stats":{"total_commits":284,"total_committers":16,"mean_commits":17.75,"dds":0.06690140845070425,"last_synced_commit":"2699f0450c28a92cd5bbd402573ce9ed64252899"},"previous_names":["atomiks/tippy.js-react"],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomiks%2Ftippyjs-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomiks%2Ftippyjs-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomiks%2Ftippyjs-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atomiks%2Ftippyjs-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atomiks","download_url":"https://codeload.github.com/atomiks/tippyjs-react/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247962460,"owners_count":21024862,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["combobox","dropdown","menu","popover","popper","react","reactjs","tooltip"],"created_at":"2024-08-01T05:01:34.048Z","updated_at":"2025-04-09T02:10:48.996Z","avatar_url":"https://github.com/atomiks.png","language":"JavaScript","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/atomiks/tippy.js-react/raw/master/logo.png\" alt=\"Logo\" height=\"105\"\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eTippy.js for React\u003c/h1\u003e\n\u003c/div\u003e\n\n⚠️⚠️⚠️\n\n**If you're new here, we recommend using [Floating UI's React DOM Interactions package](https://floating-ui.com/docs/react-dom-interactions) 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.\n\nIf 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!\n\n⚠️⚠️⚠️\n\n---\n\n[Tippy.js](https://github.com/atomiks/tippyjs/) is the complete tooltip,\npopover, dropdown, and menu solution for the web, powered by Popper.\n\nTippy is an abstraction over Popper that provides common logic involved in all\ntypes of elements that pop out on top of the UI, positioned next to a target or\nreference element. This is a React wrapper for the core library, providing full\nintegration including headless rendering abilities.\n\n## 🚀 Installation\n\n```bash\n# npm\nnpm i @tippyjs/react\n\n# Yarn\nyarn add @tippyjs/react\n```\n\nCDN: https://unpkg.com/@tippyjs/react\n\n## 🖲 Usage\n\nThere are two ways to use this component:\n\n- **Default**: With the built-in DOM rendering and optionally the default CSS.\n  This is complete \"out of the box\" behavior and requires no setup. If you want\n  something that just works, this is for you.\n- **Headless**: With React's DOM rendering for improved usage with CSS-in-JS and\n  spring libraries. If you want greater control over your poppers to integrate\n  fully with design systems, this is for you.\n\nBoth may be used in conjunction.\n\n### Default Tippy\n\nImport the `Tippy` component and (optionally) the core CSS. Wrap the `\u003cTippy /\u003e`\ncomponent around the element, supplying the tooltip's content as the `content`\nprop. It can take a string or a tree of React elements.\n\n```jsx\nimport React from 'react';\nimport Tippy from '@tippyjs/react';\nimport 'tippy.js/dist/tippy.css'; // optional\n\nconst StringContent = () =\u003e (\n  \u003cTippy content=\"Hello\"\u003e\n    \u003cbutton\u003eMy button\u003c/button\u003e\n  \u003c/Tippy\u003e\n);\n\nconst JSXContent = () =\u003e (\n  \u003cTippy content={\u003cspan\u003eTooltip\u003c/span\u003e}\u003e\n    \u003cbutton\u003eMy button\u003c/button\u003e\n  \u003c/Tippy\u003e\n);\n```\n\nDefault Tippy \"just works\" out of the box.\n\n### Headless Tippy\n\nRender your own tippy element from scratch:\n\n```jsx\nimport React from 'react';\nimport Tippy from '@tippyjs/react/headless'; // different import path!\n\nconst HeadlessTippy = () =\u003e (\n  \u003cTippy\n    render={attrs =\u003e (\n      \u003cdiv className=\"box\" tabIndex=\"-1\" {...attrs}\u003e\n        My tippy box\n      \u003c/div\u003e\n    )}\n  \u003e\n    \u003cbutton\u003eMy button\u003c/button\u003e\n  \u003c/Tippy\u003e\n);\n```\n\n`attrs` is an object containing `data-placement`, `data-reference-hidden`, and\n`data-escaped` attributes. This allows you to conditionally style your tippy.\n\n#### Headless animation\n\n- [`framer-motion`](https://codesandbox.io/s/festive-fire-hcr47)\n- [`react-spring`](https://codesandbox.io/s/vigilant-northcutt-7w3yr)\n\n#### Headless arrow\n\nTo make Popper position your custom arrow, set a `data-popper-arrow` attribute\non it:\n\n```jsx\n\u003cTippy\n  render={attrs =\u003e (\n    \u003cBox {...attrs}\u003e\n      Hello\n      \u003cArrow data-popper-arrow=\"\" /\u003e\n    \u003c/Box\u003e\n  )}\n\u003e\n  \u003cbutton\u003eReference\u003c/button\u003e\n\u003c/Tippy\u003e\n```\n\nFor details on styling the arrow from scratch,\n[take a look at the Popper tutorial](https://popper.js.org/docs/v2/tutorial/#arrow).\n\n**Note: your arrow must be an `HTMLElement` (not an `SVGElement`). To use an SVG\narrow, wrap it in a `\u003cdiv\u003e` tag with the `data-popper-arrow` attribute.**\n\nYou may also pass a ref to the element directly without the attribute using a\ncallback ref:\n\n```jsx\nfunction App() {\n  const [arrow, setArrow] = useState(null);\n\n  return (\n    \u003cTippy\n      render={attrs =\u003e (\n        \u003cBox {...attrs}\u003e\n          Content\n          \u003cArrow ref={setArrow} /\u003e\n        \u003c/Box\u003e\n      )}\n      popperOptions={{\n        modifiers: [\n          {\n            name: 'arrow',\n            options: {\n              element: arrow, // can be a CSS selector too\n            },\n          },\n        ],\n      }}\n    \u003e\n      \u003cbutton\u003eReference\u003c/button\u003e\n    \u003c/Tippy\u003e\n  );\n}\n```\n\n#### Headless root element\n\nWhen rendering an element with the `render` prop, you're rendering the inner\nelement that the root popper (positioned) node wraps.\n\nFor advanced cases you can access the root element via `instance.popper`.\n\n[Here's `moveTransition` with Framer Motion](https://codesandbox.io/s/tippyjs-react-framer-motion-j94mj).\n\n### Component children\n\nIf you want to use a component element as a child of the component, ensure you\nforward the ref to the DOM node:\n\n```jsx\nimport React, {forwardRef} from 'react';\n\nfunction ThisWontWork() {\n  return \u003cbutton\u003eReference\u003c/button\u003e;\n}\n\nconst ThisWillWork = forwardRef((props, ref) =\u003e {\n  return \u003cbutton ref={ref}\u003eReference\u003c/button\u003e;\n});\n\nfunction App() {\n  return (\n    \u003cTippy content=\"Tooltip\"\u003e\n      \u003cThisWillWork /\u003e\n    \u003c/Tippy\u003e\n  );\n}\n```\n\n`styled-components` v4+ does this for you automatically, so it should be\nseamless when using the `styled` constructor.\n\nWorkaround for old libraries that don't forward the ref is to use a `\u003cspan\u003e`\nwrapper tag:\n\n```jsx\n\u003cTippy content=\"Tooltip\"\u003e\n  \u003cspan tabIndex=\"0\"\u003e\n    \u003cLegacyComponent\u003eReference\u003c/LegacyComponent\u003e\n  \u003c/span\u003e\n\u003c/Tippy\u003e\n```\n\n## 🧬 Props\n\nAll of the native Tippy.js props can be passed to the component.\n\nVisit [All Props](https://atomiks.github.io/tippyjs/v6/all-props/) to view the\ncomplete list.\n\n```jsx\n\u003cTippy content=\"Tooltip\" interactive={true} interactiveBorder={20} delay={100}\u003e\n  \u003cbutton\u003eReference\u003c/button\u003e\n\u003c/Tippy\u003e\n```\n\nIn addition, there are 3 more props added specifically for the React component.\n\n### `className?: string`\n\n```jsx\n\u003cTippy content=\"Tooltip\" className=\"hello world\"\u003e\n  \u003cbutton\u003eReference\u003c/button\u003e\n\u003c/Tippy\u003e\n```\n\nThis allows you to use `styled(Tippy)` or the `css` prop in `styled-components`\nor `emotion`.\n\n\u003e Note: Does not apply if using Headless Tippy.\n\n### `disabled?: boolean`\n\n```jsx\nfunction App() {\n  const [disabled, setDisabled] = useState(false);\n\n  return (\n    \u003cTippy content=\"Tooltip\" disabled={disabled}\u003e\n      \u003cbutton\u003eReference\u003c/button\u003e\n    \u003c/Tippy\u003e\n  );\n}\n```\n\n### `visible?: boolean` (controlled mode)\n\nUse React's state to fully control the tippy instead of relying on the native\n`trigger` and `hideOnClick` props:\n\n```jsx\nfunction App() {\n  const [visible, setVisible] = useState(true);\n  const show = () =\u003e setVisible(true);\n  const hide = () =\u003e setVisible(false);\n\n  return (\n    \u003cTippy content=\"Tooltip\" visible={visible} onClickOutside={hide}\u003e\n      \u003cbutton onClick={visible ? hide : show}\u003eReference\u003c/button\u003e\n    \u003c/Tippy\u003e\n  );\n}\n```\n\n### `reference?: React.RefObject | Element`\n\n\u003e Available from `v4.1.0`\n\nIf you can't place your reference element as a child inside `\u003cTippy /\u003e`, you can\nuse this prop instead. It accepts a React `RefObject` (`.current` property) or a\nplain `Element`.\n\n```jsx\nfunction App() {\n  const ref = useRef();\n\n  return (\n    \u003c\u003e\n      \u003cbutton ref={ref} /\u003e\n      \u003cTippy content=\"Tooltip\" reference={ref} /\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n### Plugins\n\nTippy.js splits certain props into separate pieces of code called plugins to\nenable tree-shaking, so that components or routes that don't need the prop's\nfunctionality are not burdened with the bundle size cost of it. In addition,\nthey enable a neat way to extend the functionality of tippy instances.\n\n```jsx\nimport Tippy from '@tippyjs/react';\n// ⚠️ import from 'tippy.js/headless' if using Headless Tippy\nimport {followCursor} from 'tippy.js';\n\nfunction App() {\n  return (\n    \u003cTippy content=\"Tooltip\" followCursor={true} plugins={[followCursor]}\u003e\n      \u003cbutton\u003eReference\u003c/button\u003e\n    \u003c/Tippy\u003e\n  );\n}\n```\n\n[Read more about plugins here](https://atomiks.github.io/tippyjs/v6/plugins/).\n\n## 🌈 Multiple tippies on a single element\n\nYou can nest the components like so:\n\n```jsx\n\u003cTippy content=\"Tooltip\" placement=\"bottom\"\u003e\n  \u003cTippy content=\"Tooltip\" placement=\"left\"\u003e\n    \u003cTippy content=\"Tooltip\" placement=\"right\"\u003e\n      \u003cTippy content=\"Tooltip\"\u003e\n        \u003cbutton\u003eReference\u003c/button\u003e\n      \u003c/Tippy\u003e\n    \u003c/Tippy\u003e\n  \u003c/Tippy\u003e\n\u003c/Tippy\u003e\n```\n\n## Lazy mounting\n\nBy default, Tippy mounts your `content` or `render` elements into a container\nelement once created, even if the tippy isn't mounted on the DOM. In most cases,\nthis is fine, but in performance-sensitive scenarios or cases where mounting the\ncomponent should fire effects only when the tippy mounted, you can lazify the\ncomponent.\n\n[View the following gists to optimize your `\u003cTippy /\u003e` if needed.](https://gist.github.com/atomiks/520f4b0c7b537202a23a3059d4eec908)\n\n## 📚 useSingleton\n\nA Hook for the\n[`createSingleton()`](https://atomiks.github.io/tippyjs/v6/addons/#singleton)\naddon to re-use a single tippy element for many different reference element\ntargets.\n\n[View on CodeSandbox](https://codesandbox.io/s/unruffled-pasteur-4yy99?file=/src/App.js)\n\n```jsx\nimport Tippy, {useSingleton} from '@tippyjs/react';\n\nfunction App() {\n  const [source, target] = useSingleton();\n\n  return (\n    \u003c\u003e\n      {/* This is the tippy that gets used as the singleton */}\n      \u003cTippy singleton={source} delay={500} /\u003e\n\n      {/* These become \"virtual\" */}\n      \u003cTippy content=\"Hello\" singleton={target}\u003e\n        \u003cbutton\u003eReference\u003c/button\u003e\n      \u003c/Tippy\u003e\n      \u003cTippy content=\"Bye\" singleton={target}\u003e\n        \u003cbutton\u003eReference\u003c/button\u003e\n      \u003c/Tippy\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n`useSingleton()` takes an optional props argument:\n\n```js\nconst [source, target] = useSingleton({\n  disabled: true,\n  overrides: ['placement'],\n});\n```\n\n### Headless singleton\n\nThe `render` prop takes the singleton content as a second parameter:\n\n```jsx\nimport Tippy, {useSingleton} from '@tippyjs/react/headless';\n\nfunction App() {\n  const [source, target] = useSingleton();\n\n  return (\n    \u003c\u003e\n      \u003cTippy\n        singleton={source}\n        render={(attrs, content) =\u003e (\n          \u003cdiv className=\"box\" tabIndex=\"-1\" {...attrs}\u003e\n            {content}\n          \u003c/div\u003e\n        )}\n        delay={500}\n      /\u003e\n\n      \u003cTippy content=\"Hello\" singleton={target}\u003e\n        \u003cbutton\u003eReference\u003c/button\u003e\n      \u003c/Tippy\u003e\n      \u003cTippy content=\"Bye\" singleton={target}\u003e\n        \u003cbutton\u003eReference\u003c/button\u003e\n      \u003c/Tippy\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n## 📝 License\n\nMIT\n","funding_links":["https://github.com/sponsors/atomiks"],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatomiks%2Ftippyjs-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatomiks%2Ftippyjs-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatomiks%2Ftippyjs-react/lists"}