Skip to content

Commit bedfe33

Browse files
committed
prompt updates, vdom bug fix
1 parent 41ff2e1 commit bedfe33

2 files changed

Lines changed: 35 additions & 30 deletions

File tree

tsunami/prompts/system.md

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,15 @@ Key Points:
7777

7878
## Building Elements with vdom.H()
7979

80-
The H function creates virtual DOM elements following a React-like pattern. It takes a tag name, a props map, and any number of children:
80+
The H function creates virtual DOM elements following a React-like pattern (`React.createElement`). It takes a tag name, a props map, and any number of children:
8181

8282
```go
8383
// Basic element with no props
8484
vdom.H("div", nil, "Hello world")
8585

8686
// Element with props
8787
vdom.H("div", map[string]any{
88-
"className": "container",
88+
"className": "max-w-4xl mx-auto p-4",
8989
"id": "main",
9090
"onClick": func() {
9191
fmt.Println("clicked!")
@@ -94,38 +94,39 @@ vdom.H("div", map[string]any{
9494
"child content",
9595
)
9696

97-
// Element with style
97+
// Element with style (for custom CSS properties not available in Tailwind)
9898
vdom.H("div", map[string]any{
9999
"style": map[string]any{
100-
"marginTop": 10, // Numbers automatically convert to px
101-
"color": "red",
102-
"display": "flex",
100+
"marginTop": 10, // Numbers automatically convert to px (like React)
101+
"zIndex": 1000,
102+
"transform": "rotate(45deg)",
103103
},
104104
})
105105

106-
// Working with classes
106+
// Working with Tailwind classes
107107
vdom.H("div", map[string]any{
108108
"className": vdom.Classes(
109-
"base", // Static classes
110-
vdom.If(isActive, "active"), // Conditional class: condition first, then class
111-
vdom.If(isDisabled, "disabled"), // Another conditional
109+
"p-4 bg-white rounded-lg", // Static Tailwind classes
110+
vdom.If(isActive, "bg-blue-500 text-white"), // Conditional class: condition first, then class
111+
vdom.If(isDisabled, "opacity-50 cursor-not-allowed"), // Another conditional
112112
),
113113
})
114114

115115
// Nesting elements
116116
vdom.H("div", map[string]any{
117-
"className": "container",
117+
"className": "max-w-4xl mx-auto",
118118
},
119119
vdom.H("h1", map[string]any{
120-
"className": "title",
120+
"className": "text-2xl font-bold mb-4",
121121
}, "Hello"),
122122
vdom.H("p", map[string]any{
123-
"className": "content",
123+
"className": "text-gray-600 leading-relaxed",
124124
}, "Some content"),
125125
)
126126

127127
// Handling events
128128
vdom.H("button", map[string]any{
129+
"className": "px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600",
129130
"onClick": func() {
130131
handleClick()
131132
},
@@ -137,27 +138,31 @@ vdom.H("button", map[string]any{
137138
})
138139

139140
// List rendering
140-
vdom.H("ul", nil,
141-
vdom.ForEachIdx(items, func(item string, idx int) any {
141+
vdom.H("ul", map[string]any{
142+
"className": "space-y-2",
143+
},
144+
vdom.ForEach(items, func(item string, idx int) any {
142145
return vdom.H("li", map[string]any{
143146
"key": idx,
144-
"className": "list-item",
147+
"className": "py-2 px-4 bg-gray-100 rounded",
145148
}, item)
146149
}),
147150
)
148151

149152
// Conditional rendering
150153
vdom.H("div", nil,
151-
vdom.If(isVisible, vdom.H("span", nil, "Visible content")),
154+
vdom.If(isVisible, vdom.H("span", map[string]any{
155+
"className": "text-green-500 font-semibold",
156+
}, "Visible content")),
152157
)
153158
```
154159

155160
Arguments to H:
156161

157162
1. `tag` (string): The HTML tag name
158163
2. `props` (map[string]any or nil): Props map including:
159-
- className: String of space-separated classes
160-
- style: map[string]any of CSS properties
164+
- className: String of space-separated classes (like React)
165+
- style: map[string]any of CSS properties (like React)
161166
- Event handlers (onClick, onChange, etc)
162167
- Any other valid HTML attributes
163168
3. `children` (...any): Any number of child elements:
@@ -170,12 +175,12 @@ Arguments to H:
170175

171176
Best practices:
172177

173-
- Use Classes() with If() for conditional classes
174-
- Use camelCase for style properties (matching React)
175-
- Numbers in style are automatically converted to pixel values
176-
- Always create new slices when updating arrays in state
177-
- Use ForEach or ForEachIdx for list rendering
178-
- Include key prop when rendering lists
178+
- Use Classes() with If() for conditional classes (similar to React's conditional className patterns)
179+
- Use camelCase for style properties (exactly like React)
180+
- Numbers in style are automatically converted to pixel values (like React)
181+
- Always create new slices when updating arrays in state (like React's immutability principle)
182+
- Use ForEach for list rendering (always passes index, like React's map with index)
183+
- Include key prop when rendering lists (essential for React-like reconciliation)
179184

180185
## Conditional Rendering and Lists
181186

@@ -200,7 +205,7 @@ vdom.H("div", nil,
200205
// List rendering (adding "key" prop to li element)
201206
items := []string{"A", "B", "C"}
202207
vdom.H("ul", nil,
203-
vdom.ForEachIdx(items, func(item string, idx int) any {
208+
vdom.ForEach(items, func(item string, idx int) any {
204209
return vdom.H("li", map[string]any{
205210
"key": idx,
206211
"className": "list-item",
@@ -506,7 +511,7 @@ func MyComponent(ctx context.Context, props MyProps) any {
506511
},
507512
}),
508513
vdom.H("ul", nil,
509-
vdom.ForEach(items, func(item string) any {
514+
vdom.ForEach(items, func(item string, _ int) any {
510515
return vdom.H("li", nil, item)
511516
}),
512517
),
@@ -647,7 +652,7 @@ var TodoApp = app.DefineComponent("TodoApp",
647652
}, []any{})
648653

649654
return vdom.H("div", nil,
650-
vdom.ForEach(globalTodos, func(todo Todo) any {
655+
vdom.ForEach(globalTodos, func(todo Todo, _ int) any {
651656
return TodoItem(TodoItemProps{Todo: todo})
652657
}),
653658
)
@@ -910,7 +915,7 @@ var App = app.DefineComponent("App",
910915
911916
vdom.H("div", map[string]any{
912917
"className": "flex flex-col gap-2",
913-
}, vdom.ForEach(todos, func(todo Todo) any {
918+
}, vdom.ForEach(todos, func(todo Todo, _ int) any {
914919
return TodoItem(TodoItemProps{
915920
Todo: todo,
916921
OnToggle: func() { toggleTodo(todo.Id) },

tsunami/vdom/vdom.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ func Ternary[T any](cond bool, trueRtn T, falseRtn T) T {
145145
// ForEach applies a function to each item in a slice and returns a slice of results.
146146
// The function receives the item and its index, and can return any type for flexible VDOM generation.
147147
func ForEach[T any](items []T, fn func(T, int) any) []any {
148-
elems := make([]any, len(items))
148+
elems := make([]any, 0, len(items))
149149
for idx, item := range items {
150150
fnResult := fn(item, idx)
151151
elems = append(elems, fnResult)

0 commit comments

Comments
 (0)