react-selectable icon indicating copy to clipboard operation
react-selectable copied to clipboard

Click events within selectable component

Open SamesJeabrook opened this issue 6 years ago • 5 comments

Love this library, thanks so much for the hard work in it. I have a question around click events within a selectable component, in that unless you have a really steady hand it won't register the click event but instead will start drawing the bounding box.

I have previously got round this with JqueryUI by adding a "distance" attribute - one that I saw you had removed from version 1 - but not sure if its the same in that it would be the distance in pixels from when the mouse down event took place before it began drawing the bounding box. This enabled other events on the selectable item to fire.

Or have I missed something else in the docs or options that will enable the events?

SamesJeabrook avatar Jul 19 '18 11:07 SamesJeabrook

I'm running into this same issue. Im hoping there is a fix.

drkdelaney avatar Jul 23 '18 20:07 drkdelaney

I was able to determine that sometimes the mousemove event was getting called by the browser even though my mouse didn't move. I think adding a distance or drag tolerance prop would help. Temporarily I created my own NewSelectableGroup that extends SelectableGroup with my fix.

import { SelectableGroup } from 'react-selectable';

const DRAG_TOLERANCE = 5;

export default class NewSelectableGroup extends SelectableGroup {
    _openSelector(e) {
        const width = Math.abs(this._mouseDownData.initialW - e.pageX + this._rect.x);
        const height = Math.abs(this._mouseDownData.initialH - e.pageY + this._rect.y);

        if (width < DRAG_TOLERANCE && height < DRAG_TOLERANCE) return;

        this.setState({
            isBoxSelecting: true,
            boxWidth: width,
            boxHeight: height,
            boxLeft: Math.min(e.pageX - this._rect.x, this._mouseDownData.initialW),
            boxTop: Math.min(e.pageY - this._rect.y, this._mouseDownData.initialH),
        });

        if (this.props.selectOnMouseMove) this._throttledSelect(e);
    }
}

Then I just use <NewSelectableGroup>

Im happy to create a PR with this change if @unclecheese feels its a good solution.

drkdelaney avatar Jul 23 '18 23:07 drkdelaney

Finally had chance to put this into practice and it works really well, click events are now operating without issue, but for me I had to include a clear of selection as when dragging under the tolerance I found that it highlighted elements on the page.

if(width < DRAG_TOLERANCE && height < DRAG_TOLERANCE){
	if(window.getSelection){
		window.getSelection().removeAllRanges();
	}else{
		document.selection.empty();
	}
	return;
}

SamesJeabrook avatar Jul 25 '18 09:07 SamesJeabrook

I used the css property user-select: none;on my SelectableComponent items that can be selected. That prevented highlighting for me.

drkdelaney avatar Jul 25 '18 16:07 drkdelaney

Much better solution, should have thought of that first.

SamesJeabrook avatar Jul 25 '18 16:07 SamesJeabrook