child_router.rs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /// Components that allow the macro to add child routers. This component provides a context
  2. /// to the child router that maps child routes to root routes and vice versa.
  3. use dioxus_lib::prelude::*;
  4. use crate::prelude::Routable;
  5. /// Maps a child route into the root router and vice versa
  6. // NOTE: Currently child routers only support simple static prefixes, but this
  7. // API could be expanded to support dynamic prefixes as well
  8. pub(crate) struct ChildRouteMapping<R> {
  9. format_route_as_root_route: fn(R) -> String,
  10. parse_route_from_root_route: fn(&str) -> Option<R>,
  11. }
  12. impl<R: Routable> ChildRouteMapping<R> {
  13. pub(crate) fn format_route_as_root_route(&self, route: R) -> String {
  14. (self.format_route_as_root_route)(route)
  15. }
  16. pub(crate) fn parse_route_from_root_route(&self, route: &str) -> Option<R> {
  17. (self.parse_route_from_root_route)(route)
  18. }
  19. }
  20. /// Get the formatter that handles adding and stripping the prefix from a child route
  21. pub(crate) fn consume_child_route_mapping<R: Routable>() -> Option<ChildRouteMapping<R>> {
  22. try_consume_context()
  23. }
  24. impl<R> Clone for ChildRouteMapping<R> {
  25. fn clone(&self) -> Self {
  26. Self {
  27. format_route_as_root_route: self.format_route_as_root_route,
  28. parse_route_from_root_route: self.parse_route_from_root_route,
  29. }
  30. }
  31. }
  32. /// Props for the [`ChildHistoryProvider`] component.
  33. #[derive(Props, Clone)]
  34. pub struct ChildRouterProps<R: Routable> {
  35. /// The child route to render
  36. route: R,
  37. /// Take a parent route and return a child route or none if the route is not part of the child
  38. parse_route_from_root_route: fn(&str) -> Option<R>,
  39. /// Take a child route and return a parent route
  40. format_route_as_root_route: fn(R) -> String,
  41. }
  42. impl<R: Routable> PartialEq for ChildRouterProps<R> {
  43. fn eq(&self, _: &Self) -> bool {
  44. false
  45. }
  46. }
  47. /// A component that provides a [`History`] to a child router. The `#[child]` attribute on the router macro will insert this automatically.
  48. #[component]
  49. #[allow(missing_docs)]
  50. pub fn ChildRouter<R: Routable>(props: ChildRouterProps<R>) -> Element {
  51. use_hook(|| {
  52. provide_context(ChildRouteMapping {
  53. format_route_as_root_route: props.format_route_as_root_route,
  54. parse_route_from_root_route: props.parse_route_from_root_route,
  55. })
  56. });
  57. props.route.render(0)
  58. }