diff --git a/packages/router/examples/simple_routes.rs b/packages/router/examples/simple_routes.rs index ac408bb72..673658870 100644 --- a/packages/router/examples/simple_routes.rs +++ b/packages/router/examples/simple_routes.rs @@ -90,7 +90,7 @@ fn Route3(cx: Scope, dynamic: String) -> Element { "hello world link" } button { - onclick: move |_| { navigator.push(NavigationTarget::::External("https://www.google.com".to_string())); }, + onclick: move |_| { navigator.push("https://www.google.com"); }, "google link" } p { "Site Map" } diff --git a/packages/router/src/components/link.rs b/packages/router/src/components/link.rs index f6840b5b4..eb53c9547 100644 --- a/packages/router/src/components/link.rs +++ b/packages/router/src/components/link.rs @@ -219,15 +219,7 @@ pub fn Link<'a>(cx: Scope<'a, LinkProps<'a>>) -> Element { let do_default = onclick.is_none() || !onclick_only; let action = move |event| { if do_default && is_router_nav { - let href = match to { - IntoRoutable::FromStr(url) => url.to_string(), - IntoRoutable::Route(route) => router.any_route_to_string(&**route), - }; - let parsed_route: NavigationTarget> = match router.route_from_str(&href) { - Ok(route) => NavigationTarget::Internal(route.into()), - Err(err) => NavigationTarget::External(err), - }; - router.push_any(parsed_route); + router.push_any(router.resolve_into_routable(to)); } if let Some(handler) = onclick { diff --git a/packages/router/src/contexts/navigator.rs b/packages/router/src/contexts/navigator.rs index d8cf6aa57..2d8623aa8 100644 --- a/packages/router/src/contexts/navigator.rs +++ b/packages/router/src/contexts/navigator.rs @@ -1,4 +1,4 @@ -use crate::prelude::{ExternalNavigationFailure, NavigationTarget, Routable, RouterContext}; +use crate::prelude::{ExternalNavigationFailure, IntoRoutable, RouterContext}; /// A view into the navigation state of a router. #[derive(Clone)] @@ -34,20 +34,18 @@ impl GenericNavigator { /// Push a new location. /// /// The previous location will be available to go back to. - pub fn push( - &self, - target: impl Into>, - ) -> Option { - self.0.push(target) + pub fn push(&self, target: impl Into) -> Option { + let target = target.into(); + let as_any_navigation_target = self.0.resolve_into_routable(&target); + self.0.push_any(as_any_navigation_target) } /// Replace the current location. /// /// The previous location will **not** be available to go back to. - pub fn replace( - &self, - target: impl Into>, - ) -> Option { - self.0.replace(target) + pub fn replace(&self, target: impl Into) -> Option { + let target = target.into(); + let as_any_navigation_target = self.0.resolve_into_routable(&target); + self.0.replace_any(as_any_navigation_target) } } diff --git a/packages/router/src/contexts/router.rs b/packages/router/src/contexts/router.rs index 70b493a56..f0e67fff8 100644 --- a/packages/router/src/contexts/router.rs +++ b/packages/router/src/contexts/router.rs @@ -7,7 +7,9 @@ use std::{ use dioxus::prelude::*; use crate::{ - navigation::NavigationTarget, prelude::AnyHistoryProvider, routable::Routable, + navigation::NavigationTarget, + prelude::{AnyHistoryProvider, IntoRoutable}, + routable::Routable, router_cfg::RouterConfig, }; @@ -203,6 +205,21 @@ impl RouterContext { self.change_route() } + pub(crate) fn replace_any( + &self, + target: NavigationTarget>, + ) -> Option { + match target { + NavigationTarget::Internal(p) => { + let mut state = self.state_mut(); + state.history.replace(p) + } + NavigationTarget::External(e) => return self.external(e), + } + + self.change_route() + } + /// The route that is currently active. pub fn current(&self) -> R { *self @@ -224,6 +241,21 @@ impl RouterContext { (self.any_route_to_string)(route) } + pub(crate) fn resolve_into_routable( + &self, + into_routable: &IntoRoutable, + ) -> NavigationTarget> { + let href = match into_routable { + IntoRoutable::FromStr(url) => url.to_string(), + IntoRoutable::Route(route) => self.any_route_to_string(&**route), + }; + let parsed_route: NavigationTarget> = match self.route_from_str(&href) { + Ok(route) => NavigationTarget::Internal(route.into()), + Err(err) => NavigationTarget::External(err), + }; + parsed_route + } + /// The prefix that is currently active. pub fn prefix(&self) -> Option { self.state.read().unwrap().prefix.clone()