gpui-markup
A declarative markup DSL for building GPUI applications.
Installation
[]
= "0.1"
Usage
use *;
use ui;
Syntax
Elements
// Self-closing div
ui!
// -> div()
// Div with children
ui!
// -> div().child("content")
Deferred
The <deferred> element wraps content for deferred rendering. The child must implement IntoElement:
ui!
// -> deferred(div().child("Deferred content").into_any_element())
// Can also use expressions
let element = div.child;
ui!
// -> deferred(element.into_any_element())
Attributes
// Flag attributes (no value)
ui!
// -> div().flex().flex_col()
// Key-value attributes
ui!
// -> div().w(px(200.0)).h(px(100.0))
// Multi-value attributes
ui!
// -> div().when(condition, |d| d.bg(red()))
Children
// Children use chained .child() calls
ui!
// -> div().child("First").child("Second")
Spread Children
Use {..expr} to spread an iterable as children:
let items: = vec!;
// Spread an iterable
ui!
// -> div().children(items)
// Can be mixed with regular children
ui!
// -> div().child("Header").children(items).child("Footer")
Method Chains
Use {.method(args)} to insert method calls at any position. Supports method chains and generics:
ui!
This gives you full control over method call order.
Comments
Use standard Rust comments inside ui!:
ui!
// -> div().child("Visible content")
Components
Components used with <Component/> syntax must:
- Have a
new()constructor - Implement
IntoElement(use#[derive(IntoElement)])
Usage:
// Simple component (must be self-closing)
ui!
// -> Header::new()
// Component with configuration - use expression syntax
ui!
// -> Button::new("click me").style(ButtonStyle::Primary)
Expression Tags
For elements that need method chains or complex initialization:
// Self-closing expression
ui!
// -> icon.clone()
// Expression with attributes and children
ui!
// -> Container::new().flex().p_4().child("Content")
Nested Structures
ui!
Nested Macros
When an attribute accepts a closure that returns an element (e.g. for a list delegate), you can use the ui! macro inside that closure:
ui!
How It Works
The ui! macro transforms the JSX-like syntax into GPUI's builder pattern at compile time:
| Markup | Generated Code |
|---|---|
<div/> |
div() |
<div flex/> |
div().flex() |
<div w={x}/> |
div().w(x) |
<div when={a, b}/> |
div().when(a, b) |
<div>{a}{b}</div> |
div().child(a).child(b) |
<div>{..items}</div> |
div().children(items) |
<div>{.a().b()}</div> |
div().a().b() |
<deferred>{e}</deferred> |
deferred(e.into_any_element()) |
<Foo/> |
Foo::new() |
<{expr}/> |
expr |