Attribute Macro kobold::component

source ·
#[component]
Expand description

The #[component] attribute macro that transforms functions into proper components.

Example

#[component]
fn MyComponent() -> impl View {
    view! {
        <p>"Hello, world!"</p>
    }
}

Flags

The #[component] attribute accepts a few optional flags using syntax: #[component(<flag>)]. Multiple comma-separated flags can be used at once.

Optional parameters: #[component(<param>?)]

Allows for parameters to have default values. Available syntax:

  • #[component(foo?)]: mark the parameter foo as optional, use Default trait implementation if absent.
  • #[component(foo?: <expression>)]: mark the parameter foo as optional, default to <expression>.
Examples
#[component(
    // Make `name` an optional parameter, defaults to `"Kobold"`
    name?: "Kobold",
    // Make `age` an optional parameter, use the `Default` value
    age?,
)]
fn Greeter<'a>(name: &'a str, age: Option<u32>) -> impl View + 'a {
    let age = age.map(|age| view!(", you are "{ age }" years old"));

    view! {
        <p> "Hello "{ name }{ age }
    }
}

view! {
    // Hello Kobold
    <Greeter />
    // Hello Alice
    <Greeter name="Alice" />
    // Hello Bob, you are 42 years old
    <Greeter name="Bob" age={42} />
}

Optional parameters of any type T can be set using any type that implements Maybe<T>.

This allows you to set optional parameters using an Option:

#[component(code?: 200)]
fn StatusCode(code: u32) -> impl View {
    view! {
        <p> "Status code was "{ code }
    }
}

view! {
    // Status code was 200
    <StatusCode />
    // Status code was 404
    <StatusCode code={404} />

    // Status code was 200
    <StatusCode code={None} />
    // Status code was 500
    <StatusCode code={Some(500)} />
}

All values are lazy-evaluated:

// The owned `String` will only be created if the `name` is not set.
#[component(name?: "Kobold".to_string())]
fn Greeter(name: String) -> impl View {
    view! {
        <p> "Hello "{ name }
    }
}
💡 Note:

You can only mark types that implement the Default trait as optional, even if you provide a concrete value using param?: value. This requirement might be relaxed in the future when trait specialization is stabilized.

Enable auto-branching: #[component(auto_branch)]

Automatically resolve all invocations of the view! macro inside if and match expressions to the same type.

For more details visit the branching module documentation.

Accept children: #[component(children)]

Turns the component into a component that accepts children. Available syntax:

  • #[component(children)]: children will be captured by the children argument on the function.
  • #[component(children: my_name)]: children will be captured by the my_name argument on the function.