Only calculate position when tooltip is shown (#755)
This commit is contained in:
parent
0f7f55ec0a
commit
dcc3c61f52
|
@ -6,9 +6,14 @@ import {
|
|||
Placement,
|
||||
shift,
|
||||
useFloating,
|
||||
} from '@floating-ui/react-dom'
|
||||
useFocus,
|
||||
useHover,
|
||||
useInteractions,
|
||||
useRole,
|
||||
} from '@floating-ui/react-dom-interactions'
|
||||
import { Transition } from '@headlessui/react'
|
||||
import clsx from 'clsx'
|
||||
import { ReactNode, useRef } from 'react'
|
||||
import { ReactNode, useRef, useState } from 'react'
|
||||
|
||||
// See https://floating-ui.com/docs/react-dom
|
||||
|
||||
|
@ -23,8 +28,12 @@ export function Tooltip(props: {
|
|||
|
||||
const arrowRef = useRef(null)
|
||||
|
||||
const { x, y, refs, reference, floating, strategy, middlewareData } =
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const { x, y, reference, floating, strategy, middlewareData, context } =
|
||||
useFloating({
|
||||
open,
|
||||
onOpenChange: setOpen,
|
||||
whileElementsMounted: autoUpdate,
|
||||
placement,
|
||||
middleware: [
|
||||
|
@ -37,6 +46,11 @@ export function Tooltip(props: {
|
|||
|
||||
const { x: arrowX, y: arrowY } = middlewareData.arrow ?? {}
|
||||
|
||||
const { getReferenceProps, getFloatingProps } = useInteractions([
|
||||
useHover(context, { mouseOnly: noTap }),
|
||||
useFocus(context),
|
||||
useRole(context, { role: 'tooltip' }),
|
||||
])
|
||||
// which side of tooltip arrow is on. like: if tooltip is top-left, arrow is on bottom of tooltip
|
||||
const arrowSide = {
|
||||
top: 'bottom',
|
||||
|
@ -48,18 +62,28 @@ export function Tooltip(props: {
|
|||
return text ? (
|
||||
<div className="contents">
|
||||
<div
|
||||
className={clsx('peer inline-block', className)}
|
||||
className={clsx('inline-block', className)}
|
||||
ref={reference}
|
||||
tabIndex={noTap ? undefined : 0}
|
||||
onTouchStart={() => (refs.reference.current as HTMLElement).focus()}
|
||||
{...getReferenceProps()}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
<div
|
||||
{/* conditionally render tooltip and fade in/out */}
|
||||
<Transition
|
||||
show={open}
|
||||
enter="transition ease-out duration-200"
|
||||
enterFrom="opacity-0 "
|
||||
enterTo="opacity-100"
|
||||
leave="transition ease-in duration-150"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
// div attributes
|
||||
role="tooltip"
|
||||
ref={floating}
|
||||
style={{ position: strategy, top: y ?? 0, left: x ?? 0 }}
|
||||
className="-z-10 max-w-xs rounded bg-slate-700 px-2 py-1 text-center text-sm text-white opacity-0 transition-opacity peer-hover:z-10 peer-hover:opacity-100 peer-focus:z-10 peer-focus:opacity-100"
|
||||
className="z-10 max-w-xs rounded bg-slate-700 px-2 py-1 text-center text-sm text-white"
|
||||
{...getFloatingProps()}
|
||||
>
|
||||
{text}
|
||||
<div
|
||||
|
@ -73,7 +97,7 @@ export function Tooltip(props: {
|
|||
[arrowSide]: '-4px',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
) : (
|
||||
<>{children}</>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@amplitude/analytics-browser": "0.4.1",
|
||||
"@floating-ui/react-dom": "1.0.0",
|
||||
"@floating-ui/react-dom-interactions": "0.9.2",
|
||||
"@headlessui/react": "1.6.1",
|
||||
"@heroicons/react": "1.0.5",
|
||||
"@nivo/core": "0.74.0",
|
||||
|
|
19
yarn.lock
19
yarn.lock
|
@ -2190,7 +2190,15 @@
|
|||
dependencies:
|
||||
"@floating-ui/core" "^1.0.1"
|
||||
|
||||
"@floating-ui/react-dom@1.0.0":
|
||||
"@floating-ui/react-dom-interactions@0.9.2":
|
||||
version "0.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom-interactions/-/react-dom-interactions-0.9.2.tgz#9a364cc44ecbc242b5218dff0e0d071de115e13a"
|
||||
integrity sha512-1I0urs4jlGuo4FRukvjtMmdUwxqvgwtTlESEPVwEvFGHXVh1PKkKaPZJ0Dcp9B8DQt4ewQEbwJxsoker2pDYTQ==
|
||||
dependencies:
|
||||
"@floating-ui/react-dom" "^1.0.0"
|
||||
aria-hidden "^1.1.3"
|
||||
|
||||
"@floating-ui/react-dom@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-1.0.0.tgz#e0975966694433f1f0abffeee5d8e6bb69b7d16e"
|
||||
integrity sha512-uiOalFKPG937UCLm42RxjESTWUVpbbatvlphQAU6bsv+ence6IoVG8JOUZcy8eW81NkU+Idiwvx10WFLmR4MIg==
|
||||
|
@ -3935,6 +3943,13 @@ argparse@^2.0.1:
|
|||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
aria-hidden@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.1.3.tgz#bb48de18dc84787a3c6eee113709c473c64ec254"
|
||||
integrity sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA==
|
||||
dependencies:
|
||||
tslib "^1.0.0"
|
||||
|
||||
aria-query@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b"
|
||||
|
@ -11314,7 +11329,7 @@ tsconfig-paths@^3.14.1:
|
|||
minimist "^1.2.6"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
||||
tslib@^1.0.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
|
Loading…
Reference in New Issue
Block a user