<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/haakenlid/pen/qZOVjV?depth=everything&order=popularity&page=2&q=redux&show_forks=false" />
<link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css'>
<style class="cp-pen-styles">@charset "UTF-8";
html,
body {
margin: 0;
padding: 0;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
font-weight: inherit;
color: inherit;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #f5f5f5;
color: #4d4d4d;
min-width: 230px;
max-width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-weight: 300;
}
button,
input[type="checkbox"] {
outline: none;
}
.hidden {
display: none;
}
.todoapp {
background: #fff;
margin: 130px 0 40px 0;
position: relative;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
.todoapp input::-webkit-input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp input::-moz-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp input::input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
.todoapp h1 {
position: absolute;
top: -155px;
width: 100%;
font-size: 100px;
font-weight: 100;
text-align: center;
color: rgba(175, 47, 47, 0.15);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
.new-todo,
.edit {
position: relative;
margin: 0;
width: 100%;
font-size: 24px;
font-family: inherit;
font-weight: inherit;
line-height: 1.4em;
border: 0;
outline: none;
color: inherit;
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.003);
box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
}
.main {
position: relative;
z-index: 2;
border-top: 1px solid #e6e6e6;
}
label[for='toggle-all'] {
display: none;
}
.toggle-all {
position: absolute;
top: -55px;
left: -12px;
width: 60px;
height: 34px;
text-align: center;
border: none;
/* Mobile Safari */
}
.toggle-all:before {
content: '❯';
font-size: 22px;
color: #e6e6e6;
padding: 10px 27px 10px 27px;
}
.toggle-all:checked:before {
color: #737373;
}
.todo-list {
margin: 0;
padding: 0;
list-style: none;
}
.todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px solid #ededed;
}
.todo-list li:last-child {
border-bottom: none;
}
.todo-list li.editing {
border-bottom: none;
padding: 0;
}
.todo-list li.editing .edit {
display: block;
width: 506px;
padding: 13px 17px 12px 17px;
margin: 0 0 0 43px;
}
.todo-list li.editing .view {
display: none;
}
.todo-list li .toggle {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
border: none;
/* Mobile Safari */
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.todo-list li .toggle:after {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>');
}
.todo-list li .toggle:checked:after {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>');
}
.todo-list li label {
white-space: pre-line;
word-break: break-all;
padding: 15px 60px 15px 15px;
margin-left: 45px;
display: block;
line-height: 1.2;
-webkit-transition: color 0.4s;
transition: color 0.4s;
}
.todo-list li.completed label {
color: #d9d9d9;
text-decoration: line-through;
}
.todo-list li .destroy {
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 30px;
color: #cc9a9a;
margin-bottom: 11px;
-webkit-transition: color 0.2s ease-out;
transition: color 0.2s ease-out;
}
.todo-list li .destroy:hover {
color: #af5b5e;
}
.todo-list li .destroy:after {
content: '×';
}
.todo-list li:hover .destroy {
display: block;
}
.todo-list li .edit {
display: none;
}
.todo-list li.editing:last-child {
margin-bottom: -1px;
}
.footer {
color: #777;
padding: 10px 15px;
height: 20px;
text-align: center;
border-top: 1px solid #e6e6e6;
}
.footer:before {
content: '';
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 50px;
overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2);
}
.todo-count {
float: left;
text-align: left;
}
.todo-count strong {
font-weight: 300;
}
.filters {
margin: 0;
padding: 0;
list-style: none;
position: absolute;
right: 0;
left: 0;
}
.filters li {
display: inline;
}
.filters li a {
color: inherit;
margin: 3px;
padding: 3px 7px;
text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
}
.filters li a.selected,
.filters li a:hover {
border-color: rgba(175, 47, 47, 0.1);
}
.filters li a.selected {
border-color: rgba(175, 47, 47, 0.2);
}
.clear-completed,
html .clear-completed:active {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
cursor: pointer;
}
.clear-completed:hover {
text-decoration: underline;
}
.info {
margin: 65px auto 0;
color: #bfbfbf;
font-size: 10px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
text-align: center;
}
.info p {
line-height: 1;
}
.info a {
color: inherit;
text-decoration: none;
font-weight: 400;
}
.info a:hover {
text-decoration: underline;
}
/*
Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox
*/
@media screen and (-webkit-min-device-pixel-ratio: 0) {
.toggle-all,
.todo-list li .toggle {
background: none;
}
.todo-list li .toggle {
height: 40px;
}
.toggle-all {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
}
@media (max-width: 430px) {
.footer {
height: 50px;
}
.filters {
bottom: 10px;
}
}
</style></head><body>
<div id=root></div>
<p><footer class=info></p>
<p>Based on <a href="https://egghead.io/series/getting-started-with-redux">Getting Started with Redux</a> by <a href="https://github.com/gaearon">Dan Abramov</a></p>
<p>The example can also be found in the <a href="https://redux.js.org/docs/basics/ExampleTodoList.html">Redux Documentation</a></p>
<p>Stylesheet from <a href="http://todomvc.com">TodoMVC</a></p>
<script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script><script src='//fb.me/react-0.14.7.min.js'></script><script src='//fb.me/react-dom-0.14.7.min.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/redux/3.0.5/redux.min.js'></script><script src='https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.0.6/react-redux.min.js'></script>
<script >'use strict';
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) {if (window.CP.shouldStopExecution(2)){break;} var source = arguments[i]; for (var key in source) {if (window.CP.shouldStopExecution(1)){break;} if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } }
window.CP.exitedLoop(1);
}
window.CP.exitedLoop(2);
return target; };
// Reducers
var todo = function todo(state, action) {
switch (action.type) {
case 'ADD_TODO':
return {
id: action.id,
text: action.text,
completed: false
};
case 'TOGGLE_TODO':
return state.id !== action.id ? state : _extends({}, state, { completed: !state.completed });
default:
return state;
}
};
var todos = function todos() {
var state = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
var action = arguments[1];
switch (action.type) {
case 'ADD_TODO':
return [].concat(state, [todo(undefined, action)]);
case 'TOGGLE_TODO':
return state.map(function (t) {
return todo(t, action);
});
default:
return state;
}
};
var visibilityFilter = function visibilityFilter() {
var state = arguments.length <= 0 || arguments[0] === undefined ? 'SHOW_ALL' : arguments[0];
var action = arguments[1];
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter;
default:
return state;
}
};
var todoApp = Redux.combineReducers({
todos: todos,
visibilityFilter: visibilityFilter
});
// Action creators
var nextTodoId = 0;
var addTodo = function addTodo(text) {
return {
type: 'ADD_TODO',
id: nextTodoId++,
text: text
};
};
var toggleTodo = function toggleTodo(id) {
return {
type: 'TOGGLE_TODO',
id: id
};
};
var setVisibilityFilter = function setVisibilityFilter(filter) {
return {
type: 'SET_VISIBILITY_FILTER',
filter: filter
};
};
// Components
var _React = React;
var Component = _React.Component;
var _ReactRedux = ReactRedux;
var Provider = _ReactRedux.Provider;
var connect = _ReactRedux.connect;
var Link = function Link(_ref) {
var active = _ref.active;
var children = _ref.children;
var onClick = _ref.onClick;
var clickLink = function clickLink(e) {
e.preventDefault();
onClick();
};
var dummyLink = function dummyLink(e) {
e.preventDefault();
};
return React.createElement(
'li',
null,
React.createElement(
'a',
{
href: '#',
className: active ? "selected" : "",
onClick: active ? dummyLink : clickLink
},
children
)
);
};
// FilterLink container component
var FilterLink = connect(function (state, ownProps) {
return { // mapStateToProps
active: ownProps.filter === state.visibilityFilter
};
}, function (dispatch, ownProps) {
return { // mapDispatchToProps
onClick: function onClick() {
dispatch(setVisibilityFilter(ownProps.filter));
}
};
})(Link);
var Footer = function Footer() {
return React.createElement(
'footer',
{ className: 'footer' },
React.createElement(
'ul',
{ className: 'filters' },
React.createElement(
FilterLink,
{ filter: 'SHOW_ALL' },
'All'
),
React.createElement(
FilterLink,
{ filter: 'SHOW_ACTIVE' },
'Active'
),
React.createElement(
FilterLink,
{ filter: 'SHOW_COMPLETED' },
'Completed'
)
)
);
};
var Todo = function Todo(_ref2) {
var onClick = _ref2.onClick;
var completed = _ref2.completed;
var text = _ref2.text;
return React.createElement(
'li',
{ className: completed ? 'completed' : '' },
React.createElement(
'div',
{ className: 'view' },
React.createElement('input', {
onClick: onClick,
className: 'toggle',
type: 'checkbox',
checked: completed }),
React.createElement(
'label',
null,
text
)
)
);
};
var TodoList = function TodoList(_ref3) {
var todos = _ref3.todos;
var onTodoClick = _ref3.onTodoClick;
return React.createElement(
'section',
{ className: 'main' },
React.createElement('input', { className: 'toggle-all', type: 'checkbox' }),
React.createElement(
'ul',
{ className: 'todo-list' },
todos.map(function (todo) {
return React.createElement(Todo, _extends({
key: todo.id,
onClick: function onClick() {
return onTodoClick(todo.id);
}
}, todo));
})
)
);
};
var AddTodo = function AddTodo(_ref4) {
var dispatch = _ref4.dispatch;
var keyUpHandler = function keyUpHandler(evt) {
var ENTER = 13;
if (evt.which === ENTER && input.value) {
// hit enter, create new item if field isn't empty
dispatch(addTodo(input.value));
input.value = '';
}
};
var input = undefined;
return React.createElement(
'header',
{ className: 'header' },
React.createElement(
'h1',
null,
'todos'
),
React.createElement('input', {
autofocus: true,
className: 'new-todo',
placeholder: 'What needs to be done?',
ref: function ref(node) {
input = node;
},
onKeyDown: keyUpHandler
})
);
};
AddTodo = connect()(AddTodo);
var getVisibleTodos = function getVisibleTodos(todos, filter) {
switch (filter) {
case 'SHOW_ALL':
return todos;
case 'SHOW_COMPLETED':
return todos.filter(function (t) {
return t.completed;
});
case 'SHOW_ACTIVE':
return todos.filter(function (t) {
return !t.completed;
});
}
};
var VisibleTodoList = connect(
// mapStateToProps
function (state) {
return {
todos: getVisibleTodos(state.todos, state.visibilityFilter)
};
},
// mapDispatchToProps
function (dispatch) {
return {
onTodoClick: function onTodoClick(id) {
dispatch(toggleTodo(id));
}
};
})(TodoList);
var TodoApp = function TodoApp() {
return React.createElement(
'section',
{ className: 'todoapp' },
React.createElement(AddTodo, null),
React.createElement(VisibleTodoList, null),
React.createElement(Footer, null)
);
};
ReactDOM.render(React.createElement(
Provider,
{ store: Redux.createStore(todoApp) },
React.createElement(TodoApp, null)
), document.getElementById('root'));
//# sourceURL=pen.js
</script>
</body></html>