JSFiddle - React, Tailwind, and code Playground

by TeslaNick

HTML

<div id="todo-app">
    <label class="todo-label" for="new-todo">What do you want to do today?</label>
    <input type="text" id="new-todo" class="todo-input"
        placeholder="buy milk">

    <ul id="todo-list"></ul>
    <div id="todo-stats"></div>
</div>

<!-- This template HTML will be used to render each todo item. -->
<script type="text/x-template" id="todo-item-template">
    <div class="todo-view">
        <input type="checkbox" class="todo-checkbox" {checked}>
        <span class="todo-content" tabindex="0">{text}</span>
    </div>

    <div class="todo-edit">
        <input type="text" class="todo-input" value="{text}">
    </div>

    <a href="#" class="todo-remove" title="Remove this task">(&times;)</a>
</script>

<!-- This template HTML will be used to render the statistics at the bottom
     of the todo list. -->
<script type="text/x-template" id="todo-stats-template">
    <span class="todo-count">
        <span class="todo-remaining">{numRemaining}</span>
        <span class="todo-remaining-label">{remainingLabel}</span> left.
    </span>

    <a href="#" class="todo-clear">
        Clear <span class="todo-done">{numDone}</span>
        completed <span class="todo-done-label">{doneLabel}</span>
    </a>
</script>

CSS

#todo-app {
    margin: 1em;
    text-align: center;
}

#todo-list,
#todo-stats {
    margin: 1em auto;
    text-align: left;
    width: 450px;
}

#todo-list {
    list-style: none;
    padding: 0;
}

#todo-stats,
.todo-clear { color: #777; }

.todo-clear { float: right; }

.todo-done .todo-content {
    color: #666;
    text-decoration: line-through;
}

.todo-edit,
.editing .todo-view { display: none; }

.editing .todo-edit { display: block; }

.todo-input {
    display: block;
    font-family: Helvetica, sans-serif;
    font-size: 20px;
    line-height: normal;
    margin: 5px auto 0;
    padding: 6px;
    width: 420px;
}

.todo-item {
    border-bottom: 1px dotted #cfcfcf;
    font-size: 20px;
    padding: 6px;
    position: relative;
}

.todo-label {
    color: #444;
    font-size: 20px;
    font-weight: bold;
    text-align: center;
}

.todo-remaining {
    color: #333;
    font-weight: bold;
}

.todo-remove {
    position: absolute;
    right: 0;
    top: 12px;
    text-decoration: none;
    color: #c00;
}


.todo-remove:hover .todo-remove-icon { opacity: 1.0; }

.todo-hover .todo-remove-icon,
.todo-remove:focus .todo-remove-icon { visibility: visible; }

.editing .todo-remove-icon { visibility: hidden; }

JavaScript

YUI({filter: 'raw'}).use('event-focus', 'json', 'model', 'model-list', 'view', function (Y) {

var TodoAppView, TodoList, TodoModel, TodoView;

// -- Model --------------------------------------------------------------------

// The TodoModel class extends Y.Model and customizes it to use a localStorage
// sync provider (the source for that is further below) and to provide
// attributes and methods useful for todo items.

TodoModel = Y.TodoModel = Y.Base.create('todoModel', Y.Model, [], {
    // This tells the Model to use a localStorage sync provider (which we'll
    // create below) to save and load information about a todo item.
    sync: LocalStorageSync('todo'),

    // This method will toggle the `done` attribute from `true` to `false`, or
    // vice versa.
    toggleDone: function () {
        this.set('done', !this.get('done')).save();
    }
}, {
    ATTRS: {
        // Indicates whether or not this todo item has been completed.
        done: {value: false},

        // Contains the text of the todo item.
        text: {value: ''}
    }
});

// -- ModelList ----------------------------------------------------------------

// The TodoList class extends Y.ModelList and customizes it to hold a list of
// TodoModel instances, and to provide some convenience methods for getting
// information about the todo items in the list.

TodoList = Y.TodoList = Y.Base.create('todoList', Y.ModelList, [], {
    // This tells the list that it will hold instances of the TodoModel class.
    model: TodoModel,

    // This tells the list to use a localStorage sync provider (which we'll
    // create below) to load the list of todo items.
    sync: LocalStorageSync('todo'),

    // Returns an array of all models in this list with the `done` attribute
    // set to `true`.
    done: function () {
        return this.filter(function (model) {
            return model.get('done');
        });
    },

    // Returns an array of all models in this list with the `done` attribute
   ...