tessera

Attribute Macro tessera 

Source
#[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:

  1. Registers a new component node (push) into the global ComponentTree
  2. Injects helper closures:
    • measure(Box<MeasureFn>) – supply layout measuring logic
    • input_handler(Box<InputHandlerFn>) – supply per‑frame interaction / event handling
    • on_minimize(Box<dyn Fn(bool) + Send + Sync>) – window minimize life‑cycle hook
    • on_close(Box<dyn Fn() + Send + Sync>) – window close life‑cycle hook
  3. Executes the original user code inside an inner closure to prevent early return from skipping cleanup
  4. 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.