JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.0/dist/global/Rx.umd.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"></script>
<div id="root">
</div>

CSS

.surface {
  height: 300px;
  width: 300px;
  background-color: blue;
  color: white;
  text-align: center;
}

.present {
  background-color: white;
  color: blue;
  height: 50px;
  width: 50px;
}

button {
  margin: 1px;
  background-color: purple;
  color: white;
}

span {
  margin: 4px;
}

Babel + JSX

// view
const Surface = 
	({handleMove}) =>
  	<div className='surface' onMouseMove={handleMove}>  	      	Move mouse right and left
    </div>
 
const Number = 
	({number}) => 
  	<div className='present'>{number}</div>

const GameOver = 
	({handleClick}) => 
		<div>
  		<span>Game Over</span>
    	<button onClick={handleClick}>Restart</button>
    </div>
    
    

 // data
 const onGoingMoves = new Rx.Subject()
 const gameResets = new Rx.Subject()
  
 const dynamicNumbers = onGoingMoves
 	.merge(gameResets.map(_ => null))
  .startWith({pos: 0, number: 0})
 	.scan((acc, move) => {
  	if (!move) return {pos: 0, number: 0}
    
  	if (move.clientX > acc.pos + 5) {  
    	acc.number = acc.number + 1            
    } else if (move.clientX < acc.pos - 5) {
    	acc.number = acc.number - 1    	
    }
    acc.pos = move.clientX
    return acc
  })//, {pos: 0, number: 0})
  //.startWith({pos: 0, number: 0})
  
const aboveNumbers = dynamicNumbers
	.filter(n => n.number > 25)

// events
const handleMove = e => onGoingMoves.next(e)


const handleReset = e => gameResets.next(e)

// projecting data(in) to views
const DynamicNumberView = dynamicNumbers.map(n => Number({number: n.number}))
// projecting the emitted values(out) to views
const LiveSurface = Rx.Observable.of(Surface({handleMove}))

const DynamicGameOver =
	aboveNumbers.map(_ => GameOver({handleClick: handleReset})).merge(gameResets.map(_ => null)).startWith(null)

// projecting the list view and button to app view
const LiveApp = 
  Rx.Observable.combineLatest
    (LiveSurface, DynamicNumberView, DynamicGameOver,
      (surface, number, gameover) => 
        <div> 
          {gameover ? gameover : surface}
          {number}
        </div>
    	)

// side effect - render to screen
LiveApp.subscribe(app =>
  ReactDOM.render(app, document.getElementById('root')))