Skip to content

Instantly share code, notes, and snippets.

@OnesimusUnbound
Created January 4, 2024 09:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OnesimusUnbound/b065b8b1805169ca6ecd4faa3778b304 to your computer and use it in GitHub Desktop.
Save OnesimusUnbound/b065b8b1805169ca6ecd4faa3778b304 to your computer and use it in GitHub Desktop.
van.js simple todo app
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/yegor256/tacit@gh-pages/tacit-css.min.css"/>
<script type="module" src="main.js"></script>
<title>Document</title>
</head>
<body>
</body>
</html>
import van from "https://cdn.jsdelivr.net/gh/vanjs-org/van/public/van-1.2.7.min.js"
const { button, span, input, div } = van.tags
// TodoItem is only focused on the task item. It should only notify the parent component if the item has been deleted
const TodoItem = ({ondelete}, val) => span(val, " ", button({ onclick: ondelete }, "x"));
const TodoList = () => {
if (!localStorage.tasks) {
localStorage.tasks = "[]"
}
const tasks = van.state(JSON.parse(localStorage.tasks)), newTask = van.state("");
van.derive(() => localStorage.tasks = JSON.stringify(tasks.val))
const addTask = () => {
if (newTask.val.trim().length > 0) {
// van.js state won't trigger if I update the array itself. I should assign new array;
tasks.val = [newTask.val].concat(tasks.val);
newTask.val = "";
}
};
const deleteTask = (delIdx) => {
tasks.val = tasks.val.filter((_, idx) => idx !== delIdx);
}
return span(
input({type: "text", value: newTask, oninput: e => newTask.val = e.target.value}),
" ",
button({ onclick: addTask }, "+"),
() => div(
tasks.val.map(van._((t, i) => div(TodoItem( { ondelete: () => deleteTask(i)}, t))))
)
);
}
van.add(document.body, TodoList())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment