From 17adf7cc1467aa1ddd41ffa16fcd3c438068bb98 Mon Sep 17 00:00:00 2001
From: Greg Johnston
"Select a contact."
} /> } diff --git a/examples/ssr_modes/src/app.rs b/examples/ssr_modes/src/app.rs index 3fbb461a5..f85d431e8 100644 --- a/examples/ssr_modes/src/app.rs +++ b/examples/ssr_modes/src/app.rs @@ -18,13 +18,13 @@ pub fn App(cx: Scope) -> impl IntoView {Component
for F where F: FnOnce(::leptos::Scope, P) -> R {}
+#[doc(hidden)]
+pub trait PropsOrNoPropsBuilder {
+ type Builder;
+ fn builder_or_not() -> Self::Builder;
+}
#[doc(hidden)]
-pub fn component_props_builder ,
-) -> ::Builder {
- ::builder()
+#[derive(Copy, Clone, Debug, Default)]
+pub struct EmptyPropsBuilder {}
+
+impl EmptyPropsBuilder {
+ pub fn build(self) {}
+}
+
+impl ::Builder;
+ fn builder_or_not() -> Self::Builder {
+ Self::builder()
+ }
+}
+
+impl PropsOrNoPropsBuilder for EmptyPropsBuilder {
+ type Builder = EmptyPropsBuilder;
+ fn builder_or_not() -> Self::Builder {
+ EmptyPropsBuilder {}
+ }
+}
+
+impl Component for F
+where
+ F: FnOnce(::leptos::Scope, P) -> R,
+ P: Props,
+{
+}
+
+#[doc(hidden)]
+pub fn component_props_builder ,
+) -> ::Builder {
+ ::builder_or_not()
+}
+
+#[doc(hidden)]
+pub fn component_view (
+ f: impl ComponentConstructor ,
+ cx: Scope,
+ props: P,
+) -> View {
+ f.construct(cx, props)
+}
+
+#[doc(hidden)]
+pub trait ComponentConstructor {
+ fn construct(self, cx: Scope, props: P) -> View;
+}
+
+impl for Func
+where
+ Func: FnOnce(Scope, P) -> V,
+ V: IntoView,
+ P: PropsOrNoPropsBuilder,
+{
+ fn construct(self, cx: Scope, props: P) -> View {
+ (self)(cx, props).into_view(cx)
+ }
}
diff --git a/leptos_macro/example/src/lib.rs b/leptos_macro/example/src/lib.rs
index b7b4b37fe..27e11334e 100644
--- a/leptos_macro/example/src/lib.rs
+++ b/leptos_macro/example/src/lib.rs
@@ -36,6 +36,5 @@ pub fn TestComponent(
and_another: usize,
) -> impl IntoView {
_ = (key, another, and_another);
- todo!()
}
diff --git a/leptos_macro/src/component.rs b/leptos_macro/src/component.rs
index 1e37f48fe..2584e92c9 100644
--- a/leptos_macro/src/component.rs
+++ b/leptos_macro/src/component.rs
@@ -131,6 +131,8 @@ impl ToTokens for Model {
ret,
} = self;
+ let no_props = props.len() == 1;
+
let mut body = body.to_owned();
// check for components that end ;
@@ -213,6 +215,42 @@ impl ToTokens for Model {
}
};
+ let props_arg = if no_props {
+ quote! {}
+ } else {
+ quote! {
+ props: #props_name #generics
+ }
+ };
+
+ let destructure_props = if no_props {
+ quote! {}
+ } else {
+ quote! {
+ let #props_name {
+ #prop_names
+ } = props;
+ }
+ };
+
+ let into_view = if no_props {
+ quote! {
+ impl #generics ::leptos::IntoView for #props_name #generics #where_clause {
+ fn into_view(self, cx: ::leptos::Scope) -> ::leptos::View {
+ #name(cx).into_view(cx)
+ }
+ }
+ }
+ } else {
+ quote! {
+ impl #generics ::leptos::IntoView for #props_name #generics #where_clause {
+ fn into_view(self, cx: ::leptos::Scope) -> ::leptos::View {
+ #name(cx, self).into_view(cx)
+ }
+ }
+ }
+ };
+
let output = quote! {
#[doc = #builder_name_doc]
#[doc = ""]
@@ -231,11 +269,7 @@ impl ToTokens for Model {
}
}
- impl #generics ::leptos::IntoView for #props_name #generics #where_clause {
- fn into_view(self, cx: ::leptos::Scope) -> ::leptos::View {
- #name(cx, self).into_view(cx)
- }
- }
+ #into_view
#docs
#component_fn_prop_docs
@@ -244,15 +278,13 @@ impl ToTokens for Model {
#vis fn #name #generics (
#[allow(unused_variables)]
#scope_name: ::leptos::Scope,
- props: #props_name #generics
+ #props_arg
) #ret #(+ #lifetimes)*
#where_clause
{
#body
- let #props_name {
- #prop_names
- } = props;
+ #destructure_props
#tracing_span_expr
diff --git a/leptos_macro/src/lib.rs b/leptos_macro/src/lib.rs
index fdf5dbd1a..6768c9b55 100644
--- a/leptos_macro/src/lib.rs
+++ b/leptos_macro/src/lib.rs
@@ -502,15 +502,11 @@ pub fn template(tokens: TokenStream) -> TokenStream {
///
/// // PascalCase: Generated component will be called MyComponent
/// #[component]
-/// fn MyComponent(cx: Scope) -> impl IntoView {
-/// todo!()
-/// }
+/// fn MyComponent(cx: Scope) -> impl IntoView {}
///
/// // snake_case: Generated component will be called MySnakeCaseComponent
/// #[component]
-/// fn my_snake_case_component(cx: Scope) -> impl IntoView {
-/// todo!()
-/// }
+/// fn my_snake_case_component(cx: Scope) -> impl IntoView {}
/// ```
///
/// 3. The macro generates a type `ComponentProps` for every `Component` (so, `HomePage` generates `HomePageProps`,
@@ -526,9 +522,7 @@ pub fn template(tokens: TokenStream) -> TokenStream {
/// use leptos::*;
///
/// #[component]
-/// pub fn MyComponent(cx: Scope) -> impl IntoView {
-/// todo!()
-/// }
+/// pub fn MyComponent(cx: Scope) -> impl IntoView {}
/// }
/// ```
/// ```
@@ -542,9 +536,7 @@ pub fn template(tokens: TokenStream) -> TokenStream {
/// use leptos::*;
///
/// #[component]
-/// pub fn my_snake_case_component(cx: Scope) -> impl IntoView {
-/// todo!()
-/// }
+/// pub fn my_snake_case_component(cx: Scope) -> impl IntoView {}
/// }
/// ```
///
@@ -557,7 +549,6 @@ pub fn template(tokens: TokenStream) -> TokenStream {
///
/// #[component]
/// fn MyComponent