/// Components that allow the macro to add child routers. This component provides a context /// to the child router that maps child routes to root routes and vice versa. use dioxus_lib::prelude::*; use crate::prelude::Routable; /// Maps a child route into the root router and vice versa // NOTE: Currently child routers only support simple static prefixes, but this // API could be expanded to support dynamic prefixes as well pub(crate) struct ChildRouteMapping { format_route_as_root_route: fn(R) -> String, parse_route_from_root_route: fn(&str) -> Option, } impl ChildRouteMapping { pub(crate) fn format_route_as_root_route(&self, route: R) -> String { (self.format_route_as_root_route)(route) } pub(crate) fn parse_route_from_root_route(&self, route: &str) -> Option { (self.parse_route_from_root_route)(route) } } /// Get the formatter that handles adding and stripping the prefix from a child route pub(crate) fn consume_child_route_mapping() -> Option> { try_consume_context() } impl Clone for ChildRouteMapping { fn clone(&self) -> Self { Self { format_route_as_root_route: self.format_route_as_root_route, parse_route_from_root_route: self.parse_route_from_root_route, } } } /// Props for the [`ChildHistoryProvider`] component. #[derive(Props, Clone)] pub struct ChildRouterProps { /// The child route to render route: R, /// Take a parent route and return a child route or none if the route is not part of the child parse_route_from_root_route: fn(&str) -> Option, /// Take a child route and return a parent route format_route_as_root_route: fn(R) -> String, } impl PartialEq for ChildRouterProps { fn eq(&self, _: &Self) -> bool { false } } /// A component that provides a [`History`] to a child router. The `#[child]` attribute on the router macro will insert this automatically. #[component] #[allow(missing_docs)] pub fn ChildRouter(props: ChildRouterProps) -> Element { use_hook(|| { provide_context(ChildRouteMapping { format_route_as_root_route: props.format_route_as_root_route, parse_route_from_root_route: props.parse_route_from_root_route, }) }); props.route.render(0) }