Tooltip.jsx 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import {Component} from 'react';
  2. import cls from 'classnames';
  3. import s from './Tooltip.css';
  4. export default class Tooltip extends Component {
  5. static marginX = 10;
  6. static marginY = 30;
  7. mouseCoords = {
  8. x: 0,
  9. y: 0,
  10. };
  11. state = {
  12. left: 0,
  13. top: 0,
  14. };
  15. componentDidMount() {
  16. document.addEventListener('mousemove', this.handleMouseMove, true);
  17. }
  18. shouldComponentUpdate(nextProps) {
  19. return this.props.visible || nextProps.visible;
  20. }
  21. componentWillUnmount() {
  22. document.removeEventListener('mousemove', this.handleMouseMove, true);
  23. }
  24. render() {
  25. const {children, visible} = this.props;
  26. const className = cls({
  27. [s.container]: true,
  28. [s.hidden]: !visible,
  29. });
  30. return (
  31. <div ref={this.saveNode} className={className} style={this.getStyle()}>
  32. {children}
  33. </div>
  34. );
  35. }
  36. handleMouseMove = event => {
  37. Object.assign(this.mouseCoords, {
  38. x: event.pageX,
  39. y: event.pageY,
  40. });
  41. if (this.props.visible) {
  42. this.updatePosition();
  43. }
  44. };
  45. saveNode = node => (this.node = node);
  46. getStyle() {
  47. return {
  48. left: this.state.left - 200,
  49. top: this.state.top - 180,
  50. };
  51. }
  52. updatePosition() {
  53. if (!this.props.visible) {
  54. return;
  55. }
  56. const pos = {
  57. left: this.mouseCoords.x + Tooltip.marginX,
  58. top: this.mouseCoords.y + Tooltip.marginY,
  59. };
  60. const boundingRect = this.node.getBoundingClientRect();
  61. if (pos.left + boundingRect.width > window.innerWidth) {
  62. // Shifting horizontally
  63. pos.left = window.innerWidth - boundingRect.width;
  64. }
  65. if (pos.top + boundingRect.height > window.innerHeight) {
  66. // Flipping vertically
  67. pos.top = this.mouseCoords.y - Tooltip.marginY - boundingRect.height;
  68. }
  69. this.setState(pos);
  70. }
  71. }