Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
ngx-drag-drop
Advanced tools
Demo / StackBlitz Issue Template
npm install ngx-drag-drop --save
Angular directives for declarative drag and drop using the HTML5 Drag-And-Drop API
Port of angular-drag-drop-lists but without the lists :wink:
This has dropzones
though :+1:
The idea is that the directive does not handle lists internally so the dndDropzone
can be general purpose.
app.component.html
<!--a draggable element-->
<div
[dndDraggable]="draggable.data"
[dndEffectAllowed]="draggable.effectAllowed"
[dndDisableIf]="draggable.disable"
(dndStart)="onDragStart($event)"
(dndCopied)="onDraggableCopied($event)"
(dndLinked)="onDraggableLinked($event)"
(dndMoved)="onDraggableMoved($event)"
(dndCanceled)="onDragCanceled($event)"
(dndEnd)="onDragEnd($event)">
<!--if [dndHandle] is used inside dndDraggable drag can only start from the handle-->
<div
*ngIf="draggable.handle"
dndHandle>HANDLE
</div>
draggable ({{draggable.effectAllowed}}) <span [hidden]="!draggable.disable">DISABLED</span>
<!--optionally select a child element as drag image-->
<div dndDragImageRef>DRAG_IMAGE</div>
</div>
<!--a dropzone-->
<!--to allow dropping content that is not [dndDraggable] set dndAllowExternal to true-->
<section
dndDropzone
(dndDragover)="onDragover($event)"
(dndDrop)="onDrop($event)">
dropzone
<!--optional placeholder element for dropzone-->
<!--will be removed from DOM on init-->
<div
style="border: 1px orangered solid; border-radius: 5px; padding: 15px;"
dndPlaceholderRef>
placeholder
</div>
</section>
app.component
import {Component} from '@angular/core';
import {DndDropEvent} from 'ngx-drag-drop';
@Component()
export class AppComponent {
draggable = {
// note that data is handled with JSON.stringify/JSON.parse
// only set simple data or POJO's as methods will be lost
data: "myDragData",
effectAllowed: "all",
disable: false,
handle: false
};
onDragStart(event: DragEvent) {
console.log("drag started", JSON.stringify(event, null, 2));
}
onDragEnd(event: DragEvent) {
console.log("drag ended", JSON.stringify(event, null, 2));
}
onDraggableCopied(event: DragEvent) {
console.log("draggable copied", JSON.stringify(event, null, 2));
}
onDraggableLinked(event: DragEvent) {
console.log("draggable linked", JSON.stringify(event, null, 2));
}
onDraggableMoved(event: DragEvent) {
console.log("draggable moved", JSON.stringify(event, null, 2));
}
onDragCanceled(event: DragEvent) {
console.log("drag cancelled", JSON.stringify(event, null, 2));
}
onDragover(event: DragEvent) {
console.log("dragover", JSON.stringify(event, null, 2));
}
onDrop(event: DndDropEvent) {
console.log("dropped", JSON.stringify(event, null, 2));
}
}
app.module
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {DndModule} from 'ngx-drag-drop';
import {AppComponent} from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
DndModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect
export type DropEffect = "move" | "copy" | "link" | "none";
// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/effectAllowed
export type EffectAllowed = DropEffect | "copyMove" | "copyLink" | "linkMove" | "all";
export type DndDragImageOffsetFunction = ( event:DragEvent, dragImage:Element ) => { x:number, y:number };
@Directive( {
selector: "[dndDraggable]"
} )
export declare class DndDraggableDirective {
// the data attached to the drag
dndDraggable: any;
// the allowed drop effect
dndEffectAllowed: EffectAllowed;
// optionally set the type of dragged data to restrict dropping on compatible dropzones
dndType?: string;
// conditionally disable the draggability
dndDisableIf: boolean;
dndDisableDragIf: boolean;
// set a custom class that is applied while dragging
dndDraggingClass: string = "dndDragging";
// set a custom class that is applied to only the src element while dragging
dndDraggingSourceClass: string = "dndDraggingSource";
// set the class that is applied when draggable is disabled by [dndDisableIf]
dndDraggableDisabledClass = "dndDraggableDisabled";
// enables to set a function for calculating custom dragimage offset
dndDragImageOffsetFunction:DndDragImageOffsetFunction = calculateDragImageOffset;
// emits on drag start
readonly dndStart: EventEmitter<DragEvent>;
// emits on drag
readonly dndDrag: EventEmitter<DragEvent>;
// emits on drag end
readonly dndEnd: EventEmitter<DragEvent>;
// emits when the dragged item has been dropped with effect "move"
readonly dndMoved: EventEmitter<DragEvent>;
// emits when the dragged item has been dropped with effect "copy"
readonly dndCopied: EventEmitter<DragEvent>;
// emits when the dragged item has been dropped with effect "link"
readonly dndLinked: EventEmitter<DragEvent>;
// emits when the drag is canceled
readonly dndCanceled: EventEmitter<DragEvent>;
}
export interface DndDropEvent {
// the original drag event
event: DragEvent;
// the actual drop effect
dropEffect: DropEffect;
// true if the drag did not origin from a [dndDraggable]
isExternal:boolean;
// the data set on the [dndDraggable] that started the drag
// for external drags use the event property which contains the original drop event as this will be undefined
data?: any;
// the index where the draggable was dropped in a dropzone
// set only when using a placeholder
index?: number;
// if the dndType input on dndDraggable was set
// it will be transported here
type?: any;
}
@Directive( {
selector: "[dndDropzone]"
} )
export declare class DndDropzoneDirective {
// optionally restrict the allowed types
dndDropzone?: string[];
// set the allowed drop effect
dndEffectAllowed: EffectAllowed;
// conditionally disable the dropzone
dndDisableIf: boolean;
dndDisableDropIf: boolean;
// if draggables that are not [dndDraggable] are allowed to be dropped
// set to true if dragged text, images or files should be handled
dndAllowExternal: boolean;
// if its a horizontal list this influences how the placeholder position
// is calculated
dndHorizontal: boolean;
// set the class applied to the dropzone
// when a draggable is dragged over it
dndDragoverClass: string = "dndDragover";
// set the class applied to the dropzone
// when the dropzone is disabled by [dndDisableIf]
dndDropzoneDisabledClass = "dndDropzoneDisabled";
// emits when a draggable is dragged over the dropzone
readonly dndDragover: EventEmitter<DragEvent>;
// emits on successful drop
readonly dndDrop: EventEmitter<DndDropEvent>;
}
Install the mobile-drag-drop
module available on npm.
Add the following lines to your js code
import { polyfill } from 'mobile-drag-drop';
// optional import of scroll behaviour
import { scrollBehaviourDragImageTranslateOverride } from "mobile-drag-drop/scroll-behaviour";
polyfill( {
// use this to make use of the scroll behaviour
dragImageTranslateOverride: scrollBehaviourDragImageTranslateOverride
} );
// workaround to make scroll prevent work in iOS Safari > 10
try {
window.addEventListener( "touchmove", function() { }, { passive: false } );
}
catch(e){}
For more info on the polyfill check it out on GitHub https://github.com/timruffles/mobile-drag-drop
<button>
elements.
<button [dndDraggable]>
and <button [dndHandler]>
won't work.HTML Drag-And-Drop API implementations are not behaving the same way across browsers.
The directives contained in this module enable declarative drag and drop that "just works" across browsers in a consistent way.
Credits go to the author and contributors of angular-drag-drop-lists.
FAQs
Angular directives using the native HTML Drag And Drop API
The npm package ngx-drag-drop receives a total of 32,834 weekly downloads. As such, ngx-drag-drop popularity was classified as popular.
We found that ngx-drag-drop demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.