{"id":13481261,"url":"https://github.com/chrisjpatty/react-dragtastic","last_synced_at":"2025-04-06T15:12:15.059Z","repository":{"id":22277199,"uuid":"94812260","full_name":"chrisjpatty/react-dragtastic","owner":"chrisjpatty","description":"A simple drag and drop library for React which uses the more stable mouseDown/mouseUp event pattern instead of the problematic HTML5 drag and drop API","archived":false,"fork":false,"pushed_at":"2023-01-12T09:50:09.000Z","size":3769,"stargazers_count":190,"open_issues_count":56,"forks_count":9,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-30T13:36:54.906Z","etag":null,"topics":["dnd","drag-and-drop","draggable","droppable","react"],"latest_commit_sha":null,"homepage":"https://react-dragtastic.netlify.app/","language":"JavaScript","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/chrisjpatty.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-19T19:18:21.000Z","updated_at":"2024-12-18T11:59:17.000Z","dependencies_parsed_at":"2023-01-12T08:30:34.818Z","dependency_job_id":null,"html_url":"https://github.com/chrisjpatty/react-dragtastic","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisjpatty%2Freact-dragtastic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisjpatty%2Freact-dragtastic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisjpatty%2Freact-dragtastic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisjpatty%2Freact-dragtastic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisjpatty","download_url":"https://codeload.github.com/chrisjpatty/react-dragtastic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247500468,"owners_count":20948880,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["dnd","drag-and-drop","draggable","droppable","react"],"created_at":"2024-07-31T17:00:50.270Z","updated_at":"2025-04-06T15:12:15.040Z","avatar_url":"https://github.com/chrisjpatty.png","language":"JavaScript","funding_links":[],"categories":["Components"],"sub_categories":["Interaction"],"readme":"![react-dragtastic](https://raw.githubusercontent.com/chrisjpatty/react-dragtastic/master/logo.png)\n\n# react-dragtastic\n\n[![npm version](https://badge.fury.io/js/react-dragtastic.svg)](https://badge.fury.io/js/react-dragtastic)\n[![npm version](https://img.shields.io/npm/dt/react-dragtastic.svg)](https://badge.fury.io/js/react-dragtastic)\n[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)\n\nA simple drag and drop library for React which uses the more stable mouseDown/mouseUp pattern instead of the problematic HTML5 drag and drop API.\n\nDrag and drop interfaces are complicated and difficult to properly program, this package attempts to alleviate some of the common hangups with drag and drop libraries. It should be noted that there are more mature solutions available such as the excellent [react-dnd](https://github.com/react-dnd/react-dnd) package, however for many simple drag and drop applications, the implementation of such packages can quickly become arduous.\n\n* _Warning, version 2 represents a significant rewrite of version 1 of_ `react-dragtastic`. _The API is completely different, but with the changes come several stability improvements, primitive mobile support, and significantly increased render flexibility. Be sure you're ready to rewrite your drag-and-drop implementation before upgrading from version 1._\n\n## Example\n\n[Demo Site](https://react-dragtastic.netlify.com/)\n_More examples coming soon_\n\n[Code Sandbox Example](https://codesandbox.io/s/5z32yqk7l4)\n\n## Installation\n\n```shell\nnpm install --save react-dragtastic\nor\nyarn add react-dragtastic\n```\n\n## Usage\n\n###### For ES6 and up\n\n```javascript\nimport {\n  Draggable,\n  Droppable,\n  DragComponent,\n  DragState\n} from \"react-dragtastic\"\n```\n\n###### For ES5\n\n```javascript\nvar dnd = require(\"react-dragtastic\")\nvar Draggable = dnd.Draggable\nvar Droppable = dnd.Droppable\nvar DragComponent = dnd.DragComponent\n```\n\n## Overview\n\n`react-dragtastic` makes use of three different components, a `\u003cDraggable/\u003e` component which defines a zone on a page which can then trigger drag events, a `\u003cDroppable/\u003e` component, which defines zones which trigger drop events, and a `\u003cDragComponent/\u003e` component which defines the component that follows the user's pointer around the page while dragging.\n\n`react-dragtastic` uses the \"function-as-child\" component pattern to give you full control over the rendering details of each component.\n\n### Draggable\n\nThis defines a draggable zone. At a minimum, spread the events over the element that should be draggable (usually the root element).\n\n* `id`: An id which will be used in the draggable zone's target `\u003cDragComponent/\u003e`\n* `type`: A string, or array of strings, used to limit which droppable zones will accept `\u003cDragComponent/\u003e`'s attached to this draggable.\n* `data`: Data of any type which will be passed to the `onDrop` function of any `\u003cDroppable/\u003e` which accepts this `\u003cDraggable/\u003e`'s type.\n* `onDragStart`: A function which will be called when the `\u003cDraggable/\u003e` zone is activated (The user started dragging).\n* `onDragEnd`: A function which will be called when the `\u003cDraggable/\u003e` zone is deactivated (The user stopped dragging).\n* `onDrag`: A function which will be called every time the user's cursor moves while dragging.\n* `delay`: An optional int representing the distance in pixels the user's pointer must travel to activate the draggable. Defaults to `8`\n* `subscribeTo`: An optional array of strings. For performance reasons you can limit which keys in the dragState your component subscribes to. For example, you may pass ['type', 'data'] to only rerender if these keys change.\n\nProperties available from `dragState`:\n\n* All the properties listed in the dragState section.\n* `isActive`: A boolean representing if the draggable is currently active.\n\n```jsx\nclass DraggableZone extends React.Component {\n  render() {\n    return (\n      \u003cDraggable id=\"unique-id\" type=\"apple\"\u003e\n        {dragState =\u003e \u003cdiv {...dragState.events}\u003eI'm a draggable zone\u003c/div\u003e}\n      \u003c/Draggable\u003e\n    )\n  }\n}\n```\n\n### Droppable\n\nThis defines a droppable zone. At a minimum, spread the events over the element that should be droppable (usually the root element).\n\n* `accepts`: A string type corresponding to the `type` property of the `\u003cDraggable/\u003e` zone for which this `\u003cDroppable/\u003e` should accept drop events.\n* `onDrop`: A function which will be called when a user drops a `\u003cDragComponent/\u003e` on this `\u003cDroppable/\u003e` with an accepted type.\n* `onDragEnter`: A function which will be called when the user's cursor enters the `\u003cDroppable/\u003e` while dragging. This function will be called regardless of whether the droppable accepts the draggable currently being dragged.\n* `onDragLeave`: A function which will be called when the user's cursor leaves the `\u003cDroppable/\u003e` while dragging. This function will be called regardless of whether the droppable accepts the draggable currently being dragged.\n* `subscribeTo`: An optional array of strings. For performance reasons you can limit which keys in the dragState your component subscribes to. For example, you may pass ['type', 'data'] to only rerender if these keys change.\n\nProperties available from `dragState`:\n\n* All the properties listed in the dragState section.\n* `isOver`: A boolean representing if the user is currently hovering the `\u003cDroppable/\u003e`.\n* `willAccept`: A boolean representing if this droppable will accept the currently dragging `\u003cDragComponent/\u003e`.\n\n```jsx\nclass DroppableZone extends React.Component {\n  render() {\n    return (\n      \u003cDroppable accepts=\"apple\"\u003e\n        {dragState =\u003e \u003cdiv {...dragState.events}\u003eI'm a droppable zone\u003c/div\u003e}\n      \u003c/Droppable\u003e\n    )\n  }\n}\n```\n\n### DragComponent\n\nBy default, children passed to this component will only render if the user is currently dragging, but this can be overridden.\n\n* `for`: A string corresponding to the `id` property of the `\u003cDraggable/\u003e` zone that should trigger this component to start rendering.\n* `onDrag`: A function which will be called every time a user drags.\n* `alwaysRender`: A boolean determining whether or not the DragComponent should always render. Defaults to `false`.\n* `subscribeTo`: An optional array of strings. For performance reasons you can limit which keys in the dragState your component subscribes to. For example, you may pass ['type', 'data'] to only rerender if these keys change.\n\nProperties available from `dragState`:\n\n* All the properties listed in the dragState section.\n* `isOverAccepted`: a boolean representing whether the user is currently hovering a `\u003cDroppable/\u003e` that accepts the `type` of the currently active `\u003cDraggable/\u003e`\n\n```jsx\nclass DragComponentWrapper extends React.Component {\n  render() {\n    return (\n      \u003cDragComponent for=\"unique-id\"\u003e\n        {dragState =\u003e (\n          \u003cdiv\n            style={{\n              position: \"fixed\",\n              left: dragState.x,\n              top: dragState.y,\n              pointerEvents: \"none\"\n            }}\n          \u003e\n            I will render when my Draggable zone is activated\n          \u003c/div\u003e\n        )}\n      \u003c/DragComponent\u003e\n    )\n  }\n}\n```\n\n### DragState\n\nAll components imported from `react-dragtastic` have access the global dragState with the following properties:\n\n* `x`: The user's current horizontal position on the page.\n* `y`: The user's current vertical position on the page.\n* `startingX`: The user's initial horizontal position on the page when they started dragging.\n* `startingy`: The user's initial vertical position on the page when they started dragging.\n* `isDragging`: A boolean representing whether the user is currently dragging.\n* `currentlyDraggingId`: The id of the currently dragging element.\n* `currentlyHoveredDroppableId`: The id of the `\u003cDroppable/\u003e` currently being hovered.\n* `currentlyHoveredDroppableAccepts`: The `accepts` property of the `\u003cDroppable/\u003e` currently being hovered.\n* `data`: Data from the `data` property of the `\u003cDraggable/\u003e` which is currently active. `null` if not dragging.\n* `type`: The type of the component being currently dragged. `null` if not dragging.\n* `subscribeTo`: An optional array of strings. For performance reasons you can limit which keys in the dragState your component subscribes to. For example, you may pass ['type', 'data'] to only rerender if these keys change.\n\nOccasionally you may need to notify a component about changes in the dragState without making that component a draggable or droppable zone. For these cases there is a fourth component available called `\u003cDragState/\u003e`. This component is used just like a draggable or droppable, but does not accept or trigger any drag events.\n\n```jsx\nclass CompWithDragState extends React.Component {\n  render() {\n    return (\n      \u003cDragState\u003e\n        {dragState =\u003e (\n          \u003cdiv style={{ background: dragState.isDragging ? \"red\" : \"blue\" }}\u003e\n            I always render, and have access to the global dragState.\n          \u003c/div\u003e\n        )}\n      \u003c/DragState\u003e\n    )\n  }\n}\n```\n\n## Troubleshooting\n\n#### My Droppables aren't working!\n\n* You most likely need to set `pointer-events: none` in the css of your `DragComponent`. This allows droppables to receive drop events when the user's pointer is directly on top of the DragComponent as it is being dragged. This property is [well supported](https://caniuse.com/#feat=pointer-events).\n\n#### My app is slow when I have a lot of Draggables or Droppables\n\n* In this case the easiest fix is to use the `subscribeTo` prop to pass an array of dragState keys you want to subscribe to.\n\n## Coming Soon\n\n* A project website with live examples.\n* Screencast showing basic implementation examples.\n* Improved mobile support.\n* Additional event hooks\n\n## Contributing\n\nContributions of any kind are welcome. Please feel free to file issues, submit pull-requests, or drop us a line with feature requests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisjpatty%2Freact-dragtastic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisjpatty%2Freact-dragtastic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisjpatty%2Freact-dragtastic/lists"}