{"_id":"@arc-lang/arc-drag-and-drop","_rev":"2-428be0f5f5aed9509ac1756271158cde","name":"@arc-lang/arc-drag-and-drop","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@arc-lang/arc-drag-and-drop","version":"0.1.0","keywords":["drag-and-drop","sortable","kanban","dropzone","css","arc","zero-dependency"],"license":"MIT","_id":"@arc-lang/arc-drag-and-drop@0.1.0","maintainers":[{"name":"kobecuppens","email":"kobecuppens@hotmail.com"}],"homepage":"https://arc-language.dev","bugs":{"url":"https://github.com/arc-language/arc-drag-and-drop/issues"},"dist":{"shasum":"85f8f666fa3982818fdcb521a0a69a94088f2a98","tarball":"https://registry.npmjs.org/@arc-lang/arc-drag-and-drop/-/arc-drag-and-drop-0.1.0.tgz","fileCount":10,"integrity":"sha512-5Z7xlPVvFtHQqYejO8xmnghQa5CSat+PXOAgAJChNl4UTiC27BeuziquGAMtZFtCW4yQczC+GdOZ7Cl9KjGkHQ==","signatures":[{"sig":"MEQCIHL8zBfPyTrkYwPC0t+KsbnFEy0cs672X9JN8fwjMw0kAiBvOXDK4znSmoL623vMweFDWkj4KMngInijanFwkP6k9g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23888},"main":"index.css","gitHead":"1e6641e6f296efe526605d8f9303eee6215dac35","scripts":{"size":"du -sh src/*.css js/*.js index.css"},"_npmUser":{"name":"kobecuppens","email":"kobecuppens@hotmail.com"},"repository":{"url":"git+https://github.com/arc-language/arc-drag-and-drop.git","type":"git"},"_npmVersion":"11.12.1","description":"CSS-first drag-and-drop: sortable lists, kanban boards, file drop zones. Zero dependencies. ~1.5KB JS.","directories":{},"_nodeVersion":"24.15.0","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/arc-drag-and-drop_0.1.0_1779982283448_0.13185406221409002","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@arc-lang/arc-drag-and-drop","version":"0.1.1","description":"CSS-first drag-and-drop: sortable lists, kanban boards, file drop zones. Zero dependencies. ~1.5KB JS.","keywords":["drag-and-drop","sortable","kanban","dropzone","css","arc","zero-dependency"],"homepage":"https://arc-language.dev","repository":{"type":"git","url":"git+https://github.com/arc-language/arc-drag-and-drop.git"},"license":"MIT","main":"index.css","scripts":{"size":"du -sh src/*.css js/*.js index.css"},"publishConfig":{"access":"public","provenance":false},"gitHead":"c731bfe272ba6f193680afef6a0a7e5328219c7d","_id":"@arc-lang/arc-drag-and-drop@0.1.1","bugs":{"url":"https://github.com/arc-language/arc-drag-and-drop/issues"},"_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-+EpqHoOzAUmLTZ68U0qcok7Eunz6NLdDtGjniDEbp6jhh5evWYisRA2Car11f8K1aKNm3d+JB+eFH4ilL9nDqg==","shasum":"5455e0e47d7548664a310a018bb6322e9b841d3f","tarball":"https://registry.npmjs.org/@arc-lang/arc-drag-and-drop/-/arc-drag-and-drop-0.1.1.tgz","fileCount":10,"unpackedSize":23865,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAH1KMxtapDxL/mdjR2DF7i0bFk0JstEOUtO5L8RgL5oAiBrQ6b1EvWG/DL9NCqk7IgY5Y2ijb6i+1OX3I2HLcm+iA=="}]},"_npmUser":{"name":"kobecuppens","email":"kobecuppens@hotmail.com"},"directories":{},"maintainers":[{"name":"kobecuppens","email":"kobecuppens@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/arc-drag-and-drop_0.1.1_1779994670830_0.15013080380108001"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-28T15:31:23.252Z","modified":"2026-05-28T18:57:51.093Z","0.1.0":"2026-05-28T15:31:23.592Z","0.1.1":"2026-05-28T18:57:50.966Z"},"bugs":{"url":"https://github.com/arc-language/arc-drag-and-drop/issues"},"license":"MIT","homepage":"https://arc-language.dev","keywords":["drag-and-drop","sortable","kanban","dropzone","css","arc","zero-dependency"],"repository":{"type":"git","url":"git+https://github.com/arc-language/arc-drag-and-drop.git"},"description":"CSS-first drag-and-drop: sortable lists, kanban boards, file drop zones. Zero dependencies. ~1.5KB JS.","maintainers":[{"name":"kobecuppens","email":"kobecuppens@hotmail.com"}],"readme":"# arc-drag-and-drop\n\n[![components](https://img.shields.io/badge/components-3-blueviolet)](https://github.com/arc-language/arc-drag-and-drop)\n[![JS size](https://img.shields.io/badge/JS-~1.5KB%20optional-brightgreen)](https://github.com/arc-language/arc-drag-and-drop)\n[![dependencies](https://img.shields.io/badge/dependencies-0-brightgreen)](https://github.com/arc-language/arc-drag-and-drop)\n[![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)\n[![Part of Arc](https://img.shields.io/badge/Part%20of-Arc-5956f0)](https://arc-language.dev)\n\nCSS-first drag-and-drop: sortable lists, kanban boards, and file drop zones. CSS drives all visual states. The optional JS (~1.5KB total) handles DOM reordering and pointer tracking using the Pointer Events API — touch and mouse work identically.\n\n> **Part of [Arc](https://arc-language.dev)** — the zero-dependency web framework.\n\n**vs. alternatives:**\n| Library | Size | Touch | Framework |\n|---|---|---|---|\n| SortableJS | ~45KB | ✓ | any |\n| dnd-kit | ~30KB | ✓ | React only |\n| interact.js | ~70KB | ✓ | any |\n| **arc-drag-and-drop** | **~1.5KB** | **✓** | **any** |\n\n## Install\n\n```bash\nnpm install arc-drag-and-drop\n```\n\n**CDN:**\n```html\n<link rel=\"stylesheet\" href=\"https://unpkg.com/arc-drag-and-drop/index.css\">\n```\n\n---\n\n## Components\n\n### Sortable\n\nReorderable list. JS uses Pointer Events (mouse + touch) with rAF-throttled `pointermove` and GPU-composited clone positioning.\n\n```html\n<ul class=\"sortable\">\n  <li class=\"sortable__item\">Task one</li>\n  <li class=\"sortable__item\">Task two</li>\n  <li class=\"sortable__item\">Task three</li>\n</ul>\n<script src=\"https://unpkg.com/arc-drag-and-drop/js/sortable.js\"></script>\n```\n\n**With drag handle** — only the handle initiates a drag:\n\n```html\n<ul class=\"sortable\" data-handle=\".drag-handle\">\n  <li class=\"sortable__item\">\n    <span class=\"drag-handle\">⠿</span>\n    Item content\n  </li>\n</ul>\n```\n\n**Horizontal:**\n\n```html\n<div class=\"sortable sortable--horizontal\">\n  <div class=\"sortable__item\">A</div>\n  <div class=\"sortable__item\">B</div>\n</div>\n```\n\n**Disabled item:**\n\n```html\n<li class=\"sortable__item\" data-disabled>Cannot be moved</li>\n```\n\n| CSS property | Default | Description |\n|---|---|---|\n| `--sortable-gap` | `8px` | Gap between items |\n| `--sortable-radius` | `8px` | Item border radius |\n| `--sortable-padding` | `12px 16px` | Item padding |\n| `--sortable-item-bg` | `#fff` | Item background |\n| `--sortable-item-border` | `#e2e8f0` | Item border color |\n| `--sortable-drag-rotate` | `2deg` | Clone tilt while dragging |\n| `--sortable-placeholder-bg` | `rgba(89,86,240,0.06)` | Placeholder fill |\n| `--sortable-placeholder-border` | `rgba(89,86,240,0.3)` | Placeholder border |\n| `--sortable-handle-color` | `#94a3b8` | Handle icon color |\n| `--sortable-handle-color-hover` | `#475569` | Handle icon hover color |\n\n**Custom event:**\n\n```js\ndocument.querySelector('.sortable').addEventListener('dnd:sorted', function (e) {\n  console.log(e.detail)\n  // { item, fromIndex, toIndex, fromContainer, toContainer }\n})\n```\n\n---\n\n### Kanban\n\nMulti-column board. Cards are `.sortable__item` inside `.kanban__column` containers. Add `data-group` to enable cross-column drag.\n\n```html\n<div class=\"kanban\">\n  <div class=\"kanban__column sortable\" data-group=\"board\" data-handle=\".drag-handle\">\n    <div class=\"kanban__column-header\">To do</div>\n    <div class=\"sortable__item\">\n      <span class=\"drag-handle\">⠿</span>\n      Write docs\n    </div>\n  </div>\n\n  <div class=\"kanban__column sortable\" data-group=\"board\" data-handle=\".drag-handle\">\n    <div class=\"kanban__column-header\">In progress</div>\n    <div class=\"sortable__item\">\n      <span class=\"drag-handle\">⠿</span>\n      Build feature\n    </div>\n  </div>\n</div>\n<script src=\"https://unpkg.com/arc-drag-and-drop/js/sortable.js\"></script>\n```\n\n| CSS property | Default | Description |\n|---|---|---|\n| `--kanban-gap` | `16px` | Gap between columns |\n| `--kanban-column-width` | `280px` | Column width |\n| `--kanban-column-bg` | `#f1f5f9` | Column background |\n| `--kanban-radius` | `12px` | Column border radius |\n| `--kanban-column-min-height` | `120px` | Minimum column height |\n| `--kanban-over-bg` | `rgba(89,86,240,0.08)` | Column highlight on drag-over |\n| `--kanban-over-border` | `rgba(89,86,240,0.35)` | Column outline on drag-over |\n\n**Data attributes:**\n\n| Attribute | Value | Description |\n|---|---|---|\n| `data-group` | `\"board\"` | Containers with the same group accept cross-container drops |\n| `data-handle` | `\".drag-handle\"` | CSS selector that initiates drag |\n| `data-axis` | `\"x\"` or `\"y\"` | Lock drag to one axis |\n\n---\n\n### Dropzone\n\nFile drop zone. Uses HTML5 drag events (required for OS file drops). Fires `dnd:drop` on both file drop and click-to-browse.\n\n```html\n<div class=\"dropzone\" data-accept=\"image/*\">\n  <div class=\"dropzone__icon\">📁</div>\n  <div class=\"dropzone__label\">Drop images here</div>\n  <div class=\"dropzone__hint\">or click to browse</div>\n  <input type=\"file\" multiple accept=\"image/*\">\n</div>\n<script src=\"https://unpkg.com/arc-drag-and-drop/js/dropzone.js\"></script>\n```\n\n**`data-accept`** takes a comma-separated list of MIME types or extensions:\n- `image/*` — any image\n- `.pdf,.docx` — specific extensions\n- `text/plain` — exact MIME\n\n| CSS property | Default | Description |\n|---|---|---|\n| `--dropzone-padding` | `48px 32px` | Inner padding |\n| `--dropzone-radius` | `12px` | Border radius |\n| `--dropzone-border` | `#cbd5e1` | Default border color |\n| `--dropzone-bg` | `#f8fafc` | Default background |\n| `--dropzone-over-border` | `#5956f0` | Drag-over border color |\n| `--dropzone-over-bg` | `rgba(89,86,240,0.06)` | Drag-over background |\n| `--dropzone-success-border` | `#22c55e` | Accepted drop border |\n| `--dropzone-success-bg` | `rgba(34,197,94,0.06)` | Accepted drop background |\n| `--dropzone-error-border` | `#ef4444` | Rejected drop border |\n| `--dropzone-error-bg` | `rgba(239,68,68,0.06)` | Rejected drop background |\n\n**Custom event:**\n\n```js\ndocument.querySelector('.dropzone').addEventListener('dnd:drop', function (e) {\n  console.log(e.detail.files) // Array of File objects\n})\n```\n\n---\n\n## Tree-shaking\n\nImport only what you need:\n\n```html\n<link rel=\"stylesheet\" href=\"https://unpkg.com/arc-drag-and-drop/src/base.css\">\n<link rel=\"stylesheet\" href=\"https://unpkg.com/arc-drag-and-drop/src/sortable.css\">\n```\n\n| File | Size (approx) |\n|------|---------------|\n| `src/base.css` | ~0.5 KB |\n| `src/sortable.css` | ~1.5 KB |\n| `src/dropzone.css` | ~1 KB |\n| `src/kanban.css` | ~1.5 KB |\n| `js/sortable.js` | ~1.1 KB |\n| `js/dropzone.js` | ~0.5 KB |\n| Full bundle | ~4.5 KB CSS + ~1.6 KB JS |\n\n---\n\n## Performance\n\n| Technique | Effect |\n|---|---|\n| rAF-throttled `pointermove` | Layout reads happen at most once per frame |\n| `translate3d(x, y, 0)` on clone | GPU-composited movement, no reflow |\n| Event delegation (1 listener/container) | O(1) regardless of item count |\n| Placeholder only moves when position changes | Minimizes DOM mutations |\n| `will-change: transform` added dynamically | No wasted GPU layers when idle |\n| `pointer-events: none` on clone | `elementFromPoint` sees through it correctly |\n\n---\n\n## Browser support\n\n| Feature | Chrome | Firefox | Safari | Edge |\n|---------|--------|---------|--------|------|\n| Sortable (Pointer Events) | 55+ | 59+ | 13+ | 79+ |\n| Kanban (cross-container) | 55+ | 59+ | 13+ | 79+ |\n| Dropzone (HTML5 DnD + File API) | 21+ | 50+ | 10.1+ | 12+ |\n| `touch-action: none` | 36+ | 52+ | 13+ | 79+ |\n\n---\n\n## Accessibility\n\n- **`prefers-reduced-motion`**: `--sortable-drag-rotate` is forced to `0deg` — no tilt on the drag clone\n- **Keyboard**: sortable items are not keyboard-reorderable by default — pair with a server-side or form-based fallback for full a11y\n- **Screen readers**: drag clone gets no ARIA attributes (it's `pointer-events: none` and ephemeral); the item is moved in the DOM on drop\n\n---\n\n## License\n\n[MIT](LICENSE) © Arc contributors\n","readmeFilename":"README.md"}