Mrr Todo list example
by mikolalex
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/mrr@1.3.1/dist/bundle.js"></script>
<div id="app"></div>
CSS
body {
padding: 10px;
}
.options {
margin: 0;
padding: 0;
display: inline-block;
}
.todo-item {
border: 1px dotted grey;
padding: 10px;
margin: 10px 0;
}
.remove {
float: right;
}
.remove, .clear-completed, .options li {
color: blue;
text-decoration: underline;
display: inline-block;
margin: 0 5px;
cursor: pointer;
}
.options li.active {
border: 1px dotted grey;
color: black;
padding: 3px;
text-decoration: none;
}
.text {
display: inline-block;
padding: 0 10px;
}
.todo-app > * {
margin: 20px 0;
}
Babel + JSX
const { withMrr, skip } = mrr;
const styles = ``;
const { pipe, prop, equals, identity, not, always, inc, assoc, map, apply, filter, __, useWith, unapply } = R;
const id = identity;
const todos = localStorage.getItem('todos') ? JSON.parse(localStorage.getItem('todos')) : [];
const ifPressed = key => e => e.key == key || skip;
const TodoItem = withMrr({
i: [prop('i'), '$props'],
isEdited: ['toggle', 'startEdit', 'finishEdit'],
changes: ['merge',
[(completed, i) => [{ completed }, i], 'complete', '-i'],
[(text, i) => [{ text }, i], 'afterEdit.update', '-i'],
],
afterEdit: ['split', {
'remove': not,
'update': identity,
}, '-newText', 'finishEdit'],
remove: [prop('i'), '-$props', ['merge', 'afterEdit.remove', 'removeItem']],
}, (state, props, $) => ( <div className="todo-item">
<input type="checkbox" checked={ props.completed } onChange={ $('complete', !props.completed) } />
<div className="remove">
<a onClick={ $('removeItem') }>Remove</a>
</div>
{ state.isEdited
? <div className="text"><input
defaultValue={ props.text }
onChange={ $("newText") }
onKeyPress={ $('finishEdit', ifPressed('Enter')) } /></div>
: <div className="text" onClick={ $("startEdit") }>{ props.text }</div>
}
</div>));
const Todos = withMrr({
$init: {
todos,
shownTodos: [],
},
newTodoItem: [assoc('text', __, { completed: false }), '-newInput', 'addNewTodo'],
newInput: [always(''), 'newTodoItem'],
todos: ['coll', {
create: 'newTodoItem',
update: ['merge',
'*/changes',
[completed => ([{ completed }, {}]), 'toggleCompleted']],
delete: ['merge',
[always({ completed: true }), 'clearCompleted'],
'*/remove'],
}],
shownTodos: [(a, val) => a.filter(pipe(prop('completed'), equals(val), not)), 'todos', 'show', '$start'],
openNumber: [pipe(filter(pipe(prop('completed'), not)), prop('length')), 'todos', '$start'],
toLS: [arr => localStorage.setItem('todos',...