diff --git a/package.json b/package.json
index 82dc7a44587a..a1fd868cc3dd 100644
--- a/package.json
+++ b/package.json
@@ -154,7 +154,7 @@
"react-router-dom": "^4.2.2",
"react-router-redux": "^5.0.0-alpha.6",
"react-sidebar": "^2.2.1",
- "react-sortable": "^1.2.0",
+ "react-sortable-hoc": "^0.6.8",
"react-split-pane": "^0.1.66",
"react-toolbox": "^2.0.0-beta.12",
"react-topbar-progress-indicator": "^1.0.0",
diff --git a/src/components/Widgets/ListControl.css b/src/components/Widgets/ListControl.css
index 72aaa7dcc01a..4a28af7a170a 100644
--- a/src/components/Widgets/ListControl.css
+++ b/src/components/Widgets/ListControl.css
@@ -52,7 +52,6 @@
.nc-listControl-item {
position: relative;
padding-left: 24px;
- cursor: move;
}
.nc-listControl-objectLabel {
@@ -65,14 +64,6 @@
display: none;
}
-.nc-listControl-objectControl {
- display: block;
- border-top: 28px solid rgba(0,0,0,0.1);
- border-top-left-radius: 0;
-}
-
-.nc-listControl-expanded {}
-
.nc-listControl-collapsed {
& .nc-listControl-objectLabel {
display: block;
@@ -83,9 +74,21 @@
}
.nc-listControl-dragIcon {
+ cursor: move;
+ display: block;
position: absolute;
+ text-align: center;
top: 2px;
- display: block;
width: 100%;
- text-align: center;
+ z-index: 1;
}
+
+/**
+ * Styles for objects nested within lists.
+ */
+.nc-listControl-item .nc-listControl-objectControl {
+ display: block;
+ border-top: 28px solid rgba(0,0,0,0.1);
+ border-top-left-radius: 0;
+}
+
diff --git a/src/components/Widgets/ListControl.js b/src/components/Widgets/ListControl.js
index ddf6ece6f363..33e2f7cd19d6 100644
--- a/src/components/Widgets/ListControl.js
+++ b/src/components/Widgets/ListControl.js
@@ -1,12 +1,12 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { List, Map, fromJS } from 'immutable';
-import { sortable } from 'react-sortable';
+import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
import FontIcon from 'react-toolbox/lib/font_icon';
import ObjectControl from './ObjectControl';
function ListItem(props) {
- return
{props.children}
;
+ return {props.children}
;
}
ListItem.propTypes = {
className: PropTypes.string,
@@ -18,7 +18,12 @@ function valueToString(value) {
return value ? value.join(',').replace(/,([^\s]|$)/g, ', $1') : '';
}
-const SortableListItem = sortable(ListItem);
+const SortableListItem = SortableElement(ListItem);
+const DragHandle = SortableHandle(
+ () =>
+);
+const SortableList = SortableContainer(({ items, renderItem }) =>
+ ({items.map(renderItem)}
));
const valueTypes = {
SINGLE: 'SINGLE',
@@ -38,7 +43,7 @@ export default class ListControl extends Component {
constructor(props) {
super(props);
- this.state = { itemStates: Map(), value: valueToString(props.value) };
+ this.state = { itemsCollapsed: List(), value: valueToString(props.value) };
this.valueType = null;
}
@@ -110,9 +115,9 @@ export default class ListControl extends Component {
handleToggle(index) {
return (e) => {
e.preventDefault();
- const { itemStates } = this.state;
+ const { itemsCollapsed } = this.state;
this.setState({
- itemStates: itemStates.setIn([index, 'collapsed'], !itemStates.getIn([index, 'collapsed'])),
+ itemsCollapsed: itemsCollapsed.set(index, !itemsCollapsed.get(index, false)),
});
};
}
@@ -126,55 +131,60 @@ export default class ListControl extends Component {
return value || `No ${ labelField.get('name') }`;
}
- handleSort = (obj) => {
- this.setState({ draggingIndex: obj.draggingIndex });
- if ('items' in obj) {
- this.props.onChange(fromJS(obj.items));
- }
+ onSortEnd = ({ oldIndex, newIndex }) => {
+ const { value, onChange } = this.props;
+
+ // Update value
+ const item = value.get(oldIndex);
+ const newValue = value.delete(oldIndex).insert(newIndex, item);
+ this.props.onChange(newValue);
+
+ // Update collapsing
+ const { itemsCollapsed } = this.state;
+ const collapsed = itemsCollapsed.get(oldIndex);
+ const newItemsCollapsed = itemsCollapsed.delete(oldIndex).insert(newIndex, collapsed);
+ this.setState({ itemsCollapsed: newItemsCollapsed });
};
- renderItem(item, index) {
- const { value, field, getAsset, onAddAsset, onRemoveAsset } = this.props;
- const { itemStates } = this.state;
- const collapsed = itemStates.getIn([index, 'collapsed']);
- const classNames = ['nc-listControl-item', collapsed ? 'nc-listControl-collapsed' : 'nc-listControl-expanded'];
-
- return (
-
-
-
-
-
{this.objectLabel(item)}
-
-
+ renderItem = (item, index) => {
+ const { field, getAsset, onAddAsset, onRemoveAsset } = this.props;
+ const { itemsCollapsed } = this.state;
+ const collapsed = itemsCollapsed.get(index);
+ const classNames = ['nc-listControl-item', collapsed ? 'nc-listControl-collapsed' : ''];
+
+ return (
+
+
+
+ {this.objectLabel(item)}
+
);
- }
+ };
renderListControl() {
const { value, forID, field } = this.props;
const listLabel = field.get('label');
return (
- {value && value.map((item, index) => this.renderItem(item, index))}
+