diff --git a/package.json b/package.json index badc4a33..82dc7a44 100644 --- a/package.json +++ b/package.json @@ -144,6 +144,8 @@ "react": "^15.5.0", "react-autosuggest": "^7.0.1", "react-datetime": "^2.6.0", + "react-dnd": "^2.5.4", + "react-dnd-html5-backend": "^2.5.4", "react-dom": "^15.5.0", "react-frame-component": "^1.0.3", "react-hot-loader": "^3.0.0-beta.7", @@ -152,7 +154,6 @@ "react-router-dom": "^4.2.2", "react-router-redux": "^5.0.0-alpha.6", "react-sidebar": "^2.2.1", - "react-simple-dnd": "^0.1.2", "react-sortable": "^1.2.0", "react-split-pane": "^0.1.66", "react-toolbox": "^2.0.0-beta.12", diff --git a/src/components/UI/dndHelpers.js b/src/components/UI/dndHelpers.js new file mode 100644 index 00000000..112eaa2b --- /dev/null +++ b/src/components/UI/dndHelpers.js @@ -0,0 +1,51 @@ +import ReactDNDHTML5Backend from 'react-dnd-html5-backend'; +import { DragDropContext as ReactDNDDragDropContext, DragSource as ReactDNDDragSource, DropTarget as ReactDNDDropTarget } from 'react-dnd'; +import React from 'react'; +import PropTypes from 'prop-types'; + +export const DragSource = ({ namespace, ...props }) => { + const DragComponent = ReactDNDDragSource( + namespace, + { + beginDrag({ children, isDragging, connectDragComponent, ...ownProps }) { + // We return the rest of the props as the ID of the element being dragged. + return ownProps; + }, + }, + (connect, monitor) => ({ + connectDragComponent: connect.dragSource(), + }), + )( + ({ children, connectDragComponent }) => children(connectDragComponent) + ); + + return React.createElement(DragComponent, props, props.children); +}; +DragSource.propTypes = { + children: PropTypes.func.isRequired, +}; + +export const DropTarget = ({ onDrop, namespace, ...props }) => { + const DropComponent = ReactDNDDropTarget( + namespace, + { + drop(ownProps, monitor) { + onDrop(monitor.getItem()); + }, + }, + (connect, monitor) => ({ + connectDropTarget: connect.dropTarget(), + isHovered: monitor.isOver(), + }), + )( + ({ children, connectDropTarget, isHovered }) => children(connectDropTarget, { isHovered }) + ); + + return React.createElement(DropComponent, props, props.children); +}; +DropTarget.propTypes = { + onDrop: PropTypes.func.isRequired, + children: PropTypes.func.isRequired, +}; + +export const HTML5DragDrop = component => ReactDNDDragDropContext(ReactDNDHTML5Backend)(component); diff --git a/src/components/UnpublishedListing/UnpublishedListing.js b/src/components/UnpublishedListing/UnpublishedListing.js index 5a98a4fe..56801578 100644 --- a/src/components/UnpublishedListing/UnpublishedListing.js +++ b/src/components/UnpublishedListing/UnpublishedListing.js @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; import React from 'react'; -import { DragSource, DropTarget, HTML5DragDrop } from 'react-simple-dnd'; +import { DragSource, DropTarget, HTML5DragDrop } from '../UI/dndHelpers'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { Link } from 'react-router-dom'; import moment from 'moment'; @@ -11,6 +11,9 @@ import Button from 'react-toolbox/lib/button'; import UnpublishedListingCardMeta from './UnpublishedListingCardMeta.js'; import { status, statusDescriptions } from '../../constants/publishModes'; +// This is a namespace so that we can only drop these elements on a DropTarget with the same +const DNDNamespace = 'cms-unpublished-entries'; + class UnpublishedListing extends React.Component { static propTypes = { entries: ImmutablePropTypes.orderedMap, @@ -44,12 +47,13 @@ class UnpublishedListing extends React.Component { if (!column) { return entries.entrySeq().map(([currColumn, currEntries]) => ( - {isHovered => ( + {(connect, { isHovered }) => connect(
+ {connect => connect(
+ )} ); }) diff --git a/yarn.lock b/yarn.lock index 932a22ec..f27bd124 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2476,9 +2476,9 @@ disposables@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/disposables/-/disposables-1.0.1.tgz#064727a25b54f502bd82b89aa2dfb8df9f1b39e3" -dnd-core@^2.5.3: - version "2.5.3" - resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-2.5.3.tgz#a4163d59a01779860d2edbdadab5183ce321147c" +dnd-core@^2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-2.5.4.tgz#0c70a8dcbb609c0b222e275fcae9fa83e5897397" dependencies: asap "^2.0.6" invariant "^2.0.0" @@ -7371,18 +7371,18 @@ react-deep-force-update@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-2.1.1.tgz#8ea4263cd6455a050b37445b3f08fd839d86e909" -react-dnd-html5-backend@^2.1.2: - version "2.5.3" - resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-2.5.3.tgz#1158112e8129dfe672d4c72222f266dd05321f03" +react-dnd-html5-backend@^2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-2.5.4.tgz#974ad083f67b12d56977a5b171f5ffeb29d78352" dependencies: lodash "^4.2.0" -react-dnd@^2.1.4: - version "2.5.3" - resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-2.5.3.tgz#ee5357da19d4ebd0e0da0a070a862bbc133e3241" +react-dnd@^2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-2.5.4.tgz#0b6dc5e9d0dfc2909f4f4fe736e5534f3afd1bd9" dependencies: disposables "^1.0.1" - dnd-core "^2.5.3" + dnd-core "^2.5.4" hoist-non-react-statics "^2.1.0" invariant "^2.1.0" lodash "^4.2.0" @@ -7536,13 +7536,6 @@ react-simple-di@^1.2.0: babel-runtime "6.x.x" hoist-non-react-statics "1.x.x" -react-simple-dnd@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/react-simple-dnd/-/react-simple-dnd-0.1.2.tgz#a224231338f13b1f6328ce5c6b8c99d872e59ee0" - dependencies: - react-dnd "^2.1.4" - react-dnd-html5-backend "^2.1.2" - react-sortable@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/react-sortable/-/react-sortable-1.2.0.tgz#5acd7e1910df665408957035acb5f2354519d849"