Attribute Macro freya::prelude::component

#[component]
Expand description

Streamlines component creation. This is the recommended way of creating components, though you might want lower-level control with more advanced uses.

Arguments

  • no_case_check - Doesn’t enforce PascalCase on your component names. This will be removed/deprecated in a future update in favor of a more complete Clippy-backed linting system. The reasoning behind this is that Clippy allows more robust and powerful lints, whereas macros are extremely limited.

Features

This attribute:

  • Enforces that your component uses PascalCase. No warnings are generated for the PascalCase function name, but everything else will still raise a warning if it’s incorrectly PascalCase. Does not disable warnings anywhere else, so if you, for example, accidentally don’t use snake_case for a variable name in the function, the compiler will still warn you.
  • Automatically uses #[inline_props] if there’s more than 1 parameter in the function.
  • Verifies the validity of your component. E.g. if it has a Scope argument. Notes:
    • This doesn’t work 100% of the time, because of macro limitations.
    • Provides helpful messages if your component is not correct. Possible bugs (please, report these!):
    • There might be bugs where it incorrectly denies validity. This is bad as it means that you can’t use the attribute or you have to change the component.
    • There might be bugs where it incorrectly confirms validity. You will still know if the component is invalid once you use it, but the error might be less helpful.

Examples

  • Without props:
#[component]
fn GreetBob(cx: Scope) -> Element {
    render! { "hello, bob" }
}

// is equivalent to

#[allow(non_snake_case)]
fn GreetBob(cx: Scope) -> Element {
    #[warn(non_snake_case)]
    #[inline(always)]
    fn __dx_inner_comp(cx: Scope) -> Element {
        render! { "hello, bob" }
    }
    // There's no function call overhead since __dx_inner_comp has the #[inline(always)] attribute,
    // so don't worry about performance.
    __dx_inner_comp(cx)
}
  • With props:
#[component(no_case_check)]
fn GreetPerson(cx: Scope, person: String) -> Element {
    render! { "hello, {person}" }
}

// is equivalent to

#[derive(Props, PartialEq)]
#[allow(non_camel_case_types)]
struct GreetPersonProps {
    person: String,
}

#[allow(non_snake_case)]
fn GreetPerson<'a>(cx: Scope<'a, GreetPersonProps>) -> Element {
    #[warn(non_snake_case)]
    #[inline(always)]
    fn __dx_inner_comp<'a>(cx: Scope<'a, GreetPersonProps>e) -> Element {
        let GreetPersonProps { person } = &cx.props;
        {
            render! { "hello, {person}" }
        }
    }

    __dx_inner_comp(cx)
}