{"_id":"@cloud-ru/ds-drag-and-drop","_rev":"10-348ef3e941a2c3ae74029ef3b39207ad","name":"@cloud-ru/ds-drag-and-drop","dist-tags":{"preview":"1.1.2-preview-d50a3da1.0","latest":"1.1.3"},"versions":{"1.0.1-preview-f10e3e8f.0":{"name":"@cloud-ru/ds-drag-and-drop","version":"1.0.1-preview-f10e3e8f.0","author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"license":"Apache-2.0","_id":"@cloud-ru/ds-drag-and-drop@1.0.1-preview-f10e3e8f.0","maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"dist":{"shasum":"f29c508c6f6bd91e56a8de9c68c0efe16307ea88","tarball":"https://registry.npmjs.org/@cloud-ru/ds-drag-and-drop/-/ds-drag-and-drop-1.0.1-preview-f10e3e8f.0.tgz","fileCount":81,"integrity":"sha512-VXaZS3N+Qm4DonPpcKwK8Sq2C9LbU7NZ2Pz1jX13MeHAeZsJYRu6i5CCkZuzdyVHnoiIvy3DZfLhS8xUZ3jquQ==","signatures":[{"sig":"MEQCICzRAfEgV7/fuDWR+haYgUZomcdNBeQ7JCLMkwcySqU3AiBHOAgiISo0FmAGxOH4q+m8oUVAV5VC+VJqnOHKgJT/Lw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":298688},"main":"./dist/cjs/index.js","type":"module","_from":"file:cloud-ru-ds-drag-and-drop-1.0.1-preview-f10e3e8f.0.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","source":"./src/index.ts","require":"./dist/cjs/index.js"}},"_npmUser":{"name":"cloud-ru-tech","email":"robot@cloud.ru"},"_resolved":"/tmp/9ba0e92d4546accd1d5fef53588a3c48/cloud-ru-ds-drag-and-drop-1.0.1-preview-f10e3e8f.0.tgz","_integrity":"sha512-VXaZS3N+Qm4DonPpcKwK8Sq2C9LbU7NZ2Pz1jX13MeHAeZsJYRu6i5CCkZuzdyVHnoiIvy3DZfLhS8xUZ3jquQ==","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"_npmVersion":"11.6.2","description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","directories":{},"sideEffects":["*.css","**/*.css"],"_nodeVersion":"24.11.1","dependencies":{"classnames":"^2.5.1","@cloud-ru/ds-utils":"1.0.0","@cloud-ru/ds-materials":"1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2"},"_npmOperationalInternal":{"tmp":"tmp/ds-drag-and-drop_1.0.1-preview-f10e3e8f.0_1787065172644_0.08406467869195766","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@cloud-ru/ds-drag-and-drop","version":"1.1.0","author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"license":"Apache-2.0","_id":"@cloud-ru/ds-drag-and-drop@1.1.0","maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"dist":{"shasum":"00e34c6802a63dc3dde9328db15e81138c7c7483","tarball":"https://registry.npmjs.org/@cloud-ru/ds-drag-and-drop/-/ds-drag-and-drop-1.1.0.tgz","fileCount":81,"integrity":"sha512-L0nPohRmp/GmkRa7VvoPDTsJayCtRTe7vxcqs4hKd2SCDupuUAUrd7YcOoqQ6qCQAMFqHv0qf4rAZUgFO/lj/A==","signatures":[{"sig":"MEUCIQCivRH5EH6g4mCjX+6fIB7+mCMs9WMEpGjsebYKFvMExQIgVHtkzrsBOY8s2ZlLBvpC/D0kuYwcBpOrNxNVg79aJ7E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":298853},"main":"./dist/cjs/index.js","type":"module","_from":"file:cloud-ru-ds-drag-and-drop-1.1.0.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","source":"./src/index.ts","require":"./dist/cjs/index.js"}},"_npmUser":{"name":"cloud-ru-tech","email":"robot@cloud.ru"},"_resolved":"/tmp/750ab38d8dda350d66e93375c7f0e4cd/cloud-ru-ds-drag-and-drop-1.1.0.tgz","_integrity":"sha512-L0nPohRmp/GmkRa7VvoPDTsJayCtRTe7vxcqs4hKd2SCDupuUAUrd7YcOoqQ6qCQAMFqHv0qf4rAZUgFO/lj/A==","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"_npmVersion":"11.6.2","description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","directories":{},"sideEffects":["*.css","**/*.css"],"_nodeVersion":"24.11.1","dependencies":{"classnames":"^2.5.1","@cloud-ru/ds-utils":"^1.0.0","@cloud-ru/ds-materials":"^1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2"},"_npmOperationalInternal":{"tmp":"tmp/ds-drag-and-drop_1.1.0_1787068495449_0.3542130919827253","host":"s3://npm-registry-packages-npm-production"}},"1.1.1-preview-7665e9c3.0":{"name":"@cloud-ru/ds-drag-and-drop","version":"1.1.1-preview-7665e9c3.0","author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"license":"Apache-2.0","_id":"@cloud-ru/ds-drag-and-drop@1.1.1-preview-7665e9c3.0","maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"dist":{"shasum":"8c9adef913277e8ad0209cfd364f9cdd5c31f052","tarball":"https://registry.npmjs.org/@cloud-ru/ds-drag-and-drop/-/ds-drag-and-drop-1.1.1-preview-7665e9c3.0.tgz","fileCount":81,"integrity":"sha512-ZcQ7Xgr69JWlVl/Ne4zkFfkQDqOiwEeOvfDJ+b5mQOEslO1Ru3ZrNmlt5tUbtKVRPdim+ssQAlM9BQuOEI3sDA==","signatures":[{"sig":"MEUCIQDQxNe8rRUkljPm2AymgLMM/I3qGB2mEYW9XxrOHCXBygIgWhOJn8FtLxOvEkcP/38zOwaQrnIZ47Ct2XuvAFeTEq0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":298892},"main":"./dist/cjs/index.js","type":"module","_from":"file:cloud-ru-ds-drag-and-drop-1.1.1-preview-7665e9c3.0.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","source":"./src/index.ts","require":"./dist/cjs/index.js"}},"_npmUser":{"name":"cloud-ru-tech","email":"robot@cloud.ru"},"_resolved":"/tmp/f0f919da492c21abe7d36f445046e23c/cloud-ru-ds-drag-and-drop-1.1.1-preview-7665e9c3.0.tgz","_integrity":"sha512-ZcQ7Xgr69JWlVl/Ne4zkFfkQDqOiwEeOvfDJ+b5mQOEslO1Ru3ZrNmlt5tUbtKVRPdim+ssQAlM9BQuOEI3sDA==","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"_npmVersion":"11.6.2","description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","directories":{},"sideEffects":["*.css","**/*.css"],"_nodeVersion":"24.11.1","dependencies":{"classnames":"^2.5.1","@cloud-ru/ds-utils":"1.0.1-preview-7665e9c3.0","@cloud-ru/ds-materials":"1.0.1-preview-7665e9c3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2"},"_npmOperationalInternal":{"tmp":"tmp/ds-drag-and-drop_1.1.1-preview-7665e9c3.0_1787206719467_0.16575684512161093","host":"s3://npm-registry-packages-npm-production"}},"1.1.1-preview-fb311860.0":{"name":"@cloud-ru/ds-drag-and-drop","version":"1.1.1-preview-fb311860.0","author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"license":"Apache-2.0","_id":"@cloud-ru/ds-drag-and-drop@1.1.1-preview-fb311860.0","maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"dist":{"shasum":"d6c4f5ba005ee1b7bcc81e22d79b7f0875f69eed","tarball":"https://registry.npmjs.org/@cloud-ru/ds-drag-and-drop/-/ds-drag-and-drop-1.1.1-preview-fb311860.0.tgz","fileCount":81,"integrity":"sha512-bb2ui/xWiKK4qcQtLfFEDHMEHPg5o/GW5uEguqx267hotznFnt/gqUwqgFvuvPFmZmhdcHx4mupwpW+mRwagWg==","signatures":[{"sig":"MEQCIGKVZw/GDHy0ov/uGXvdIrTkLC5PweCZ4xVsXaZtkXu6AiAYpaNib5uT3TVicPbuGDJdtspXCy4rzJerqNL5fo5F4Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":298892},"main":"./dist/cjs/index.js","type":"module","_from":"file:cloud-ru-ds-drag-and-drop-1.1.1-preview-fb311860.0.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","source":"./src/index.ts","require":"./dist/cjs/index.js"}},"_npmUser":{"name":"cloud-ru-tech","email":"robot@cloud.ru"},"_resolved":"/tmp/86662c9ed53e6ec273840496c1114579/cloud-ru-ds-drag-and-drop-1.1.1-preview-fb311860.0.tgz","_integrity":"sha512-bb2ui/xWiKK4qcQtLfFEDHMEHPg5o/GW5uEguqx267hotznFnt/gqUwqgFvuvPFmZmhdcHx4mupwpW+mRwagWg==","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"_npmVersion":"11.6.2","description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","directories":{},"sideEffects":["*.css","**/*.css"],"_nodeVersion":"24.11.1","dependencies":{"classnames":"^2.5.1","@cloud-ru/ds-utils":"1.0.1-preview-fb311860.0","@cloud-ru/ds-materials":"1.0.1-preview-fb311860.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2"},"_npmOperationalInternal":{"tmp":"tmp/ds-drag-and-drop_1.1.1-preview-fb311860.0_1787209023801_0.7005118412181908","host":"s3://npm-registry-packages-npm-production"}},"1.1.1-preview-95bfb925.0":{"name":"@cloud-ru/ds-drag-and-drop","version":"1.1.1-preview-95bfb925.0","author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"license":"Apache-2.0","_id":"@cloud-ru/ds-drag-and-drop@1.1.1-preview-95bfb925.0","maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"dist":{"shasum":"5c628fc2eb41aab61be12410df89b5c77d285dcc","tarball":"https://registry.npmjs.org/@cloud-ru/ds-drag-and-drop/-/ds-drag-and-drop-1.1.1-preview-95bfb925.0.tgz","fileCount":81,"integrity":"sha512-SmP7ZErSFc4fQaC0JXYYLSMDbJenZ8CqC369IAX8U/7FWg1mXMYiAO/NdoTBkLsvfg/RQFIqesS6vkPNZ4Da7w==","signatures":[{"sig":"MEYCIQCGjiXlCwsDwIjfI+opCuhdkxRbMY5+Q5xlInoK5neVyQIhAKUIO/boqm85L3SPma8033Eg9tUImkqFlw6H8VGs3gbM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":298892},"main":"./dist/cjs/index.js","type":"module","_from":"file:cloud-ru-ds-drag-and-drop-1.1.1-preview-95bfb925.0.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","source":"./src/index.ts","require":"./dist/cjs/index.js"}},"_npmUser":{"name":"cloud-ru-tech","email":"robot@cloud.ru"},"_resolved":"/tmp/81fbf6f074be37777cde979e5dba6d3b/cloud-ru-ds-drag-and-drop-1.1.1-preview-95bfb925.0.tgz","_integrity":"sha512-SmP7ZErSFc4fQaC0JXYYLSMDbJenZ8CqC369IAX8U/7FWg1mXMYiAO/NdoTBkLsvfg/RQFIqesS6vkPNZ4Da7w==","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"_npmVersion":"11.6.2","description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","directories":{},"sideEffects":["*.css","**/*.css"],"_nodeVersion":"24.11.1","dependencies":{"classnames":"^2.5.1","@cloud-ru/ds-utils":"1.0.1-preview-95bfb925.0","@cloud-ru/ds-materials":"1.0.1-preview-95bfb925.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2"},"_npmOperationalInternal":{"tmp":"tmp/ds-drag-and-drop_1.1.1-preview-95bfb925.0_1787566103251_0.8545404536870627","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@cloud-ru/ds-drag-and-drop","version":"1.1.1","author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"license":"Apache-2.0","_id":"@cloud-ru/ds-drag-and-drop@1.1.1","maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"dist":{"shasum":"da27169ccd157e045bb0037d7823b4e3574df521","tarball":"https://registry.npmjs.org/@cloud-ru/ds-drag-and-drop/-/ds-drag-and-drop-1.1.1.tgz","fileCount":81,"integrity":"sha512-JGwZej4/uEEiaSdbVS8oDgNLniWedsxzQ69JXPsmyX9a/XLpxWcjxCLszPc5V8xN2lO8ufNfRP6i3VrHImGVWQ==","signatures":[{"sig":"MEQCIE36fuOKgqi7lD3mC1f+sJKDMrPMh0RO+jYnEh2DXW3GAiAV0xalKFtzxVGu9xrkQFMZSenknKcPNcnULUGCHkTfpA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":298919},"main":"./dist/cjs/index.js","type":"module","_from":"file:cloud-ru-ds-drag-and-drop-1.1.1.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","source":"./src/index.ts","require":"./dist/cjs/index.js"}},"_npmUser":{"name":"cloud-ru-tech","email":"robot@cloud.ru"},"_resolved":"/tmp/38eb0a7884c4a75fdb85ba3349513fb7/cloud-ru-ds-drag-and-drop-1.1.1.tgz","_integrity":"sha512-JGwZej4/uEEiaSdbVS8oDgNLniWedsxzQ69JXPsmyX9a/XLpxWcjxCLszPc5V8xN2lO8ufNfRP6i3VrHImGVWQ==","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"_npmVersion":"11.6.2","description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","directories":{},"sideEffects":["*.css","**/*.css"],"_nodeVersion":"24.11.1","dependencies":{"classnames":"^2.5.1","@cloud-ru/ds-utils":"^1.1.0","@cloud-ru/ds-materials":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2"},"_npmOperationalInternal":{"tmp":"tmp/ds-drag-and-drop_1.1.1_1787569354221_0.5650894593240672","host":"s3://npm-registry-packages-npm-production"}},"1.1.2-preview-a2208aeb.0":{"name":"@cloud-ru/ds-drag-and-drop","version":"1.1.2-preview-a2208aeb.0","author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"license":"Apache-2.0","_id":"@cloud-ru/ds-drag-and-drop@1.1.2-preview-a2208aeb.0","maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"dist":{"shasum":"60070173d57ff682885db588867d7eae6a07fc65","tarball":"https://registry.npmjs.org/@cloud-ru/ds-drag-and-drop/-/ds-drag-and-drop-1.1.2-preview-a2208aeb.0.tgz","fileCount":81,"integrity":"sha512-UDcnmdbP+NVtYz9FYDvhXo0jM6F9PBlWr+AtrRKynSSJpJPKD4139Ghv0EqxFDEEROxm+3zYB/Lml+Pzg/fDbA==","signatures":[{"sig":"MEQCIBSHiGvzwO9UGTROcNyjhOFRLtlToDydRv151Qdi42fgAiBeYoyxpoqurpogfhcSYB6RscfQW/Sx9QVFSqqD6xnJdQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIAPcks5PfPCwvPytyq6n47NDtrFsPOrJ656EY5HYm9sbAiA9q/P7axCOahtdHWWxGaTULtIp/qj95Qx/urDc9UnUTA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":295755},"main":"./dist/cjs/index.js","type":"module","_from":"file:cloud-ru-ds-drag-and-drop-1.1.2-preview-a2208aeb.0.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","source":"./src/index.ts","require":"./dist/cjs/index.js"}},"_npmUser":{"name":"cloud-ru-tech","email":"robot@cloud.ru"},"_resolved":"/tmp/c2022e12198906fa705845d9dcd0210c/cloud-ru-ds-drag-and-drop-1.1.2-preview-a2208aeb.0.tgz","_integrity":"sha512-UDcnmdbP+NVtYz9FYDvhXo0jM6F9PBlWr+AtrRKynSSJpJPKD4139Ghv0EqxFDEEROxm+3zYB/Lml+Pzg/fDbA==","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"_npmVersion":"11.6.2","description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","directories":{},"sideEffects":["*.css","**/*.css"],"_nodeVersion":"24.11.1","dependencies":{"classnames":"^2.5.1","@cloud-ru/ds-utils":"1.1.0","@cloud-ru/ds-materials":"1.0.2-preview-a2208aeb.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2"},"_npmOperationalInternal":{"tmp":"tmp/ds-drag-and-drop_1.1.2-preview-a2208aeb.0_1790236744467_0.36806572139117244","host":"s3://npm-registry-packages-npm-production"}},"1.1.2-preview-d50a3da1.0":{"name":"@cloud-ru/ds-drag-and-drop","version":"1.1.2-preview-d50a3da1.0","author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"license":"Apache-2.0","_id":"@cloud-ru/ds-drag-and-drop@1.1.2-preview-d50a3da1.0","maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"dist":{"shasum":"6cba12c11528492f09539e6541bb2605a6598e9f","tarball":"https://registry.npmjs.org/@cloud-ru/ds-drag-and-drop/-/ds-drag-and-drop-1.1.2-preview-d50a3da1.0.tgz","fileCount":81,"integrity":"sha512-L7xcYQMfabhWKroSeRsOFKSn+DPT7gy6IS+QM9yliwm9m7k3qEHK/SSOHs1eLPBYFnbKSTCsXzvN6bmtjUr1Pg==","signatures":[{"sig":"MEYCIQDJ6h8qyBwg4+0NwqYtjwtYNqZDfdgFDcbHpfjbrvQj6AIhAOnUL4gNqQ60mdenUEIzfumjCznpR+uURgTDZ5JqVyPE","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIB0HVDcxsAHAJKKqnp9ifmrdj8cRiJKxpFSScXqRoIBaAiBwarOFcCJuTwI9vKWvmYro1YLIv0QjSHUsy1pnlt/eyw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":295755},"main":"./dist/cjs/index.js","type":"module","_from":"file:cloud-ru-ds-drag-and-drop-1.1.2-preview-d50a3da1.0.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","source":"./src/index.ts","require":"./dist/cjs/index.js"}},"_npmUser":{"name":"cloud-ru-tech","email":"robot@cloud.ru"},"_resolved":"/tmp/9aa341f49910f8b4941f2532e0580140/cloud-ru-ds-drag-and-drop-1.1.2-preview-d50a3da1.0.tgz","_integrity":"sha512-L7xcYQMfabhWKroSeRsOFKSn+DPT7gy6IS+QM9yliwm9m7k3qEHK/SSOHs1eLPBYFnbKSTCsXzvN6bmtjUr1Pg==","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"_npmVersion":"11.6.2","description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","directories":{},"sideEffects":["*.css","**/*.css"],"_nodeVersion":"24.11.1","dependencies":{"classnames":"^2.5.1","@cloud-ru/ds-utils":"1.1.0","@cloud-ru/ds-materials":"1.0.2-preview-d50a3da1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2"},"_npmOperationalInternal":{"tmp":"tmp/ds-drag-and-drop_1.1.2-preview-d50a3da1.0_1790327479679_0.15033538287356008","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@cloud-ru/ds-drag-and-drop","version":"1.1.2","author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"license":"Apache-2.0","_id":"@cloud-ru/ds-drag-and-drop@1.1.2","maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"dist":{"shasum":"23196c06d9ce5d7be0fc6da46a16c620ebb42474","tarball":"https://registry.npmjs.org/@cloud-ru/ds-drag-and-drop/-/ds-drag-and-drop-1.1.2.tgz","fileCount":81,"integrity":"sha512-omyyP0DaMflE4oacGw7+qO7b/11v6vxi0pdrk1LEj9FI3V8eqPLZ8quG0LjX39JcLdF9rS5agRT648dVlD0iIg==","signatures":[{"sig":"MEQCIF+H0iOLYB0qhbLaLtUuDGoWz/C67pFLr0HlJBT6EI4YAiAHsK+Lh+Wvt/V1PG5eaF+1BeirPTNZq6qY1SBMc6omsQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIB3aZ+o4As2imsZRgkJgpL8rk7ov9jld7ndMd152UL0vAiEAhuuZ+HTJg0R3NbeZQPBYQJNj2P+B6MjNCBFKoC1PV5Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":295801},"main":"./dist/cjs/index.js","type":"module","_from":"file:cloud-ru-ds-drag-and-drop-1.1.2.tgz","types":"./dist/esm/index.d.ts","module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","source":"./src/index.ts","require":"./dist/cjs/index.js"}},"_npmUser":{"name":"cloud-ru-tech","email":"robot@cloud.ru"},"_resolved":"/tmp/a88cb28b4db1f70b222db9a757200d79/cloud-ru-ds-drag-and-drop-1.1.2.tgz","_integrity":"sha512-omyyP0DaMflE4oacGw7+qO7b/11v6vxi0pdrk1LEj9FI3V8eqPLZ8quG0LjX39JcLdF9rS5agRT648dVlD0iIg==","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"_npmVersion":"11.6.2","description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","directories":{},"sideEffects":["*.css","**/*.css"],"_nodeVersion":"24.11.1","dependencies":{"classnames":"^2.5.1","@cloud-ru/ds-utils":"^1.1.0","@cloud-ru/ds-materials":"^2.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2"},"_npmOperationalInternal":{"tmp":"tmp/ds-drag-and-drop_1.1.2_1790343922592_0.8643008532360199","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"_id":"@cloud-ru/ds-drag-and-drop@1.1.3","bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"dist":{"shasum":"28bc5f3e29ccd4d1804fc45da3f805e0ffa44ee9","tarball":"https://registry.npmjs.org/@cloud-ru/ds-drag-and-drop/-/ds-drag-and-drop-1.1.3.tgz","fileCount":81,"integrity":"sha512-/vj9ZH1/KjYMQ6QIYRVGhV6eR9lpdHSlsU/7A6LlQ+f/UiOvx/8sXUbb8lye++ncpBAQTL7k3Qz/oC0F0A0Mpw==","signatures":[{"sig":"MEUCIQCVPpMmbQtoV5e023HOEZwRvQ3udpag2a6+86PJdAIifAIgJJ0PP5pyDaDv2so+op7kmhYarwkbp4c0ZhF8iA/Z7hU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDmVkHxHuNNYBCEugcRnag0SeTmAOWYMDyp6kyzU4rLGQIhAPIZIivh9N8VB0HD6mk7jiLzlsegWDAYbJn8tEuXRF26"}],"unpackedSize":296201},"main":"./dist/cjs/index.js","name":"@cloud-ru/ds-drag-and-drop","type":"module","_from":"file:cloud-ru-ds-drag-and-drop-1.1.3.tgz","types":"./dist/esm/index.d.ts","author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"module":"./dist/esm/index.js","exports":{".":{"types":"./dist/esm/index.d.ts","import":"./dist/esm/index.js","source":"./src/index.ts","require":"./dist/cjs/index.js"}},"license":"Apache-2.0","version":"1.1.3","_npmUser":{"name":"cloud-ru-tech","email":"robot@cloud.ru"},"homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","_resolved":"/tmp/7a39256701b0c5dfe9870bce8c029e75/cloud-ru-ds-drag-and-drop-1.1.3.tgz","_integrity":"sha512-/vj9ZH1/KjYMQ6QIYRVGhV6eR9lpdHSlsU/7A6LlQ+f/UiOvx/8sXUbb8lye++ncpBAQTL7k3Qz/oC0F0A0Mpw==","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"_npmVersion":"11.6.2","description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","directories":{},"maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"sideEffects":["*.css","**/*.css"],"_nodeVersion":"24.11.1","dependencies":{"classnames":"^2.5.1","@cloud-ru/ds-utils":"^1.2.0","@cloud-ru/ds-materials":"^2.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@dnd-kit/core":"^6.3.1","@dnd-kit/sortable":"^10.0.0","@dnd-kit/utilities":"^3.2.2"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ds-drag-and-drop_1.1.3_1790606872931_0.4771068815739883"}}},"time":{"created":"2026-08-18T14:59:32.486Z","modified":"2026-09-28T14:47:53.193Z","1.0.1-preview-f10e3e8f.0":"2026-08-18T14:59:32.796Z","1.1.0":"2026-08-18T15:54:55.599Z","1.1.1-preview-7665e9c3.0":"2026-08-20T06:18:39.643Z","1.1.1-preview-fb311860.0":"2026-08-20T06:57:03.971Z","1.1.1-preview-95bfb925.0":"2026-08-24T10:08:23.397Z","1.1.1":"2026-08-24T11:02:34.389Z","1.1.2-preview-a2208aeb.0":"2026-09-24T07:59:04.542Z","1.1.2-preview-d50a3da1.0":"2026-09-25T09:11:19.759Z","1.1.2":"2026-09-25T13:45:22.682Z","1.1.3":"2026-09-28T14:47:53.020Z"},"bugs":{"url":"https://github.com/cloud-ru-tech/snack-v2/issues"},"author":{"name":"Anna Kozlova","email":"apkozlova@cloud.ru"},"license":"Apache-2.0","homepage":"https://github.com/cloud-ru-tech/snack-v2/tree/master/packages/drag-and-drop","repository":{"url":"git+https://github.com/cloud-ru-tech/snack-v2.git","type":"git","directory":"packages/drag-and-drop"},"description":"Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.","maintainers":[{"name":"cloud-ru-tech","email":"robot@cloud.ru"}],"readme":"# DragAndDrop\n\n`@cloud-ru/ds-drag-and-drop` — Визуальные примитивы перетаскивания — поверхность копии, линия вставки и зона приёма.\n\nТри презентационных примитива, из которых собирается визуальная часть для состояния перетаскивания. Логику переноса\n(сенсоры, коллизии, порядок) пакет на себя не берёт — её реализует DnD-библиотека потребителя\n(`@dnd-kit`, HTML5 DnD, собственные обработчики). Примитивы отвечают только за то, как перенос\nвыглядит, и делают это одинаково во всех компонентах дизайн-системы.\n\n- `DragGhost` — исходная сущность на время переноса: приглушённая либо уступившая своё место.\n- `DragPreview` — поверхность копии, которая едет за курсором.\n- `DropIndicator` — линия будущей позиции.\n- `DropTarget` — рамка области, в которую переносят сущность из другой зоны.\n\n## Когда использовать\n\n- Перетаскивание собирается в своём компоненте, и нужен вид, совпадающий с остальной дизайн-системой.\n- Элемент переносится из одной зоны в другую, и нужно показать, какая зона его примет (`DropTarget`).\n- Порядок меняется вставкой, а не обменом местами — точку вставки показывает `DropIndicator` (статический\n  перенос) либо пустой слот (динамический).\n\nКогда **не** нужен:\n\n- Готовое переупорядочивание уже есть в компоненте:\n  - у `@cloud-ru/ds-list` переупорядочивание строк включается пропом `onItemsReorder` — примитивы там уже встроены.\n- Нужна сама механика переноса (сенсоры, коллизии, автоскролл):\n  - нужна DnD-библиотека, эти примитивы — только визуальный слой.\n\n## Анатомия\n\n### Режимы переноса (default `static`)\n\nПеренос показывается одним из двух способов. Режим выбирается на весь компонент-потребитель, а не\nна отдельную сущность: смешивать оба в одном списке нельзя — пользователь читает их как разные\nинтерфейсы.\n\n- `static` — соседи стоят на месте, исходная сущность приглушается (`DragGhost` с `dragging`),\n  будущую позицию отмечает линия (`DropIndicator`). Раскладка на время переноса не меняется, поэтому\n  режим уместен там, где сдвиг соседей дорог или сбивает: длинные списки, таблицы, сетки со скроллом.\n- `dynamic` — соседи расступаются сразу, а на месте попадания остаётся пустой слот (`DragGhost`\n  с `dragging` и `mode='dynamic'`). Линию в этом режиме не рисуют: точку вставки уже показывает\n  пустота, а вместе они дублируют друг друга.\n\nРежим не отменяет остальные примитивы: копия за курсором (`DragPreview`) и рамка зоны-приёмника\n(`DropTarget`) одинаковы в обоих.\n\n### DragGhost (default `dragging: false`, `mode: static`)\n\nИсходная сущность на время переноса. `dragging` включает вид переноса, `mode` выбирает какой:\n`static` — приглушение на своём месте, `dynamic` — сущность становится невидимой, сохраняя своё\nместо в раскладке, поэтому на её месте получается пустой слот.\n\nЗаменяет собой обёртку сущности, а не добавляет уровень вложенности: принимает `innerRef`,\n`className` и остальные атрибуты `<div>`. Создаёт контекст позиционирования, поэтому `DropIndicator`\nс `placement` можно рендерить прямо внутри.\n\n### DragPreview\n\nОбёртка перетаскиваемой сущности: непрозрачная поверхность с тенью, поэтому копия читается над\nлюбым фоном страницы — в том числе в портале, где своей подложки у сущности нет.\n\nФорму задаёт содержимое — обёртка наследует его скругление. Собственных размеров у неё нет,\nширину и высоту тоже задаёт содержимое.\n\n### DropIndicator (default `horizontal`)\n\nПунктирная линия будущей позиции — примитив статического переноса. В динамическом её место\nзанимает пустой слот, и линия не рисуется.\n\nОриентация:\n\n- `horizontal` — вставка между строками, линия занимает всю ширину родителя.\n- `vertical` — вставка между колонками, линия занимает всю высоту родителя.\n\nВдоль своей оси линия размеров не имеет — их задаёт родитель.\n\n`placement` ставит линию по нужному краю элемента-цели: `before` — перед ним, `after` — после.\nС ним линия позиционируется абсолютно (появление не сдвигает раскладку) и центрируется на границе\nс соседом. Без `placement` линия остаётся в потоке, и её размещает потребитель.\n\n`atEdge` нужен для первой и последней позиции: у края зоны приёма линия иначе ложится на её обводку\nили обрезается скроллом, поэтому смещается внутрь элемента-цели.\n\n### DropTarget (default `active: false`)\n\nОбласть, принимающая сущность. `active` включает рамку и заливку зоны.\n\nРамка — признак **переноса между зонами**: она появляется, когда сущность взяли в одной зоне,\nа отпускают в другой (перенос из списка в список, из колонки в колонку). Перестановка внутри своей\nзоны рамкой не сопровождается: там всё уже показывает линия вставки либо расступившиеся соседи,\nа лишняя подсветка только шумит.\n\nОбводка рисуется **внутри** зоны, поэтому рамка не двигает соседей и не меняет её размеры.\n\n## Установка\n\n```bash\npnpm add @cloud-ru/ds-drag-and-drop\n```\n\n```ts\nimport {\n  DRAG_MODE,\n  DragGhost,\n  DragPreview,\n  DropIndicator,\n  DropTarget,\n  ORIENTATION,\n  PLACEMENT,\n} from '@cloud-ru/ds-drag-and-drop'\n```\n\n## Примеры использования\n\n### Поверхность копии\n\nDragPreview перенимает скругление сущности внутри\n\n```tsx\nimport { DragPreview } from '@cloud-ru/ds-drag-and-drop';\n\nimport styles from './demo.module.scss';\n\nexport function PreviewSurface() {\n  return (\n    <DragPreview className={styles.entity}>\n      <div className={styles.row}>ListItem 2</div>\n    </DragPreview>\n  );\n}\n```\n\nЖивой перенос в примерах ниже ведёт `@dnd-kit` — примитивы пакета отвечают только за вид. С другой\nDnD-библиотекой меняются источники `isDragging` / `over`, разметка остаётся той же.\n\n### Статический перенос\n\nПотяните строку: соседи стоят на месте, исходная строка приглушена, будущую позицию отмечает линия\n\n```tsx\nimport { closestCenter, DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';\nimport { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';\nimport { DRAG_MODE, DragGhost, DragPreview, DropIndicator, PLACEMENT } from '@cloud-ru/ds-drag-and-drop';\nimport { useState } from 'react';\n\nimport styles from './demo.module.scss';\n\nconst INITIAL_ROWS = [\n  { id: 'row-1', label: 'ListItem 1' },\n  { id: 'row-2', label: 'ListItem 2' },\n  { id: 'row-3', label: 'ListItem 3' },\n  { id: 'row-4', label: 'ListItem 4' },\n];\n\nfunction Row({ id, label, lastIndex }: { id: string; label: string; lastIndex: number }) {\n  const { activeIndex, attributes, index, isDragging, listeners, overIndex, setNodeRef } = useSortable({ id });\n\n  // Статический перенос: соседи стоят на месте, поэтому трансляцию от `@dnd-kit` строке\n  // не применяем. Точку вставки отмечает линия на строке-цели, сторона — по тому, откуда\n  // пришла перетаскиваемая строка.\n  const showIndicator = activeIndex !== -1 && index === overIndex && index !== activeIndex;\n  const placement = overIndex > activeIndex ? PLACEMENT.After : PLACEMENT.Before;\n\n  return (\n    <DragGhost\n      innerRef={setNodeRef}\n      dragging={isDragging}\n      mode={DRAG_MODE.Static}\n      className={styles.grabbable}\n      {...attributes}\n      {...listeners}\n    >\n      <div className={styles.row}>{label}</div>\n      {showIndicator && (\n        <DropIndicator\n          placement={placement}\n          atEdge={\n            (index === 0 && placement === PLACEMENT.Before) || (index === lastIndex && placement === PLACEMENT.After)\n          }\n        />\n      )}\n    </DragGhost>\n  );\n}\n\nexport function InsertionLine() {\n  const [rows, setRows] = useState(INITIAL_ROWS);\n  const [activeId, setActiveId] = useState<string>();\n  // Порог в 4px: без него клик по строке уже считался бы началом переноса.\n  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }));\n\n  const activeRow = rows.find(row => row.id === activeId);\n\n  return (\n    <DndContext\n      // Фиксированный id: без него `@dnd-kit` нумерует свои aria-узлы счётчиком, и на\n      // SSR-странице разметка расходится с клиентской.\n      id='insertion-line'\n      sensors={sensors}\n      collisionDetection={closestCenter}\n      onDragStart={({ active }) => setActiveId(String(active.id))}\n      onDragCancel={() => setActiveId(undefined)}\n      onDragEnd={({ active, over }) => {\n        setActiveId(undefined);\n\n        if (!over || active.id === over.id) {\n          return;\n        }\n\n        setRows(rows =>\n          arrayMove(\n            rows,\n            rows.findIndex(row => row.id === active.id),\n            rows.findIndex(row => row.id === over.id),\n          ),\n        );\n      }}\n    >\n      <SortableContext items={rows.map(row => row.id)} strategy={verticalListSortingStrategy}>\n        <div className={styles.list}>\n          {rows.map(row => (\n            <Row key={row.id} id={row.id} label={row.label} lastIndex={rows.length - 1} />\n          ))}\n        </div>\n      </SortableContext>\n      {/* Копия за курсором: позиционирует её `DragOverlay`, поверхность даёт `DragPreview`. */}\n      <DragOverlay dropAnimation={null}>\n        {activeRow && (\n          <DragPreview className={styles.entity}>\n            <div className={styles.row}>{activeRow.label}</div>\n          </DragPreview>\n        )}\n      </DragOverlay>\n    </DndContext>\n  );\n}\n```\n\n### Динамический перенос\n\nПотяните строку: соседи расступаются сразу, а её слот пустеет и сам показывает точку вставки — линия не нужна\n\n```tsx\nimport { closestCenter, DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';\nimport { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';\nimport { CSS } from '@dnd-kit/utilities';\nimport { DRAG_MODE, DragGhost, DragPreview } from '@cloud-ru/ds-drag-and-drop';\nimport { useState } from 'react';\n\nimport styles from './demo.module.scss';\n\nconst INITIAL_ROWS = [\n  { id: 'row-1', label: 'ListItem 1' },\n  { id: 'row-2', label: 'ListItem 2' },\n  { id: 'row-3', label: 'ListItem 3' },\n  { id: 'row-4', label: 'ListItem 4' },\n];\n\nfunction Row({ id, label }: { id: string; label: string }) {\n  const { attributes, isDragging, listeners, setNodeRef, transform, transition } = useSortable({ id });\n\n  return (\n    <DragGhost\n      innerRef={setNodeRef}\n      dragging={isDragging}\n      mode={DRAG_MODE.Dynamic}\n      className={styles.grabbable}\n      // Динамический перенос: соседи расступаются трансляцией от `@dnd-kit`, а слот\n      // перетаскиваемой строки пустеет и сам показывает точку вставки — линия не нужна.\n      style={{ transform: CSS.Translate.toString(transform), transition }}\n      {...attributes}\n      {...listeners}\n    >\n      <div className={styles.row}>{label}</div>\n    </DragGhost>\n  );\n}\n\nexport function DynamicGap() {\n  const [rows, setRows] = useState(INITIAL_ROWS);\n  const [activeId, setActiveId] = useState<string>();\n  // Порог в 4px: без него клик по строке уже считался бы началом переноса.\n  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }));\n\n  const activeRow = rows.find(row => row.id === activeId);\n\n  return (\n    <DndContext\n      // Фиксированный id: без него `@dnd-kit` нумерует свои aria-узлы счётчиком, и на\n      // SSR-странице разметка расходится с клиентской.\n      id='dynamic-gap'\n      sensors={sensors}\n      collisionDetection={closestCenter}\n      onDragStart={({ active }) => setActiveId(String(active.id))}\n      onDragCancel={() => setActiveId(undefined)}\n      onDragEnd={({ active, over }) => {\n        setActiveId(undefined);\n\n        if (!over || active.id === over.id) {\n          return;\n        }\n\n        setRows(rows =>\n          arrayMove(\n            rows,\n            rows.findIndex(row => row.id === active.id),\n            rows.findIndex(row => row.id === over.id),\n          ),\n        );\n      }}\n    >\n      <SortableContext items={rows.map(row => row.id)} strategy={verticalListSortingStrategy}>\n        <div className={styles.list}>\n          {rows.map(row => (\n            <Row key={row.id} id={row.id} label={row.label} />\n          ))}\n        </div>\n      </SortableContext>\n      <DragOverlay dropAnimation={null}>\n        {activeRow && (\n          <DragPreview className={styles.entity}>\n            <div className={styles.row}>{activeRow.label}</div>\n          </DragPreview>\n        )}\n      </DragOverlay>\n    </DndContext>\n  );\n}\n```\n\n### Перенос между зонами\n\nПеретащите строку в соседнюю зону: рамку получает только чужая зона — та, в которую переносят\n\n```tsx\nimport {\n  DndContext,\n  DragOverlay,\n  PointerSensor,\n  useDraggable,\n  useDroppable,\n  useSensor,\n  useSensors,\n} from '@dnd-kit/core';\nimport { DragGhost, DragPreview, DropTarget } from '@cloud-ru/ds-drag-and-drop';\nimport { useState } from 'react';\n\nimport styles from './demo.module.scss';\n\nconst ZONES = [\n  { id: 'zone-1', label: 'Зона 1' },\n  { id: 'zone-2', label: 'Зона 2' },\n];\n\nconst INITIAL_ITEMS = [\n  { id: 'item-1', label: 'ListItem 1', zoneId: 'zone-1' },\n  { id: 'item-2', label: 'ListItem 2', zoneId: 'zone-1' },\n  { id: 'item-3', label: 'ListItem 3', zoneId: 'zone-2' },\n];\n\ntype Item = (typeof INITIAL_ITEMS)[number];\n\nfunction Row({ id, label }: Pick<Item, 'id' | 'label'>) {\n  const { attributes, isDragging, listeners, setNodeRef } = useDraggable({ id });\n\n  return (\n    <DragGhost innerRef={setNodeRef} dragging={isDragging} className={styles.grabbable} {...attributes} {...listeners}>\n      <div className={styles.row}>{label}</div>\n    </DragGhost>\n  );\n}\n\nfunction Zone({ id, label, items, sourceZoneId }: { id: string; label: string; items: Item[]; sourceZoneId?: string }) {\n  const { isOver, setNodeRef } = useDroppable({ id });\n\n  // Рамка — признак переноса между зонами: своя зона её не получает.\n  const active = isOver && sourceZoneId !== undefined && sourceZoneId !== id;\n\n  return (\n    <DropTarget innerRef={setNodeRef} active={active} className={styles.zone}>\n      <div className={styles.zoneLabel}>{label}</div>\n      {items.map(item => (\n        <Row key={item.id} id={item.id} label={item.label} />\n      ))}\n    </DropTarget>\n  );\n}\n\nexport function ActiveZone() {\n  const [items, setItems] = useState(INITIAL_ITEMS);\n  const [activeId, setActiveId] = useState<string>();\n  // Порог в 4px: без него клик по строке уже считался бы началом переноса.\n  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }));\n\n  const activeItem = items.find(item => item.id === activeId);\n\n  return (\n    <DndContext\n      // Фиксированный id: без него `@dnd-kit` нумерует свои aria-узлы счётчиком, и на\n      // SSR-странице разметка расходится с клиентской.\n      id='active-zone'\n      sensors={sensors}\n      onDragStart={({ active }) => setActiveId(String(active.id))}\n      onDragCancel={() => setActiveId(undefined)}\n      onDragEnd={({ active, over }) => {\n        setActiveId(undefined);\n\n        if (!over) {\n          return;\n        }\n\n        setItems(items => items.map(item => (item.id === active.id ? { ...item, zoneId: String(over.id) } : item)));\n      }}\n    >\n      <div className={styles.zones}>\n        {ZONES.map(zone => (\n          <Zone\n            key={zone.id}\n            id={zone.id}\n            label={zone.label}\n            items={items.filter(item => item.zoneId === zone.id)}\n            sourceZoneId={activeItem?.zoneId}\n          />\n        ))}\n      </div>\n      <DragOverlay dropAnimation={null}>\n        {activeItem && (\n          <DragPreview className={styles.entity}>\n            <div className={styles.row}>{activeItem.label}</div>\n          </DragPreview>\n        )}\n      </DragOverlay>\n    </DndContext>\n  );\n}\n```\n\n## Props\n\n### DragGhost\n\n**DragGhostProps**\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `children` | `ReactNode` | — | Сущность, остающаяся на своей позиции на время переноса. |\n| `className` | `string` | — | CSS-класс |\n| `data-test-id` | `string` | — |  |\n| `dragging` | `boolean` | `false` | Сущность переносится прямо сейчас. По умолчанию: false |\n| `innerRef` | `Ref<HTMLDivElement>` | — | Ref на корневой элемент — к нему привязывается sortable-узел DnD-библиотеки. |\n| `mode` | `\"dynamic\"` \\| `\"static\"` | `static` | Режим переноса: `static` — соседи стоят на месте, сущность приглушается, точку вставки <br/> показывает `DropIndicator`; `dynamic` — соседи расступаются сразу, а слот сущности пустеет <br/> и сам показывает точку вставки (линия в этом режиме не нужна). По умолчанию: static |\n\n#### Related types\n\n- `DragMode` = `\"dynamic\"` \\| `\"static\"`\n\n### DragPreview\n\n**DragPreviewProps**\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `children` | `ReactNode` | — | Перетаскиваемая сущность: строка списка, карточка, чип — то, что едет за курсором. |\n| `className` | `string` | — | CSS-класс |\n| `data-test-id` | `string` | — |  |\n| `innerRef` | `Ref<HTMLDivElement>` | — | Ref на корневой элемент |\n\n### DropIndicator\n\n**DropIndicatorProps**\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `atEdge` | `boolean` | `false` | Линия стоит у края зоны приёма (первая или последняя позиция). Смещает её внутрь зоны, иначе <br/> линия ложится на обводку зоны либо обрезается скроллом. Работает вместе с `placement`. <br/> По умолчанию: false |\n| `className` | `string` | — | CSS-класс |\n| `data-test-id` | `string` | — |  |\n| `innerRef` | `Ref<HTMLDivElement>` | — | Ref на корневой элемент |\n| `orientation` | `\"horizontal\"` \\| `\"vertical\"` | `horizontal` | Ориентация линии: horizontal — вставка между строками, vertical — между колонками. По умолчанию: horizontal |\n| `placement` | `\"after\"` \\| `\"before\"` | — | Край элемента-цели, у которого стоит линия. Задан — линия позиционируется абсолютно по этому <br/> краю и центрируется на границе с соседом; не задан — линия остаётся в потоке, и её размещает <br/> потребитель. Требует `position` на элементе-цели. |\n\n#### Related types\n\n- `Orientation` = `\"horizontal\"` \\| `\"vertical\"`\n\n- `Placement` = `\"after\"` \\| `\"before\"`\n\n### DropTarget\n\n**DropTargetProps**\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `active` | `boolean` | `false` | Зона принимает перетаскиваемую сущность прямо сейчас — включает рамку и заливку. По умолчанию: false |\n| `children` | `ReactNode` | — | Содержимое зоны |\n| `className` | `string` | — | CSS-класс |\n| `data-test-id` | `string` | — |  |\n| `innerRef` | `Ref<HTMLDivElement>` | — | Ref на корневой элемент — к нему привязывается droppable-узел DnD-библиотеки. |\n\nВсе четыре компонента принимают атрибуты `<div>`, `data-test-id` и ARIA — через них передаются обработчики\nи `innerRef` для droppable-узла DnD-библиотеки.\n\n## Смотри также\n\n- **List** — переупорядочивание строк на этих примитивах.\n","readmeFilename":"README.md"}