Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
import React from 'react'
import toClassName from 'classnames'
import { isFunction, isNil, isObj } from 'exotic'
import { func, node, string } from '@skava/modules/___dist/view-container/types'
import { isClickOutsideElement, isClickInsideElement } from './deps'

class ClickBoundary extends React.PureComponent {
  dom: HTMLElement

  // static isClickOutsideElement = isClickOutsideElement
  static propTypes = {
    // @todo @name onClickOutside
    onClickOutside: func,
    className: string,
    children: node,

    /**
     * @todo @name @example
     *    maybe aria has a standard one too
     *    [provide]  |  [consume]
     *
     *    parentRef  | childrenRef
     *               | childRef
     *               | innerRef
     *
     *    wrapRef    | boxWrap
     *    giveRef    | getRef
     *    provideRef |
     */
    parentRef: func,
  }

  // only happens in browser, `willMount` in server
  componentDidMount() {
    if (IS_BROWSER) {
      document.body.addEventListener('click', this.handleClick)
      document.body.addEventListener('ontouchstart', this.handleClick)
    }
  }

  // only happens browser
  componentWillUnmount() {
    if (IS_BROWSER) {
      // remember to remove all events to avoid memory leaks
      document.body.removeEventListener('click', this.handleClick)
      document.body.removeEventListener('ontouchstart', this.handleClick)
    }
  }

  setRef = dom => {
    this.dom = dom
  }

  handleClick = event => {
    // if (event.persist) event.persist()
    // console.log('onClickBoundary', event)

    // get click outside callback
    const { onClickOutside } = this.props

    // if there is no proper callback - no point of checking
    if (isFunction(onClickOutside) === false) {
      return
    }

    if (isClickOutsideElement(event, this.dom) === true) {
      onClickOutside(event)
    }
  }

  get className(): string {
    return toClassName('click-boundary', this.props.className)
  }

  render() {
    // why a diff dom?
    // if (IS_BROWSER === false) {
    //   return React.Children.only(this.props.children)
    // } else {

    const children = isFunction(this.props.children)
      ? this.props.children(this)
      : this.props.children

    /**
     * @todo - should use a ref to this.props.children to avoid pollouting the dom
     * @todo - should maybe pass in `getParentRef` if it's inside...
     */
    if (isFunction(this.props.parentRef) === true) {
      this.setRef(this.props.parentRef)
      return children
    } else {
      return (
        <div ref={this.setRef} className={this.className}>
          {this.props.children}
        </div>
      )
    }
  }
}

export default ClickBoundary
export { ClickBoundary }
export { isClickInsideElement }