Skip to content

Commit 306d426

Browse files
committed
Update <Tooltip> to not require an element
1 parent 86dadff commit 306d426

1 file changed

Lines changed: 49 additions & 30 deletions

File tree

src/components/Tooltip.tsx

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
'use client';
2+
13
import classNames from 'classnames';
24
import React from 'react';
35
import ReactPortal from './ReactPortal';
@@ -7,7 +9,7 @@ export interface TooltipProps {
79
arrow?: 'down' | 'up' | 'right' | 'left';
810
children: React.ReactNode;
911
className?: string;
10-
element: HTMLElement;
12+
element?: HTMLElement | null;
1113
theme?: ThemeToken;
1214
}
1315

@@ -18,36 +20,53 @@ export default function Tooltip({
1820
element,
1921
theme = 'high-contrast',
2022
}: TooltipProps) {
21-
const rect = element.getBoundingClientRect();
22-
const position = getPosition(rect, arrow);
23+
const props: React.ComponentPropsWithoutRef<'div'> & {
24+
'data-theme': string;
25+
} = {
26+
'aria-hidden': true,
27+
className: classNames(
28+
'caption tooltip',
29+
{
30+
[`tooltip--${arrow}`]: arrow,
31+
},
32+
className,
33+
),
34+
'data-theme': theme,
35+
role: 'tooltip',
36+
};
37+
38+
const content =
39+
typeof children === 'string' && children.includes('\n')
40+
? children.split('\n').map((line, index, array) => (
41+
<>
42+
{line}
43+
{index != array.length - 1 && <br />}
44+
</>
45+
))
46+
: children;
47+
48+
if (element) {
49+
const rect = element.getBoundingClientRect();
50+
const position = getPosition(rect, arrow);
51+
return (
52+
<ReactPortal>
53+
<div
54+
{...props}
55+
style={{
56+
top: position.top,
57+
left: position.left,
58+
}}
59+
>
60+
{content}
61+
</div>
62+
</ReactPortal>
63+
);
64+
}
65+
2366
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>
67+
<div {...props} style={{ transform: 'none' }}>
68+
{content}
69+
</div>
5170
);
5271
}
5372

0 commit comments

Comments
 (0)