Make deprecated use router (#1260)

* make router props expansion better

* fix router data fields

* make a deprecated use_router hook
This commit is contained in:
ealmloff authored and GitHub committed 2023-07-27 10:32:23 -07:00
1 parent 5e3451a6f2
commit cfd62e274e
12 files changed
+82 -149

No files matched your search

+3 -25
View File
@@ -1,5 +1,5 @@
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use quote::quote;
use syn::Path;
use crate::nest::{Nest, NestId};
@@ -10,25 +10,20 @@ pub struct LayoutId(pub usize);
#[derive(Debug)]
pub struct Layout {
pub comp: Path,
pub props_name: Path,
pub active_nests: Vec<NestId>,
}
impl Layout {
pub fn routable_match(&self, nests: &[Nest]) -> TokenStream {
let props_name = &self.props_name;
let comp_name = &self.comp;
let name_str = self.comp.segments.last().unwrap().ident.to_string();
let dynamic_segments = self
.active_nests
.iter()
.flat_map(|id| nests[id.0].dynamic_segments());
quote! {
let comp = #props_name { #(#dynamic_segments,)* };
let dynamic = cx.component(#comp_name, comp, #name_str);
render! {
dynamic
#comp_name { #(#dynamic_segments: #dynamic_segments,)* }
}
}
}
@@ -40,23 +35,6 @@ impl Layout {
let _ = input.parse::<syn::Token![,]>();
let comp: Path = input.parse()?;
// Then parse the props name
let _ = input.parse::<syn::Token![,]>();
let props_name = input.parse::<Path>().unwrap_or_else(|_| {
let last = format_ident!("{}Props", comp.segments.last().unwrap().ident.to_string());
let mut segments = comp.segments.clone();
segments.pop();
segments.push(last.into());
Path {
leading_colon: None,
segments,
}
});
Ok(Self {
comp,
props_name,
active_nests,
})
Ok(Self { comp, active_nests })
}
}
+11 -13
View File
@@ -43,8 +43,8 @@ mod segment;
/// #[rustfmt::skip]
/// #[derive(Clone, Debug, PartialEq, Routable)]
/// enum Route {
/// // Define routes with the route macro. If the name of the component is not the same as the variant, you can specify it as the second parameter and the props type as the third
/// #[route("/", IndexComponent, ComponentProps)]
/// // Define routes with the route macro. If the name of the component is not the same as the variant, you can specify it as the second parameter
/// #[route("/", IndexComponent)]
/// Index {},
/// // Nests with parameters have types taken from child routes
/// // Everything inside the nest has the added parameter `user_id: usize`
@@ -52,7 +52,7 @@ mod segment;
/// // All children of layouts will be rendered inside the Outlet in the layout component
/// // Creates a Layout UserFrame that has the parameter `user_id: usize`
/// #[layout(UserFrame)]
/// // If there is a component with the name Route1 and props with the name Route1Props, you do not need to pass in the component and type
/// // If there is a component with the name Route1, you do not need to pass in the component name
/// #[route("/:dynamic?:query")]
/// Route1 {
/// // The type is taken from the first instance of the dynamic parameter
@@ -78,12 +78,11 @@ mod segment;
/// }
/// ```
///
/// # `#[route("path", component, props)]`
/// # `#[route("path", component)]`
///
/// The `#[route]` attribute is used to define a route. It takes up to 3 parameters:
/// - `path`: The path to the enum variant (relative to the parent nest)
/// - (optional) `component`: The component to render when the route is matched. If not specified, the name of the variant is used
/// - (optional) `props`: The props type for the component. If not specified, the name of the variant with `Props` appended is used
///
/// Routes are the most basic attribute. They allow you to define a route and the component to render when the route is matched. The component must take all dynamic parameters of the route and all parent nests.
/// The next variant will be tied to the component. If you link to that variant, the component will be rendered.
@@ -91,9 +90,9 @@ mod segment;
/// ```rust, skip
/// #[derive(Clone, Debug, PartialEq, Routable)]
/// enum Route {
/// // Define routes that renders the IndexComponent that takes the IndexProps
/// // Define routes that renders the IndexComponent
/// // The Index component will be rendered when the route is matched (e.g. when the user navigates to /)
/// #[route("/", Index, IndexProps)]
/// #[route("/", Index)]
/// Index {},
/// }
/// ```
@@ -109,7 +108,7 @@ mod segment;
/// enum Route {
/// // Redirects the /:id route to the Index route
/// #[redirect("/:id", |_: usize| Route::Index {})]
/// #[route("/", Index, IndexProps)]
/// #[route("/", Index)]
/// Index {},
/// }
/// ```
@@ -131,7 +130,7 @@ mod segment;
/// // This is at /blog/:id
/// #[redirect("/:id", |_: usize| Route::Index {})]
/// // This is at /blog
/// #[route("/", Index, IndexProps)]
/// #[route("/", Index)]
/// Index {},
/// }
/// ```
@@ -147,7 +146,7 @@ mod segment;
/// // This is at /blog/:id
/// #[redirect("/:id", |_: usize| Route::Index {})]
/// // This is at /blog
/// #[route("/", Index, IndexProps)]
/// #[route("/", Index)]
/// Index {},
/// // Ends the nest
/// #[end_nest]
@@ -161,7 +160,6 @@ mod segment;
///
/// The `#[layout]` attribute is used to define a layout. It takes 2 parameters:
/// - `component`: The component to render when the route is matched. If not specified, the name of the variant is used
/// - (optional) `props`: The props type for the component. If not specified, the name of the variant with `Props` appended is used
///
/// The layout component allows you to wrap all children of the layout in a component. The child routes are rendered in the Outlet of the layout component. The layout component must take all dynamic parameters of the nests it is nested in.
///
@@ -171,7 +169,7 @@ mod segment;
/// #[layout(BlogFrame)]
/// #[redirect("/:id", |_: usize| Route::Index {})]
/// // Index will be rendered in the Outlet of the BlogFrame component
/// #[route("/", Index, IndexProps)]
/// #[route("/", Index)]
/// Index {},
/// }
/// ```
@@ -186,7 +184,7 @@ mod segment;
/// #[layout(BlogFrame)]
/// #[redirect("/:id", |_: usize| Route::Index {})]
/// // Index will be rendered in the Outlet of the BlogFrame component
/// #[route("/", Index, IndexProps)]
/// #[route("/", Index)]
/// Index {},
/// // Ends the layout
/// #[end_layout]
+5 -25
View File
@@ -21,7 +21,6 @@ use crate::segment::RouteSegment;
struct RouteArgs {
route: LitStr,
comp_name: Option<Path>,
props_name: Option<Path>,
}
impl Parse for RouteArgs {
@@ -34,10 +33,6 @@ impl Parse for RouteArgs {
let _ = input.parse::<syn::Token![,]>();
input.parse().ok()
},
props_name: {
let _ = input.parse::<syn::Token![,]>();
input.parse().ok()
},
})
}
}
@@ -83,22 +78,8 @@ impl Route {
Some(attr) => {
let args = attr.parse_args::<RouteArgs>()?;
let comp_name = args.comp_name.unwrap_or_else(|| parse_quote!(#route_name));
let props_name = args.props_name.unwrap_or_else(|| {
let last = format_ident!(
"{}Props",
comp_name.segments.last().unwrap().ident.to_string()
);
let mut segments = comp_name.segments.clone();
segments.pop();
segments.push(last.into());
Path {
leading_colon: None,
segments,
}
});
ty = RouteType::Leaf {
component: comp_name,
props: props_name,
};
route = args.route.value();
}
@@ -227,7 +208,6 @@ impl Route {
pub fn routable_match(&self, layouts: &[Layout], nests: &[Nest]) -> TokenStream2 {
let name = &self.route_name;
let name_str = name.to_string();
let mut tokens = TokenStream2::new();
@@ -261,16 +241,16 @@ impl Route {
}
}
}
RouteType::Leaf { component, props } => {
RouteType::Leaf { component } => {
let dynamic_segments = self.dynamic_segments();
let dynamic_segments_from_route = self.dynamic_segments();
quote! {
#[allow(unused)]
(#last_index, Self::#name { #(#dynamic_segments,)* }) => {
let comp = #props { #(#dynamic_segments_from_route,)* };
let dynamic = cx.component(#component, comp, #name_str);
render! {
dynamic
#component {
#(#dynamic_segments_from_route: #dynamic_segments_from_route,)*
}
}
}
}
@@ -364,5 +344,5 @@ impl Route {
#[derive(Debug)]
pub(crate) enum RouteType {
Child(Field),
Leaf { component: Path, props: Path },
Leaf { component: Path },
}