viewof todos = {
const root = html`<div>`;
let todos;
function addTodo(i = todos.length) {
const newTodos = todos.slice();
newTodos.splice(i, 0, "");
setTodos(newTodos);
root.children[i].querySelector("input").focus();
}
function modifyTodo(i, value) {
const newTodos = todos.slice();
newTodos[i] = value;
setTodos(newTodos);
}
function removeTodo(i) {
const newTodos = todos.slice();
newTodos.splice(i, 1);
setTodos(newTodos);
root.children[i - 1].querySelector("input").focus();
}
function setTodos(newTodos) {
todos = newTodos.map(t => t.toUpperCase());
morph(root, html`<div>
${todos.map((todo, i) => html`<div>
${html`<input value=${todo}
oninput=${event => modifyTodo(i, event.currentTarget.value)}
onkeydown=${event => {
switch (event.key) {
case "Enter": {
if (event.currentTarget.value) {
addTodo(i + 1);
}
break;
}
case "Backspace": {
if (event.altKey && !event.currentTarget.value) {
removeTodo(i);
event.preventDefault();
}
break;
}
}
}}>`}
${html`<button onclick=${() => removeTodo(i)}>-`}
</div>`)}
${html`<button onclick=${() => addTodo()}>+`}
</div>`);
root.value = todos;
root.dispatchEvent(new CustomEvent("input"));
}
setTodos(["clean house", "buy milk"]);
return root;
}