Reshuffle

by evgkch

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.1/JSXTransformer.js"></script>
<div id="app"></div>

SCSS

$primary-color-o: #DB424A;
$primary-color: #F04851;

.box {
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: all 0.3s;
  
  .item {
    display: flex;
    position: absolute;
    justify-content: center;
    align-items: center;
    height: 60px;
    padding: 10px;
    width: 50%;
    background-color: $primary-color-o;
    color: #BCA9AA;
    font-weight: bold;
    transition: all 0.3s;
    user-select: none;
    &:hover {
      background-color: $primary-color;
    }
  }
}

Babel + JSX

const DATA = Array.from({ length: 5 }, (v, k) => ({ id: k + 1, title: `${k + 1}` }));

class FrameListener {
	constructor(id) {
  	this._coordinates = { x: 0, y: 0 };
    this._isMouseDown = false;
    const el = document.getElementById(id);
    el.addEventListener('mousemove', (e) => {
    	this.setClientXY.call(this, e.clientX, e.clientY);
    })
    el.addEventListener('mousedown', (e) => {
    	this._isMouseDown = true;
    })
    el.addEventListener('mouseup', (e) => {
    	this._isMouseDown = false;
    })
  }
  setClientXY(x, y) {
  	this._coordinates = { x, y };
  }
  getClientXY(x, y) {
  	return this._coordinates;
  }
  view() {
  	console.log(this)
  }
}

class ListOrder {
	constructor() {
  	this.list = [];
  }
  _getItemId(id) {
  	return this.list.findIndex(item => item.id === id);
  }
  addItem(id, height) {
  	const listLength = this.list.length;
    const lastItem = this.list[listLength - 1];
    this.list.push({
    	id,
      height,
      top: listLength !== 0 ? lastItem.top + lastItem.height : 0,
    });
  }
  shiftTop(id) {
  	const index = this._getItemById.call(this, id);
    if (index !== 0) {
    	const seniorItem = this.list[index - 1];
      const thisItem = this.list[index];
      this.list[index - 1].top = thisItem.top;
      this.list[index].top = seniorItem.top;
    }
  }
}

const BoxListener = new FrameListener('app');

const BoxOrder = new ListOrder();

const FrameController = (update, getState) => class ctrl {
  static setPageXY(pageX, pageY) {
  	update({ pageX, pageY });
  }
}

const ItemController = (update, getState, getProps) => class ctrl {
	static setDeltaXY(left, top) {
  	const { pageX, pageY } = getProps();
  	update({
    	deltaX: pageX - left,
      deltaY: pageY - top,
    })
  }
}

class Box extends React.Component {
	constructor() {
  	super();
  	this.ctrl = FrameController(
    	this.setState.bind(this),
      () => this.state
    );
    this.state = { delta: 0 }
  }
  componentWillMount() {
 ...