-
-
Notifications
You must be signed in to change notification settings - Fork 503
Expand file tree
/
Copy pathTooltip.jsx
More file actions
88 lines (69 loc) · 1.77 KB
/
Tooltip.jsx
File metadata and controls
88 lines (69 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { Component } from "preact";
import cls from "classnames";
import * as s from "./Tooltip.css";
export default class Tooltip extends Component {
static marginX = 10;
static marginY = 30;
mouseCoords = {
x: 0,
y: 0,
};
state = {
left: 0,
top: 0,
};
componentDidMount() {
document.addEventListener("mousemove", this.handleMouseMove, true);
}
shouldComponentUpdate(nextProps) {
return this.props.visible || nextProps.visible;
}
componentWillUnmount() {
document.removeEventListener("mousemove", this.handleMouseMove, true);
}
render() {
const { children, visible } = this.props;
const className = cls({
[s.container]: true,
[s.hidden]: !visible,
});
return (
<div ref={this.saveNode} className={className} style={this.getStyle()}>
{children}
</div>
);
}
handleMouseMove = (event) => {
Object.assign(this.mouseCoords, {
x: event.pageX,
y: event.pageY,
});
if (this.props.visible) {
this.updatePosition();
}
};
saveNode = (node) => (this.node = node);
getStyle() {
return {
left: this.state.left,
top: this.state.top,
};
}
updatePosition() {
if (!this.props.visible) return;
const pos = {
left: this.mouseCoords.x + Tooltip.marginX,
top: this.mouseCoords.y + Tooltip.marginY,
};
const boundingRect = this.node.getBoundingClientRect();
if (pos.left + boundingRect.width > window.innerWidth) {
// Shifting horizontally
pos.left = window.innerWidth - boundingRect.width;
}
if (pos.top + boundingRect.height > window.innerHeight) {
// Flipping vertically
pos.top = this.mouseCoords.y - Tooltip.marginY - boundingRect.height;
}
this.setState(pos);
}
}