UNPKG

@f4ndor/react-click-n-hold

Version:

Long press event for react. Click and hold wrapper component.

105 lines (91 loc) 3.46 kB
import React, {Component} from 'react'; export default class ClickNHold extends Component { constructor(props) { super(props); this.state = { holding: false, start: 0, ended: 'begin', }; this._timer = null; this._unmounted = false; this.start = this.start.bind(this); this.end = this.end.bind(this); this.timeout = this.timeout.bind(this); } componentWillUnmount() { this._unmounted = true; clearTimeout(this._timer); this._timer = null; } /* componentDidUpdate(nextState) { if (this.state.holding !== nextState.holding) { if (this.state.holding === false && this.state.ended === false) { document.documentElement.addEventListener('mouseup', this.end); } } }*/ /*Start callback*/ start(e){ let ended = this.state.ended; let start = Date.now(); this.setState({start: start, holding: true, ended: false}); let rightNumber = this.props.time && this.props.time > 0; let time = rightNumber ? this.props.time : 2; if (!rightNumber) {console.warn("You have specified an unvalid time prop for ClickNHold. You need to specify a number > 0. Default time is 2.")} if (ended) { this._timer = setTimeout(function(){this.timeout(start)}.bind(this), time*1000+1); } if (this.props.onStart) { this.props.onStart(e); } document.documentElement.addEventListener('mouseup', this.end); } /*End callback*/ end(e) { document.documentElement.removeEventListener('mouseup', this.end); if(this.state.ended || this._unmounted) { return false; } let endTime = Date.now(); //End time let minDiff = this.props.time * 1000; // In seconds let startTime = this.state.start; // Start time let diff = endTime - startTime; // Time difference let isEnough = diff >= minDiff; // It has been held for enough time this.setState({holding: false, ended: true}); if (this.props.onEnd){ this.props.onEnd(e, isEnough); } } /*Timeout callback*/ timeout(start){ if (!this.state.ended && start === this.state.start){ if(this.props.onClickNHold) { this.props.onClickNHold(start); if (!this._unmounted) { this.setState({holding: false}); } } } } render() { let classList = this.props.className ? (this.props.className +' '):' '; classList += this.state.holding ? 'cnh_holding ':''; classList += this.state.ended ? 'cnh_ended ':''; return ( <div style={this.props.style} className={classList} onMouseDown={this.start} onTouchStart={this.start} onMouseUp={this.end} onTouchCancel={this.end} onTouchEnd={this.end}> { typeof this.props.children === 'object' ? React.cloneElement(this.props.children, { ref: (n) => this.node = n }) : null } </div>); } }