pleroma/app/soapbox/components/ui/tooltip/tooltip.tsx

88 lines
2 KiB
TypeScript
Raw Normal View History

2023-03-23 12:19:18 -07:00
import {
arrow,
FloatingArrow,
FloatingPortal,
offset,
useFloating,
useHover,
useInteractions,
useTransitionStyles,
} from '@floating-ui/react';
import React, { useRef, useState } from 'react';
2022-03-21 11:09:01 -07:00
interface ITooltip {
2023-03-23 12:19:18 -07:00
/** Element to display the tooltip around. */
children: React.ReactElement<any, string | React.JSXElementConstructor<any>>
/** Text to display in the tooltip. */
text: string
2022-03-21 11:09:01 -07:00
}
2023-03-23 12:19:18 -07:00
/**
* Tooltip
*/
const Tooltip: React.FC<ITooltip> = (props) => {
const { children, text } = props;
2022-07-06 11:19:51 -07:00
2023-03-23 12:19:18 -07:00
const [isOpen, setIsOpen] = useState<boolean>(false);
2022-07-06 11:19:51 -07:00
2023-03-23 12:19:18 -07:00
const arrowRef = useRef<SVGSVGElement>(null);
const { x, y, strategy, refs, context } = useFloating({
open: isOpen,
onOpenChange: setIsOpen,
placement: 'top',
middleware: [
offset(6),
arrow({
element: arrowRef,
}),
],
});
const hover = useHover(context);
const { isMounted, styles } = useTransitionStyles(context, {
initial: {
opacity: 0,
transform: 'scale(0.8)',
},
duration: {
open: 200,
close: 200,
},
});
const { getReferenceProps, getFloatingProps } = useInteractions([
hover,
]);
2022-07-06 11:19:51 -07:00
2022-03-21 11:09:01 -07:00
return (
2023-03-23 12:19:18 -07:00
<>
{React.cloneElement(children, {
ref: refs.setReference,
...getReferenceProps(),
})}
2022-07-06 11:19:51 -07:00
2023-03-23 12:19:18 -07:00
{(isMounted) && (
<FloatingPortal>
2022-07-06 11:19:51 -07:00
<div
2023-03-23 12:19:18 -07:00
ref={refs.setFloating}
2022-07-06 11:19:51 -07:00
style={{
2023-03-23 12:19:18 -07:00
position: strategy,
top: y ?? 0,
left: x ?? 0,
...styles,
2022-07-06 11:19:51 -07:00
}}
2023-03-23 12:19:18 -07:00
className='pointer-events-none z-[100] whitespace-nowrap rounded bg-gray-800 px-2.5 py-1.5 text-xs font-medium text-gray-100 shadow dark:bg-gray-100 dark:text-gray-900'
{...getFloatingProps()}
>
{text}
<FloatingArrow ref={arrowRef} context={context} className='fill-gray-800 dark:fill-gray-100' />
</div>
</FloatingPortal>
2022-07-06 11:19:51 -07:00
)}
2023-03-23 12:19:18 -07:00
</>
2022-03-21 11:09:01 -07:00
);
};
2023-03-23 12:19:18 -07:00
export default Tooltip;