JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="http://seanjm.nfshost.com/peach/peach.min.js"></script>
<div class="todo-container" id="todo-container">
<h2 class="todo-header">TODO list</h2>
</div>
CSS
* {
margin : 0;
padding : 0;
vertical-align : top;
box-sizing : border-box;
}
body {
font-family :'Arial', 'Helvetica', 'Sans-serif';
background : #f1f1f1;
}
.button {
display : inline-block;
width : 80px;
padding : 0 10px;
color : #fff;
line-height : 28px;
border-radius : 3px;
text-align : center;
font-size : 13px;
}
.button-add {
background : linear-gradient(to top, #52AD52, #67d067);
}
.button-remove {
background : linear-gradient(to top, #cf5d5d, #df6d6d);
}
.todo-container {
position : absolute;
top : 0;
right : 0;
bottom : 0;
left : 0;
padding-bottom : 30px;
background : #fff;
}
.todo-header {
padding : 10px;
color : #ffffff;
line-height : 20px;
text-align : center;
font-size : 16px;
background : #0686cf;
}
.todo-input {
width : 100%;
height : 28px;
padding : 5px;
border : 1px solid #d6d6d6;
border-radius : 3px;
font-size : 13px;
}
.todo-control {
position : relative;
padding : 10px;
padding-right : 100px;
border-bottom : 1px solid #e2e2e2;
}
.todo-control .button-add {
position : absolute;
top : 10px;
right : 10px;
}
.todo-item-container {
border-top : 0;
background : #fff;
}
.todo-item {
position : relative;
padding : 10px;
transition : opacity 0.3s;
}
.todo-item + .todo-item {
border-top : 1px solid #D4D4D4;
}
.todo-item--remove {
opacity : 0.3;
}
.todo-item-control {
position : absolute;
top : 17px;
left : 15px;
}
.todo-item-text {
padding-left : 28px;
line-height : 26px;
font-size : 13px;
}
.todo-item--remove .todo-item-text {
text-decoration : line-through;
}
.todo-status-line {
position : absolute;
right : 0;
bottom : 0;
left : 0;
padding : 5px 0;
color : #818181;
line-height : 20px;
border-top : 1px solid #d6d6d6;
text-align : center;
font-size : 13px;
}
JavaScript
// A couple of utility functions
// https://github.com/sindresorhus/multiline/blob/master/index.js
var multiline = function (fn) {
if (typeof fn !== 'function') throw new TypeError('Expected a function');
var match = multiline.re.exec(fn.toString());
if (!match) throw new TypeError('Multiline comment missing.');
return match[1];
};
multiline.re = /\/\*!?(?:\@preserve)?[ \t]*(?:\r\n|\n)([\s\S]*?)(?:\r\n|\n)[ \t]*\*\//;
// This one should be on Peach
function initPeachs(peachs) {
Object.keys(peachs).forEach(function (key) {
var current = peachs[key];
if (current.template) {
var fruit = {};
fruit[key] = {
value: current.template
};
peach.add(fruit);
}
if (current.render) {
peach.on('render', key, current.render);
}
if (current.node) {
peach.on('node', key, current.node);
}
if (current.set) {
peach.set(key, current.set);
}
})
}
var peach = Peach();
var todos = [{
text: 'My first todo'
}];
function addTodo() {
var val = document.querySelector('#todo-input').value.trim();
// Check to see if 'val' has content
if (val.length) {
todos.push({
text: val
});
peach.update('todo-list');
}
}
function removeTodo(e) {
// Grab the index of '#' from the ID of the item, which is 'todo-item-#'
var todoItem = e.target.closest('.todo-item');
var index = Number(todoItem.id.split('-').slice(-1)[0]);
todoItem.className += ' todo-item--remove';
todos.splice(index, 1);
setTimeout(function () {
peach.update('todo-list');
}, 300);
}
var peachs = {
"button": {
template: '<div {{attr}}>{{text}}</div>',
render: function (mixin) {
var addClass = peach.tools(this).addClass;
addClass('{{self}}-' + mixin.join('-'));
// Use the first mixin value to generate...