restore navigator
This commit is contained in:
1 parent
92755a381d
commit
fe601e2a48
7 files changed
+137
-58
No files matched your search
@@ -61,14 +61,14 @@ pub fn routable(input: TokenStream) -> TokenStream {
|
|||||||
dioxus_router::prelude::GenericGoForwardButton::<#name>(cx)
|
dioxus_router::prelude::GenericGoForwardButton::<#name>(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
#vis fn use_router(cx: &dioxus::prelude::ScopeState) -> &dioxus_router::prelude::GenericRouterContext<#name> {
|
|
||||||
dioxus_router::prelude::use_generic_router(cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
#vis fn use_route(cx: &dioxus::prelude::ScopeState) -> Option<#name> {
|
#vis fn use_route(cx: &dioxus::prelude::ScopeState) -> Option<#name> {
|
||||||
dioxus_router::prelude::use_generic_route(cx)
|
dioxus_router::prelude::use_generic_route(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#vis fn use_navigator(cx: &dioxus::prelude::ScopeState) -> &dioxus_router::prelude::GenericNavigator<#name> {
|
||||||
|
dioxus_router::prelude::use_generic_navigator(cx)
|
||||||
|
}
|
||||||
|
|
||||||
#error_type
|
#error_type
|
||||||
|
|
||||||
#parse_impl
|
#parse_impl
|
||||||
|
|||||||
@@ -79,10 +79,10 @@ fn Route2(cx: Scope, user_id: usize) -> Element {
|
|||||||
|
|
||||||
#[inline_props]
|
#[inline_props]
|
||||||
fn Route3(cx: Scope, dynamic: String) -> Element {
|
fn Route3(cx: Scope, dynamic: String) -> Element {
|
||||||
let router = use_router(cx);
|
let navigator = use_navigator(cx);
|
||||||
let router_route = router.current();
|
let current_route = use_route(cx)?;
|
||||||
let current_route = use_ref(cx, String::new);
|
let current_route_str = use_ref(cx, String::new);
|
||||||
let parsed = Route::from_str(¤t_route.read());
|
let parsed = Route::from_str(¤t_route_str.read());
|
||||||
|
|
||||||
let site_map = Route::SITE_MAP
|
let site_map = Route::SITE_MAP
|
||||||
.iter()
|
.iter()
|
||||||
@@ -92,9 +92,9 @@ fn Route3(cx: Scope, dynamic: String) -> Element {
|
|||||||
render! {
|
render! {
|
||||||
input {
|
input {
|
||||||
oninput: move |evt| {
|
oninput: move |evt| {
|
||||||
*current_route.write() = evt.value.clone();
|
*current_route_str.write() = evt.value.clone();
|
||||||
},
|
},
|
||||||
value: "{current_route.read()}"
|
value: "{current_route_str.read()}"
|
||||||
}
|
}
|
||||||
"dynamic: {dynamic}"
|
"dynamic: {dynamic}"
|
||||||
Link {
|
Link {
|
||||||
@@ -102,14 +102,14 @@ fn Route3(cx: Scope, dynamic: String) -> Element {
|
|||||||
"hello world link"
|
"hello world link"
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
onclick: move |_| { router.push(NavigationTarget::External("https://www.google.com".to_string())); },
|
onclick: move |_| { navigator.push(NavigationTarget::External("https://www.google.com".to_string())); },
|
||||||
"google link"
|
"google link"
|
||||||
}
|
}
|
||||||
p { "Site Map" }
|
p { "Site Map" }
|
||||||
pre { "{site_map:#?}" }
|
pre { "{site_map:#?}" }
|
||||||
p { "Dynamic link" }
|
p { "Dynamic link" }
|
||||||
if let Ok(route) = parsed {
|
if let Ok(route) = parsed {
|
||||||
if route != router_route {
|
if route != current_route {
|
||||||
render! {
|
render! {
|
||||||
Link {
|
Link {
|
||||||
target: route.clone(),
|
target: route.clone(),
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
use crate::prelude::{ExternalNavigationFailure, GenericRouterContext, NavigationTarget, Routable};
|
||||||
|
|
||||||
|
/// A view into the navigation state of a router.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct GenericNavigator<R: Routable>(pub(crate) GenericRouterContext<R>);
|
||||||
|
|
||||||
|
impl<R: Routable> GenericNavigator<R> {
|
||||||
|
/// Check whether there is a previous page to navigate back to.
|
||||||
|
#[must_use]
|
||||||
|
pub fn can_go_back(&self) -> bool {
|
||||||
|
self.0.can_go_back()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check whether there is a future page to navigate forward to.
|
||||||
|
#[must_use]
|
||||||
|
pub fn can_go_forward(&self) -> bool {
|
||||||
|
self.0.can_go_forward()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Go back to the previous location.
|
||||||
|
///
|
||||||
|
/// Will fail silently if there is no previous location to go to.
|
||||||
|
pub fn go_back(&self) {
|
||||||
|
self.0.go_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Go back to the next location.
|
||||||
|
///
|
||||||
|
/// Will fail silently if there is no next location to go to.
|
||||||
|
pub fn go_forward(&self) {
|
||||||
|
self.0.go_forward();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Push a new location.
|
||||||
|
///
|
||||||
|
/// The previous location will be available to go back to.
|
||||||
|
pub fn push(
|
||||||
|
&self,
|
||||||
|
target: impl Into<NavigationTarget<R>>,
|
||||||
|
) -> Option<ExternalNavigationFailure> {
|
||||||
|
self.0.push(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replace the current location.
|
||||||
|
///
|
||||||
|
/// The previous location will **not** be available to go back to.
|
||||||
|
pub fn replace(
|
||||||
|
&self,
|
||||||
|
target: impl Into<NavigationTarget<R>>,
|
||||||
|
) -> Option<ExternalNavigationFailure> {
|
||||||
|
self.0.replace(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
use dioxus::prelude::ScopeState;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
prelude::{GenericNavigator, GenericRouterContext},
|
||||||
|
routable::Routable,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A hook that provides access to the navigator to change the router history. Unlike [`use_router`], this hook will not cause a rerender when the current route changes
|
||||||
|
///
|
||||||
|
/// > The Routable macro will define a version of this hook with an explicit type.
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use dioxus::prelude::*;
|
||||||
|
/// # use dioxus_router::prelude::*;
|
||||||
|
/// # use serde::{Deserialize, Serialize};
|
||||||
|
/// #[derive(Clone, Serialize, Deserialize, Routable)]
|
||||||
|
/// enum Route {
|
||||||
|
/// #[route("/")]
|
||||||
|
/// Index {},
|
||||||
|
/// #[route("/:id")]
|
||||||
|
/// Dynamic { id: usize },
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// fn App(cx: Scope) -> Element {
|
||||||
|
/// render! {
|
||||||
|
/// Router {}
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #[inline_props]
|
||||||
|
/// fn Index(cx: Scope) -> Element {
|
||||||
|
/// let navigator = use_navigator(&cx);
|
||||||
|
///
|
||||||
|
/// render! {
|
||||||
|
/// button {
|
||||||
|
/// onclick: move |_| { navigator.push(Route::Dynamic { id: 1234 }); },
|
||||||
|
/// "Go to /1234"
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #[inline_props]
|
||||||
|
/// fn Dynamic(cx: Scope, id: usize) -> Element {
|
||||||
|
/// render! {
|
||||||
|
/// p {
|
||||||
|
/// "Current ID: {id}"
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// # let mut vdom = VirtualDom::new(App);
|
||||||
|
/// # let _ = vdom.rebuild();
|
||||||
|
/// ```
|
||||||
|
pub fn use_generic_navigator<R: Routable + Clone>(cx: &ScopeState) -> &GenericNavigator<R> {
|
||||||
|
&*cx.use_hook(|| {
|
||||||
|
let router = cx
|
||||||
|
.consume_context::<GenericRouterContext<R>>()
|
||||||
|
.expect("Must be called in a descendant of a Router component");
|
||||||
|
|
||||||
|
GenericNavigator(router)
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -5,6 +5,8 @@ use crate::utils::use_router_internal::use_router_internal;
|
|||||||
|
|
||||||
/// A hook that provides access to information about the current routing location.
|
/// A hook that provides access to information about the current routing location.
|
||||||
///
|
///
|
||||||
|
/// > The Routable macro will define a version of this hook with an explicit type.
|
||||||
|
///
|
||||||
/// # Return values
|
/// # Return values
|
||||||
/// - None, when not called inside a [`GenericRouter`] component.
|
/// - None, when not called inside a [`GenericRouter`] component.
|
||||||
/// - Otherwise the current route.
|
/// - Otherwise the current route.
|
||||||
|
|||||||
@@ -5,50 +5,7 @@ use crate::{
|
|||||||
utils::use_router_internal::use_router_internal,
|
utils::use_router_internal::use_router_internal,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A hook that provides access to information about the router. The Router will define a version of this hook with an explicit type.
|
/// A hook that provides access to information about the router.
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # use dioxus::prelude::*;
|
|
||||||
/// # use dioxus_router::prelude::*;
|
|
||||||
/// # use serde::{Deserialize, Serialize};
|
|
||||||
/// #[derive(Clone, Serialize, Deserialize, Routable)]
|
|
||||||
/// enum Route {
|
|
||||||
/// #[route("/")]
|
|
||||||
/// Index {},
|
|
||||||
/// #[route("/:id")]
|
|
||||||
/// Dynamic { id: usize },
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// fn App(cx: Scope) -> Element {
|
|
||||||
/// render! {
|
|
||||||
/// Router {}
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// #[inline_props]
|
|
||||||
/// fn Index(cx: Scope) -> Element {
|
|
||||||
/// let router = use_router(&cx);
|
|
||||||
///
|
|
||||||
/// render! {
|
|
||||||
/// button {
|
|
||||||
/// onclick: move |_| { router.push(Route::Dynamic { id: 1234 }); },
|
|
||||||
/// "Go to /1234"
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// #[inline_props]
|
|
||||||
/// fn Dynamic(cx: Scope, id: usize) -> Element {
|
|
||||||
/// render! {
|
|
||||||
/// p {
|
|
||||||
/// "Current ID: {id}"
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// # let mut vdom = VirtualDom::new(App);
|
|
||||||
/// # let _ = vdom.rebuild();
|
|
||||||
/// ```
|
|
||||||
pub fn use_generic_router<R: Routable + Clone>(cx: &ScopeState) -> &GenericRouterContext<R> {
|
pub fn use_generic_router<R: Routable + Clone>(cx: &ScopeState) -> &GenericRouterContext<R> {
|
||||||
use_router_internal(cx)
|
use_router_internal(cx)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|||||||
@@ -25,9 +25,11 @@ mod components {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod contexts {
|
mod contexts {
|
||||||
|
pub(crate) mod navigator;
|
||||||
pub(crate) mod outlet;
|
pub(crate) mod outlet;
|
||||||
pub(crate) mod router;
|
pub(crate) mod router;
|
||||||
pub use router::*;
|
pub use navigator::*;
|
||||||
|
pub(crate) use router::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod router_cfg;
|
mod router_cfg;
|
||||||
@@ -37,10 +39,13 @@ mod history;
|
|||||||
/// Hooks for interacting with the router in components.
|
/// Hooks for interacting with the router in components.
|
||||||
mod hooks {
|
mod hooks {
|
||||||
mod use_router;
|
mod use_router;
|
||||||
pub use use_router::*;
|
pub(crate) use use_router::*;
|
||||||
|
|
||||||
mod use_route;
|
mod use_route;
|
||||||
pub use use_route::*;
|
pub use use_route::*;
|
||||||
|
|
||||||
|
mod use_navigator;
|
||||||
|
pub use use_navigator::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A collection of useful items most applications might need.
|
/// A collection of useful items most applications might need.
|
||||||
|
|||||||
Reference in new issue
Block a user