Center tooltips and add arrow
This commit is contained in:
parent
3f74455484
commit
b2f2bcb833
|
@ -6,3 +6,7 @@
|
|||
@apply pointer-events-none absolute px-2.5 py-1.5 rounded shadow whitespace-nowrap text-xs font-medium bg-gray-800 text-white;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
[data-reach-tooltip-arrow] {
|
||||
@apply absolute z-50 w-0 h-0 border-l-8 border-solid border-l-transparent border-r-8 border-r-transparent border-b-8 border-b-gray-800;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { default as ReachTooltip } from '@reach/tooltip';
|
||||
import Portal from '@reach/portal';
|
||||
import { TooltipPopup, useTooltip } from '@reach/tooltip';
|
||||
import React from 'react';
|
||||
|
||||
import './tooltip.css';
|
||||
|
@ -8,15 +9,55 @@ interface ITooltip {
|
|||
text: string,
|
||||
}
|
||||
|
||||
const centered = (triggerRect: any, tooltipRect: any) => {
|
||||
const triggerCenter = triggerRect.left + triggerRect.width / 2;
|
||||
const left = triggerCenter - tooltipRect.width / 2;
|
||||
const maxLeft = window.innerWidth - tooltipRect.width - 2;
|
||||
return {
|
||||
left: Math.min(Math.max(2, left), maxLeft) + window.scrollX,
|
||||
top: triggerRect.bottom + 8 + window.scrollY,
|
||||
};
|
||||
};
|
||||
|
||||
/** Hoverable tooltip element. */
|
||||
const Tooltip: React.FC<ITooltip> = ({
|
||||
children,
|
||||
text,
|
||||
}) => {
|
||||
// get the props from useTooltip
|
||||
const [trigger, tooltip] = useTooltip();
|
||||
|
||||
// destructure off what we need to position the triangle
|
||||
const { isVisible, triggerRect } = tooltip;
|
||||
|
||||
return (
|
||||
<ReachTooltip label={text}>
|
||||
{children}
|
||||
</ReachTooltip>
|
||||
<React.Fragment>
|
||||
{React.cloneElement(children as any, trigger)}
|
||||
|
||||
{isVisible && (
|
||||
// The Triangle. We position it relative to the trigger, not the popup
|
||||
// so that collisions don't have a triangle pointing off to nowhere.
|
||||
// Using a Portal may seem a little extreme, but we can keep the
|
||||
// positioning logic simpler here instead of needing to consider
|
||||
// the popup's position relative to the trigger and collisions
|
||||
<Portal>
|
||||
<div
|
||||
data-reach-tooltip-arrow='true'
|
||||
style={{
|
||||
left:
|
||||
triggerRect && triggerRect.left - 10 + triggerRect.width / 2 as any,
|
||||
top: triggerRect && triggerRect.bottom + window.scrollY as any,
|
||||
}}
|
||||
/>
|
||||
</Portal>
|
||||
)}
|
||||
<TooltipPopup
|
||||
{...tooltip}
|
||||
label={text}
|
||||
aria-label={text}
|
||||
position={centered}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue