React

by Abdul Ahmad

HTML

<div id="app"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.done {
  color: rgba(0, 0, 0, 0.3);
  text-decoration: line-through;
}

input {
  margin-right: 5px;
}

.item {
  border: 1px solid #ddd;
  padding: 10px;
  font-size: 12px;
  border-radius: 5px;
  margin: 5px 0;
}

.move {
  padding: 5px;
  border: 1px solid #eee;
  border-radius: 5px;
  font-size: 12px;
  display: inline-block;
  vertical-align: top;
}

React

class App extends React.PureComponent {
  state = {
  	items: [],
  };
  
  addItem = () => {
  	const { items } = this.state;
    const newItem = newModel(items.length);
    this.setState({ items: [...items, newItem] });
  };
  
  moveItem = () => {
  	const items = [...this.state.items];
    const randomNumber = getRandomNumber(items.length - 1);
    const randomItemToMove = items[randomNumber];
    const previousOrder = randomItemToMove.order;
    
    const randomPlaceToMove = findRandomNewPosition(randomNumber, items.length);
    const newOrder = calculateNewOrder(randomPlaceToMove, randomItemToMove, items); 
    items[randomNumber].order = newOrder;
    items[randomNumber].moves.push({ 
    	from: randomNumber, 
      to: randomPlaceToMove,
      previousOrder,
    });
    this.setState({ items });
  };
  
  render() {
  	const items = sortItemsByOrder(this.state.items);
    
    return (
      <div>
        <button onClick={this.addItem}>
          add item
        </button>
        <button onClick={this.moveItem}>
          move item
        </button>
        <div>
          {
          	items.map(i =>
              <div key={i.itemNumber} className='item'>
                <div>item number: { i.itemNumber }</div>
                <div>order: { i.order }</div>
                {
                	i.moves.map(m => 
                  	<span key={m.from + m.to + m.previousOrder} className='move'>
                  	  from: {m.from}, to: {m.to}, previousOrder: {m.previousOrder}
                  	</span>
                  )
                }
              </div>
            )
          }
        </div>
      </div>
    )
  }
}

let itemNumber = 1;
let order = 0;
let orderSkipAmount = 10000;

function newModel(numberOfItems) {
	const model = { itemNumber, order, moves: [] };
  
  itemNumber++;
  order += orderSkipAmount;
  
  return model;
}

function getRandomNumber(max = 1, min = 0) {
	min = Math.ceil(min);
  max = Math.floor(max);
  return...