Skip to content

Commit

Permalink
Add nesting sources example
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon committed Mar 19, 2015
1 parent ddc3e52 commit c0209ea
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 129 deletions.
1 change: 1 addition & 0 deletions TODO
Expand Up @@ -6,6 +6,7 @@
* drag offsets and alignments
* are we okay with this API for refs? ask people & see how that works with actual refs
* conflicting backends: must be a nicer solution.
* using initial state in observe(): bummer

dnd-core
* smarter canDrop()
Expand Down
28 changes: 15 additions & 13 deletions examples/_nesting-sources/Container.js
@@ -1,27 +1,29 @@
'use strict';

import React from 'react';
import makeSource from './makeSource';
import Source from './Source';
import Colors from './Colors';
import Target from './Target';
import { DragDropContext, HTML5Backend } from 'react-dnd';

const Container = React.createClass({
render() {
const YellowSource = makeSource(Colors.YELLOW);
const BlueSource = makeSource(Colors.BLUE);
mixins: [DragDropContext({
dragDrop: HTML5Backend
})],

render() {
return (
<div style={{ height: 320 }}>
<div style={{ float: 'left' }}>
<BlueSource>
<YellowSource>
<YellowSource />
<BlueSource />
</YellowSource>
<BlueSource>
<YellowSource />
</BlueSource>
</BlueSource>
<Source color={Colors.BLUE}>
<Source color={Colors.YELLOW}>
<Source color={Colors.YELLOW} />
<Source color={Colors.BLUE} />
</Source>
<Source color={Colors.BLUE}>
<Source color={Colors.YELLOW} />
</Source>
</Source>
</div>

<div style={{ float: 'left', marginLeft: 100, marginTop: 50 }}>
Expand Down
81 changes: 81 additions & 0 deletions examples/_nesting-sources/Source.js
@@ -0,0 +1,81 @@
'use strict';

import React, { createClass, PropTypes } from 'react';
import LinkedStateMixin from 'react/lib/LinkedStateMixin';
import Colors from './Colors';
import { DragSource, ObservePolyfill } from 'react-dnd';

class ColorDragSource extends DragSource {
canDrag() {
var { state } = this.component;
return state && !state.forbidDrag || false;
}

beginDrag() {
return { };
}
}

const style = {
border: '1px dashed gray',
padding: '0.5rem',
margin: '0.5rem'
};

const Source = createClass({
propTypes: {
color: PropTypes.string.isRequired
},

contextTypes: {
dragDrop: PropTypes.object.isRequired
},

mixins: [LinkedStateMixin, ObservePolyfill({
constructor() {
this.dragSource = new ColorDragSource(this);
},

observe() {
return {
dragSource: this.dragSource.connectTo(this.context.dragDrop, this.props.color)
};
}
})],

getInitialState() {
return {
forbidDrag: false
};
},

render() {
const { color, children } = this.props;
const { isDragging, ref } = this.state.data.dragSource;
const opacity = isDragging ? 0.4 : 1;

let backgroundColor;
switch (color) {
case Colors.YELLOW:
backgroundColor = 'lightgoldenrodyellow';
break;
case Colors.BLUE:
backgroundColor = 'lightblue';
break;
}

return (
<div ref={ref}
style={{ ...style, backgroundColor, opacity }}>
<input type='checkbox'
checkedLink={this.linkState('forbidDrag')}>
Forbid drag
</input>

{children}
</div>
);
}
});

export default Source;
66 changes: 31 additions & 35 deletions examples/_nesting-sources/Target.js
@@ -1,17 +1,15 @@
'use strict';

import React from 'react';
import React, { PropTypes, createClass } from 'react';
import Colors from './Colors';
import { DragDropMixin } from 'react-dnd';
import { DropTarget, ObservePolyfill } from 'react-dnd';

function makeDropTarget(color) {
return {
acceptDrop(component) {
component.setState({
lastDroppedColor: color
});
}
};
class ColorDropTarget extends DropTarget {
drop(monitor) {
this.component.setState({
lastDroppedColor: monitor.getItemType()
});
}
}

const style = {
Expand All @@ -22,20 +20,22 @@ const style = {
textAlign: 'center'
};

const Target = React.createClass({
mixins: [DragDropMixin],
const Target = createClass({
contextTypes: {
dragDrop: PropTypes.object.isRequired
},

statics: {
configureDragDrop(register) {
register(Colors.YELLOW, {
dropTarget: makeDropTarget(Colors.YELLOW)
});
mixins: [ObservePolyfill({
constructor() {
this.dropTarget = new ColorDropTarget(this);
},

register(Colors.BLUE, {
dropTarget: makeDropTarget(Colors.BLUE)
});
observe() {
return {
dropTarget: this.dropTarget.connectTo(this.context.dragDrop, [Colors.YELLOW, Colors.BLUE])
};
}
},
})],

getInitialState() {
return {
Expand All @@ -45,30 +45,26 @@ const Target = React.createClass({

render() {
const { lastDroppedColor } = this.state;
const blueDropState = this.getDropState(Colors.BLUE);
const yellowDropState = this.getDropState(Colors.YELLOW);
const isDragging = blueDropState.isDragging || yellowDropState.isDragging;
const isHovering = blueDropState.isHovering || yellowDropState.isHovering;
const opacity = isHovering ? 1 : 0.7;
const { canDrop, isOver, itemType, ref } = this.state.data.dropTarget;
const opacity = isOver ? 1 : 0.7;

let backgroundColor = '#fff';
if (blueDropState.isDragging) {
switch (itemType) {
case Colors.BLUE:
backgroundColor = 'lightblue';
} else if (yellowDropState.isDragging) {
break;
case Colors.YELLOW:
backgroundColor = 'lightgoldenrodyellow';
break;
}

return (
<div {...this.dropTargetFor(Colors.YELLOW, Colors.BLUE)}
style={{
...style,
backgroundColor,
opacity
}}>
<div ref={ref}
style={{ ...style, backgroundColor, opacity }}>

<p>Drop here.</p>

{!isDragging && lastDroppedColor &&
{!canDrop && lastDroppedColor &&
<p>Last dropped: {lastDroppedColor}</p>
}
</div>
Expand Down
77 changes: 0 additions & 77 deletions examples/_nesting-sources/makeSource.js

This file was deleted.

7 changes: 3 additions & 4 deletions examples/index.js
Expand Up @@ -4,13 +4,12 @@ import React from 'react';
import Router, { Route, Link, Redirect, RouteHandler } from 'react-router';
import DustbinSimple from './_dustbin-simple';
import DustbinInteresting from './_dustbin-interesting';
import NestingSources from './_nesting-sources';

/*
DragAroundNaive = require('./_drag-around-naive/index'),
DragAroundCustom = require('./_drag-around-custom/index'),
DustbinInteresting = require('./_dustbin-interesting'),
SortableSimple = require('./_sortable-simple'),
NestingSources = require('./_nesting-sources');
*/

const App = React.createClass({
Expand All @@ -20,6 +19,7 @@ const App = React.createClass({
<h1>react-dnd examples (<a target='_href' href='https://github.com/gaearon/react-dnd/blob/master/examples'>source</a>)</h1>
<ul>
<li>Dustbin (<Link to='dustbin-simple'>simple</Link>, <Link to='dustbin-interesting'>interesting</Link>)</li>
<li>Nesting (<Link to='nesting-sources'>drag sources</Link>)</li>
</ul>
<hr />
<RouteHandler />
Expand All @@ -32,7 +32,6 @@ const App = React.createClass({
<ul>
<li>Dustbin (<Link to='dustbin-simple'>simple</Link>, <Link to='dustbin-interesting'>interesting</Link>)</li>
<li>Drag Around (<Link to='drag-around-naive'>naive</Link>, <Link to='drag-around-custom'>custom</Link>)</li>
<li>Nesting (<Link to='nesting-sources'>drag sources</Link>)</li>
<li>Sortable (<Link to='sortable-simple'>simple</Link>)</li>
</ul>
*/
Expand All @@ -41,6 +40,7 @@ const routes = (
<Route handler={App}>
<Route name='dustbin-simple' path='dustbin-simple' handler={DustbinSimple} />
<Route name='dustbin-interesting' path='dustbin-interesting' handler={DustbinInteresting} />
<Route name='nesting-sources' path='nesting-sources' handler={NestingSources} />
<Redirect from='/' to='dustbin-simple' />
</Route>
);
Expand All @@ -49,7 +49,6 @@ const routes = (
<Route name='dustbin-interesting' path='dustbin-interesting' handler={DustbinInteresting} />
<Route name='drag-around-naive' path='drag-around-naive' handler={DragAroundNaive} />
<Route name='drag-around-custom' path='drag-around-custom' handler={DragAroundCustom} />
<Route name='nesting-sources' path='nesting-sources' handler={NestingSources} />
<Route name='sortable-simple' path='sortable-simple' handler={SortableSimple} />
*/

Expand Down
1 change: 1 addition & 0 deletions modules/ReactDropTarget.js
Expand Up @@ -48,6 +48,7 @@ class TargetAdapter {
canDrop: monitor.canDrop(handle),
isOver: monitor.canDrop(handle) && monitor.isOver(handle),
isOverShallow: monitor.canDrop(handle) && monitor.isOver(handle, true),
itemType: monitor.getItemType(),
ref: (component) => backend.updateTargetNode(handle, findDOMNode(component))
};
}
Expand Down

0 comments on commit c0209ea

Please sign in to comment.