<todo />

<script type="riot/tag">

  <entry>
    <form onsubmit={ create }>
      <input type="text" value={ name } placeholder="新規タスクを入力" onkeyup={ changeName }>
      <button disabled={ name === '' }>追加</button>
    </form>

    this.name = '';

    changeName(e) {
      this.name = e.target.value;
    }

    create(e){
      e.preventDefault();
      opts.onCreate(this.name);
      this.name = '';
    }

    <style>
      form {
        padding : 10px;
      }
      input[type="text"],
      button {
        vertical-align : middle;
        border-radius  : .5rem;
      }
      input[type="text"] {
        font-size : 1.6rem;
        padding   : .4rem;
        border    : 1px solid #ccc;
      }
      button {
        font-size        : 1.4rem;
        padding          : .6rem 1rem;
        color            : #fff;
        background-color : #333;
      }
      button:disabled {
        background-color : #ccc;
        cursor           : default;
      }
    </style>
  </entry>

  <task>
    <p>#{ opts.index } { opts.name }</p>
    <p><button onclick={ remove }>削除</button></p>

    remove() {
      opts.onRemove(opts.index);
    }

    <style>
      :scope {
        display          : flex;
        align-items      : center;
        padding          : 5px 5px 5px 10px;
        border-radius    : .5rem;
        background-color : #fff;
        box-shadow       : 0 1px 0 rgba(0,0,0,.05);
      }
      p:first-child {
        flex-grow : 1;
      }
      p:last-child {
        flex-basis : auto;
      }
      button {
        font-size        : 1.4rem;
        padding          : .6rem 1rem;
        border-radius    : .5rem;
        color            : #fff;
        background-color : #333;
      }
    </style>
  </task>

  <todo>
    <h1>TODO List</h1>

    <entry on-create={ createTask } />

    <ul>
      <li each={ task, i in tasks }>
        <task index={ i } name={ task } on-remove={ parent.removeTask } />
      </li>
    </ul>

    this.tasks = [];

    createTask(value) {
      this.tasks.push(value);
      this.update();
    }

    removeTask(index) {
      this.tasks.splice(index, 1);
      this.update();
    }

    <style>
      :scope {
        display          : block;
        background-color : #fff;
        font-size        : 1.6rem;
      }
      > h1 {
        font-size : 1.8rem;
        color     : #666;
        padding   : 10px 10px 0;
      }
      > ul {
        height           : 200px;
        padding          : 10px;
        overflow-y       : scroll;
        background-color : #eee;
        box-sizing       : border-box;
      }
      > ul > li:not(:first-child) {
        margin-top : 10px;
      }
    </style>
  </todo>

</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/riot/3.3.1/riot+compiler.min.js"></script>
<script>
  riot.mount('todo');
</script>
html {
  font-size : 62.5%;
}

body {
  font-family      : sans-serif;
  font-size        : 1.4rem;
  line-height      : 1.5;
  color            : #333;
  background-color : #fff;
}

input[type="text"], select, button {
  appearance  : none;
  font-family : inherit;
  font-size   : inherit;
  line-height : inherit;
}

input[type="checkbox"] {
  margin : 0;
}

button {
  border  : none;
  cursor  : pointer;
  outline : none;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.