UNPKG

react-components

Version:

React components used by Khan Academy

79 lines (74 loc) 2.56 kB
/* This component makes its children a drag target. Example: * * <DragTarget onDrop={this.handleDrop}>Drag to me</DragTarget> * * ... * * handleDrop: function(e) { * this.addImages(e.nativeEvent.dataTransfer.files); * } * * Now "Drag to me" will be a drag target - when something is dragged over it, * the element will become partially transparent as a visual indicator that * it's a target. */ // TODO(joel) - indicate before the hover is over the target that it's possible // to drag into the target. This would (I think) require a high level handler - // like on Perseus itself, waiting for onDragEnter, then passing down the // event. Sounds like a pain. Possible workaround - create a div covering the // entire page... // // Other extensions: // * custom styles for global drag and dragOver // * only respond to certain types of drags (only images for instance)! const React = require('react'); const DragTarget = React.createClass({displayName: "DragTarget", propTypes: { onDrop: React.PropTypes.func.isRequired, component: React.PropTypes.any, // component type shouldDragHighlight: React.PropTypes.func, style: React.PropTypes.any, }, getDefaultProps: function() { return { component: "div", shouldDragHighlight: function() {return true;}, }; }, getInitialState: function() { return {dragHover: false}; }, handleDrop: function(e) { e.stopPropagation(); e.preventDefault(); this.setState({dragHover: false}); this.props.onDrop(e); }, handleDragEnd: function() { this.setState({dragHover: false}); }, handleDragOver: function(e) { e.preventDefault(); }, handleDragLeave: function() { this.setState({dragHover: false}); }, handleDragEnter: function(e) { this.setState({dragHover: this.props.shouldDragHighlight(e)}); }, render: function() { const opacity = this.state.dragHover ? {"opacity": 0.3} : {}; const Component = this.props.component; return ( React.createElement(Component, { style: Object.assign({}, this.props.style, opacity), onDrop: this.handleDrop, onDragEnd: this.handleDragEnd, onDragOver: this.handleDragOver, onDragEnter: this.handleDragEnter, onDragLeave: this.handleDragLeave} ) ); }, }); module.exports = DragTarget;