dnd 1.4.3

  • Readme
  • Changelog
  • Example
  • Installing
  • 94

Dart Drag and Drop #

Drag and Drop for Dart web apps with mouse and touch support.

Star this Repo Pub Package

GitHub | Pub | Demos and Examples

DnD Screenshot

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.

Usage #

Before you read the instructions below, you should take a look at the examples.

Basic Set Up #

Create a Draggable and give it some HTML elements; this will make them draggable. You can either pass a single Element to the constructor or an ElementList that is returned by querySelectorAll.

If you also want to drop somewhere, you'll need a Dropzone.

// Install draggable (no avatar).
Draggable draggable = Draggable(querySelectorAll('.draggable'));

// Install dropzone.
Dropzone dropzone = Dropzone(querySelector('.dropzone'));

You'll most likely want some drag avatar to show the user that a drag is going on. There are two predefined AvatarHandlers that you can use as follows. But you could also provide your own implementation of AvatarHandler.

// Draggable with clone as avatar.
Draggable draggable = Draggable(querySelectorAll('.draggable'),
    avatarHandler: AvatarHandler.clone());

// Draggable with original element as avatar.
Draggable draggable = Draggable(querySelectorAll('.draggable'),
    avatarHandler: AvatarHandler.original());

Draggable Options #

The following options can be passed as named parameters to the constructor of Draggable:

  • 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
    • AvatarHandler.original() - handler that uses the original draggable as avatar. See OriginalAvatarHandler.
    • 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 AvatarHandler.
  • 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. This enables horizontal touch dragging to be used for scrolling.

  • 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 specified elements.

  • 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 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 Streams on Draggable:

  • 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.

  • 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 Dropzone:

  • acceptor: Is used to determine which Draggables will be accepted by this Dropzone. If none is specified, all Draggables will be 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 draggable is dragged over it. If set to null, no such css class is added.

Dropzone Events #

Available event Streams on Dropzone:

  • onDragEnter: Fired when a Draggable enters this Dropzone.

  • onDragOver: Fired periodically while a Draggable is moved over a Dropzone.

  • onDragLeave: Fired when a Draggable leaves this Dropzone.

  • 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 #

Web Components create a nice ecapsulation through Shadow DOM. But this creates a problem with dropzones inside the Shadow DOM as they never receive events because all events are captured by the host element. To make this work we need to retarget events to the Shadow DOM children through recursive elementFromPoint() calls.

For performance reasons it wouldn't make sense to retarget all drag and drop events. If you wish to retarget events to the Shadow DOM children, you must add a dnd-retarget attribute to the host:

// Retarget drag and drop events to Shadow DOM children.
<my-element dnd-retarget></my-element>

Attribution #

The Dart Drag and Drop library is inspired by

Thank you for your work!

Running / Building / Testing #

  • Run from the terminal: webdev serve
  • Build from the terminal: webdev build

License #

The MIT License (MIT)

Changelog #

Version 1.4.3 (2019-12-10) #

  • Remove unnecessary new keyword.

Version 1.4.2 (2019-02-13) #

  • Fix #30: Cannot initialize Dropzone with List
  • Follow more code style conventions.
  • Update dependencies.

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).

Version 1.1.0 (2018-06-21) #

  • Remove cursor files. Support for grab, -webkit-grab, grabbing, and -webkit-grabbing is good enough.

Version 1.0.0 (2018-06-13) #

  • Migrate to Dart 2.
  • Since Chrome 56 touch event listeners are treated as passive by default. This disables the possibility to call preventDefault on an element which we must do to tell the browser not to scroll while dragging. To fix this in Chrome we set the touch-action css property. With this Chrome will not scroll (none) or only scroll in one direction (pan-y or pan-x).

Version 0.4.0 (2017-06-27) #

  • Fix strong mode errors (#20).

Version 0.3.6 (2017-06-06) #

  • Fix bug: Provide reasonable fallback for event target when mouse position exits viewport (#19).

Version 0.3.5 (2016-11-22) #

  • Handle the edge case where destroy is called while dragging an avatar (#17).

Version 0.3.4 (2016-10-19) #

  • Fix strong-mode type errors (#15).
  • Remove Shadow DOM example and (dev)dependency on Polymer (was causing some confusion).

Version 0.3.3 (2016-09-22) #

  • Allow a configurable clickSuppression distance (#13). We found that the click suppression was a little too aggressive for users with less mousing accuracy. They would attempt to click and trigger a small drag. Which then suppressed the click event and prevented the action they intended to complete.

Version 0.3.2 (2016-07-26) #

  • Remove null-aware operator since drone.io uses an old version of Dart that doesn't support this yet.

Version 0.3.1 (2016-07-26) #

  • Support for programmatic drag abort (see issue #11).

Version 0.3.0 (2015-04-18) #

  • BREAKING CHANGE: Refactoring the AvatarHandler. Only if you've implemented a custom AvatarHandler you might need to do some changes:
    • setPointerEventsNone and resetPointerEvents were removed and don't need to be called any more. Pointer event styles are handled automatically.
  • Fix AvatarHandler margin caching: The AvatarHandler only cached the margins once for every Draggable. This caused problems when margins of elements in the same Draggable had different margins or the margins were changed. Now the margins are reset after every drag.

Version 0.2.1 (2015-03-09) #

  • Fix #9: Using transformers in the main pubspec.yaml caused problems with projects depending on the dnd package.

Version 0.2.0 (2015-03-09) #

  • Fix #3: Shadow DOM is now supported. A dnd-retarget attribute must be added to all custom elements where events should be forwarded to the Shadow DOM children.
  • Fix #7: Add a css class (dnd-invalid by default) to dropzones when a not-accepted draggable is dragged over.

Version 0.1.4 (2014-10-20) #

  • Add a sortable example.
  • Change comments according to new Dart Style Guide rule (/// instead of /** */).
  • Move event dispatching calls from EventManager to Draggable (refactoring).

Version 0.1.3 (2014-08-09) #

  • Fix #4: Problem when an ancestor of the dragged element was positioned (relative, absolute, fixed).

Version 0.1.2 (2014-07-22) #

  • Correcting small bug that occurred when setSelectionRange() was called on an element that does not support it.
  • Fix Pointer Event bug: Too many event listeners in move, end, cancel.
  • Fix for Bug #1 - Not working in Windows 8.1 IE11
  • Adding a cancelled flag to DraggableEvent to indicate if a drag ended because of a cancelling operation like esc key, etc.

Version 0.1.1 (2014-07-21) #

  • Support for IE10 and IE11 touch screens through pointer events.
  • Removed disableTouch and disableMouse options. The goal was to unify touch and mouse dragging, so it should not be necessary to disable one or the other.

Version 0.1.0 (2014-07-17) #

  • First version.


// Only used as placeholder.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  dnd: ^1.4.3

2. Install it

You can install packages from the command line:

with pub:

$ pub get

with Flutter:

$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:dnd/dnd.dart';
Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

We analyzed this package on Apr 4, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0 <3.0.0
Dev dependencies
build_runner ^1.2.5
build_web_compilers ^1.1.0