summaryrefslogtreecommitdiff
path: root/docs/adr/003-htmx-write-operations.md
blob: 2471a90cb45b0134a815bc6137c3dda2a197a934 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# ADR 003: HTMX-Based Write Operations

## Status
Accepted

## Context
Phase 1-2 of the dashboard were read-only views. Phase 3 required transforming it into an active command center where users can:
- Complete tasks/cards
- Create new tasks
- Add shopping items
- Toggle item states

Traditional approaches would require either:
- Full page reloads (poor UX)
- Complex JavaScript SPA framework (React, Vue)
- Custom AJAX handlers

## Decision
Use **HTMX attributes** for all write operations, returning HTML partials that swap into the DOM.

### Technical Details:

**Pattern: Form submission with partial swap**
```html
<form hx-post="/complete-atom"
      hx-vals='{"id": "{{.ID}}", "source": "{{.Source}}"}'
      hx-target="closest .task-card"
      hx-swap="outerHTML">
    <button type="submit">✓</button>
</form>
```

**Handler returns HTML partial:**
```go
func (h *Handler) HandleCompleteAtom(w http.ResponseWriter, r *http.Request) {
    // ... complete the task via API
    // Return completed state HTML or empty response
    HTMLResponse(w, h.renderer, "completed-atom", data)
}
```

**Quick Add Pattern:**
```html
<input hx-post="/unified-add"
       hx-trigger="keyup[key=='Enter']"
       hx-target="#task-list"
       hx-swap="afterbegin"
       name="content">
```

**Optimistic UI:**
- Use CSS transitions for immediate visual feedback
- On error, swap in error banner partial
- HTMX `hx-on` events for state management

**Unified Quick Add:**
- Single input parses text for routing hints
- `#groceries` tag → routes to shopping
- `#work` tag → routes to Trello
- Default → routes to Todoist

## Consequences

**Pros:**
- No JavaScript framework needed
- Server renders all HTML (single source of truth)
- Progressive enhancement (works without JS, enhanced with)
- Trivial to test (just HTTP handlers)
- Fast development cycle

**Cons:**
- More HTTP requests than SPA approach
- Partial HTML responses require careful template organization
- Limited offline capability

## Alternatives Considered

**Option A: React/Vue SPA**
- Rejected: Overkill for this use case, adds build complexity, harder to maintain

**Option B: Full page reloads**
- Rejected: Poor UX, especially on mobile

**Option C: Custom JavaScript + JSON APIs**
- Rejected: Reinventing what HTMX provides, more code to maintain