diff --git a/examples/demos/selectable.js b/examples/demos/selectable.js index c005962a7..34d5b5602 100644 --- a/examples/demos/selectable.js +++ b/examples/demos/selectable.js @@ -19,7 +19,8 @@ let Selectable = React.createClass({ onSelectEvent={event => alert(event.title)} onSelectSlot={(slotInfo) => alert( `selected slot: \n\nstart ${slotInfo.start.toLocaleString()} ` + - `\nend: ${slotInfo.end.toLocaleString()}` + `\nend: ${slotInfo.end.toLocaleString()}` + + `\naction: ${slotInfo.action}` )} /> diff --git a/src/BackgroundCells.js b/src/BackgroundCells.js index 883f776c6..efb48fed3 100644 --- a/src/BackgroundCells.js +++ b/src/BackgroundCells.js @@ -91,6 +91,27 @@ class BackgroundCells extends React.Component { longPressThreshold: this.props.longPressThreshold, }) + let selectorClicksHandler = (point, actionType) => { + if (!isEvent(findDOMNode(this), point)) { + let rowBox = getBoundsForNode(node) + let { range, rtl } = this.props; + + if (pointInBox(rowBox, point)) { + let width = slotWidth(getBoundsForNode(node), range.length); + let currentCell = getCellAtX(rowBox, point.x, width, rtl, range.length); + + this._selectSlot({ + startIdx: currentCell, + endIdx: currentCell, + action: actionType, + }) + } + } + + this._initial = {} + this.setState({ selecting: false }) + }; + selector.on('selecting', box => { let { range, rtl } = this.props; @@ -125,26 +146,10 @@ class BackgroundCells extends React.Component { }) selector - .on('click', point => { - if (!isEvent(findDOMNode(this), point)) { - let rowBox = getBoundsForNode(node) - let { range, rtl } = this.props; - - if (pointInBox(rowBox, point)) { - let width = slotWidth(getBoundsForNode(node), range.length); - let currentCell = getCellAtX(rowBox, point.x, width, rtl, range.length); - - this._selectSlot({ - startIdx: currentCell, - endIdx: currentCell, - action: 'click', - }) - } - } + .on('click', point => selectorClicksHandler(point, 'click')) - this._initial = {} - this.setState({ selecting: false }) - }) + selector + .on('doubleClick', point => selectorClicksHandler(point, 'doubleClick')) selector .on('select', () => { diff --git a/src/Calendar.js b/src/Calendar.js index f5d946dd7..483e530b8 100644 --- a/src/Calendar.js +++ b/src/Calendar.js @@ -110,7 +110,7 @@ class Calendar extends React.Component { * start: Date, * end: Date, * slots: Array, - * action: "select" | "click" + * action: "select" | "click" | "doubleClick" * } * ) => any * ``` diff --git a/src/DayColumn.js b/src/DayColumn.js index 85385d3eb..ceb8d2fdc 100644 --- a/src/DayColumn.js +++ b/src/DayColumn.js @@ -297,6 +297,13 @@ class DayColumn extends React.Component { } } + let selectorClicksHandler = (box, actionType) => { + if (!isEvent(findDOMNode(this), box)) + this._selectSlot({ ...selectionState(box), action: actionType }) + + this.setState({ selecting: false }) + } + selector.on('selecting', maybeSelect) selector.on('selectStart', maybeSelect) @@ -307,12 +314,10 @@ class DayColumn extends React.Component { }) selector - .on('click', (box) => { - if (!isEvent(findDOMNode(this), box)) - this._selectSlot({ ...selectionState(box), action: 'click' }) + .on('click', box => selectorClicksHandler(box, 'click')) - this.setState({ selecting: false }) - }) + selector + .on('doubleClick', (box) => selectorClicksHandler(box, 'doubleClick')) selector .on('select', () => { diff --git a/src/Selection.js b/src/Selection.js index 7fef436ed..b036977b7 100644 --- a/src/Selection.js +++ b/src/Selection.js @@ -34,6 +34,7 @@ function getEventCoordinates(e) { } const clickTolerance = 5; +const clickInterval = 250; class Selection { @@ -224,7 +225,7 @@ class Selection { } _handleTerminatingEvent(e) { - const { pageX, pageY, clientX, clientY } = getEventCoordinates(e); + const { pageX, pageY } = getEventCoordinates(e); this.selecting = false; @@ -243,17 +244,40 @@ class Selection { return this.emit('reset') } - if(click && inRoot) - return this.emit('click', { + if(click && inRoot) { + return this._handleClickEvent(e); + } + + // User drag-clicked in the Selectable area + if(!click) + return this.emit('select', bounds) + } + + _handleClickEvent(e) { + const { pageX, pageY, clientX, clientY } = getEventCoordinates(e); + const now = new Date().getTime(); + + if (this._lastClickData && now - this._lastClickData.timestamp < clickInterval) { + // Double click event + this._lastClickData = null; + return this.emit('doubleClick', { x: pageX, y: pageY, clientX: clientX, clientY: clientY, }) + } - // User drag-clicked in the Selectable area - if(!click) - return this.emit('select', bounds) + // Click event + this._lastClickData = { + timestamp: now, + }; + return this.emit('click', { + x: pageX, + y: pageY, + clientX: clientX, + clientY: clientY, + }); } _handleMoveEvent(e) {