A complete todo application demonstrating component communication, state management, and reactive lists with WatchList.
<x-todo-form>
<input type="text" placeholder="What needs to be done?"
value="{{todo}}" x-enter-pressed="add"/>
<button x-click="add">Add Task</button>
</x-todo-form>
<x-todo-list>
<div>Total: {{count}} | Done: {{done}} | Left: {{left}}</div>
<div x-list="items"></div>
</x-todo-list>
function TodoItem(self, name) {
self.name = name;
self.done = false;
self.delete = () => self.emit('del-todo', self);
self.changed = () => {
self.done = !self.done;
self.emit('task-changed');
};
self.template = `
<div class="todo-item">
<input type="checkbox" x-change="changed" />
<div class="task-text" x-class="done:done">{{name}}</div>
<button x-click="delete" class="delete-btn">Delete</button>
</div>`;
}
function TodoForm(self) {
self.todo = "";
self.add = () => {
if (!self.todo) {
alert("Task cannot be empty");
return;
}
self.emit("new-todo", self.todo);
self.todo = "";
}
}
function TodoList(self) {
self.items = new WatchList([$(TodoItem, "Example task")]);
self.left = self.done = self.count = 0;
self.countTasks = () => {
self.count = self.items.count();
self.done = self.items.count(x => x.done);
self.left = self.count - self.done;
};
self.on('new-todo', todo => {
self.items.add($(TodoItem, todo));
self.countTasks();
});
self.on('del-todo', todo => {
self.items.delete(x => x === todo);
self.countTasks();
});
self.on('task-changed', self.countTasks);
// Initialize counts
self.countTasks();
}
$([TodoForm, TodoList, TodoItem]);
emit() and on(){{property}} syntax for reactive valuesx-click, x-change, x-class for behavior