use dioxus_lib::prelude::*; 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 { #[allow(clippy::type_complexity)] config: Rc RouterConfig>>>>, } impl Default for RouterConfigFactory where ::Err: std::fmt::Display, { fn default() -> Self { Self::from(RouterConfig::default) } } impl RouterConfig + 'static> From for RouterConfigFactory { fn from(value: F) -> Self { Self { config: Rc::new(RefCell::new(Some(Box::new(value)))), } } } /// The props for [`Router`]. #[derive(Props)] pub struct RouterProps where ::Err: std::fmt::Display, { #[props(default, into)] config: RouterConfigFactory, } impl Clone for RouterProps where ::Err: std::fmt::Display, { fn clone(&self) -> Self { Self { config: self.config.clone(), } } } impl Default for RouterProps where ::Err: std::fmt::Display, { fn default() -> Self { Self { config: RouterConfigFactory::default(), } } } impl PartialEq for RouterProps where ::Err: std::fmt::Display, { fn eq(&self, _: &Self) -> bool { // prevent the router from re-rendering when the initial url or config changes true } } /// A component that renders the current route. pub fn Router(props: RouterProps) -> Element where ::Err: std::fmt::Display, { use crate::prelude::{outlet::OutletContext, RouterContext}; use_hook(|| { provide_context(RouterContext::new( (props .config .config .take() .expect("use_context_provider ran twice"))(), schedule_update_any(), )); provide_context(OutletContext:: { current_level: 0, _marker: std::marker::PhantomData, }); }); rsx! { Outlet:: {} } }