Svelte Search

About

Generate a basic todo app with Svelte 5

Let's create a basic todo app using Svelte 5 concepts. I'll walk you through the process step by step, explaining each part as we go.

1. Setting Up the Project

First, create a new Svelte project using the recommended method:

npx sv create todo-app
cd todo-app
npm install
npm run dev

This sets up a new Svelte project with all the necessary dependencies and starts a development server.

2. Basic Todo App Structure

Here's a simple todo app implementation. We'll create this in src/routes/+page.svelte:

<script>
  // Reactive state for todos
  let todos = [
    { id: 1, text: 'Learn Svelte', done: false },
    { id: 2, text: 'Build a todo app', done: true }
  ];

  // State for new todo input
  let newTodo = '';

  // Function to add a new todo
  function addTodo() {
    if (newTodo.trim()) {
      todos = [...todos, {
        id: Date.now(), // Use timestamp as unique ID
        text: newTodo,
        done: false
      }];
      newTodo = ''; // Clear input
    }
  }

  // Function to toggle todo completion
  function toggleTodo(id) {
    todos = todos.map(todo => 
      todo.id === id ? { ...todo, done: !todo.done } : todo
    );
  }

  // Function to remove a todo
  function removeTodo(id) {
    todos = todos.filter(todo => todo.id !== id);
  }
</script>

<style>
  .todo-list {
    max-width: 400px;
    margin: 2rem auto;
  }
  
  .todo-item {
    display: flex;
    align-items: center;
    margin: 0.5rem 0;
  }
  
  .done {
    text-decoration: line-through;
    opacity: 0.7;
  }
</style>

<div class="todo-list">
  <h1>Todo App</h1>
  
  <!-- Add Todo Form -->
  <form on:submit|preventDefault={addTodo}>
    <input
      bind:value={newTodo}
      placeholder="Add a new todo..."
      aria-label="New todo"
    />
    <button type="submit">Add</button>
  </form>

  <!-- Todo List -->
  <ul>
    {#each todos as todo (todo.id)}
      <li class="todo-item {todo.done ? 'done' : ''}">
        <input
          type="checkbox"
          checked={todo.done}
          on:change={() => toggleTodo(todo.id)}
        />
        <span>{todo.text}</span>
        <button on:click={() => removeTodo(todo.id)}>×</button>
      </li>
    {/each}
  </ul>
</div>

Key Concepts Explained:

  1. Reactive State:

    • todos is an array that holds our todo items
    • newTodo tracks the input for adding new todos
    • Svelte automatically updates the UI when these values change
  2. Two-Way Binding:

    • bind:value={newTodo} connects the input to our state
    • Changes in the input update newTodo, and changes to newTodo update the input
  3. Event Handling:

    • on:submit|preventDefault handles form submission
    • on:change handles checkbox toggling
    • on:click handles todo deletion
  4. Conditional Classes:

    • class="todo-item {todo.done ? 'done' : ''}" applies the 'done' class conditionally
    • This shows completed todos with a strikethrough style
  5. List Rendering:

    • {#each todos as todo (todo.id)} efficiently renders the list
    • The (todo.id) key ensures proper DOM updates when items change

3. Running the App

After creating this code:

  1. Save the file
  2. The development server should automatically reload
  3. Visit http://localhost:5173 to see your todo app in action

4. Next Steps

This basic implementation can be enhanced with:

  • Persistent storage (using localStorage or a backend)
  • More advanced filtering (show all/active/completed)
  • Drag-and-drop reordering
  • Animations for adding/removing items

Remember, this is a Svelte 5 implementation. If you're using an older version of Svelte, some syntax might need adjustment. The core concepts of reactivity and component structure remain the same across versions.

Would you like me to explain any part in more detail or help with adding any of these enhancements?