Skip to content

Commit 183ae23

Browse files
committed
Add new <Tooltip> component
1 parent 44e9493 commit 183ae23

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

src/components/Tooltip.tsx

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import classNames from 'classnames';
2+
import React from 'react';
3+
import ReactPortal from './ReactPortal';
4+
import type { ThemeToken } from '../types';
5+
6+
export interface TooltipProps {
7+
arrow?: 'down' | 'up' | 'right' | 'left';
8+
children: React.ReactNode;
9+
className?: string;
10+
element: HTMLElement;
11+
theme?: ThemeToken;
12+
}
13+
14+
export default function Tooltip({
15+
arrow,
16+
children,
17+
className,
18+
element,
19+
theme = 'high-contrast',
20+
}: TooltipProps) {
21+
const rect = element.getBoundingClientRect();
22+
const position = getPosition(rect, arrow);
23+
return (
24+
<ReactPortal>
25+
<div
26+
aria-hidden
27+
className={classNames(
28+
'caption tooltip',
29+
{
30+
[`tooltip--${arrow}`]: arrow,
31+
},
32+
className,
33+
)}
34+
data-theme={theme}
35+
role="tooltip"
36+
style={{
37+
top: position.top,
38+
left: position.left,
39+
}}
40+
>
41+
{typeof children === 'string' && children.includes('\n')
42+
? children.split('\n').map((line, index, array) => (
43+
<>
44+
{line}
45+
{index != array.length - 1 && <br />}
46+
</>
47+
))
48+
: children}
49+
</div>
50+
</ReactPortal>
51+
);
52+
}
53+
54+
function getPosition(rect: DOMRect, arrow?: 'down' | 'up' | 'right' | 'left') {
55+
switch (arrow) {
56+
case 'left':
57+
return {
58+
top: rect.top + rect.height / 2,
59+
left: rect.right,
60+
};
61+
case 'right':
62+
return {
63+
top: rect.top + rect.height / 2,
64+
left: rect.left,
65+
};
66+
case 'up':
67+
return {
68+
top: rect.bottom,
69+
left: rect.left + rect.width / 2,
70+
};
71+
case 'down':
72+
default:
73+
return {
74+
top: rect.top,
75+
left: rect.left + rect.width / 2,
76+
};
77+
}
78+
}

src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ export { default as Stack, type StackProps } from './Stack'; // prettier-ignore
3737
export { default as Text, type TextProps } from './Text'; // prettier-ignore
3838
export { default as Thumbnail, type ThumbnailProps } from './Thumbnail'; // prettier-ignore
3939
export { default as Toggle, type ToggleProps } from './Toggle'; // prettier-ignore
40+
export { default as Tooltip, type TooltipProps } from './Tooltip'; // prettier-ignore

0 commit comments

Comments
 (0)