Skip to content

Commit

Permalink
FIX Various updates to DND to work better
Browse files Browse the repository at this point in the history
Forms now collapse while being dragged around
Much refactor to move away from state updates where possible
  • Loading branch information
ScopeyNZ committed Oct 23, 2018
1 parent 03421c8 commit dfe2913
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 119 deletions.
2 changes: 1 addition & 1 deletion client/src/components/ElementEditor/Content.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Content extends PureComponent {
SummaryComponent,
activeTab,
onFormInit,
handleLoadingError
handleLoadingError,
} = this.props;

return (
Expand Down
80 changes: 43 additions & 37 deletions client/src/components/ElementEditor/Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,7 @@ import { loadElementSchemaValue } from 'state/editor/loadElementSchemaValue';
import * as TabsActions from 'state/tabs/TabsActions';
import { DragSource, DropTarget } from 'react-dnd';
import { getEmptyImage } from 'react-dnd-html5-backend';

const elementSource = {
beginDrag(props) {
const { element, onDragStart } = props;
if (onDragStart) {
onDragStart(element);
}
return element;
}
};

const elementTarget = {
drop(props) {
const { element, onDragDrop } = props;

if (onDragDrop) {
onDragDrop(element);
}
},

hover(props) {
const { element, onDragOver } = props;

if (onDragOver) {
onDragOver(element);
}
}
};

import { isOverTop } from 'lib/dragHelpers';

/**
* The Element component used in the context of an ElementEditor shows the summary
Expand Down Expand Up @@ -244,7 +216,6 @@ class Element extends Component {
link={link}
editTabs={editTabs}
previewExpanded={previewExpanded}
expandable={element.InlineEditable}
handleEditTabsClick={this.handleTabClick}
activeTab={activeTab}
disableTooltip={isDragging}
Expand All @@ -254,7 +225,7 @@ class Element extends Component {
fileUrl={element.BlockSchema.fileURL}
fileTitle={element.BlockSchema.fileTitle}
content={element.BlockSchema.content}
previewExpanded={previewExpanded}
previewExpanded={previewExpanded && !isDragging}
activeTab={activeTab}
onFormInit={() => this.updateFormTab(activeTab)}
handleLoadingError={this.handleLoadingError}
Expand Down Expand Up @@ -321,7 +292,7 @@ Element.propTypes = {
isDragging: PropTypes.bool.isRequired,
isOver: PropTypes.bool.isRequired,
onDragOver: PropTypes.func, // eslint-disable-line react/no-unused-prop-types
onDragDrop: PropTypes.func, // eslint-disable-line react/no-unused-prop-types
onDragEnd: PropTypes.func, // eslint-disable-line react/no-unused-prop-types
onDragStart: PropTypes.func, // eslint-disable-line react/no-unused-prop-types
};

Expand All @@ -331,14 +302,49 @@ Element.defaultProps = {

export { Element as Component };

const elementSource = {
beginDrag(props) {
return props.element;
},

endDrag(props, monitor) {
const { onDragEnd } = props;

if (!onDragEnd || !monitor.getDropResult()) {
return;
}

onDragEnd(monitor.getItem().ID, monitor.getDropResult().dropAfterID);
}
};

const elementTarget = {
drop(props, monitor, component) {
const { element } = props;

return {
target: element.ID,
dropSpot: isOverTop(monitor, component) ? 'top' : 'bottom',
};
},

hover(props, monitor, component) {
const { element, onDragOver } = props;

if (onDragOver) {
onDragOver(element, isOverTop(monitor, component));
}
},
};

export default compose(
DropTarget('element', elementTarget, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
DropTarget('element', elementTarget, (connector, monitor) => ({
connectDropTarget: connector.dropTarget(),
isOver: monitor.isOver(),
})),
DragSource('element', elementSource, (connect, monitor) => ({
connectDragSource: connect.dragSource(),
connectDragPreview: connect.dragPreview(),
DragSource('element', elementSource, (connector, monitor) => ({
connectDragSource: connector.dragSource(),
connectDragPreview: connector.dragPreview(),
isDragging: monitor.isDragging(),
})),
connect(mapStateToProps, mapDispatchToProps),
Expand Down
4 changes: 0 additions & 4 deletions client/src/components/ElementEditor/Element.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
}
}

&:last-child {
border-bottom: 0;
}

&--dragging {
opacity: 0.3;
cursor: grabbing;
Expand Down
61 changes: 26 additions & 35 deletions client/src/components/ElementEditor/ElementEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { compose } from 'redux';
import { elementTypeType } from 'types/elementTypeType';
import { connect } from 'react-redux';
import { loadElementFormStateName } from 'state/editor/loadElementFormStateName';
import { DragDropContext } from 'react-dnd';
import { DragDropContext, DropTarget } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import classnames from 'classnames';
import sortBlockMutation from 'state/editor/sortBlockMutation';
Expand All @@ -19,47 +19,32 @@ class ElementEditor extends PureComponent {
super(props);

this.state = {
dragTargetElementId: undefined,
isDragging: false,
draggedElement: null,
dragTargetElementId: null,
dragSpot: null,
};

this.handleDragOver = this.handleDragOver.bind(this);
this.handleDragDrop = this.handleDragDrop.bind(this);
this.handleDragStart = this.handleDragStart.bind(this);
this.handleDragEnd = this.handleDragEnd.bind(this);
}

handleDragStart(element) {
this.setState({
draggedElement: element,
});
}

handleDragOver(element) {
handleDragOver(element = null, isOverTop = null) {
const id = element ? element.ID : false;

if (this.state.dragTargetElementId !== id) {
this.setState({
dragTargetElementId: id,
isDragging: true,
});
}
this.setState({
dragTargetElementId: id,
dragSpot: isOverTop === false ? 'bottom' : 'top',
});
}

handleDragDrop() {
const { dragTargetElementId: targetId, draggedElement: element } = this.state;
handleDragEnd(sourceId, afterId) {
const { actions: { handleSortBlock }, pageId } = this.props;

handleSortBlock(sourceId, afterId, pageId);

this.setState({
dragTargetElementId: undefined,
isDragging: false,
dragTargetElementId: null,
dragSpot: null,
});

if (!handleSortBlock || (targetId && targetId === element.ID)) {
return;
}

handleSortBlock(element.ID, targetId || 0, pageId);
}

render() {
Expand All @@ -71,30 +56,32 @@ class ElementEditor extends PureComponent {
pageId,
elementalAreaId,
elementTypes,
isDraggingOver,
connectDropTarget,
} = this.props;
const { dragTargetElementId, isDragging } = this.state;
const { dragTargetElementId, dragSpot } = this.state;

const classNames = classnames('element-editor', {
'element-editor--dragging': isDragging,
// 'element-editor--dragging': isDragging,
});

return (
return connectDropTarget(
<div className={classNames}>
<ToolbarComponent
elementTypes={elementTypes}
elementalAreaId={elementalAreaId}
onDragOver={this.handleDragOver}
onDragDrop={this.handleDragDrop}
/>
<ListComponent
elementTypes={elementTypes}
pageId={pageId}
elementalAreaId={elementalAreaId}
onDragOver={this.handleDragOver}
onDragDrop={this.handleDragDrop}
onDragStart={this.handleDragStart}
onDragEnd={this.handleDragEnd}
dragSpot={dragSpot}
isDraggingOver={isDraggingOver}
dragTargetElementId={dragTargetElementId}
isDragging={isDragging}
/>
<ElementDragPreview />
<input name={fieldName} type="hidden" value={JSON.stringify(formState)} />
Expand Down Expand Up @@ -136,6 +123,10 @@ function mapStateToProps(state) {
export { ElementEditor as Component };
export default compose(
DragDropContext(HTML5Backend),
DropTarget('element', {}, (connector, monitor) => ({
connectDropTarget: connector.dropTarget(),
isDraggingOver: monitor.isOver(), // isDragging is not available on DropTargetMonitor
})),
connect(mapStateToProps),
inject(
['ElementToolbar', 'ElementList'],
Expand Down
Loading

0 comments on commit dfe2913

Please sign in to comment.