Todo App Example

A simple todo list application built with Nahir UI and K2

Nahir UI Todo App

K2 Language
  • Learn K2 language
  • Install K2 compiler
  • Build a Nahir UI application
  • Deploy to production

How It Works

This Todo App is built using Nahir UI, a component-based UI framework for K2 language. The application uses ramdisk caching for ultra-fast state management and rendering.

todo_app.k2
# Todo App Example using Nahir UI
import NahirUI

# Define the Todo item component
component TodoItem {
  props = {
    text: "",
    completed: false,
    onToggle: null,
    onDelete: null
  }
  
  render {
    element = "div"
    className = "todo-item"
    children = [
      {
        element: "input",
        type: "checkbox",
        checked: props.completed,
        onChange: props.onToggle
      },
      {
        element: "span",
        className: props.completed ? "todo-text completed" : "todo-text",
        content: props.text
      },
      {
        element: "button",
        className: "delete-button",
        onClick: props.onDelete,
        content: "Delete"
      }
    ]
  }
}

# Define the Todo App component
component TodoApp {
  state = {
    todos: [],
    newTodo: "",
    filter: "all"
  }
  
  # Add a new todo
  function addTodo() {
    if (state.newTodo.trim() == "") {
      return
    }
    
    state.todos.push({
      id: generateId(),
      text: state.newTodo,
      completed: false
    })
    
    state.newTodo = ""
    updateState()
  }
  
  # Toggle a todo's completed status
  function toggleTodo(id) {
    for (todo in state.todos) {
      if (todo.id == id) {
        todo.completed = !todo.completed
        break
      }
    }
    
    updateState()
  }
  
  # Delete a todo
  function deleteTodo(id) {
    state.todos = state.todos.filter(todo => todo.id != id)
    updateState()
  }
  
  # Clear completed todos
  function clearCompleted() {
    state.todos = state.todos.filter(todo => !todo.completed)
    updateState()
  }
  
  # Set the filter
  function setFilter(filter) {
    state.filter = filter
    updateState()
  }
  
  # Get filtered todos
  function getFilteredTodos() {
    if (state.filter == "active") {
      return state.todos.filter(todo => !todo.completed)
    } else if (state.filter == "completed") {
      return state.todos.filter(todo => todo.completed)
    } else {
      return state.todos
    }
  }
  
  render {
    element = "div"
    className = "todo-app"
    children = [
      # Header
      {
        element: "div",
        className: "todo-header",
        children: [
          {
            element: "h2",
            content: "Nahir UI Todo App"
          }
        ]
      },
      
      # Input
      {
        element: "div",
        className: "todo-input-container",
        children: [
          {
            element: "input",
            className: "todo-input",
            placeholder: "What needs to be done?",
            value: state.newTodo,
            onChange: (e) => { state.newTodo = e.target.value }
          },
          {
            element: "button",
            className: "add-button",
            content: "Add",
            onClick: addTodo
          }
        ]
      },
      
      # Todo list
      {
        element: "ul",
        className: "todo-list",
        children: getFilteredTodos().map(todo => {
          return TodoItem.new({
            text: todo.text,
            completed: todo.completed,
            onToggle: () => toggleTodo(todo.id),
            onDelete: () => deleteTodo(todo.id)
          })
        })
      },
      
      # Footer
      {
        element: "div",
        className: "todo-footer",
        children: [
          {
            element: "span",
            className: "todo-count",
            content: getFilteredTodos().length + " items left"
          },
          {
            element: "div",
            className: "filter-buttons",
            children: [
              {
                element: "button",
                className: state.filter == "all" ? "filter-button active" : "filter-button",
                content: "All",
                onClick: () => setFilter("all")
              },
              {
                element: "button",
                className: state.filter == "active" ? "filter-button active" : "filter-button",
                content: "Active",
                onClick: () => setFilter("active")
              },
              {
                element: "button",
                className: state.filter == "completed" ? "filter-button active" : "filter-button",
                content: "Completed",
                onClick: () => setFilter("completed")
              }
            ]
          },
          {
            element: "button",
            className: "clear-completed",
            content: "Clear completed",
            onClick: clearCompleted
          }
        ]
      }
    ]
  }
}

# Create and render the Todo App
app = TodoApp.new()
UI.render(app)

Ready to Build Your Own Nahir UI App?

Get started with Nahir UI and build ultra-fast user interfaces for your K2 applications.