impl ComponentFunction for Routes
This commit is contained in:
1 parent
7e4d2debe0
commit
d2cdcc602b
9 files changed
+154
-106
No files matched your search
@@ -213,6 +213,7 @@ pub fn routable(input: TokenStream) -> TokenStream {
|
||||
let parse_impl = route_enum.parse_impl();
|
||||
let display_impl = route_enum.impl_display();
|
||||
let routable_impl = route_enum.routable_impl();
|
||||
let component_impl = route_enum.component_impl();
|
||||
|
||||
(quote! {
|
||||
#error_type
|
||||
@@ -221,6 +222,8 @@ pub fn routable(input: TokenStream) -> TokenStream {
|
||||
|
||||
#routable_impl
|
||||
|
||||
#component_impl
|
||||
|
||||
#parse_impl
|
||||
})
|
||||
.into()
|
||||
@@ -599,6 +602,25 @@ impl RouteEnum {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn component_impl(&self) -> TokenStream2 {
|
||||
let name = &self.name;
|
||||
|
||||
quote! {
|
||||
impl dioxus_core::ComponentFunction<#name> for #name {
|
||||
type Props = ::std::rc::Rc<::std::cell::Cell<::dioxus_router::prelude::RouterConfig<#name>>>;
|
||||
|
||||
fn call(&self, props: Self::Props) -> dioxus_core::Element {
|
||||
let initial_route = self.clone();
|
||||
render! {
|
||||
::dioxus_router::prelude::Router::<#name> {
|
||||
config: move || props.take().initial_route(initial_route)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SiteMapSegment {
|
||||
|
||||
@@ -28,7 +28,7 @@ async fn main() {
|
||||
get(move |ws: WebSocketUpgrade| async move {
|
||||
ws.on_upgrade(move |socket| async move {
|
||||
_ = view
|
||||
.launch(dioxus_liveview::axum_socket(socket), Root)
|
||||
.launch(dioxus_liveview::axum_socket(socket), Route::Home {})
|
||||
.await;
|
||||
})
|
||||
}),
|
||||
@@ -44,23 +44,7 @@ async fn main() {
|
||||
|
||||
#[cfg(not(feature = "liveview"))]
|
||||
fn main() {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
dioxus_desktop::launch(Root);
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
dioxus_web::launch(root);
|
||||
}
|
||||
|
||||
#[cfg(feature = "liveview")]
|
||||
#[component]
|
||||
fn Root() -> Element {
|
||||
render! { Router::<Route> {} }
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "liveview"))]
|
||||
#[component]
|
||||
fn Root() -> Element {
|
||||
render! { Router::<Route> {} }
|
||||
launch(Route::Home {})
|
||||
}
|
||||
|
||||
#[component]
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
use dioxus_lib::prelude::*;
|
||||
|
||||
use std::{cell::RefCell, str::FromStr};
|
||||
use std::{cell::RefCell, rc::Rc, str::FromStr};
|
||||
|
||||
use crate::{prelude::Outlet, routable::Routable, router_cfg::RouterConfig};
|
||||
|
||||
/// The config for [`Router`].
|
||||
#[derive(Clone)]
|
||||
pub struct RouterConfigFactory<R: Routable> {
|
||||
#[allow(clippy::type_complexity)]
|
||||
config: RefCell<Option<Box<dyn FnOnce() -> RouterConfig<R>>>>,
|
||||
config: Rc<RefCell<Option<Box<dyn FnOnce() -> RouterConfig<R>>>>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
@@ -34,7 +35,7 @@ where
|
||||
impl<R: Routable, F: FnOnce() -> RouterConfig<R> + 'static> From<F> for RouterConfigFactory<R> {
|
||||
fn from(value: F) -> Self {
|
||||
Self {
|
||||
config: RefCell::new(Some(Box::new(value))),
|
||||
config: Rc::new(RefCell::new(Some(Box::new(value)))),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +68,9 @@ where
|
||||
<T as FromStr>::Err: std::fmt::Display,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
todo!()
|
||||
Self {
|
||||
config: self.config.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,21 +130,21 @@ where
|
||||
{
|
||||
use crate::prelude::{outlet::OutletContext, RouterContext};
|
||||
|
||||
todo!();
|
||||
// use_context_provider(|| {
|
||||
// RouterContext::new(
|
||||
// (props
|
||||
// .config
|
||||
// .config
|
||||
// .take()
|
||||
// .expect("use_context_provider ran twice"))(),
|
||||
// schedule_update_any(),
|
||||
// )
|
||||
// });
|
||||
// use_context_provider(|| OutletContext::<R> {
|
||||
// current_level: 0,
|
||||
// _marker: std::marker::PhantomData,
|
||||
// });
|
||||
use_hook(|| {
|
||||
provide_context(RouterContext::new(
|
||||
(props
|
||||
.config
|
||||
.config
|
||||
.take()
|
||||
.expect("use_context_provider ran twice"))(),
|
||||
schedule_update_any(),
|
||||
));
|
||||
|
||||
provide_context(OutletContext::<R> {
|
||||
current_level: 0,
|
||||
_marker: std::marker::PhantomData,
|
||||
});
|
||||
});
|
||||
|
||||
render! { Outlet::<R> {} }
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ pub struct RouterConfig<R: Routable> {
|
||||
pub(crate) failure_external_navigation: fn() -> Element,
|
||||
pub(crate) history: Option<Box<dyn AnyHistoryProvider>>,
|
||||
pub(crate) on_update: Option<RoutingCallback<R>>,
|
||||
pub(crate) initial_route: Option<R>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
@@ -77,6 +78,7 @@ where
|
||||
failure_external_navigation: FailureExternalNavigation,
|
||||
history: None,
|
||||
on_update: None,
|
||||
initial_route: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,18 +90,22 @@ where
|
||||
{
|
||||
pub(crate) fn take_history(&mut self) -> Box<dyn AnyHistoryProvider> {
|
||||
self.history.take().unwrap_or_else(|| {
|
||||
#[allow(unused)]
|
||||
let initial_route = self.initial_route.clone().unwrap_or("/".parse().unwrap_or_else(|err|
|
||||
panic!("index route does not exist:\n{}\n use MemoryHistory::with_initial_path or RouterConfig::initial_route to set a custom path", err)
|
||||
));
|
||||
// If we are on wasm32 and the web feature is enabled, use the web history.
|
||||
#[cfg(all(target_arch = "wasm32", feature = "web"))]
|
||||
let history = Box::<AnyHistoryProviderImplWrapper<R, WebHistory<R>>>::default();
|
||||
let history = Box::<AnyHistoryProviderImplWrapper::<WebHistory::<R>>>::default();
|
||||
// If we are not on wasm32 and the liveview feature is enabled, use the liveview history.
|
||||
#[cfg(all(feature = "liveview", not(target_arch = "wasm32")))]
|
||||
let history = Box::<AnyHistoryProviderImplWrapper<R, LiveviewHistory<R>>>::default();
|
||||
let history = Box::new(AnyHistoryProviderImplWrapper::new(LiveviewHistory::new(initial_route)));
|
||||
// If neither of the above are true, use the memory history.
|
||||
#[cfg(all(
|
||||
not(all(target_arch = "wasm32", feature = "web")),
|
||||
not(all(feature = "liveview", not(target_arch = "wasm32"))),
|
||||
))]
|
||||
let history = Box::<AnyHistoryProviderImplWrapper<R, MemoryHistory<R>>>::default();
|
||||
let history = Box::new(AnyHistoryProviderImplWrapper::new(MemoryHistory::with_initial_path(initial_route)));
|
||||
history
|
||||
})
|
||||
}
|
||||
@@ -135,7 +141,7 @@ where
|
||||
|
||||
/// The [`HistoryProvider`] the router should use.
|
||||
///
|
||||
/// Defaults to a default [`MemoryHistory`].
|
||||
/// Defaults to a different history provider depending on the target platform.
|
||||
pub fn history(self, history: impl HistoryProvider<R> + 'static) -> Self {
|
||||
Self {
|
||||
history: Some(Box::new(AnyHistoryProviderImplWrapper::new(history))),
|
||||
@@ -143,6 +149,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// The initial route the router should use if no history provider is set.
|
||||
pub fn initial_route(self, route: R) -> Self {
|
||||
Self {
|
||||
initial_route: Some(route),
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
/// A component to render when an external navigation fails.
|
||||
///
|
||||
/// Defaults to a router-internal component called [`FailureExternalNavigation`]
|
||||
|
||||
Reference in new issue
Block a user