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
// Single child uses .child()
ui!
// -> div().child("Hello")
// Multiple children use .children([...])
ui!
// -> div().children(["First".into_any_element(), "Second".into_any_element()])
Comments
Use {/* ... */} for JSX-style comments:
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!
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) |
<deferred>{e}</deferred> |
deferred(e.into_any_element()) |
<Foo/> |
Foo::new() |
<{expr}/> |
expr |