diff --git a/docs/concepts/function-components/attribute.md b/docs/concepts/function-components/attribute.md
index 4dd99078eae..aa7262df48b 100644
--- a/docs/concepts/function-components/attribute.md
+++ b/docs/concepts/function-components/attribute.md
@@ -3,14 +3,14 @@ title: #[function_component]
description: The #[function_component] attribute
---
-
-The `#[function_component(_)]` turns a normal Rust function into a function component.
-Functions with the attribute have to return `Html` and may take a single parameter for the type of props the component should accept.
+`#[function_component(_)]` turns a normal Rust function into a function component.
+Functions with the attribute have to return `Html` and may take a single parameter for the type of props the component should accept.
The parameter type needs to be a reference to a type which implements `Properties` and `PartialEq` (ex. `props: &MyProps`).
If the function doesn't have any parameters the resulting component doesn't accept any props.
The attribute doesn't replace your original function with a component. You need to provide a name as an input to the attribute which will be the identifier of the component.
Assuming you have a function called `chat_container` and you add the attribute `#[function_component(ChatContainer)]` you can use the component like this:
+
```rust
html! { }
```
@@ -19,6 +19,7 @@ html! { }
+
```rust
#[derive(Properties, Clone, PartialEq)]
pub struct RenderedAtProps {
@@ -37,6 +38,7 @@ pub fn rendered_at(props: &RenderedAtProps) -> Html {
```
+
```rust
#[function_component(App)]
fn app() -> Html {
@@ -46,7 +48,7 @@ fn app() -> Html {
let counter = Rc::clone(&counter);
Callback::from(move |_| set_counter(*counter + 1))
};
-
+
html! {
@@ -58,4 +60,38 @@ fn app() -> Html {
}
}
```
+
+
+## Generic function components
+
+The `#[function_component(_)]` attribute also works with generic functions for creating generic components.
+
+```rust
+#[derive(Properties, Clone, PartialEq)]
+pub struct Props
+ where T: Clone + PartialEq
+{
+ data: T,
+}
+
+#[function_component(MyGenericComponent)]
+pub fn my_generic_component(props: &Props) -> Html
+ where T: Clone + PartialEq + Display
+{
+ html! {
+
+ }
+}
+
+struct MissingTypeBounds;
+
+fn compile_fail() {
+ // missing prop 'a'
+ html! { /> };
+
+ // invalid type parameter
+ html! { /> };
+ // parameter doesn't match bounds
+ html! { /> };
+
+ // missing type param
+ html! { };
+}
+
+fn main() {}
diff --git a/packages/yew-functional-macro/tests/function_attr/generic-props-fail.stderr b/packages/yew-functional-macro/tests/function_attr/generic-props-fail.stderr
new file mode 100644
index 00000000000..1d1bfcd3dc1
--- /dev/null
+++ b/packages/yew-functional-macro/tests/function_attr/generic-props-fail.stderr
@@ -0,0 +1,58 @@
+error[E0412]: cannot find type `INVALID` in this scope
+ --> $DIR/generic-props-fail.rs:26:19
+ |
+21 | fn compile_fail() {
+ | - help: you might be missing a type parameter: ``
+...
+26 | html! { /> };
+ | ^^^^^^^ not found in this scope
+
+error[E0599]: no method named `build` found for struct `PropsBuilder` in the current scope
+ --> $DIR/generic-props-fail.rs:23:14
+ |
+4 | #[derive(Clone, Properties, PartialEq)]
+ | ---------- method `build` not found for this
+...
+23 | html! { /> };
+ | ^^^^ method not found in `PropsBuilder`
+ |
+ = help: items from traits can only be used if the trait is implemented and in scope
+ = note: the following trait defines an item `build`, perhaps you need to implement it:
+ candidate #1: `proc_macro::bridge::server::TokenStreamBuilder`
+
+error[E0599]: no function or associated item named `new` found for struct `yew::virtual_dom::vcomp::VChild>>` in the current scope
+ --> $DIR/generic-props-fail.rs:28:14
+ |
+28 | html! { /> };
+ | ^^^^ function or associated item not found in `yew::virtual_dom::vcomp::VChild>>`
+ |
+ ::: $WORKSPACE/packages/yew-functional/src/lib.rs
+ |
+ | pub struct FunctionComponent {
+ | ----------------------------------------------------------- doesn't satisfy `_: yew::html::component::Component`
+ |
+ = note: the method `new` exists but the following trait bounds were not satisfied:
+ `yew_functional::FunctionComponent>: yew::html::component::Component`
+
+error[E0277]: the trait bound `MissingTypeBounds: yew::html::component::properties::Properties` is not satisfied
+ --> $DIR/generic-props-fail.rs:28:14
+ |
+28 | html! { /> };
+ | ^^^^ the trait `yew::html::component::properties::Properties` is not implemented for `MissingTypeBounds`
+ |
+ = note: required because of the requirements on the impl of `yew_functional::FunctionProvider` for `comp`
+
+error[E0277]: can't compare `MissingTypeBounds` with `MissingTypeBounds`
+ --> $DIR/generic-props-fail.rs:28:14
+ |
+28 | html! { /> };
+ | ^^^^ no implementation for `MissingTypeBounds == MissingTypeBounds`
+ |
+ = help: the trait `std::cmp::PartialEq` is not implemented for `MissingTypeBounds`
+ = note: required because of the requirements on the impl of `yew_functional::FunctionProvider` for `comp`
+
+error[E0107]: wrong number of type arguments: expected 1, found 0
+ --> $DIR/generic-props-fail.rs:31:14
+ |
+31 | html! { };
+ | ^^^^ expected 1 type argument