All files / tooltip index.js

93.33% Statements 14/15
75% Branches 3/4
100% Functions 3/3
100% Lines 14/14
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 89  1x 1x                                                                               4x 4x 4x 4x 4x 4x 4x                           8x 8x   8x             8x 12x                              
 
import React from 'react'
import {Motion, spring} from 'react-motion'
 
/**
 * Tooltip
 */
export default class Tooltip extends React.Component {
 
  /**
   * Property types
   */
  static propTypes = {
    content: React.PropTypes.string,
    visible: React.PropTypes.bool
  }
 
  /**
   * Default properties
   */
  static defaultProps = {
    content: 'tooltip content',
    visible: false
  }
 
  /**
   * Initial state
   */
  state = {
    left: 'auto'
  }
 
  /**
   * Get width of tooltip
   */
  componentDidMount () {
    // to get the right width we have to make sure
    // that the tooltip is scaled properly
    // invisible tooltips are scaled down to 0
    // and there we aren't able to get the right width
 
    // when initially hidden we do not have any refs
    Iif (!this.tooltipRef) { return }
    var tooltipDOM = this.tooltipRef
    tooltipDOM.style.transform = 'scale(1)'
    var tooltipRect = tooltipDOM.getBoundingClientRect()
    var contentRect = this.refs.content.getBoundingClientRect()
    var left = (contentRect.width / 2) + contentRect.left - (tooltipRect.width / 2)
    this.setState({left})
  }
 
  /**
   * Placeholder for tooltip ref
   * first-class references
   * https://github.com/reactjs/react-future/blob/master/01%20-%20Core/06%20-%20Refs.js
   * https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute
   */
  tooltipRef = null
 
  /**
   * Render component
   */
  render () {
    return (
      <div>
        {React.Children.map(this.props.children, child =>
          React.cloneElement(child, {
            ref: 'content'
          })
        )}
        <Motion style={{val: spring(this.props.visible ? 1 : 0)}}>
          {style => {
            return (
              <div className='Tooltip' ref={(component) => { this.tooltipRef = component }} style={{
                left: this.state.left,
                opacity: style.val,
                transform: `scale(${style.val})`
              }}>
                {this.props.content}
              </div>
            )
          }}
        </Motion>
      </div>
    )
  }
 
}