Hoverable component: we've come full circle

This commit is contained in:
Alex Gleason
2022-04-01 14:55:42 -05:00
parent 1742236074
commit 6c8bc3f329
3 changed files with 54 additions and 36 deletions

View File

@@ -1,5 +1,6 @@
import Portal from '@reach/portal';
import classNames from 'classnames';
import React, { useState, useRef } from 'react';
import { usePopper } from 'react-popper';
interface IHoverable {
component: React.Component,
@@ -12,7 +13,9 @@ const Hoverable: React.FC<IHoverable> = ({
}): JSX.Element => {
const [portalActive, setPortalActive] = useState(false);
const ref = useRef<HTMLDivElement>(null);
const popperRef = useRef<HTMLDivElement>(null);
const handleMouseEnter = () => {
setPortalActive(true);
@@ -22,17 +25,18 @@ const Hoverable: React.FC<IHoverable> = ({
setPortalActive(false);
};
const setPortalPosition = (): React.CSSProperties => {
if (!ref.current) return {};
const { top, height, left, width } = ref.current.getBoundingClientRect();
return {
top: top + height,
left,
width,
};
};
const { styles, attributes } = usePopper(ref.current, popperRef.current, {
placement: 'top-start',
strategy: 'fixed',
modifiers: [
{
name: 'offset',
options: {
offset: [-10, 0],
},
},
],
});
return (
<div
@@ -41,7 +45,17 @@ const Hoverable: React.FC<IHoverable> = ({
ref={ref}
>
{children}
{portalActive && <Portal><div className='fixed' style={setPortalPosition()}>{component}</div></Portal>}
<div
className={classNames('fixed z-50 transition-opacity duration-100', {
'opacity-0 pointer-events-none': !portalActive,
})}
ref={popperRef}
style={styles.popper}
{...attributes.popper}
>
{component}
</div>
</div>
);
};