#[tessera]
Expand description
Transforms a regular Rust function into a Tessera UI component.
§What It Generates
The macro rewrites the function body so that on every invocation (every frame in an immediate‑mode pass) it:
- Registers a new component node (push) into the global
ComponentTree
- Injects helper closures:
measure(Box<MeasureFn>)
– supply layout measuring logicinput_handler(Box<InputHandlerFn>)
– supply per‑frame interaction / event handlingon_minimize(Box<dyn Fn(bool) + Send + Sync>)
– window minimize life‑cycle hookon_close(Box<dyn Fn() + Send + Sync>)
– window close life‑cycle hook
- Executes the original user code inside an inner closure to prevent early
return
from skipping cleanup - Pops (removes) the component node (ensuring balanced push/pop even with early return)
§Usage
Annotate a free function (no captured self) with #[tessera]
. You may then (optionally)
call any of the injected helpers exactly once (last call wins if repeated).
§Example
ⓘ
use tessera_ui::tessera;
#[tessera]
pub fn simple_button(label: String) {
// Optional layout definition
measure(Box::new(|_input| {
use tessera_ui::{ComputedData, Px};
Ok(ComputedData { width: Px(90), height: Px(32) })
}));
// Optional interaction handling
input_handler(Box::new(|input| {
// Inspect input.cursor_events / keyboard_events ...
let _ = input.cursor_events.len();
}));
on_close(Box::new(|| {
println!("Window closing – component had registered an on_close hook.");
}));
// Build children here (invoke child closures so they register themselves)
// child();
}
§Error Handling & Early Return
Your original function body is wrapped in an inner closure; an early return
inside
the body only returns from that closure, after which cleanup (node pop) still occurs.
§Parameters
- Attribute arguments are currently unused; pass nothing or
#[tessera]
.
§When NOT to Use
- For function that should not be a component.
§See Also
#[shard]
for navigation‑aware components with injectable shard state.