{"_id":"@chubkoiv/ngx-drag-drop","_rev":"3-637dbf8f9afe3dc789b87a182c348004","name":"@chubkoiv/ngx-drag-drop","dist-tags":{"latest":"21.0.0"},"versions":{"18.0.2":{"name":"@chubkoiv/ngx-drag-drop","version":"18.0.2","keywords":["angular","html","drag","drop","dragdrop","dragndrop","dnd","directive","touch"],"author":{"name":"Stefan Steinhart","email":"stefanreppner@googlemail.com"},"license":"BSD-3-Clause","_id":"@chubkoiv/ngx-drag-drop@18.0.2","maintainers":[{"name":"chubkoiv","email":"chubkoiv@gmail.com"}],"contributors":[{"name":"Christof Fritz","email":"npm@christof.me"}],"homepage":"https://reppners.github.io/ngx-drag-drop/","bugs":{"url":"https://github.com/reppners/ngx-drag-drop/issues"},"dist":{"shasum":"cad618bc0c15e3ab87ccf583b51ca13555a9c789","tarball":"https://registry.npmjs.org/@chubkoiv/ngx-drag-drop/-/ngx-drag-drop-18.0.2.tgz","fileCount":13,"integrity":"sha512-oY3woR4txly+OYkWIXGzdu9XbHEZyUtKbBOp7oW5H1QfsIcV3A3GZKsZcRbkDrLNlz8aBIl2FVjwZsVymedZSw==","signatures":[{"sig":"MEUCIC5voBoGkrsP9uebexR11PBfyTsJ8V1dxWUWYSgdlM1FAiEAiIWfGzHapOaNU4xVfoJrmZ9rBCM86K2hBnImFZH5av8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":103951},"module":"fesm2022/chubkoiv-ngx-drag-drop.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/chubkoiv-ngx-drag-drop.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"afbcf717caeb849bc86b39806a2ef6318b386fc6","typings":"index.d.ts","_npmUser":{"name":"chubkoiv","email":"chubkoiv@gmail.com"},"repository":{"url":"git+https://github.com/reppners/ngx-drag-drop.git","type":"git"},"_npmVersion":"10.8.2","description":"Angular directives using the native HTML Drag And Drop API","directories":{},"sideEffects":false,"_nodeVersion":"20.18.2","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":"^18.0.0","@angular/common":"^18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ngx-drag-drop_18.0.2_1738090397638_0.9437118833196927","host":"s3://npm-registry-packages-npm-production"}},"19.0.0":{"name":"@chubkoiv/ngx-drag-drop","version":"19.0.0","keywords":["angular","html","drag","drop","dragdrop","dragndrop","dnd","directive","touch"],"author":{"name":"Stefan Steinhart","email":"stefanreppner@googlemail.com"},"license":"BSD-3-Clause","_id":"@chubkoiv/ngx-drag-drop@19.0.0","maintainers":[{"name":"chubkoiv","email":"chubkoiv@gmail.com"}],"contributors":[{"name":"Christof Fritz","email":"npm@christof.me"}],"homepage":"https://reppners.github.io/ngx-drag-drop/","bugs":{"url":"https://github.com/reppners/ngx-drag-drop/issues"},"dist":{"shasum":"29c64890a45579d8d520f443be6225003c1b2d4b","tarball":"https://registry.npmjs.org/@chubkoiv/ngx-drag-drop/-/ngx-drag-drop-19.0.0.tgz","fileCount":13,"integrity":"sha512-kHc2b0wo/N0ey6LP3TUaNMaKYJrP6LDDBOVUdK3ehIMrEbPQjqpZibcwlREbVKgqPxtlCp38tWXWTp9tlX8MKg==","signatures":[{"sig":"MEQCIBw6VS71+YSvwVCRFZFQM0tphrchuNiRh2fgtNaqMQgSAiB7nmFG86eYzxlFg1jFmDRDrqTyBLXCieGUBkbS3FKusg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":103951},"module":"fesm2022/chubkoiv-ngx-drag-drop.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/chubkoiv-ngx-drag-drop.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"7b01473fa979da433c556ab38e07acbf17580066","typings":"index.d.ts","_npmUser":{"name":"chubkoiv","email":"chubkoiv@gmail.com"},"repository":{"url":"git+https://github.com/reppners/ngx-drag-drop.git","type":"git"},"_npmVersion":"10.8.2","description":"Angular directives using the native HTML Drag And Drop API","directories":{},"sideEffects":false,"_nodeVersion":"20.18.2","dependencies":{"tslib":"^2.3.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":"^19.0.0","@angular/common":"^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ngx-drag-drop_19.0.0_1738091341116_0.7913324785613984","host":"s3://npm-registry-packages-npm-production"}},"21.0.0":{"name":"@chubkoiv/ngx-drag-drop","version":"21.0.0","description":"Angular directives using the native HTML Drag And Drop API","repository":{"type":"git","url":"git+https://github.com/reppners/ngx-drag-drop.git"},"homepage":"https://reppners.github.io/ngx-drag-drop/","author":{"name":"Stefan Steinhart","email":"stefanreppner@googlemail.com"},"contributors":[{"name":"Christof Fritz","email":"npm@christof.me"}],"license":"BSD-3-Clause","keywords":["angular","html","drag","drop","dragdrop","dragndrop","dnd","directive","touch"],"peerDependencies":{"@angular/common":"^21.0.0","@angular/core":"^21.0.0"},"dependencies":{"tslib":"^2.3.0"},"module":"fesm2022/chubkoiv-ngx-drag-drop.mjs","typings":"types/chubkoiv-ngx-drag-drop.d.ts","exports":{"./package.json":{"default":"./package.json"},".":{"types":"./types/chubkoiv-ngx-drag-drop.d.ts","default":"./fesm2022/chubkoiv-ngx-drag-drop.mjs"}},"sideEffects":false,"gitHead":"0b1e2ad89cc2963ee0dce9762a5e312f700b12f9","_id":"@chubkoiv/ngx-drag-drop@21.0.0","bugs":{"url":"https://github.com/reppners/ngx-drag-drop/issues"},"_nodeVersion":"22.16.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-BFkbmLaL6a0dZj84LbCQT9ufvIyIsopKw4iwWpqzRtUeYEBZRPI3nPS/lkUxf5W9qVjJAOnpRgDrO497Vb8bcw==","shasum":"762b00fa8ab440ba1c77b8d390b4e9bf8dda6cb3","tarball":"https://registry.npmjs.org/@chubkoiv/ngx-drag-drop/-/ngx-drag-drop-21.0.0.tgz","fileCount":5,"unpackedSize":100705,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICqDhW5relAZsPz6sT2QYNoP7arLk6CfpWdk3wggPQ1iAiEA0s01dxNh/aH9tTWsINwlvZZjXgaHCvZlAbzcBzA6z5g="}]},"_npmUser":{"name":"chubkoiv","email":"chubkoiv@gmail.com"},"directories":{},"maintainers":[{"name":"chubkoiv","email":"chubkoiv@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ngx-drag-drop_21.0.0_1773815174250_0.9563909209753794"},"_hasShrinkwrap":false}},"time":{"created":"2025-01-28T18:53:17.502Z","modified":"2026-03-18T06:26:14.484Z","18.0.2":"2025-01-28T18:53:17.812Z","19.0.0":"2025-01-28T19:09:01.285Z","21.0.0":"2026-03-18T06:26:14.384Z"},"bugs":{"url":"https://github.com/reppners/ngx-drag-drop/issues"},"author":{"name":"Stefan Steinhart","email":"stefanreppner@googlemail.com"},"license":"BSD-3-Clause","homepage":"https://reppners.github.io/ngx-drag-drop/","keywords":["angular","html","drag","drop","dragdrop","dragndrop","dnd","directive","touch"],"repository":{"type":"git","url":"git+https://github.com/reppners/ngx-drag-drop.git"},"description":"Angular directives using the native HTML Drag And Drop API","contributors":[{"name":"Christof Fritz","email":"npm@christof.me"}],"maintainers":[{"name":"chubkoiv","email":"chubkoiv@gmail.com"}],"readme":"[![npm](https://img.shields.io/npm/v/ngx-drag-drop.svg)](https://www.npmjs.com/package/ngx-drag-drop)\r\n[![npm (next)](https://img.shields.io/npm/v/ngx-drag-drop/next.svg)](https://www.npmjs.com/package/ngx-drag-drop)\r\n[![NpmLicense](https://img.shields.io/npm/l/ngx-drag-drop.svg)](https://www.npmjs.com/package/ngx-drag-drop)\r\n[![GitHub issues](https://img.shields.io/github/issues/reppners/ngx-drag-drop.svg)](https://github.com/reppners/ngx-drag-drop/issues)\r\n[![Twitter](https://img.shields.io/twitter/url/https/github.com/reppners/ngx-drag-drop.svg?style=social)](https://twitter.com/intent/tweet?text=Angular%20drag%20and%20drop%20with%20ease:&url=https://github.com/reppners/ngx-drag-drop)\r\n\r\n# NgxDragDrop\r\n\r\n[_Demo_](https://reppners.github.io/ngx-drag-drop/) / [_StackBlitz Issue\r\nTemplate_](https://stackblitz.com/edit/ngx-drag-drop-issue-template)\r\n\r\n`npm install ngx-drag-drop --save`\r\n\r\n**Angular directives for declarative drag and drop using the HTML5 Drag-And-Drop API**\r\n\r\n- sortable lists by using placeholder element (vertical and horizontal)\r\n- nestable\r\n- dropzones optionally support external/native draggables (img, txt, file)\r\n- conditional drag/drop\r\n- typed drag/drop\r\n- utilize [EffectAllowed](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/effectAllowed)\r\n- custom CSS classes\r\n- touch support by using a [polyfill](#touch-support)\r\n- [AOT](https://angular.io/guide/aot-compiler) compatible\r\n\r\nPort of [angular-drag-drop-lists](https://github.com/marceljuenemann/angular-drag-and-drop-lists) but without the lists :wink:\r\n\r\nThis has `dropzones` though :+1:\r\nThe idea is that the directive does not handle lists internally so the `dndDropzone` can be general purpose.\r\n\r\n## Usage\r\n\r\n`app.component.html`\r\n\r\n```HTML\r\n<!--a draggable element-->\r\n<div\r\n  [dndDraggable]=\"draggable.data\"\r\n  [dndEffectAllowed]=\"draggable.effectAllowed\"\r\n  [dndDisableIf]=\"draggable.disable\"\r\n  (dndStart)=\"onDragStart($event)\"\r\n  (dndCopied)=\"onDraggableCopied($event)\"\r\n  (dndLinked)=\"onDraggableLinked($event)\"\r\n  (dndMoved)=\"onDraggableMoved($event)\"\r\n  (dndCanceled)=\"onDragCanceled($event)\"\r\n  (dndEnd)=\"onDragEnd($event)\">\r\n\r\n  <!--if [dndHandle] is used inside dndDraggable drag can only start from the handle-->\r\n  <div\r\n    *ngIf=\"draggable.handle\"\r\n    dndHandle>HANDLE\r\n  </div>\r\n\r\n  draggable ({{draggable.effectAllowed}}) <span [hidden]=\"!draggable.disable\">DISABLED</span>\r\n\r\n  <!--optionally select a child element as drag image-->\r\n  <div dndDragImageRef>DRAG_IMAGE</div>\r\n\r\n</div>\r\n\r\n<!--a dropzone-->\r\n<!--to allow dropping content that is not [dndDraggable] set dndAllowExternal to true-->\r\n<section\r\n  dndDropzone\r\n  (dndDragover)=\"onDragover($event)\"\r\n  (dndDrop)=\"onDrop($event)\">\r\n\r\n  dropzone\r\n\r\n  <!--optional placeholder element for dropzone-->\r\n  <!--will be removed from DOM on init-->\r\n  <div\r\n    style=\"border: 1px orangered solid; border-radius: 5px; padding: 15px;\"\r\n    dndPlaceholderRef>\r\n    placeholder\r\n  </div>\r\n\r\n</section>\r\n```\r\n\r\n`app.component`\r\n\r\n```JS\r\nimport {Component} from '@angular/core';\r\n\r\nimport {DndDropEvent} from 'ngx-drag-drop';\r\n\r\n@Component()\r\nexport class AppComponent {\r\n\r\n  draggable = {\r\n    // note that data is handled with JSON.stringify/JSON.parse\r\n    // only set simple data or POJO's as methods will be lost\r\n    data: \"myDragData\",\r\n    effectAllowed: \"all\",\r\n    disable: false,\r\n    handle: false\r\n  };\r\n\r\n  onDragStart(event: DragEvent) {\r\n\r\n    console.log(\"drag started\", JSON.stringify(event, null, 2));\r\n  }\r\n\r\n  onDragEnd(event: DragEvent) {\r\n\r\n    console.log(\"drag ended\", JSON.stringify(event, null, 2));\r\n  }\r\n\r\n  onDraggableCopied(event: DragEvent) {\r\n\r\n    console.log(\"draggable copied\", JSON.stringify(event, null, 2));\r\n  }\r\n\r\n  onDraggableLinked(event: DragEvent) {\r\n\r\n    console.log(\"draggable linked\", JSON.stringify(event, null, 2));\r\n  }\r\n\r\n  onDraggableMoved(event: DragEvent) {\r\n\r\n    console.log(\"draggable moved\", JSON.stringify(event, null, 2));\r\n  }\r\n\r\n  onDragCanceled(event: DragEvent) {\r\n\r\n    console.log(\"drag cancelled\", JSON.stringify(event, null, 2));\r\n  }\r\n\r\n  onDragover(event: DragEvent) {\r\n\r\n    console.log(\"dragover\", JSON.stringify(event, null, 2));\r\n  }\r\n\r\n  onDrop(event: DndDropEvent) {\r\n\r\n    console.log(\"dropped\", JSON.stringify(event, null, 2));\r\n  }\r\n}\r\n```\r\n\r\n`app.module`\r\n\r\n```JS\r\nimport {BrowserModule} from '@angular/platform-browser';\r\nimport {NgModule} from '@angular/core';\r\n\r\nimport {DndModule} from 'ngx-drag-drop';\r\n\r\nimport {AppComponent} from './app.component';\r\n\r\n@NgModule({\r\n  declarations: [\r\n    AppComponent\r\n  ],\r\n  imports: [\r\n    BrowserModule,\r\n    DndModule\r\n  ],\r\n  providers: [],\r\n  bootstrap: [AppComponent]\r\n})\r\nexport class AppModule {\r\n}\r\n```\r\n\r\n## API\r\n\r\n```TS\r\n// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/dropEffect\r\nexport type DropEffect = \"move\" | \"copy\" | \"link\" | \"none\";\r\n\r\n// https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/effectAllowed\r\nexport type EffectAllowed = DropEffect | \"copyMove\" | \"copyLink\" | \"linkMove\" | \"all\";\r\n```\r\n\r\n```TS\r\nexport type DndDragImageOffsetFunction = ( event:DragEvent, dragImage:Element ) => { x:number, y:number };\r\n\r\n@Directive( {\r\n  selector: \"[dndDraggable]\"\r\n} )\r\nexport declare class DndDraggableDirective {\r\n\r\n    // the data attached to the drag\r\n    dndDraggable: any;\r\n\r\n    // the allowed drop effect\r\n    dndEffectAllowed: EffectAllowed;\r\n\r\n    // optionally set the type of dragged data to restrict dropping on compatible dropzones\r\n    dndType?: string;\r\n\r\n    // conditionally disable the draggability\r\n    dndDisableIf: boolean;\r\n    dndDisableDragIf: boolean;\r\n\r\n    // set a custom class that is applied while dragging\r\n    dndDraggingClass: string = \"dndDragging\";\r\n\r\n    // set a custom class that is applied to only the src element while dragging\r\n    dndDraggingSourceClass: string = \"dndDraggingSource\";\r\n\r\n    // set the class that is applied when draggable is disabled by [dndDisableIf]\r\n    dndDraggableDisabledClass = \"dndDraggableDisabled\";\r\n\r\n    // enables to set a function for calculating custom dragimage offset\r\n    dndDragImageOffsetFunction:DndDragImageOffsetFunction = calculateDragImageOffset;\r\n\r\n    // emits on drag start\r\n    readonly dndStart: EventEmitter<DragEvent>;\r\n\r\n    // emits on drag\r\n    readonly dndDrag: EventEmitter<DragEvent>;\r\n\r\n    // emits on drag end\r\n    readonly dndEnd: EventEmitter<DragEvent>;\r\n\r\n    // emits when the dragged item has been dropped with effect \"move\"\r\n    readonly dndMoved: EventEmitter<DragEvent>;\r\n\r\n    // emits when the dragged item has been dropped with effect \"copy\"\r\n    readonly dndCopied: EventEmitter<DragEvent>;\r\n\r\n    // emits when the dragged item has been dropped with effect \"link\"\r\n    readonly dndLinked: EventEmitter<DragEvent>;\r\n\r\n    // emits when the drag is canceled\r\n    readonly dndCanceled: EventEmitter<DragEvent>;\r\n}\r\n```\r\n\r\n```TS\r\nexport interface DndDropEvent {\r\n\r\n    // the original drag event\r\n    event: DragEvent;\r\n\r\n    // the actual drop effect\r\n    dropEffect: DropEffect;\r\n\r\n    // true if the drag did not origin from a [dndDraggable]\r\n    isExternal:boolean;\r\n\r\n    // the data set on the [dndDraggable] that started the drag\r\n    // for external drags use the event property which contains the original drop event as this will be undefined\r\n    data?: any;\r\n\r\n    // the index where the draggable was dropped in a dropzone\r\n    // set only when using a placeholder\r\n    index?: number;\r\n\r\n    // if the dndType input on dndDraggable was set\r\n    // it will be transported here\r\n    type?: any;\r\n}\r\n\r\n@Directive( {\r\n  selector: \"[dndDropzone]\"\r\n} )\r\nexport declare class DndDropzoneDirective {\r\n\r\n    // optionally restrict the allowed types\r\n    dndDropzone?: string[];\r\n\r\n    // set the allowed drop effect\r\n    dndEffectAllowed: EffectAllowed;\r\n\r\n    // conditionally disable the dropzone\r\n    dndDisableIf: boolean;\r\n    dndDisableDropIf: boolean;\r\n\r\n    // if draggables that are not [dndDraggable] are allowed to be dropped\r\n    // set to true if dragged text, images or files should be handled\r\n    dndAllowExternal: boolean;\r\n\r\n    // if its a horizontal list this influences how the placeholder position\r\n    // is calculated\r\n    dndHorizontal: boolean;\r\n\r\n    // set the class applied to the dropzone\r\n    // when a draggable is dragged over it\r\n    dndDragoverClass: string = \"dndDragover\";\r\n\r\n    // set the class applied to the dropzone\r\n    // when the dropzone is disabled by [dndDisableIf]\r\n    dndDropzoneDisabledClass = \"dndDropzoneDisabled\";\r\n\r\n    // emits when a draggable is dragged over the dropzone\r\n    readonly dndDragover: EventEmitter<DragEvent>;\r\n\r\n    // emits on successful drop\r\n    readonly dndDrop: EventEmitter<DndDropEvent>;\r\n}\r\n```\r\n\r\n## Touch support\r\n\r\nInstall the `mobile-drag-drop` module available on npm.\r\n\r\nAdd the following lines to your js code\r\n\r\n```JS\r\nimport { polyfill } from 'mobile-drag-drop';\r\n// optional import of scroll behaviour\r\nimport { scrollBehaviourDragImageTranslateOverride } from \"mobile-drag-drop/scroll-behaviour\";\r\n\r\npolyfill( {\r\n  // use this to make use of the scroll behaviour\r\n  dragImageTranslateOverride: scrollBehaviourDragImageTranslateOverride\r\n} );\r\n\r\n// workaround to make scroll prevent work in iOS Safari > 10\r\ntry {\r\n  window.addEventListener( \"touchmove\", function() { }, { passive: false } );\r\n}\r\ncatch(e){}\r\n```\r\n\r\nFor more info on the polyfill check it out on GitHub\r\nhttps://github.com/timruffles/mobile-drag-drop\r\n\r\n## Known issues\r\n\r\n### Firefox\r\n\r\n- Beware that Firefox does not support dragging on `<button>` elements.\r\n  - `<button [dndDraggable]>` and `<button [dndHandler]>` won't work.\r\n  - See https://bugzilla.mozilla.org/show_bug.cgi?id=568313\r\n\r\n## Why?\r\n\r\nHTML Drag-And-Drop API implementations are not behaving the same way across browsers.\r\n\r\nThe directives contained in this module enable declarative drag and drop that \"just works\" across browsers in a consistent way.\r\n\r\nCredits go to the author and contributors of [angular-drag-drop-lists](https://github.com/marceljuenemann/angular-drag-and-drop-lists).\r\n","readmeFilename":"README.md"}