gpui-rsx 0.3.1

A JSX-like macro for GPUI - simplify UI development with HTML-like syntax
Documentation
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
# Migration Guide

Guide for upgrading between versions and migrating from manual GPUI code.

## Migrating from Manual GPUI

### Benefits of GPUI-RSX

- **More concise**: Less boilerplate code
- **Better readability**: HTML-like structure is easier to understand
- **Familiar syntax**: JSX-like for those coming from React
- **Type safe**: Full Rust type checking
- **No runtime overhead**: Compiles to the same GPUI code

### Basic Element Migration

**Before (Manual GPUI):**
```rust
div()
    .flex()
    .flex_col()
    .gap(px(16.0))
    .bg(rgb(0x3b82f6))
```

**After (GPUI-RSX):**
```rust
rsx! {
    <div class="flex flex-col gap-4 bg-blue-500" />
}
```

### Children Migration

**Before (Manual GPUI):**
```rust
div()
    .child("Hello")
    .child(span().child("World"))
    .child(button().child("Click"))
```

**After (GPUI-RSX):**
```rust
rsx! {
    <div>
        "Hello"
        <span>"World"</span>
        <button>"Click"</button>
    </div>
}
```

### Event Handlers

**Before (Manual GPUI):**
```rust
button()
    .on_click(cx.listener(|view, _event, cx| {
        view.count += 1;
        cx.notify();
    }))
    .child("Click")
```

**After (GPUI-RSX):**
```rust
rsx! {
    <button onClick={cx.listener(|view, _event, cx| {
        view.count += 1;
        cx.notify();
    })}>
        "Click"
    </button>
}
```

### Conditional Rendering

**Before (Manual GPUI):**
```rust
let mut element = div();

if show_message {
    element = element.child("Message visible");
}

element
```

**After (GPUI-RSX):**
```rust
rsx! {
    <div>
        {if show_message {
            rsx! { <span>"Message visible"</span> }
        }}
    </div>
}
```

Or use `when` attribute:

```rust
rsx! {
    <div
        when={(show_message, |el| el.child("Message visible"))}
    />
}
```

### Lists

**Before (Manual GPUI):**
```rust
let mut list = div().flex().flex_col();

for item in &self.items {
    list = list.child(
        div()
            .child(item.name.clone())
    );
}

list
```

**After (GPUI-RSX):**
```rust
rsx! {
    <div class="flex flex-col">
        {for item in &self.items {
            <div>{item.name.as_str()}</div>
        }}
    </div>
}
```

### Complex Nested Structures

**Before (Manual GPUI):**
```rust
div()
    .flex()
    .child(
        div()
            .w(px(200.0))
            .bg(rgb(0xf3f4f6))
            .child(
                div()
                    .p(px(16.0))
                    .child("Sidebar")
            )
    )
    .child(
        div()
            .flex_1()
            .child(
                div()
                    .p(px(16.0))
                    .child("Main content")
            )
    )
```

**After (GPUI-RSX):**
```rust
rsx! {
    <div flex>
        <div class="w-48 bg-gray-100">
            <div class="p-4">"Sidebar"</div>
        </div>
        <div flex_1>
            <div class="p-4">"Main content"</div>
        </div>
    </div>
}
```

### Method Chaining

Both styles can coexist:

```rust
rsx! {
    <div class="flex">
        {div()
            .flex_1()
            .bg(self.compute_color())
            .child("Mixed style")}
    </div>
}
```

## Version Migrations

### 0.1.0 → 0.1.1

**Changes:**
- Added `when` and `whenSome` attributes
- Added `styled` flag for semantic HTML tags
- Improved error messages

**Migration steps:**

1. **No breaking changes** - all 0.1.0 code continues to work

2. **Optional: Use new `when` attribute:**

   Before:
   ```rust
   <div>
       {if condition {
           rsx! { <div bg={color} /> }
       } else {
           rsx! { <div /> }
       }}
   </div>
   ```

   After:
   ```rust
   <div when={(condition, |el| el.bg(color))} />
   ```

3. **Optional: Use `styled` flag:**

   Before:
   ```rust
   <h1 class="text-3xl font-bold">"Title"</h1>
   ```

   After:
   ```rust
   <h1 styled>"Title"</h1>
   ```

### 0.1.1 → 0.1.2

**Changes:**
- Improved compile-time performance
- Better type inference
- Enhanced error messages with helpful hints

**Migration steps:**

1. **No breaking changes** - all 0.1.1 code continues to work

2. **Optional: Update Cargo.toml:**
   ```toml
   [dependencies]
   gpui-rsx = "0.1.2"
   ```

3. **Optional: Simplify code with better type inference:**

   The macro now generates more efficient code automatically - no changes needed.

## Best Practices for Migration

### Incremental Migration

Don't migrate everything at once. Start with:

1. **New components** - Use RSX for all new code
2. **Simple components** - Migrate straightforward components first
3. **Complex components** - Migrate as you gain confidence

### Hybrid Approach

You can mix RSX and manual GPUI:

```rust
impl Render for MyView {
    fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
        rsx! {
            <div>
                {self.legacy_method()}  // Manual GPUI
                <div>"New RSX content"</div>
            </div>
        }
    }
}

fn legacy_method(&self) -> impl IntoElement {
    div().child("Legacy code")
}
```

### Testing Migration

1. **Visual testing**: Ensure UI looks the same
2. **Behavior testing**: Verify interactions work
3. **Performance testing**: Check for regressions

### Common Migration Patterns

#### Pattern 1: Simple Replacement

Before:
```rust
div().child("Hello")
```

After:
```rust
rsx! { <div>"Hello"</div> }
```

#### Pattern 2: Variable Interpolation

Before:
```rust
div().child(format!("Count: {}", count))
```

After:
```rust
rsx! { <div>{format!("Count: {}", count)}</div> }
```

#### Pattern 3: Builder Pattern to Attributes

Before:
```rust
div()
    .w(px(200.0))
    .h(px(100.0))
    .bg(rgb(0xff0000))
```

After:
```rust
rsx! {
    <div
        w={px(200.0)}
        h={px(100.0)}
        bg={rgb(0xff0000)}
    />
}
```

#### Pattern 4: Dynamic Children

Before:
```rust
let mut container = div();
for item in items {
    container = container.child(div().child(item));
}
container
```

After:
```rust
rsx! {
    <div>
        {for item in items {
            <div>{item}</div>
        }}
    </div>
}
```

## Troubleshooting Migration

### Type Mismatches

If you get type errors after migration:

```rust
// Add explicit type annotations
let items: &[Item] = &self.items;

rsx! {
    <div>
        {for item in items {
            <div>{item.render()}</div>
        }}
    </div>
}
```

### Performance Regressions

If performance degrades:

1. **Use references instead of clones:**
   ```rust
   {for item in &items {
       <div>{item.name.as_str()}</div>
   }}
   ```

2. **Extract static content:**
   ```rust
   fn static_header() -> impl IntoElement {
       rsx! { <header>"Static"</header> }
   }
   ```

3. **Batch state updates:**
   ```rust
   self.field1 = value1;
   self.field2 = value2;
   cx.notify(); // Single update
   ```

### Compile Time Increases

If compile times increase significantly:

1. **Split large RSX blocks** into smaller methods
2. **Use incremental compilation:** `cargo build` for development
3. **Consider caching:** Results are cached between builds

## GPUI Version Compatibility

GPUI-RSX aims to stay compatible with the latest stable GPUI release.

### Checking Compatibility

```bash
cargo tree | grep gpui
```

### Updating Dependencies

```bash
cargo update
cargo build
```

### Version Matrix

| GPUI-RSX Version | Compatible GPUI Versions |
|------------------|-------------------------|
| 0.1.0 - 0.1.2   | 0.1.x                  |
| Future releases | Will maintain compatibility |

## Getting Help

If you encounter issues during migration:

1. **Review documentation:**
   - [Getting Started]getting-started.md
   - [API Reference]api-reference.md
   - [Best Practices]best-practices.md

3. **Ask for help:**
   - [GitHub Issues]https://github.com/wsafight/gpui-rsx/issues
   - Include: version numbers, minimal code example, error messages

## Migration Checklist

- [ ] Updated `Cargo.toml` with `gpui-rsx` dependency
- [ ] Imported `rsx` macro: `use gpui_rsx::rsx;`
- [ ] Tested simple component migration
- [ ] Migrated event handlers
- [ ] Migrated conditional rendering
- [ ] Migrated list rendering
- [ ] Tested UI appearance
- [ ] Tested interactions
- [ ] Verified performance
- [ ] Updated tests
- [ ] Updated documentation