Only calculate position when tooltip is shown (#755)

This commit is contained in:
Sinclair Chen 2022-08-12 20:35:08 -07:00 committed by GitHub
parent 0f7f55ec0a
commit dcc3c61f52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 11 deletions

View File

@ -6,9 +6,14 @@ import {
Placement, Placement,
shift, shift,
useFloating, 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 clsx from 'clsx'
import { ReactNode, useRef } from 'react' import { ReactNode, useRef, useState } from 'react'
// See https://floating-ui.com/docs/react-dom // See https://floating-ui.com/docs/react-dom
@ -23,8 +28,12 @@ export function Tooltip(props: {
const arrowRef = useRef(null) 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({ useFloating({
open,
onOpenChange: setOpen,
whileElementsMounted: autoUpdate, whileElementsMounted: autoUpdate,
placement, placement,
middleware: [ middleware: [
@ -37,6 +46,11 @@ export function Tooltip(props: {
const { x: arrowX, y: arrowY } = middlewareData.arrow ?? {} 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 // which side of tooltip arrow is on. like: if tooltip is top-left, arrow is on bottom of tooltip
const arrowSide = { const arrowSide = {
top: 'bottom', top: 'bottom',
@ -48,18 +62,28 @@ export function Tooltip(props: {
return text ? ( return text ? (
<div className="contents"> <div className="contents">
<div <div
className={clsx('peer inline-block', className)} className={clsx('inline-block', className)}
ref={reference} ref={reference}
tabIndex={noTap ? undefined : 0} tabIndex={noTap ? undefined : 0}
onTouchStart={() => (refs.reference.current as HTMLElement).focus()} {...getReferenceProps()}
> >
{children} {children}
</div> </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" role="tooltip"
ref={floating} ref={floating}
style={{ position: strategy, top: y ?? 0, left: x ?? 0 }} 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} {text}
<div <div
@ -73,7 +97,7 @@ export function Tooltip(props: {
[arrowSide]: '-4px', [arrowSide]: '-4px',
}} }}
/> />
</div> </Transition>
</div> </div>
) : ( ) : (
<>{children}</> <>{children}</>

View File

@ -21,7 +21,7 @@
}, },
"dependencies": { "dependencies": {
"@amplitude/analytics-browser": "0.4.1", "@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", "@headlessui/react": "1.6.1",
"@heroicons/react": "1.0.5", "@heroicons/react": "1.0.5",
"@nivo/core": "0.74.0", "@nivo/core": "0.74.0",

View File

@ -2190,7 +2190,15 @@
dependencies: dependencies:
"@floating-ui/core" "^1.0.1" "@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" version "1.0.0"
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-1.0.0.tgz#e0975966694433f1f0abffeee5d8e6bb69b7d16e" resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-1.0.0.tgz#e0975966694433f1f0abffeee5d8e6bb69b7d16e"
integrity sha512-uiOalFKPG937UCLm42RxjESTWUVpbbatvlphQAU6bsv+ence6IoVG8JOUZcy8eW81NkU+Idiwvx10WFLmR4MIg== 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" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 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: aria-query@^4.2.2:
version "4.2.2" version "4.2.2"
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" 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" minimist "^1.2.6"
strip-bom "^3.0.0" 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" version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==