React List

A simple list app made with React.

by Perry Kaufman

HTML

<h1>React List</h1>
<p>By Perry Kaufman</p>

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

SCSS

/* Colors */
$dark: #151515;
$light: #fafcfc;
$primary: #0e87c8;
$primary-light: lighten($primary, 30%);
$primary-lighter: lighten($primary-light, 25%);
$primary-dark: darken($primary, 25%);
$secondary: #c84f0e;
$secondary-light: lighten($secondary, 30%);
$secondary-lighter: lighten($secondary-light, 25%);
$secondary-dark: darken($secondary, 25%);

/* UI Colors */
$color-page: $light;
$color-text: $dark;

$color-item-text: $dark;
$color-item: $primary-lighter;
$color-item-border: $primary;

$color-button: $primary;
$color-button-symbol: $light;
$color-button-hover: $primary-lighter;
$color-button-hover-symbol: $primary;
$color-button-active: $primary-dark;
$color-button-active-symbol: $color-button-symbol;
$color-button-focus: $primary-dark;

$color-item-changed: $secondary-lighter;
$color-item-changed-border: $secondary;

$color-button-changed: $secondary;
$color-button-changed-hover: $secondary-lighter;
$color-button-changed-hover-symbol: $secondary;
$color-button-changed-active: $secondary-dark;
$color-button-changed-active-symbol: $color-button-symbol;
$color-button-changed-focus: $secondary-dark;

$color-input-border: $primary;
$color-input-border-focus: $primary-dark;

/* UI Dimensions */
$line-width: 2px;
$item-spacing: 2px;
$item-height: 28px + (2 * $line-width) + (2 * $item-spacing);
$item-width: 300px;

$button-dim: 26px;
$button-symbol-weight: $line-width;

/* General */

html, body {
  background: $color-page;
  box-sizing: border-box;
  color: $color-text;
  font-family: sans-serif;
  padding: 10px;
}

h1 {
  color: $primary;
  font-size: 2.5rem;
  margin: 0;
  text-align: center;
}

p {
  color: $primary;
  font-weight: 600;
  margin: 5px;
  text-align: center;
}

* {
  box-sizing: inherit;
}

/* List */

.list-wrapper {
  display: flex;
  flex-flow: column nowrap;
  align-items: center;
}

.list {
  width: $item-width;
}

.list-item {
  align-items: center;
  background: $color-item;
  border: $line-width solid $color-item-border;
  border-radius:...

React

class ListItem extends React.Component {
	constructor(props) {
  	super(props)
    
    this._moveDown = this._moveDown.bind(this)
    this._moveUp = this._moveUp.bind(this)
    this._remove = this._remove.bind(this)
  }
  _moveDown(e) {
  	this.props.moveItemDown(this.props.id)
  }
  _moveUp(e) {
  	this.props.moveItemUp(this.props.id)
  }
  _remove(e) {
  	this.props.removeItem(this.props.id)
  }
  render() {
  	const text = this.props.text
  	return (
    	<li className={'list-item' + (this.props.changed ? ' changed' : '')}>
        <span className="item-text" onClick={()=>console.log(this.props.text)}>{text}</span>
        <button className="up-button"
          onClick={this._moveUp}
          title="up">up</button>
        <button className="down-button"
          onClick={this._moveDown}
          title="down">down</button>
        <button className="remove-button"
          onClick={this._remove}
          title="remove">remove</button>
      </li>
    )
  }
}

class ListForm extends React.Component {
	constructor(props) {
  	super(props)
    this.state = {text: ''}
    
    this._add = this._add.bind(this)
    this._updateText = this._updateText.bind(this)
  }
  _add(e) {
  	e.preventDefault()
    this.props.addItem(this.state.text)
    this.setState({text: ''})
  }
  _updateText(e) {
  	e.preventDefault()
    const text = e.target.value
    this.setState({text})
  }
  render() {
  	return (
    	<form className="list-form" onSubmit={this._add}>
    	  <input className="text-input"
          type="text"
          placeholder="add an item"
          maxLength="20"
          value={this.state.text}
          onChange={this._updateText} />
        <button className="add-button"
          type="submit"
          title="add">add</button>
    	</form>
    )
  }
}

class List extends React.Component {
	constructor(props) {
  	super(props)
    const changed = 0;
    this.state = {
    	list: props.initialList	? props.initialList.map( (text, id) => ({text, id,...