diff --git a/package.json b/package.json
index 7c14bdfe..9720fbb0 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
"react-hotkeys": "git+https://github.com/brusherru/react-hotkeys.git#npm",
"react-redux": "^4.0.6",
"react-skylight": "^0.4.0",
+ "react-sortable-hoc": "0.0.7",
"react-ui-tree": "^2.5.0",
"redux": "^3.0.5",
"redux-thunk": "^2.1.0",
diff --git a/src/client/app-browser/styles/components/TabsItem.scss b/src/client/app-browser/styles/components/TabsItem.scss
index ba9b527c..394ede11 100644
--- a/src/client/app-browser/styles/components/TabsItem.scss
+++ b/src/client/app-browser/styles/components/TabsItem.scss
@@ -5,6 +5,8 @@
padding: 0 10px 0 14px;
height: 26px;
+ box-sizing: border-box;
+
background: $color-tabs-unactive-background;
color: $color-tabs-unactive-text;
line-height: 30px;
@@ -13,6 +15,7 @@
border-top-left-radius: 4px;
text-shadow: 0 1px 0 rgba(0,0,0, .5);
cursor: default;
+ white-space: nowrap;
transition: 0.1s ease-out all;
diff --git a/src/client/editor/components/TabsItem.jsx b/src/client/editor/components/TabsItem.jsx
index 5070106c..3f7e5372 100644
--- a/src/client/editor/components/TabsItem.jsx
+++ b/src/client/editor/components/TabsItem.jsx
@@ -15,14 +15,14 @@ const TabsItem = ({ data, onClick, onClose }) => {
return (
{data.name}
×
diff --git a/src/client/editor/containers/Tabs.jsx b/src/client/editor/containers/Tabs.jsx
index bd51c376..19786eee 100644
--- a/src/client/editor/containers/Tabs.jsx
+++ b/src/client/editor/containers/Tabs.jsx
@@ -5,15 +5,65 @@ import { bindActionCreators } from 'redux';
import * as Actions from '../actions';
import * as EditorSelectors from '../selectors';
+import { arrayMoveIndex, arrayUpdateIndex, arrayIndexById } from 'xod/client/utils/array';
+
+import {
+ SortableContainer as sortableContainer,
+ SortableElement as sortableElement,
+} from 'react-sortable-hoc';
+
import TabsContainer from '../components/TabsContainer';
import TabsItem from '../components/TabsItem';
+const SortableItem = sortableElement(
+ ({ value }) => {
+ return (
+
+ );
+ }
+);
+
+const SortableList = sortableContainer(
+ ({ items, onClick, onClose }) => (
+
+ {items.map((value, index) => {
+ const item = R.merge(
+ value,
+ {
+ onClick,
+ onClose,
+ }
+ );
+
+ return (
+
+ );
+ }
+ )}
+
+ )
+);
+
+
class Tabs extends React.Component {
constructor(props) {
super(props);
this.onSwitchPatch = this.onSwitchPatch.bind(this);
this.onCloseTab = this.onCloseTab.bind(this);
+ this.onSortEnd = this.onSortEnd.bind(this);
}
onSwitchPatch(patchId) {
@@ -24,6 +74,14 @@ class Tabs extends React.Component {
return this.props.actions.closeTab(patchId);
}
+ onSortEnd(changes) {
+ const sortedTabs = arrayMoveIndex(changes.oldIndex, changes.newIndex, this.getTabs());
+ const newTabs = arrayUpdateIndex(sortedTabs);
+ const indexedTabs = arrayIndexById(newTabs);
+
+ this.props.actions.sortTabs(indexedTabs);
+ }
+
getTabs() {
return R.sortBy(
R.prop('index')
@@ -33,16 +91,17 @@ class Tabs extends React.Component {
render() {
const tabs = this.getTabs();
return (
-
- {tabs.map(tab =>
-
- )}
-
+
);
}
}
diff --git a/src/client/utils/array.js b/src/client/utils/array.js
new file mode 100644
index 00000000..9f10f3a2
--- /dev/null
+++ b/src/client/utils/array.js
@@ -0,0 +1,19 @@
+import R from 'ramda';
+
+const mapIndexed = R.addIndex(R.map);
+
+export const arrayMoveIndex = R.curry(
+ (oldIndex, newIndex, array) => {
+ const oldItem = R.nth(oldIndex, array);
+ const newItem = R.nth(newIndex, array);
+
+ return R.pipe(
+ R.update(oldIndex, newItem),
+ R.update(newIndex, oldItem)
+ )(array);
+ }
+);
+
+export const arrayUpdateIndex = mapIndexed((item, index) => R.assoc('index', index, item));
+
+export const arrayIndexById = R.indexBy(R.prop('id'));