{"id":30356610,"url":"https://github.com/obsfx/react-optimized-dnd","last_synced_at":"2026-03-09T04:31:41.746Z","repository":{"id":295819820,"uuid":"990419894","full_name":"obsfx/react-optimized-dnd","owner":"obsfx","description":"A React package for building performant drag-and-drop interfaces.","archived":false,"fork":false,"pushed_at":"2025-05-27T20:09:38.000Z","size":269,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-09T08:53:11.200Z","etag":null,"topics":["board","component","context","dnd","drag-and-drop","draggable","droppable","hooks","kanban","library","performant","react","react-dnd","trello","typescript"],"latest_commit_sha":null,"homepage":"https://react-optimized-dnd.omercan.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/obsfx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-26T05:04:57.000Z","updated_at":"2025-05-27T20:09:41.000Z","dependencies_parsed_at":"2025-05-27T14:47:39.395Z","dependency_job_id":"41e86647-8308-41e8-9e43-cce49eb14746","html_url":"https://github.com/obsfx/react-optimized-dnd","commit_stats":null,"previous_names":["obsfx/react-optimized-dnd"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/obsfx/react-optimized-dnd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obsfx%2Freact-optimized-dnd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obsfx%2Freact-optimized-dnd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obsfx%2Freact-optimized-dnd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obsfx%2Freact-optimized-dnd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/obsfx","download_url":"https://codeload.github.com/obsfx/react-optimized-dnd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obsfx%2Freact-optimized-dnd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30283414,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T02:57:19.223Z","status":"ssl_error","status_checked_at":"2026-03-09T02:56:26.373Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["board","component","context","dnd","drag-and-drop","draggable","droppable","hooks","kanban","library","performant","react","react-dnd","trello","typescript"],"created_at":"2025-08-19T06:14:29.773Z","updated_at":"2026-03-09T04:31:41.727Z","avatar_url":"https://github.com/obsfx.png","language":"TypeScript","readme":"# react-optimized-dnd\n\nA React package for building performant drag-and-drop interfaces. Provides context provider, hooks, and type definitions for flexible, optimized DnD in React apps.\n\n## Features\n\n- Simple API: Provider and hooks for drag-and-drop\n- Optimized for React performance\n- TypeScript support\n- No external dependencies\n\n## Installation\n\n```\nnpm install react-optimized-dnd\n```\n\nor\n\n```\nyarn add react-optimized-dnd\n```\n\n## Usage Example\n\nBelow is a minimal Trello-like board with draggable cards and droppable columns.\n\n```tsx\nimport { useState } from 'react';\nimport { ReactOptimizedDndProvider, useDraggable, useDroppable } from 'react-optimized-dnd';\n\nconst columnsData = [\n  [\n    { title: 'Card 1', description: 'Desc 1', color: '#60a5fa' },\n    { title: 'Card 2', description: 'Desc 2', color: '#f59e42' },\n  ],\n  [{ title: 'Card 3', description: 'Desc 3', color: '#10b981' }],\n  [{ title: 'Card 4', description: 'Desc 4', color: '#f43f5e' }],\n];\n\nfunction Card({ index, columnIndex, title, description, color }) {\n  const { droppableRef, isOver } = useDroppable({ data: { index, columnIndex, type: 'card' } });\n  const { handleRef, deltaPos, isDragging } = useDraggable({\n    data: { index, columnIndex, type: 'card' },\n  });\n  return (\n    \u003cdiv\n      ref={droppableRef}\n      style={{\n        border: isDragging ? '1px solid #e5e7eb' : '1px solid transparent',\n        background: isDragging ? '#fafaf9' : 'white',\n        borderRadius: 6,\n      }}\n    \u003e\n      \u003cdiv\n        ref={handleRef}\n        style={{\n          cursor: isDragging ? 'grabbing' : 'grab',\n          background: isDragging ? '#93c5fd' : '#fff',\n          borderRadius: 6,\n          padding: 12,\n          boxShadow: '0 1px 2px #0001',\n          transform: `translate(${deltaPos.x}px, ${deltaPos.y}px)`,\n        }}\n      \u003e\n        \u003cdiv style={{ display: 'flex', alignItems: 'center', gap: 8 }}\u003e\n          \u003cdiv\n            style={{\n              width: 24,\n              height: 24,\n              borderRadius: '50%',\n              background: color,\n              color: '#fff',\n              display: 'flex',\n              alignItems: 'center',\n              justifyContent: 'center',\n              fontWeight: 700,\n            }}\n          \u003e\n            {title.charAt(0)}\n          \u003c/div\u003e\n          \u003cdiv\u003e\n            \u003cdiv style={{ fontWeight: 500 }}\u003e{title}\u003c/div\u003e\n            \u003cdiv style={{ fontSize: 12, color: '#6b7280' }}\u003e{description}\u003c/div\u003e\n          \u003c/div\u003e\n        \u003c/div\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  );\n}\n\nfunction Column({ children, index }) {\n  const { droppableRef, isOver } = useDroppable({ data: { index, type: 'column' } });\n  return (\n    \u003cdiv\n      ref={droppableRef}\n      style={{\n        width: 280,\n        background: '#f3f4f6',\n        borderRadius: 8,\n        padding: 16,\n        display: 'flex',\n        flexDirection: 'column',\n        gap: 8,\n      }}\n    \u003e\n      {children}\n      {isOver \u0026\u0026 (\n        \u003cdiv\n          style={{\n            height: 48,\n            background: '#dbeafe',\n            border: '1px solid #bfdbfe',\n            borderRadius: 6,\n          }}\n        /\u003e\n      )}\n    \u003c/div\u003e\n  );\n}\n\nexport default function Example() {\n  const [columns, setColumns] = useState(columnsData);\n  return (\n    \u003cdiv style={{ display: 'flex', gap: 16 }}\u003e\n      \u003cReactOptimizedDndProvider\n        onDragStart={() =\u003e {}}\n        onDragEnd={(state) =\u003e {\n          const dragging = state.draggingElement.data;\n          const over = state.overElement.data;\n          if (!dragging || !over) return;\n          if (over.type === 'card') {\n            const newColumns = [...columns];\n            const targetCol = over.columnIndex;\n            const targetIdx = over.index;\n            const dragCol = dragging.columnIndex;\n            const dragIdx = dragging.index;\n            const item = newColumns[dragCol][dragIdx];\n            newColumns[dragCol] = newColumns[dragCol].filter((_, i) =\u003e i !== dragIdx);\n            newColumns[targetCol].splice(targetIdx, 0, item);\n            setColumns(newColumns);\n            return;\n          }\n          if (over.type === 'column') {\n            const newColumns = [...columns];\n            const targetCol = over.index;\n            const dragCol = dragging.columnIndex;\n            const dragIdx = dragging.index;\n            const item = newColumns[dragCol][dragIdx];\n            newColumns[dragCol] = newColumns[dragCol].filter((_, i) =\u003e i !== dragIdx);\n            newColumns[targetCol] = [...newColumns[targetCol], item];\n            setColumns(newColumns);\n            return;\n          }\n        }}\n        onDragOver={() =\u003e {}}\n      \u003e\n        {columns.map((column, columnIndex) =\u003e (\n          \u003cColumn key={columnIndex} index={columnIndex}\u003e\n            {column.map((item, cardIndex) =\u003e (\n              \u003cCard key={cardIndex} index={cardIndex} columnIndex={columnIndex} {...item} /\u003e\n            ))}\n          \u003c/Column\u003e\n        ))}\n      \u003c/ReactOptimizedDndProvider\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n## API\n\n### `ReactOptimizedDndProvider`\n\nWrap your app or a subtree to enable drag-and-drop. Accepts optional callbacks:\n\n- `onDragStart: (state) =\u003e void`\n- `onDragEnd: (state) =\u003e void`\n- `onDragOver: (state) =\u003e void`\n\n### `useDraggable`\n\nHook to make an element draggable.\n\n- `data`: Any object to identify the draggable (required)\n- Returns: `{ handleRef, deltaPos, isDragging }`\n\n### `useDroppable`\n\nHook to make an element a drop target.\n\n- `data`: Any object to identify the droppable (required)\n- Returns: `{ droppableRef, isOver }`\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobsfx%2Freact-optimized-dnd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fobsfx%2Freact-optimized-dnd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobsfx%2Freact-optimized-dnd/lists"}