APIs
DndService
is the single class provided in bcx-aurelia-dnd
. Technically, it can work with any front-end framework.
DndService Constructor
You don’t need to use constructor in Aurelia app, Aurelia DI (dependency injection) handles creation of shared singleton instance for you.
in Aurelia app, use dependency injection to create shared singleton instance.
in other kind of apps, create a shared instance for the whole app to share.
If you use bcx-aurelia-dnd not in an Aurelia app, you can create an instance manually, like
const dndService = new DndService();
That’s an instance without Aurelia Event Aggregator support. Events 'dnd:willStart'
, 'dnd:didStart'
, 'dnd:willEnd'
, 'dnd:didEnd'
, 'dnd:didCancel'
would not fire.
You can also create an instance with Aurelia Event Aggregator support. Use that sharedEa
to subscribe to events.
import {EventAggregator} from 'aurelia-event-aggregator';
const sharedEa = new EventAggregator();
const dndService = new DndService(sharedEa)
Published events through Aurelia Event Aggregator
dnd:willStart
just before starting of DnD session, allisProcessing
,model
,isHovering
… are stillundefined
.dnd:didStart
just after starting of DnD session, allisProcessing
,model
,isHovering
… have been set. But none of any targets receiveddndHover()
/dndDrop()
callback.dnd:willEnd
just before end of a DnD session, allisProcessing
,model
,isHovering
… are still set. Just before a target (if there is valid one with canDrop:true under the mouse) receivesdndDrop()
callback.dnd:didEnd
after a DnD session finished. allisProcessing
,model
, … are set toundefined
. FinaldndDrop()
callback has been fired if there is a valid target.dnd:didCancel
after a DnD session is cancelled by ESC key. allisProcessing
,model
, … are set toundefined
. NodndDrop()
callback will be called. None ofdnd:willEnd
anddnd:didEnd
events will be fired.
dndService.isProcessing
true
during a DnD session.undefined
when not in a DnD session.
dndService.model
- the
model
object cached from the result ofsourceDelegate.dndModel()
.undefined
when not in a DnD session.
dndService.addSource(delegate: SourceDelegate, options: SourceOptions)
- typically called inside Aurelia component’s
attached()
callback.
Source delegate
TypeScript type import { SourceDelegate } from 'bcx-aurelia-dnd';
- if
options.element
is absent,delegate.dndElement
must be a DOM element, used for source element. - if
options.element
is present,delegate.dndElement
is ignored,options.element
is used as source element. delegate.dndModel()
is mandatory. Called once, when DnD session starts. It needs to return a model describing the meaning of a drag. There is no requirement on the shape of returned model.delegate.dndCanDrag()
is optional. Checked when DnD session starts. If it returns falsy value, the Dnd session would not start from this source delegate. The session could still start from another source delegate whose DOM element is the parent (or ancestor) of this one, aka nested dnd sources.delegate.dndPreview(model)
is optional. Called once, when DnD session starts. It needs to return a newly created DOM element, with reasonable size, and not yet attached to DOM tree. Inputmodel
is the cached result ofsourceDelegate.dndModel()
. It could also return null or undefined, in that case,DndService
will fall back to use default preview.- if
options.noPreview
is true,delegate.dndPreview(model)
is ignored.
dnd property on source delegate
TypeScript type import { SourceDelegateInjectedDnd } from 'bcx-aurelia-dnd';
dnd
property was filled or created (if does not exist) for every source delegate bydndService
.delegate.dnd.isProcessing
exactly same asdndService.isProcessing
.delegate.dnd.isStartingSource
a boolean. During a DnD session, it’strue
for the DnD source that the DnD session was started with, false for every other DnD sources..
Source options (optional)
TypeScript type import { SourceOptions } from 'bcx-aurelia-dnd';
options.element
manually pass a DOM element as source element, instead of defaultdelegate.dndElement
.options.handler
a DOM element as drag handler. It should be a decedent of source element. It limits where drag can start, doesn’t affect preview.options.noPreview
turn off preview.options.hideCursor
hide cursor during a DnD session.options.centerPreviewToMousePosition
center preview to mouse position. Default preview position is aligned to source element top left corner.
dndService.addTarget(delegate: TargetDelegate, options: TargetOptions)
- typically called inside Aurelia component’s
attached()
callback.
Target delegate
TypeScript type import { TargetDelegate } from 'bcx-aurelia-dnd';
- if
options.element
is absent,delegate.dndElement
must be a DOM element, used for target element. - if
options.element
is present,delegate.dndElement
is ignored,options.element
is used as target element. delegate.dndCanDrop(model)
, mandatory. Called once, when DnD session starts. Inputmodel
is the cached result ofsourceDelegate.dndModel()
.delegate.dndDrop(location)
, mandatory. Called once, when DnD session ends (mouse released) on target element anddelegate.dnd.canDrop
is true.delegate.dndHover(location)
, optional. Called every time mouse moves during a DnD session, whendelegate.dnd.canDrop
is true and eitherdelegate.dnd.isHovering
ordelegate.dnd.isHoveringShallowly
is true.- When two (or more) target elements overlap, and both have
delegate.dnd.canDrop
true,dndHover()
could be called on both target delegates at same time, butdndDrop()
would be only called on the top target.
dnd property on target delegate
TypeScript type import { TargetDelegateInjectedDnd } from 'bcx-aurelia-dnd';
dnd
property was filled or created (if does not exist) for every target delegate bydndService
.delegate.dnd.isProcessing
exactly same asdndService.isProcessing
.delegate.dnd.model
exactly same asdndService.model
.delegate.dnd.canDrop
cached result ofdelegate.dndCanDrop(model)
.undefined
when not in a DnD session.delegate.dnd.isHoveringShallowly
true
when mouse is hovering directly over target element.undefined
when not in a DnD session.delegate.dnd.isHovering
true
when mouse is hovering within target element region.undefined
when not in a DnD session.
Target options (optional)
TypeScript type import { TargetOptions } from 'bcx-aurelia-dnd';
options.element
, manually pass a DOM element as target element, instead of defaultdelegate.dndElement
.
Location payload for dndHover(location: DndLocation) and dndDrop(location: DndLocation)
TypeScript type import { DndLocation } from 'bcx-aurelia-dnd';
location.mouseStartAt
drag start mouse location {x, y} (not {left, top}).location.mouseEndAt
drop end mouse location {x, y} fordndDrop()
, or current mouse location fordndHover()
.location.sourceElementRect
source element location and size {x, y, width, height}.location.previewElementRect
preview element location and size {x, y, width, height}.location.targetElementRect
target element location and size {x, y, width, height}.
All
x
andy
, are page offset (relative to whole HTML body), not client offset (relative to browser current view-port). Page offset is stabler to use than client offset, especially when there is scrolling or browser zooming.
For convenience,
previewElementRect
always presents. Even if you turn off the preview, it still reports location and size as if you were using default preview.
sourceElementRect
is not current location of source element. It is a cached location for the source element when DnD session started.
dndService.removeSource(delegateOrElement: SourceDelegate | Element) and dndService.removeTarget(delegateOrElement: TargetDelegate | Element)
- typically called inside Aurelia component’s
detached()
callback.