@@ -0,0 +1,53 @@
1+import React, { useState, useCallback } from 'react';
2+import { useMemo } from 'react';
3+
4+export enum TooltipPosition {
5+ Top,
6+ TopRight,
7+ // Add more as necessary here and in #positionStyle
8+}
9+
10+type WithTooltipArgs = {
11+ content: string;
12+ children: React.ReactNode;
13+ className?: string | undefined;
14+ position?: TooltipPosition;
15+};
16+
17+export default function WithTooltip({
18+ content,
19+ children,
20+ className,
21+ position = TooltipPosition.Top,
22+}: WithTooltipArgs) {
23+ const [isHovered, setHovered] = useState(false);
24+ const onMouseEnter = useCallback(() => setHovered(true), []);
25+ const onMouseLeave = useCallback(() => setHovered(false), []);
26+
27+ const positionStyle = useMemo(() => {
28+ switch (position) {
29+ case TooltipPosition.Top:
30+ return { bottom: '100%' };
31+ case TooltipPosition.TopRight:
32+ return { bottom: '90%', left: '90%' };
33+ default:
34+ return { bottom: '100%' };
35+ }
36+ }, [position]);
37+
38+ return (
39+ <div
40+ className={className || 'rel nowrap inline-block'}
41+ onMouseEnter={onMouseEnter}
42+ onMouseLeave={onMouseLeave}>
43+ {children}
44+ {isHovered && (
45+ <div
46+ className="abs mb1 bg-black white ph4 pv2 r4"
47+ style={positionStyle}>
48+ {content}
49+ </div>
50+ )}
51+ </div>
52+ );
53+}