Skip to content

Components

wirelessEye edited this page Jun 29, 2026 · 1 revision

Components

Components are the reusable units of a Nestix tree. Most are written with the #[component] macro.

Function Components

A component function can accept:

  • no arguments;
  • &Props;
  • &Props and &Element.
#[component]
fn NoProps() -> Element {
    layout! { Text("Hello") }
}

#[component]
fn WithProps(props: &TextProps) -> Element {
    layout! { Text(props.label.clone()) }
}

#[component]
fn WithElement(props: &BoxProps, element: &Element) -> Element {
    element.after_mount(|| log::debug!("mounted"));
    layout! { Fragment(.children = props.children.clone()) }
}

The props argument must be passed by reference. Components with no props use ().

Return Values

Component functions return any ComponentOutput:

  • (): produces no child output;
  • Element: mounts a single element;
  • Option<Element>: mounts the element when present.

In practice, most components return Element or a layout! expression.

#[component]
fn MaybeLabel(props: &MaybeLabelProps) -> Option<Element> {
    props.visible.get().then(|| layout! { Text("Visible") })
}

Generic Components

Use #[component(generics(...))] when the generated component type needs generic parameters.

#[component(generics(T))]
fn Show<T: Clone + ToString + 'static>(props: &ShowProps<T>) -> Element {
    layout! { Text(props.value.get().to_string()) }
}

The built-in For and ContextProvider components use this pattern.

Manual Component Trait

The Component trait is public, but manual implementations are usually only needed for advanced component factories.

pub trait Component: 'static {
    type Props: Props;
    fn on_mount(element: &Element);
}

The runtime identifies components with component_id::<C>(), which stores the component type name, TypeId, and mount function.

Host Components

Renderer components often return child layouts and use lifecycle hooks:

#[component]
pub fn Div(props: &DivProps, element: &Element) -> Element {
    let html_element = create_dom_div();

    element.on_place(closure!([html_element] |placement| {
        // insert relative to placement.parent or placement.pred
    }));

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

    element.provide_handle(html_element);

    layout! {
        Fragment(.children = props.children.clone())
    }
}

Host components are the bridge between the Nestix tree and the platform.

Component Naming

The macro-generated component type uses the same identifier as the function. Inside the generated on_mount, the original function is reintroduced locally and called to produce output.

Clone this wiki locally