Skip to content

Commit 8f80d0c

Browse files
authored
Merge pull request #18 from Portrucci/fix/router-not-working
removed unnecessary calls to multiple leptos functions
2 parents d2d6308 + 4be4730 commit 8f80d0c

File tree

5 files changed

+107
-24
lines changed

5 files changed

+107
-24
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ leptos-mview-macro = { path = "leptos-mview-macro", version = "0.4.0" }
1717
trybuild = "1"
1818
# needs to use ssr for some view-to-HTML features to work.
1919
leptos = { version = "0.7.0", features = ["ssr", "nightly"] }
20+
leptos_router = { version = "0.7.0", features = ["ssr", "nightly"] }
2021
leptos-mview = { path = ".", features = ["nightly"] }
2122

2223
[features]

leptos-mview-core/src/ast/children.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl ToTokens for NodeChild {
3030
Self::Element(e) => e.into_token_stream(),
3131
};
3232
tokens.extend(quote! {
33-
::leptos::prelude::IntoRender::into_render(#child_tokens)
33+
#child_tokens
3434
});
3535
}
3636
}

leptos-mview-core/src/expand.rs

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ mod utils;
2424
#[allow(clippy::wildcard_imports)]
2525
use utils::*;
2626

27-
/// Converts the children into a `leptos::Fragment::lazy()` token stream.
27+
/// Converts the children into a `View::new()` token stream.
2828
///
2929
/// Example:
3030
/// ```ignore
@@ -41,9 +41,7 @@ use utils::*;
4141
/// {"b"},
4242
/// ))
4343
/// ```
44-
45-
// used in the root or for component children
46-
pub fn children_fragment_tokens<'a>(
44+
pub fn root_children_tokens<'a>(
4745
children: impl Iterator<Item = &'a NodeChild>,
4846
span: Span,
4947
) -> TokenStream {
@@ -54,6 +52,25 @@ pub fn children_fragment_tokens<'a>(
5452
}
5553
}
5654

55+
// used for component children
56+
pub fn children_fragment_tokens<'a>(
57+
children: impl Iterator<Item = &'a NodeChild>,
58+
span: Span,
59+
) -> TokenStream {
60+
let children = children.collect::<Vec<_>>();
61+
let has_multiple_children = children.len() > 1;
62+
63+
if has_multiple_children {
64+
quote_spanned! { span=>
65+
( #( #children, )* )
66+
}
67+
} else {
68+
quote_spanned! { span=>
69+
#( #children )*
70+
}
71+
}
72+
}
73+
5774
/// Converts an xml (like html, svg or math) element to tokens.
5875
///
5976
/// Returns `None` if the element is not an xml element (custom component).
@@ -291,23 +308,22 @@ pub fn component_to_tokens<const IS_SLOT: bool>(element: &Element) -> Option<Tok
291308
path.span()=> ::leptos::component::component_props_builder(&#path)
292309
};
293310

311+
let directive_paths = (!directive_paths.is_empty()).then(|| {
312+
quote! {
313+
.add_any_attr((#(#directive_paths,)*))
314+
}
315+
});
316+
294317
Some(quote! {
295-
// the .build() returns `!` if not all props are present.
296-
// this causes unreachable code warning in ::leptos::component_view
297-
#[allow(unreachable_code)]
298-
::leptos::prelude::View::new(
299-
::leptos::component::component_view(
300-
&#path,
301-
#component_props_builder
302-
#attrs
303-
#children
304-
#slot_children
305-
#build
306-
)
307-
.add_any_attr((
308-
#(#directive_paths,)*
309-
))
318+
::leptos::component::component_view(
319+
&#path,
320+
#component_props_builder
321+
#attrs
322+
#children
323+
#slot_children
324+
#build
310325
)
326+
#directive_paths
311327
})
312328
}
313329
}

leptos-mview-core/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ mod kw;
1212
mod parse;
1313
mod span;
1414

15-
use ast::Child;
15+
use ast::{Child, Children};
16+
use expand::root_children_tokens;
1617
use proc_macro2::{Span, TokenStream};
1718
use proc_macro_error2::abort;
1819
use quote::quote;
1920
use syn::spanned::Spanned;
2021

21-
use crate::{ast::Children, expand::children_fragment_tokens};
22-
2322
#[must_use]
2423
pub fn mview_impl(input: TokenStream) -> TokenStream {
2524
// return () in case of any errors, to avoid "unexpected end of macro
@@ -54,7 +53,7 @@ pub fn mview_impl(input: TokenStream) -> TokenStream {
5453
);
5554
};
5655

57-
let fragment = children_fragment_tokens(children.element_children(), Span::call_site());
56+
let fragment = root_children_tokens(children.element_children(), Span::call_site());
5857
quote! {
5958
{
6059
#[allow(unused_braces)]

tests/router.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use leptos::prelude::*;
2+
use leptos_router::{components::{Route, Router, Routes}, location::RequestUrl, StaticSegment};
3+
use leptos_mview::mview;
4+
5+
mod utils;
6+
use utils::check_str;
7+
8+
#[test]
9+
fn router() {
10+
#[component]
11+
fn RouterContext(children: ChildrenFn, path: &'static str) -> impl IntoView {
12+
// `Router` panicks if it is not provided with a `RequestUrl` context
13+
Owner::new().set();
14+
provide_context(RequestUrl::new(path));
15+
16+
mview! {
17+
{children()}
18+
}
19+
}
20+
21+
22+
let router = || mview! {
23+
Router {
24+
main {
25+
Routes
26+
fallback=[mview! { p { "not found" }}]
27+
{
28+
Route
29+
path={StaticSegment("")}
30+
view=[mview! { p { "root route" } }];
31+
32+
Route
33+
path={StaticSegment("route2")}
34+
view=[mview! { p { "you are on /route2" } }];
35+
}
36+
}
37+
}
38+
};
39+
40+
let router_context1 = mview! {
41+
RouterContext
42+
path="/"
43+
{{
44+
router()
45+
}}
46+
};
47+
48+
let router_context2 = mview! {
49+
RouterContext
50+
path="/route2"
51+
{{
52+
router()
53+
}}
54+
};
55+
56+
let router_context3 = mview! {
57+
RouterContext
58+
path="/does-not-exist"
59+
{{
60+
router()
61+
}}
62+
};
63+
64+
check_str(router_context1, "<p>root route");
65+
check_str(router_context2, "<p>you are on /route2");
66+
check_str(router_context3, "<p>not found");
67+
}

0 commit comments

Comments
 (0)