{"_id":"@bitboss-dev/vue-dnd","_rev":"3-df252914b4d2c1c8140c18b722f1090a","name":"@bitboss-dev/vue-dnd","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.0":{"name":"@bitboss-dev/vue-dnd","version":"0.0.0","_id":"@bitboss-dev/vue-dnd@0.0.0","maintainers":[{"name":"bitboss-service","email":"service@bitboss.it"},{"name":"gianluigil","email":"gianluigi@bitboss.it"}],"dist":{"shasum":"5e75d96a5b04d3ee250254c57df31292837f5388","tarball":"https://registry.npmjs.org/@bitboss-dev/vue-dnd/-/vue-dnd-0.0.0.tgz","fileCount":16,"integrity":"sha512-osfsqN1KyHK0NYSFgki/+UDiQYRh/J3LonumVc4OXOJfu3KfmQ4YlLd2K+Q+ihVH1GKZTpale3qYQ3W1vpzP1A==","signatures":[{"sig":"MEQCID0Cps7I9IrAMfItdFBhIjShvw1GMWwy3kp2k+YloIMdAiAeUcEljudXIbKLou5ez2Vj04MaowS3JvNb89bAYzjJ2w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18287},"type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"3fd721c00fb64b014f414a4b961a35a0b8441e40","private":false,"scripts":{"dev":"vite","lint":"eslint . --fix","build":"run-p type-check \"build-only {@}\" --","format":"prettier --write src/","preview":"vite preview","test:e2e":"playwright test","test:unit":"vitest","build-only":"vite build","type-check":"vue-tsc --build"},"_npmUser":{"name":"gianluigil","email":"gianluigi@bitboss.it"},"_npmVersion":"10.8.3","description":"A lightweight **(4kb)**, performant drag and drop library for Vue 3.","directories":{},"_nodeVersion":"22.9.0","dependencies":{"vue":"^3.5.17","mitt":"^3.0.1"},"_hasShrinkwrap":false,"devDependencies":{"jiti":"^2.4.2","vite":"^7.0.0","jsdom":"^26.1.0","eslint":"^9.29.0","vitest":"^3.2.4","vue-tsc":"^2.2.10","prettier":"3.5.3","typescript":"~5.8.0","@types/node":"^22.15.32","tailwindcss":"^4.1.11","@types/jsdom":"^21.1.7","npm-run-all2":"^8.0.4","@vue/tsconfig":"^0.7.0","@vue/test-utils":"^2.4.6","vite-plugin-dts":"^4.5.4","@playwright/test":"^1.53.1","@tsconfig/node22":"^22.0.2","@tailwindcss/vite":"^4.1.11","eslint-plugin-vue":"~10.2.0","@vitejs/plugin-vue":"^6.0.0","@vitest/eslint-plugin":"^1.2.7","eslint-plugin-playwright":"^2.2.0","vite-plugin-vue-devtools":"^7.7.7","@vue/eslint-config-prettier":"^10.2.0","@vue/eslint-config-typescript":"^14.5.1"},"_npmOperationalInternal":{"tmp":"tmp/vue-dnd_0.0.0_1752848469306_0.06485701301554214","host":"s3://npm-registry-packages-npm-production"}},"0.0.1":{"name":"@bitboss-dev/vue-dnd","version":"0.0.1","_id":"@bitboss-dev/vue-dnd@0.0.1","maintainers":[{"name":"bitboss-service","email":"service@bitboss.it"},{"name":"gianluigil","email":"gianluigi@bitboss.it"}],"dist":{"shasum":"bc24dc38909fbb4a22000a7854b33866f324fb0d","tarball":"https://registry.npmjs.org/@bitboss-dev/vue-dnd/-/vue-dnd-0.0.1.tgz","fileCount":17,"integrity":"sha512-dTrihW1J2pdwKu1VOwfGVCTmLq7/XA6s/KIzfWlvMb2npm3jbqJbT1PZ80jMgP1GaF6LNTEU0sVSyNSXQL3tOQ==","signatures":[{"sig":"MEUCIE27vfEXVXvt9zw89fuX2WZEu/sj25KT1IHTOipr3lBjAiEAloy6syXhL5mDU/c2HqGTprhOvj/blEtwz75zOAwV3Ug=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":21214},"type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"22c00faae7b7ad5059edcfd952269b780758cf7a","scripts":{"dev":"vite","lint":"eslint . --fix","build":"run-p type-check \"build-only {@}\" --","format":"prettier --write src/","preview":"vite preview","test:e2e":"playwright test","test:unit":"vitest","build-only":"vite build","type-check":"vue-tsc --build"},"_npmUser":{"name":"gianluigil","email":"gianluigi@bitboss.it"},"_npmVersion":"10.8.3","description":"A lightweight **(4kb)**, performant drag and drop library for Vue 3.","directories":{},"_nodeVersion":"22.9.0","dependencies":{"vue":"^3.5.17","mitt":"^3.0.1"},"_hasShrinkwrap":false,"devDependencies":{"jiti":"^2.4.2","vite":"^7.0.0","jsdom":"^26.1.0","eslint":"^9.29.0","vitest":"^3.2.4","vue-tsc":"^2.2.10","prettier":"3.5.3","typescript":"~5.8.0","@types/node":"^22.15.32","tailwindcss":"^4.1.11","@types/jsdom":"^21.1.7","npm-run-all2":"^8.0.4","@vue/tsconfig":"^0.7.0","@vue/test-utils":"^2.4.6","vite-plugin-dts":"^4.5.4","@playwright/test":"^1.53.1","@tsconfig/node22":"^22.0.2","@tailwindcss/vite":"^4.1.11","eslint-plugin-vue":"~10.2.0","@vitejs/plugin-vue":"^6.0.0","@vitest/eslint-plugin":"^1.2.7","eslint-plugin-playwright":"^2.2.0","vite-plugin-vue-devtools":"^7.7.7","@vue/eslint-config-prettier":"^10.2.0","@vue/eslint-config-typescript":"^14.5.1"},"_npmOperationalInternal":{"tmp":"tmp/vue-dnd_0.0.1_1753181431804_0.3581988493117758","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@bitboss-dev/vue-dnd","version":"0.0.2","type":"module","scripts":{"dev":"vite","build":"run-p type-check \"build-only {@}\" --","preview":"vite preview","test:unit":"vitest","test:e2e":"playwright test","build-only":"vite build","type-check":"vue-tsc --build","lint":"eslint . --fix","format":"prettier --write src/"},"dependencies":{"mitt":"^3.0.1","vue":"^3.5.17"},"devDependencies":{"@playwright/test":"^1.53.1","@tailwindcss/vite":"^4.1.11","@tsconfig/node22":"^22.0.2","@types/jsdom":"^21.1.7","@types/node":"^22.15.32","@vitejs/plugin-vue":"^6.0.0","@vitest/eslint-plugin":"^1.2.7","@vue/eslint-config-prettier":"^10.2.0","@vue/eslint-config-typescript":"^14.5.1","@vue/test-utils":"^2.4.6","@vue/tsconfig":"^0.7.0","eslint":"^9.29.0","eslint-plugin-playwright":"^2.2.0","eslint-plugin-vue":"~10.2.0","jiti":"^2.4.2","jsdom":"^26.1.0","npm-run-all2":"^8.0.4","prettier":"3.5.3","tailwindcss":"^4.1.11","typescript":"~5.8.0","vite":"^7.0.0","vite-plugin-dts":"^4.5.4","vite-plugin-vue-devtools":"^7.7.7","vitest":"^3.2.4","vue-tsc":"^2.2.10"},"exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"_id":"@bitboss-dev/vue-dnd@0.0.2","gitHead":"f7cf9b6a4892ffcc525dbf5208cf424f85dff583","description":"A lightweight **(4kb)**, performant drag and drop library for Vue 3.","_nodeVersion":"22.9.0","_npmVersion":"10.8.3","dist":{"integrity":"sha512-MdqYeSM8yI1nG50ap6B3cxrAAV2kgeqK09/2zbFfp7WxfmijDgCc4jvfbBCFmLhRze8rLTBWpsZMbNkkEBxWKg==","shasum":"3a807d96ba603a85d963ec461a5e97c560fbfcf6","tarball":"https://registry.npmjs.org/@bitboss-dev/vue-dnd/-/vue-dnd-0.0.2.tgz","fileCount":17,"unpackedSize":22942,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBF0ZRnYriCtA1LCTID3MgJlwgQUbmZu05BiLOXrRWTpAiANpOWdIVFeBbuYijS7Q/VS2D1NZmUb9R/faUGocLXdNw=="}]},"_npmUser":{"name":"gianluigil","email":"gianluigi@bitboss.it"},"directories":{},"maintainers":[{"name":"bitboss-service","email":"service@bitboss.it"},{"name":"gianluigil","email":"gianluigi@bitboss.it"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vue-dnd_0.0.2_1753195416592_0.1728735710857232"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-18T14:21:09.169Z","modified":"2025-07-22T14:43:36.970Z","0.0.0":"2025-07-18T14:21:09.483Z","0.0.1":"2025-07-22T10:50:32.016Z","0.0.2":"2025-07-22T14:43:36.781Z"},"description":"A lightweight **(4kb)**, performant drag and drop library for Vue 3.","maintainers":[{"name":"bitboss-service","email":"service@bitboss.it"},{"name":"gianluigil","email":"gianluigi@bitboss.it"}],"readme":"# Vue DnD\n\nA lightweight **(4kb)**, performant drag and drop library for Vue 3.\n\n## Features\n\n- 🚀 **Vue 3 & Composition API** - Built specifically for Vue 3 with script setup syntax\n- 📦 **TypeScript First** - Full TypeScript support with comprehensive type definitions\n- 🎯 **Namespace-based** - Avoid conflicts between separate drag operations. A subject within the `to-do-list` namespace will exclusively interact with events on targets sharing the same namespace. Seamlessly.\n- 🔄 **Deduplicated** - Built-in deduplication. Only the topmost element will receive the event but you can change that if you want.\n- 🎨 **Visual Feedback** - Built-in clone dragging with smooth animations\n- 🔧 **Flexible** - Make it as granular as you need.\n- 📱 **Touch Support** - Works on mobile devices with touch events\n\n## Installation\n\n```bash\nnpm install @bitboss-dev/vue-dnd\n```\n\n## Quick Start\n\n```vue\n<template>\n  <div class=\"app\">\n    <!-- Draggable Item -->\n    <div\n      ref=\"draggableItem\"\n      class=\"draggable-item\"\n      :class=\"{ 'draggable-item--dragging': isDragging }\"\n    >\n      Drag me!\n    </div>\n\n    <!-- Drop Zone -->\n    <div\n      ref=\"dropZone\"\n      class=\"drop-zone\"\n      :class=\"{ 'drag-zone--active': isOver }\"\n    >\n      Drop here\n    </div>\n  </div>\n</template>\n\n<script setup lang=\"ts\">\nimport { useTemplateRef } from 'vue'\nimport {\n  useDragSubject,\n  useDragTarget,\n  useDragClone,\n} from '@bitboss-dev/vue-dnd'\n\nconst draggableItem = useTemplateRef('draggableItem')\nconst dropZone = useTemplateRef('dropZone')\n\n// Set up drag subject (the element to be dragged)\nconst { isDragging, attributes } = useDragSubject(\n  draggableItem,\n  'my-drag-namespace'\n)\n\n// Set up drop target\nconst { isOver } = useDragTarget(dropZone, 'my-drag-namespace')\n\n// Create visual clone during drag\nuseDragClone(draggableItem, attributes)\n</script>\n```\n\n## Why and how\n\nThis library is designed for a straightforward task: dragging an item from point A to point B. Once you release the dragged item, everything resets. You can't continue dragging the item indefinitely; it either reaches the target or resets. This approach addresses the most basic use case.\n\nThe API is clear and easy to use.\n\nSteps to get started:\n\n- Define a namespace. For example, if you're dragging a user card into a contact list, use a `user-contacts` namespace.\n- Create a card to act as the draggable item and apply the composable with the specified namespace.\n- Set up a surface as the drop target and apply the composable with the same namespace.\n- That's it!\n\n## API Reference\n\n### `useDragAttributes` low level helper to track drag events.\n\nProvides reactive drag attributes and a basic flag. Useful for low-level drag tracking or custom drag-and-drop implementations.\n\n```typescript\nfunction useDragAttributes(\n  elementRef: MaybeRefOrGetter<unknown>,\n  options?: DragAttributesOptions\n): {\n  attributes: Ref<Attributes>\n  isDragging: Ref<boolean>\n}\n```\n\n#### Parameters\n\n- `elementRef` - Vue template ref or DOM element to track for pointer events.\n- `options` - Optional configuration object\n\n#### Options\n\n```typescript\ntype DragAttributesOptions = {\n  // when the element is unmounted clears all document event listeners.\n  // Set to false to continue dragging if the original container is removed\n  autoCleanup?: boolean\n  onPointerDown?: (event: PointerEvent) => void\n  onPointerMove?: (event: PointerEvent) => void\n  onPointerUp?: (event: PointerEvent) => void\n}\n```\n\n#### Returns\n\n- `attributes` - Reactive object containing position and size data\n- `isDragging` - Boolean indicating if element is currently being dragged\n\n### `useDragSubject` Creates a draggable element that can be dragged around the page.\n\nThe subject receives the same events of the target so you can act with the callbacks `onEnter`, `onOver`, `onLeave`, `onDrop`.\n\nEverything is lazy, no events are fired or listened to unless they are useful.\n\n```typescript\nfunction useDragSubject<T = unknown>(\n  elementRef: MaybeRefOrGetter<unknown>,\n  namespace: NameSpace,\n  item?: T,\n  options?: DragSubjectOptions<T>\n): {\n  attributes: Ref<Attributes> // See later definition\n  isDragging: Ref<boolean>\n  isOver: Ref<boolean>\n}\n```\n\n#### Parameters\n\n- `elementRef` - Vue template ref to the draggable element\n- `namespace` - Unique identifier that links the subject to its drop area.\n- `item` - Optional data to pass with drag events\n- `options` - Configuration options\n\n#### Options\n\n```typescript\ntype DragSubjectOptions<T = unknown> = {\n  /**\n   * Automatically cleans up event listeners when the element is unmounted.\n   * Set to false to keep listeners active even if the original container is removed.\n   * @default true\n   */\n  autoCleanup?: boolean\n\n  /**\n   * Callback function triggered when the draggable element enters a drop target.\n   * @param data  - The data associated with the drag event.\n   * @param event - The original event object.\n   */\n  onEnter?: ClientEventHandler<T>\n\n  /**\n   * Callback function triggered when the draggable element is moved over a drop target.\n   * @param data - The data associated with the drag event.\n   * @param event - The original event object.\n   */\n  onOver?: ClientEventHandler<T>\n\n  /**\n   * Callback function triggered when the draggable element is dropped on a drop target.\n   * @param data - The data associated with the drag event.\n   * @param event - The original event object.\n   */\n  onDrop?: ClientEventHandler<T>\n\n  /**\n   * Callback function triggered when the draggable element leaves a drop target.\n   * @param data - The data associated with the drag event.\n   * @param event - The original event object.\n   */\n  onLeave?: ClientEventHandler<T>\n}\n```\n\n#### Returns\n\n- `attributes` - Reactive object containing position and size data\n- `isDragging` - Boolean indicating if element is currently being dragged\n- `isOver` - Boolean indicating if element is over a drop target\n\n### `useDragTarget`\n\nCreates a drop target area.\nIt fires the same events of the subject. you can act with the callbacks `onEnter`, `onOver`, `onLeave`, `onDrop`.\n\nEverything is lazy, no events are fired or listened to unless they are useful\n\n```typescript\nfunction useDragTarget<T = unknown>(\n  elementRef: MaybeRefOrGetter<unknown>,\n  namespace: NameSpace,\n  options?: UseDragTargetOptions<T>\n): {\n  isDragging: Ref<boolean>\n  isOver: Ref<boolean>\n  item: Ref<T | null>\n}\n```\n\n#### Parameters\n\n- `elementRef` - Vue template ref to the drop target element\n- `namespace` - Must match the namespace of the drag subject\n- `options` - Configuration options\n\n#### Options\n\n```typescript\ntype UseDragTargetOptions<T> = {\n  onEnter?: ClientEventHandler<T>\n  onOver?: ClientEventHandler<T>\n  onLeave?: ClientEventHandler<T>\n  onDrop?: ClientEventHandler<T>\n  nested?: boolean // Default: true - when true only the topmost surface area will eb reactive\n}\n```\n\n#### Returns\n\n- `isDragging` - Boolean indicating if any item in this namespace is being dragged\n- `isOver` - Boolean indicating if an item is over this target\n- `item` - The currently dragged item data\n\n### `useDragClone`\n\nCreates a visual clone that follows the cursor during drag operations.\n\n```typescript\nfunction useDragClone(\n  elementRef: MaybeRefOrGetter<unknown>,\n  attributes: MaybeRefOrGetter<Attributes>,\n  options?: Options\n): {\n  clone: Ref<HTMLElement | null>\n  removeClone: () => void\n}\n```\n\n#### Parameters\n\n- `elementRef` - Vue template ref to the original element\n- `attributes` - Attributes from useDragSubject\n- `options` - Configuration options\n\n#### Options\n\n```typescript\ntype Options = {\n  cloneClass?: string // Default: 'clone'\n}\n```\n\n## Types\n\n### `Attributes`\n\n```typescript\ntype Attributes = {\n  // The container rect data\n  container: {\n    x: number\n    y: number\n    width: number\n    height: number\n  }\n  // Event data\n  event: {\n    x: number\n    y: number\n  }\n  // Projected data of the container after translating it (used by the clone)\n  translated: {\n    x: number\n    y: number\n  }\n  // The x, y delta from the initial event\n  delta: {\n    x: number\n    y: number\n  }\n}\n```\n\n## Best Practices\n\n1. **Use Descriptive Namespaces** - Choose meaningful names like `'user-contact-list'` or `'document-file-upload'`\n2. **Handle Cleanup** - The library automatically cleans up event listeners\n3. **Touch Support** - The library handles touch events automatically\n\n## License\n\nMIT License - see LICENSE file for details.\n","readmeFilename":"README.md"}