Skip to content

Examples

wirelessEye edited this page Jun 30, 2026 · 2 revisions

Examples

The repository contains a web-oriented example app under nestix/examples/example-web-app. It defines renderer components and then uses them to build a counter and todo list.

Counter

#[component]
fn Counter() -> Element {
    let count = create_state(0);

    layout! {
        Div(.class = "counter".to_string()) {
            Div {
                Text(computed!(
                    [count] || format!("Count: {}", count.get())
                ))
            }

            Button(
                .on_click = callback!(
                    [count] || {
                        count.mutate(|value| *value += 1);
                    }
                ),
            ) {
                Text("Click")
            }

            if count.get() % 2 == 0 {
                Div {
                    Text("Is even!")
                }
            }
        }
    }
}

This demonstrates:

  • local component state;
  • a computed text prop;
  • a callback event handler;
  • a reactive conditional branch.

Todo List State

The todo list stores keyed items in an IndexMap.

let items = create_state::<IndexMap<String, String>>(IndexMap::new());
let input_value = create_state(String::new());

Callbacks mutate state:

let add = callback!(
    [input_value, items] || {
        items.mutate(|items| {
            items.insert(nanoid!(), input_value.get());
        });
        input_value.set(String::new());
    }
);

Keyed List Rendering

layout! {
    Div(.class = "todo-list".to_string()) {
        for item in items.clone() where key = |item| item.0.clone() {
            TodoListItem(
                .data = item,
                .remove = remove.clone(),
                .move_up = move_up.clone(),
                .move_down = move_down.clone(),
                .set_content = set_content.clone(),
            )
        }
    }
}

The For component reuses children by key and updates each item's readonly signal when the backing map changes.

Reactive Callback Props

The todo item builds callbacks from computed values so handlers always use the latest key and parent callbacks.

Button(
    .on_click = computed!([key, props.remove] || {
        callback!([key: key.get(), remove: remove.get()] || remove(&key))
    })
) {
    Text("Remove")
}

This works because normal props accept plain values, signals, or existing PropValue<T>.

Minimal Renderer Pattern

The example renderer components follow the same lifecycle shape:

#[component]
pub fn Text(props: &TextProps, element: &Element) {
    let text_node = document.create_text_node(&props.text.get());

    element.on_place(closure!([text_node] |placement| {
        // append or insert after placement handles
    }));

    effect!(
        [props.text, text_node] || text_node.set_data(&text.get())
    );

    element.on_unmount(closure!([text_node] || {
        text_node.remove();
    }));

    element.provide_handle(text_node.clone());
}

Use this as the starting point for new renderer components.

Clone this wiki locally