Skip to content

Instantly share code, notes, and snippets.

@samholmes
Created March 23, 2020 00:18
Show Gist options
  • Save samholmes/d66360731dc4b4205241f6c185813c6d to your computer and use it in GitHub Desktop.
Save samholmes/d66360731dc4b4205241f6c185813c6d to your computer and use it in GitHub Desktop.
IronJS TodoMVC
<!DOCTYPE html>
<html lang="en" data-framework="ironjs">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>IronJS • TodoMVC</title>
<link rel="stylesheet" href="https://unpkg.com/todomvc-common/base.css" />
<link rel="stylesheet" href="https://unpkg.com/todomvc-app-css/index.css" />
</head>
<body>
<script src="https://unpkg.com/todomvc-common/base.js"></script>
<script type="module" src="iron-todomvc.js"></script>
</body>
</html>
import plur from 'https://cdn.pika.dev/plur';
import { e, v, jarvis } from 'https://unpkg.com/ironjs@0.0.22-alpha';
// init store
// State
// Debugging toggle for mutation API
const useMutationAPI = true;
// Hash
const hashchangeEvent = v.fromEvent(window, 'hashchange');
const hash = v(() => (hashchangeEvent.v, window.location.hash || '#all'));
// Items
const items = v([]);
// How many items remain
const remains = v(() => items.v.filter(item => !item.v.done).length);
// Debugging Logs
// console.log(items);
// v.log(items);
// App entry
const App = () =>
e.section.todoapp(
e.header.header(
e.h1('todos'),
e.input['new-todo']({
placeholder: 'What needs to be done?',
autofocus: true,
keypress: newTodoKeypressHandler,
})
),
e.section.main(
e.input['#toggle-all.toggle-all']({
type: 'checkbox',
click: toggleAll,
}),
e.label({ for: 'toggle-all' }, 'Mark all as complete'),
ListElements
),
e.footer.footer(
{ hidden: v(() => !items.v.length) },
TodoCount,
e.ul.filters(
Filter({ tag: '#all' }, 'All'),
Filter({ tag: '#active' }, 'Active'),
Filter({ tag: '#completed' }, 'Completed')
),
e.button['clear-completed']('Clear completed', {
click: clearCompleted,
hidden: v(() => !items.v.some(item => item.v.done)),
})
)
);
// Elements
const ListElements = e.ul['todo-list'](
v(() =>
items.map((item, index) =>
Item({ item, onRemove: () => removeItem(index) })
)
)
);
const Item = ({ item, onRemove }) => {
const editRef = v();
const editing = v(false);
const hidden = v(
() =>
hash.v !== '#all' &&
((hash.v === '#active' && item.v.done) ||
(hash.v === '#completed' && !item.v.done))
);
const classes = v(() => [
item.v.done ? 'completed' : '',
editing.v ? 'editing' : '',
]);
const startEditing = () => ((editing.v = true), editRef.v.focus());
const stopEditing = () => (editing.v = false);
return e.li(
{ classes, hidden },
e.div.view(
e.input.toggle({
type: 'checkbox',
checked: v(() => item.v.done),
click: () => (item.v = { ...item.v, done: !item.v.done }),
}),
e.label({ dblclick: startEditing }, item.v.text),
e.button.destroy({ click: onRemove })
),
e.input.edit({
value: item.v.text,
ref: editRef,
change: ev => (item.v = { ...item.v, text: ev.target.value }),
blur: stopEditing,
keypress: ev => ev.key === 'Enter' && ev.target.blur(),
})
);
};
const Filter = e(({ tag }, children) =>
e.li(
e.a(
{
href: tag,
classes: v(() => (hash.v === tag ? ['selected'] : [])),
},
children
)
)
);
const TodoCount = e.span['todo-count'](
v(() => [e.strong(remains.v), plur(' item', remains.v), ' left'])
);
// Events
function newTodoKeypressHandler(ev) {
if (ev.key === 'Enter') {
const text = ev.target.value;
ev.target.value = '';
const item = v({ text, done: false });
if (useMutationAPI) items.push(item);
else items.v = items.v.concat(item);
}
}
function clearCompleted() {
if (useMutationAPI) {
let count = 0;
items.v
.map(item => item)
.forEach(({ v: { done } }, index) => {
if (done) {
items.pull(index - count);
count += 1;
}
});
} else {
items.v = items.v.filter(item => !item.v.done);
}
}
function removeItem(index) {
if (useMutationAPI) {
items.pull(index);
} else {
items.v = items.v.filter((item, i) => index !== i);
}
}
function toggleAll() {
const done = !items.v.every(item => item.v.done);
items.v.forEach(item => {
if (item.v.done !== done) item.v = { ...item.v, done };
});
}
// Render
jarvis.render(App(), document.body);
// Local Storage
// Get localStorageData
let localStorageData = localStorage.getItem('todomvc.items');
// Retrieve
items.v = localStorageData
? JSON.parse(localStorageData).map(item => v(item))
: [];
// Store
v(() =>
localStorage.setItem(
'todomvc.items',
JSON.stringify(items.v.map(item => item.v))
)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment