Skip to content

Commit

Permalink
Add option for minDragStartDistance to improve on clickSuppression (
Browse files Browse the repository at this point in the history
#26)

Add an option `minDragStartDistance` on `Draggable` to define the minimum distance in
  pixels that is needed for a drag to start (#26). Default is `4` pixels. This allows for clicks with tiny movement. The option `clickSuppression` has been marked as DEPRECATED as it had the same goal but a misleading name.
  • Loading branch information
spencercornish-wk authored and marcojakob committed Oct 12, 2018
1 parent e724042 commit a2bfd93
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 76 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
@@ -1,10 +1,14 @@
# Changelog

## Version 1.4.0 (2018-10-12)

- Add an option `minDragStartDistance` on `Draggable` to define the minimum distance in
pixels that is needed for a drag to start (#26). Default is `4` pixels. This allows for clicks with tiny movement. The option `clickSuppression` has been marked as DEPRECATED as it had the same goal but a misleading name.

## Version 1.3.0 (2018-08-15)

- Align dart version to support Dart 2 (#25).


## Version 1.2.0 (2018-06-21)

- Support for creating a Draggable with `List<Element>` (in addition to `ElementList` and `Element`).
Expand Down
97 changes: 45 additions & 52 deletions README.md
Expand Up @@ -5,35 +5,30 @@ Drag and Drop for Dart web apps with mouse and touch support.
[![Star this Repo](https://img.shields.io/github/stars/marcojakob/dart-dnd.svg?style=flat-square)](https://github.com/marcojakob/dart-dnd)
[![Pub Package](https://img.shields.io/pub/v/dnd.svg?style=flat-square)](https://pub.dartlang.org/packages/dnd)


[GitHub](https://github.com/marcojakob/dart-dnd) |
[Pub](https://pub.dartlang.org/packages/dnd) |
[Demos and Examples](http://code.makery.ch/library/dart-drag-and-drop/)


![DnD Screenshot](https://raw.githubusercontent.com/marcojakob/dart-dnd/master/doc/dnd-screenshot.png)


## Features

* Use any HTML Element as `Draggable` or `Dropzone`.
* Mouse and Touch dragging.
* Draggable events: `dragStart`, `drag`, and `dragEnd`
* Dropzone events: `dragEnter`, `dragOver`, `dragLeave`, and `drop`
* Drag avatars as visual indication of a drag operation:
* Original element as drag avatar.
* Clone as drag avatar.
* Custom drag avatar.
* Support for Shadow DOM (Web Components, Custom Elements, Polymer, etc.).
* Much more... see examples.

- Use any HTML Element as `Draggable` or `Dropzone`.
- Mouse and Touch dragging.
- Draggable events: `dragStart`, `drag`, and `dragEnd`
- Dropzone events: `dragEnter`, `dragOver`, `dragLeave`, and `drop`
- Drag avatars as visual indication of a drag operation:
- Original element as drag avatar.
- Clone as drag avatar.
- Custom drag avatar.
- Support for Shadow DOM (Web Components, Custom Elements, Polymer, etc.).
- Much more... see examples.

## Usage

Before you read the instructions below, you should take a look at the
[examples](http://code.makery.ch/library/dart-drag-and-drop/).


### Basic Set Up

Create a `Draggable` and give it some HTML elements; this will make them
Expand Down Expand Up @@ -65,88 +60,87 @@ Draggable draggable = new Draggable(querySelectorAll('.draggable'),
avatarHandler: new AvatarHandler.original());
```


### Draggable Options

The following options can be passed as *named parameters* to the constructor of
The following options can be passed as _named parameters_ to the constructor of
`Draggable`:

* `avatarHandler`: Is responsible for creating, position, and removing a drag
- `avatarHandler`: Is responsible for creating, position, and removing a drag
avatar. A drag avatar provides visual feedback during a drag operation. Here
are possible options (see above for an example):
* `null` (the default) - will not create a drag avatar
* `new AvatarHandler.original()` - handler that uses the original

- `null` (the default) - will not create a drag avatar
- `new AvatarHandler.original()` - handler that uses the original
draggable as avatar. See `OriginalAvatarHandler`.
* `new AvatarHandler.clone()` - handler that uses a clone of the draggable
- `new AvatarHandler.clone()` - handler that uses a clone of the draggable
element as avatar. See `CloneAvatarHandler`.
* A custom `AvatarHandler` - you can provide your own implementation of
- A custom `AvatarHandler` - you can provide your own implementation of
`AvatarHandler`.

* `horizontalOnly`: If set to true, only horizontal dragging is tracked.
- `horizontalOnly`: If set to true, only horizontal dragging is tracked.
This enables vertical touch dragging to be used for scrolling.

* `verticalOnly`: If set to true, only vertical dragging is tracked.
- `verticalOnly`: If set to true, only vertical dragging is tracked.
This enables horizontal touch dragging to be used for scrolling.

* `handle`: If handle query String is specified, it restricts the dragging from
- `handle`: If handle query String is specified, it restricts the dragging from
starting unless it occurs on the specified element(s). Only elements that
descend from the draggables elements are permitted.

* `cancel`: If cancel query String is specified, drag starting is prevented on
- `cancel`: If cancel query String is specified, drag starting is prevented on
specified elements.

* `draggingClass`: Is the css class set to the dragged element
- `draggingClass`: Is the css class set to the dragged element
during a drag. If set to null, no such css class is added.

* `draggingClassBody`: Is the css class set to the html body tag
- `draggingClassBody`: Is the css class set to the html body tag
during a drag. If set to null, no such css class is added.

- `minDragStartDistance`: Is the minimum distance in pixels that is needed
for a drag to start. Default is `4`. This allows for clicks with tiny movement.

### Draggable Events

Available event `Stream`s on `Draggable`:

* `onDragStart`: Fired when the user starts dragging.
*Note: `onDragStart` is fired not on touchStart or mouseDown but as
- `onDragStart`: Fired when the user starts dragging.
_Note: `onDragStart` is fired not on touchStart or mouseDown but as
soon as there is a drag movement. When a drag is started an `onDrag` event
will also be fired.*
will also be fired._

* `onDrag`: Fired periodically throughout the drag operation.

* `onDragEnd`: Fired when the user ends the dragging.
*Note: Is also fired when the user clicks the 'esc'-key or the window loses focus.*
- `onDrag`: Fired periodically throughout the drag operation.

- `onDragEnd`: Fired when the user ends the dragging.
_Note: Is also fired when the user clicks the 'esc'-key or the window loses focus._

### Dropzone Options

The following options can be passed as *named parameters* to the constructor of
The following options can be passed as _named parameters_ to the constructor of
`Dropzone`:

* `acceptor`: Is used to determine which `Draggable`s will be accepted by
- `acceptor`: Is used to determine which `Draggable`s will be accepted by
this `Dropzone`. If none is specified, all `Draggable`s will be accepted.

* `overClass`: Is the css class set to the dropzone element when an accepted
- `overClass`: Is the css class set to the dropzone element when an accepted
draggable is dragged over it. If set to null, no such css class is added.

* `invalidClass`: Is the css class set to the dropzone element when a not-accepted
- `invalidClass`: Is the css class set to the dropzone element when a not-accepted
draggable is dragged over it. If set to null, no such css class is added.


### Dropzone Events

Available event `Stream`s on `Dropzone`:

* `onDragEnter`: Fired when a `Draggable` enters this `Dropzone`.

* `onDragOver`: Fired periodically while a `Draggable` is moved over a `Dropzone`.
- `onDragEnter`: Fired when a `Draggable` enters this `Dropzone`.

* `onDragLeave`: Fired when a `Draggable` leaves this `Dropzone`.
- `onDragOver`: Fired periodically while a `Draggable` is moved over a `Dropzone`.

* `onDrop`: Fired when a `Draggable` is dropped inside this `Dropzone`.
- `onDragLeave`: Fired when a `Draggable` leaves this `Dropzone`.

*Note: `Dropzone` events are only fired when the `Draggable` is accepted by
the `Acceptor`.*
- `onDrop`: Fired when a `Draggable` is dropped inside this `Dropzone`.

_Note: `Dropzone` events are only fired when the `Draggable` is accepted by
the `Acceptor`._

### Shadow DOM

Expand All @@ -165,16 +159,15 @@ a `dnd-retarget` attribute to the host:
<my-element dnd-retarget></my-element>
```


## Attribution

The *Dart Drag and Drop* library is inspired by
The _Dart Drag and Drop_ library is inspired by

* [jQuery UI Draggable](http://jqueryui.com/draggable/)
* [Draggabilly](http://draggabilly.desandro.com/)
- [jQuery UI Draggable](http://jqueryui.com/draggable/)
- [Draggabilly](http://draggabilly.desandro.com/)

Thank you for your work!


## License

The MIT License (MIT)
5 changes: 0 additions & 5 deletions analysis_options.yaml
@@ -1,8 +1,3 @@
analyzer:
strong-mode: true
errors:
uri_has_not_been_generated: ignore

# Lint rules and documentation, see http://dart-lang.github.io/linter/lints
linter:
rules:
Expand Down
26 changes: 19 additions & 7 deletions lib/src/draggable.dart
Expand Up @@ -53,8 +53,18 @@ class Draggable {
/// See [Draggable] constructor.
String draggingClassBody;

/// The minimum distance in pixels that is needed for a drag to start.
/// See [Draggable] constructor.
int minDragStartDistance;

/// The minimum distance for a drag to prevent click events.
int clickSuppression = 0;
/// DEPRECATED: Please use [minDragStartDistance] instead.
@deprecated
get clickSuppression => minDragStartDistance;

/// DEPRECATED: Please use [minDragStartDistance] instead.
@deprecated
set clickSuppression(int distance) => minDragStartDistance = distance;

// -------------------
// Events
Expand Down Expand Up @@ -148,14 +158,19 @@ class Draggable {
///
/// The [draggingClassBody] is the css class set to the html body tag
/// during a drag. If set to null, no such css class is added.
///
/// The [minDragStartDistance] is the minimum distance in pixels that is needed
/// for a drag to start. Default is `4`. This allows for clicks with tiny movement.
///
Draggable(elementOrElementList,
{this.avatarHandler: null,
this.horizontalOnly: false,
this.verticalOnly: false,
this.handle: null,
this.cancel: 'input, textarea, button, select, option',
this.draggingClass: 'dnd-dragging',
this.draggingClassBody: 'dnd-drag-occurring'}) {
this.draggingClassBody: 'dnd-drag-occurring',
this.minDragStartDistance: 4}) {
// Wrap in a List if it is not a list but a single Element.
_elements = elementOrElementList is List
? elementOrElementList
Expand Down Expand Up @@ -262,11 +277,8 @@ class Draggable {
event.preventDefault();
}

if (event is MouseEvent &&
(clickSuppression <= 0 ||
_currentDrag.startPosition.distanceTo(_currentDrag.position) >
clickSuppression)) {
// Prevent MouseEvent from firing a click after mouseUp event if the move was significant.
// Prevent MouseEvent from firing a click after mouseUp event.
if (event is MouseEvent) {
_suppressClickEvent(_currentDrag.element);
}

Expand Down
19 changes: 9 additions & 10 deletions lib/src/draggable_manager.dart
Expand Up @@ -86,16 +86,15 @@ abstract class _EventManager {
// Set the current position.
_currentDrag.position = position;

if (!_currentDrag.started &&
_currentDrag.startPosition != _currentDrag.position) {
// This is the first drag move.

// Handle dragStart.
drg._handleDragStart(event);
}

// Handle drag (will also be called after drag start).
if (_currentDrag.started) {
if (!_currentDrag.started) {
// Test if drag has moved far enough to start drag.
if (_currentDrag.startPosition.distanceTo(_currentDrag.position) >=
drg.minDragStartDistance) {
// Drag starts now.
drg._handleDragStart(event);
}
} else {
// Drag already started.
Element realTarget = _getRealTarget(clientPosition);
drg._handleDrag(event, realTarget);
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
@@ -1,5 +1,5 @@
name: dnd
version: 1.3.0
version: 1.4.0
author: Marco Jakob <majakob@gmx.ch>
description: Drag and Drop for Dart web apps with mouse and touch support.
homepage: http://code.makery.ch/library/dart-drag-and-drop/
Expand Down

0 comments on commit a2bfd93

Please sign in to comment.