Intigrate macro with router hooks and components
This commit is contained in:
1 parent
ef6551a6cd
commit
e4b8fbfafe
37 files changed
+1442
-3009
No files matched your search
@@ -1,14 +1,15 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_router_core::{navigation::NavigationTarget, RouterMessage};
|
||||
use log::error;
|
||||
|
||||
use crate::navigation::NavigationTarget;
|
||||
use crate::routable::Routable;
|
||||
use crate::utils::use_router_internal::use_router_internal;
|
||||
|
||||
/// The properties for a [`Link`].
|
||||
#[derive(Props)]
|
||||
pub struct LinkProps<'a> {
|
||||
pub struct LinkProps<'a, R: Routable> {
|
||||
/// A class to apply to the generate HTML anchor tag if the `target` route is active.
|
||||
pub active_class: Option<&'a str>,
|
||||
/// The children to render within the generated HTML anchor tag.
|
||||
@@ -18,11 +19,6 @@ pub struct LinkProps<'a> {
|
||||
/// If `active_class` is [`Some`] and the `target` route is active, `active_class` will be
|
||||
/// appended at the end of `class`.
|
||||
pub class: Option<&'a str>,
|
||||
/// Require the __exact__ `target` to be active, for the [`Link`] to be active.
|
||||
///
|
||||
/// See [`RouterState::is_at`](dioxus_router_core::RouterState::is_at) for more details.
|
||||
#[props(default)]
|
||||
pub exact: bool,
|
||||
/// The id attribute for the generated HTML anchor tag.
|
||||
pub id: Option<&'a str>,
|
||||
/// When [`true`], the `target` route will be opened in a new tab.
|
||||
@@ -46,22 +42,21 @@ pub struct LinkProps<'a> {
|
||||
pub rel: Option<&'a str>,
|
||||
/// The navigation target. Roughly equivalent to the href attribute of an HTML anchor tag.
|
||||
#[props(into)]
|
||||
pub target: NavigationTarget,
|
||||
pub target: NavigationTarget<R>,
|
||||
}
|
||||
|
||||
impl Debug for LinkProps<'_> {
|
||||
impl<R: Routable> Debug for LinkProps<'_, R> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("LinkProps")
|
||||
.field("active_class", &self.active_class)
|
||||
.field("children", &self.children)
|
||||
.field("class", &self.class)
|
||||
.field("exact", &self.exact)
|
||||
.field("id", &self.id)
|
||||
.field("new_tab", &self.new_tab)
|
||||
.field("onclick", &self.onclick.as_ref().map(|_| "onclick is set"))
|
||||
.field("onclick_only", &self.onclick_only)
|
||||
.field("rel", &self.rel)
|
||||
.field("target", &self.target)
|
||||
.field("target", &self.target.to_string())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@@ -130,12 +125,11 @@ impl Debug for LinkProps<'_> {
|
||||
/// # );
|
||||
/// ```
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Link<'a>(cx: Scope<'a, LinkProps<'a>>) -> Element {
|
||||
pub fn Link<'a, R: Routable + Clone>(cx: Scope<'a, LinkProps<'a, R>>) -> Element {
|
||||
let LinkProps {
|
||||
active_class,
|
||||
children,
|
||||
class,
|
||||
exact,
|
||||
id,
|
||||
new_tab,
|
||||
onclick,
|
||||
@@ -145,7 +139,7 @@ pub fn Link<'a>(cx: Scope<'a, LinkProps<'a>>) -> Element {
|
||||
} = cx.props;
|
||||
|
||||
// hook up to router
|
||||
let router = match use_router_internal(cx) {
|
||||
let router = match use_router_internal::<R>(cx) {
|
||||
Some(r) => r,
|
||||
#[allow(unreachable_code)]
|
||||
None => {
|
||||
@@ -156,19 +150,19 @@ pub fn Link<'a>(cx: Scope<'a, LinkProps<'a>>) -> Element {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let state = loop {
|
||||
if let Some(state) = router.state.try_read() {
|
||||
break state;
|
||||
}
|
||||
};
|
||||
let sender = router.sender.clone();
|
||||
|
||||
let href = state.href(target);
|
||||
let current_route = router.current();
|
||||
let href = current_route.to_string();
|
||||
let ac = active_class
|
||||
.and_then(|active_class| {
|
||||
state
|
||||
.is_at(target, *exact)
|
||||
.then(|| format!(" {active_class}"))
|
||||
.and_then(|active_class| match target {
|
||||
NavigationTarget::Internal(target) => {
|
||||
if href == target.to_string() {
|
||||
Some(format!(" {active_class}"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
@@ -186,7 +180,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 _ = sender.unbounded_send(RouterMessage::Push(target.clone()));
|
||||
router.push(target.clone());
|
||||
}
|
||||
|
||||
if let Some(handler) = onclick {
|
||||
|
||||
Reference in new issue
Block a user