gpui-markup
A declarative markup DSL for building GPUI applications.
Installation
[]
= "0.4"
Usage
use *;
use ui;
Syntax
Elements
All elements require braces {}. Attributes go inside braces with [...]:
// Empty div
ui!
// -> div()
// Div with attributes
ui!
// -> div().flex().flex_col()
// Div with children
ui!
// -> div().child("content")
// Full form: attributes followed by children
ui!
// -> div().flex().child("content")
Attributes
Attributes go inside { [...] }, comma-separated:
// 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 (use tuples)
ui!
// -> div().when(condition, |d| d.bg(red()))
Children
Children go inside {...}, comma-separated (after optional attributes):
ui!
// -> div().child("First").child("Second").child(div().bold().child("Nested"))
Deferred
The deferred element wraps content for deferred rendering:
ui!
// -> deferred(div().child("Deferred content").into_any_element())
Spread Children
Use ..expr to spread an iterable as children:
let items: = vec!;
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:
ui!
Comments
Use standard Rust comments inside ui!:
ui!
// -> div().child("Visible content")
Components
Components are any non-native element names. They automatically call ::new():
// Simple component
ui!
// -> Header::new()
// Component with attributes
ui!
// -> Button::new().style(Primary)
// Component with children
ui!
// -> Container::new().child("Content").child(Footer::new())
Expression Elements
Any expression can be used as an element. Braces are required:
// Custom constructor
ui!
// -> Button::with_label("Click")
// Expression with attributes
ui!
// -> Button::with_label("Click").style(Primary)
// Builder pattern expression
ui!
// -> div().flex().flex_col().child("Content")
// Parentheses for complex expressions (braces optional)
ui!
// -> a + b
Nested Structures
ui!
How It Works
The ui! macro transforms the markup 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().child(a).child(b) |
div { ..items } |
div().children(items) |
div { .a().b() } |
div().a().b() |
deferred { e } |
deferred(e.into_any_element()) |
Header {} |
Header::new() |
Header { [a] } |
Header::new().a() |
expr {} |
expr |
expr { [a] } |
expr.a() |
(expr) |
expr |