1# UI Development Instructions
2
3## General Guidelines
4
5- Never use commands to send messages when you can directly mutate children or state.
6- Keep things simple; do not overcomplicate.
7- Create files if needed to separate logic; do not nest models.
8- Never do IO or expensive work in `Update`; always use a `tea.Cmd`.
9- Never change the model state inside of a command use messages and than update the state in the main loop
10- Use the `github.com/charmbracelet/x/ansi` package for any string manipulation
11 that might involves ANSI codes. Do not manipulate ANSI strings at byte level!
12 Some useful functions:
13 * `ansi.Cut`
14 * `ansi.StringWidth`
15 * `ansi.Strip`
16 * `ansi.Truncate`
17
18
19## Architecture
20
21### Main Model (`model/ui.go`)
22
23Keep most of the logic and state in the main model. This is where:
24- Message routing happens
25- Focus and UI state is managed
26- Layout calculations are performed
27- Dialogs are orchestrated
28
29### Components Should Be Dumb
30
31Components should not handle bubbletea messages directly. Instead:
32- Expose methods for state changes
33- Return `tea.Cmd` from methods when side effects are needed
34- Handle their own rendering via `Render(width int) string`
35
36### Chat Logic (`model/chat.go`)
37
38Most chat-related logic belongs here. Individual chat items in `chat/` should be simple renderers that cache their output and invalidate when data changes (see `cachedMessageItem` in `chat/messages.go`).
39
40## Key Patterns
41
42### Composition Over Inheritance
43
44Use struct embedding for shared behaviors. See `chat/messages.go` for examples of reusable embedded structs for highlighting, caching, and focus.
45
46### Interfaces
47
48- List item interfaces are in `list/item.go`
49- Chat message interfaces are in `chat/messages.go`
50- Dialog interface is in `dialog/dialog.go`
51
52### Styling
53
54- All styles are defined in `styles/styles.go`
55- Access styles via `*common.Common` passed to components
56- Use semantic color fields rather than hardcoded colors
57
58### Dialogs
59
60- Implement the dialog interface in `dialog/dialog.go`
61- Return message types from `Update()` to signal actions to the main model
62- Use the overlay system for managing dialog lifecycle
63
64## File Organization
65
66- `model/` - Main UI model and major components (chat, sidebar, etc.)
67- `chat/` - Chat message item types and renderers
68- `dialog/` - Dialog implementations
69- `list/` - Generic list component with lazy rendering
70- `common/` - Shared utilities and the Common struct
71- `styles/` - All style definitions
72- `anim/` - Animation system
73- `logo/` - Logo rendering
74
75## Common Gotchas
76
77- Always account for padding/borders in width calculations
78- Use `tea.Batch()` when returning multiple commands
79- Pass `*common.Common` to components that need styles or app access