<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<!DOCTYPE html><html class=''>
<head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/KemPavel/pen/dOOJVZ?depth=everything&order=popularity&page=84&q=react&show_forks=false" />
<style class="cp-pen-styles">body {
background: #e8e8e8;
}
.container {
margin: 0 auto;
width: 650px;
}
.header {
text-align: center;
}
.form__input {
background: transparent;
border: 1px solid black;
border-radius: 5px;
font-size: 1.4em;
height: 40px;
padding: 0 10px;
width: 500px;
}
.form__button {
background: transparent;
border: 1px solid black;
border-radius: 5px;
cursor: pointer;
font-size: 1.4em;
float: right;
padding: 0;
line-height: 40px;
vertical-align: top;
width: 115px;
}
.todos-list {
font-size: 1.4em;
}
.todo-item {
border-bottom: 1px solid #ccc3c3;
cursor: pointer;
line-height: 40px;
}
.todo-item__name--disabled {
text-decoration: line-through;
}
.todo-item__delete-button {
float: right;
text-align: center;
width: 30px;
}
.footer__button {
background: transparent;
border: 1px solid black;
border-radius: 5px;
cursor: pointer;
font-size: 1.4em;
outline: 0;
padding: 0 10px;
line-height: 40px;
vertical-align: top;
margin-right: 10px;
}
.footer__button--active {
border: 1px solid black;
box-sizing: border-box;
box-shadow: 0 0 2px black;
font-style: italic;
font-weight: bold;
}
.footer__button--delete-completed {
float: right;
margin-right: 0;
}
</style></head><body>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TODO List</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
<script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js'></script>
<script >'use strict';
var TodoHeader = React.createClass({
displayName: 'TodoHeader',
propTypes: {
todosAmount: React.PropTypes.number.isRequired
},
render: function render() {
return React.createElement(
'header',
{ className: 'header' },
React.createElement(
'h1',
null,
'Simple Todo app (React only)'
),
React.createElement(
'h3',
null,
'To-Do (',
this.props.todosAmount,
')'
)
);
}
});
var TodoForm = React.createClass({
displayName: 'TodoForm',
propTypes: {
addTodo: React.PropTypes.func.isRequired
},
handleAddTodoClick: function handleAddTodoClick() {
if (this.refs.input.value.replace(/\s+/g, '').length !== 0) {
this.props.addTodo(this.refs.input.value);
this.refs.input.value = ''; /**/
}
this.refs.input.focus();
},
handleEnterClick: function handleEnterClick(e) {
if (e.key === 'Enter') {
this.handleAddTodoClick();
}
},
componentDidMount: function componentDidMount() {
this.refs.input.focus();
},
render: function render() {
return React.createElement(
'div',
{ className: 'form' },
React.createElement('input', { className: 'form__input', ref: 'input', maxLength: '50', placeholder: 'Add todo', onKeyUp: this.handleEnterClick }),
React.createElement(
'button',
{ className: 'form__button', onClick: this.handleAddTodoClick },
'╋'
)
);
}
});
var TodoItem = React.createClass({
displayName: 'TodoItem',
propTypes: {
removeTodo: React.PropTypes.func.isRequired,
toggleTodo: React.PropTypes.func.isRequired,
todo: React.PropTypes.object.isRequired
},
handleToggleTodoClick: function handleToggleTodoClick() {
this.props.toggleTodo(this.props.todo.id);
},
handleRemoveTodoClick: function handleRemoveTodoClick(e) {
e.stopPropagation();
this.props.removeTodo(this.props.todo.id);
},
render: function render() {
var itemNameClasses = this.props.todo.completed ? 'todo-item__name todo-item__name--disabled' : 'todo-item__name';
return React.createElement(
'li',
{ className: 'todo-item', onClick: this.handleToggleTodoClick },
React.createElement(
'span',
{ className: itemNameClasses },
this.props.todo.text
),
React.createElement(
'span',
{ className: 'todo-item__delete-button', onClick: this.handleRemoveTodoClick },
'×'
)
);
}
});
var TodoList = React.createClass({
displayName: 'TodoList',
propTypes: {
items: React.PropTypes.array,
removeTodo: React.PropTypes.func.isRequired,
toggleTodo: React.PropTypes.func.isRequired
},
handleToggleTodo: function handleToggleTodo(id) {
this.props.toggleTodo(id);
},
handleRemoveTodo: function handleRemoveTodo(id) {
this.props.removeTodo(id);
},
render: function render() {
var _this = this;
return React.createElement(
'ul',
{ className: 'todos-list' },
this.props.todos.map(function (todo) {
return React.createElement(TodoItem, { todo: todo, key: todo.id, removeTodo: _this.handleRemoveTodo, toggleTodo: _this.handleToggleTodo });
})
);
}
});
var TodoFooter = React.createClass({
displayName: 'TodoFooter',
propTypes: {
activeTab: React.PropTypes.string.isRequired,
showAll: React.PropTypes.func.isRequired,
showActive: React.PropTypes.func.isRequired,
showCompleted: React.PropTypes.func.isRequired,
deleteCompleted: React.PropTypes.func.isRequired
},
componentDidUpdate: function componentDidUpdate() {
for (var key in this.refs) {if (window.CP.shouldStopExecution(1)){break;}
this.refs[key].classList.remove('footer__button--active');
if (key === this.props.activeTab) {
this.refs[key].classList.add('footer__button--active');
}
}
window.CP.exitedLoop(1);
},
handleShowAllClick: function handleShowAllClick() {
this.props.showAll();
},
handleShowActiveClick: function handleShowActiveClick() {
this.props.showActive();
},
handleShowCompletedClick: function handleShowCompletedClick() {
this.props.showCompleted();
},
handleDeleteCompletedClick: function handleDeleteCompletedClick() {
this.props.deleteCompleted();
},
render: function render() {
return React.createElement(
'footer',
{ className: 'footer' },
React.createElement(
'button',
{ ref: 'all', className: 'footer__button footer__button--active', onClick: this.handleShowAllClick },
'All'
),
React.createElement(
'button',
{ ref: 'active', className: 'footer__button', onClick: this.handleShowActiveClick },
'Active'
),
React.createElement(
'button',
{ ref: 'completed', className: 'footer__button', onClick: this.handleShowCompletedClick },
'Completed'
),
React.createElement(
'button',
{ className: 'footer__button footer__button--delete-completed', onClick: this.handleDeleteCompletedClick },
'Delete completed'
)
);
}
});
var TodoApp = React.createClass({
displayName: 'TodoApp',
propTypes: {
children: React.PropTypes.node
},
getInitialState: function getInitialState() {
return {
todos: JSON.parse(localStorage.getItem("todos")) || [],
id: JSON.parse(localStorage.getItem("id")) || 1,
visibility: 'all'
};
},
componentDidUpdate: function componentDidUpdate() {
localStorage.setItem("todos", JSON.stringify(this.state.todos));
localStorage.setItem("id", JSON.stringify(this.state.id));
},
getCompletedTodos: function getCompletedTodos() {
return this.state.todos.filter(function (todo) {
return todo.completed;
});
},
getActiveTodos: function getActiveTodos() {
return this.state.todos.filter(function (todo) {
return !todo.completed;
});
},
handleAddTodo: function handleAddTodo(value) {
var todos = this.state.todos.slice();
var todo = {
id: this.state.id++,
text: value,
completed: false
};
todos.push(todo);
this.setState({
todos: todos
});
},
handleToggleTodo: function handleToggleTodo(id) {
var todos = this.state.todos.map(function (todo) {
if (todo.id === id) {
todo.completed = !todo.completed;
}
return todo;
});
this.setState({
todos: todos
});
},
handleRemoveTodo: function handleRemoveTodo(id) {
var todos = this.state.todos.filter(function (todo) {
return todo.id !== id;
});
this.setState({
todos: todos
});
},
handleShowAll: function handleShowAll() {
this.setState({
visibility: 'all'
});
},
handleShowActive: function handleShowActive() {
this.setState({
visibility: 'active'
});
},
handleShowCompleted: function handleShowCompleted() {
this.setState({
visibility: 'completed'
});
},
handleDeleteCompleted: function handleDeleteCompleted() {
var todos = this.state.todos.filter(function (todo) {
return !todo.completed;
});
this.setState({
todos: todos
});
},
render: function render() {
var todos = undefined;
var activeTodos = this.getActiveTodos();
switch (this.state.visibility) {
case 'active':
todos = activeTodos;
break;
case 'completed':
todos = this.getCompletedTodos();
break;
case 'all':
default:
todos = this.state.todos;
break;
}
return React.createElement(
'div',
{ className: 'container' },
React.createElement(TodoHeader, { todosAmount: activeTodos.length }),
React.createElement(TodoForm, { addTodo: this.handleAddTodo }),
React.createElement(TodoList, { todos: todos, removeTodo: this.handleRemoveTodo, toggleTodo: this.handleToggleTodo }),
React.createElement(TodoFooter, { activeTab: this.state.visibility, showAll: this.handleShowAll, showActive: this.handleShowActive, showCompleted: this.handleShowCompleted, deleteCompleted: this.handleDeleteCompleted })
);
}
});
ReactDOM.render(React.createElement(TodoApp, null), document.getElementById('app'));
//# sourceURL=pen.js
</script>
</body></html>