JSFiddle - React, Tailwind, and code Playground

by Sasha Morozov

JavaScript

import React from 'react';
import ReactDOM from 'react-dom';

import * as dom from 'utils/dom';

import classNames from 'classnames';

export default class Tooltip extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      placement: 'top',
      title: '',
      animation: true,
      animationDelay: 150,
      delayHide: 0,
      show: false,
      currentEvent: null,
      currentTarget: null,
      scrollableTable: false
    };

    this.mount = false;
    this.delayHideLoop = null;
    this.delayResetStyle = null;

    // For events on the fixed container
    this.tableInner = null;
    this.tableViewer = null;
  }

  componentDidMount() {
    this.mount = true;

    this.bindListeners();
    this.checkScrollableTable();
  }

  componentWillUnmount() {
    this.mount = false;

    this.clearTimer();
    this.unbindListeners();
    this.removeScrollListener();
  }

  componentWillReceiveProps() {
    this.bindListeners();
  }

  /**
   * Pick out target elements
   */
  getTargetArray(allElements) {
    let targetArray = [];

    if (!allElements) {
      targetArray = [].slice.call(document.querySelectorAll('[data-tooltip]:not([data-tooltip-mount])'));
    } else {
      targetArray = [].slice.call(document.querySelectorAll('[data-tooltip]'));
    }

    return targetArray;
  }

  /**
   * Bind listener to the target elements
   * These listeners used to trigger showing or hiding the tooltip
   */
  bindListeners() {
    let targetArray = this.getTargetArray();

    targetArray.forEach(target => {
      target.setAttribute('data-tooltip-mount', true);
      target.addEventListener('mouseenter', this.showTooltip);
      target.addEventListener('mouseleave', this.hideTooltip);
    });
  }

  /**
   * Unbind listeners on target elements
   */
  unbindListeners() {
    let targetArray = this.getTargetArray(true);

    targetArray.forEach(target => {
      this.unbindBasicListener(target);
     ...