How It Works
The state is an array of groups, each containing aname, a todos array, and a new_todo input buffer. ForEach iterates the groups, and a nested ForEach iterates each group’s todos.
Nested loops — with ForEach("groups") as (gi, group) destructures the loop binding into an index (gi) and item (group), matching Python’s enumerate convention. Each ForEach automatically captures $item and $index into scoped let bindings, so the outer loop’s group and gi survive even after the inner loop shadows $item and $index. The inner ForEach(f"groups.{gi}.todos") as (ti, todo) uses gi to target the right group and ti to target individual todos.
Inline editing — instead of showing todo text as a Text component, each item uses a borderless Input styled with border-0 shadow-none p-0 so it looks like plain text but is directly editable. Dot-path auto-binding handles the read and write — the input’s name points at the exact item in state (f"groups.{gi}.todos.{ti}.text").
Disabling the Add button — disabled=~group.new_todo evaluates to true when the input is empty, so the button stays disabled until you type something. group is the outer ForEach’s item, so group.new_todo accesses the group’s input buffer.
Hiding completed items — each group has a show_done flag toggled by a small checkbox in the footer. Inside the inner todo loop, If(~todo.done | group.show_done) checks the todo’s completion against the group’s visibility flag. Both references survive nesting because ForEach’s auto-bind captured them.
Adding a group — the dashed card at the end appends a new group object with AppendState("groups", {...}). ForEach picks it up and renders a new card automatically.