yew_router_nested/components/
router_link.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! A component wrapping an `<a>` tag that changes the route.
use crate::{
    agent::{RouteAgentDispatcher, RouteRequest},
    route::Route,
    Switch,
};
use std::marker::PhantomData;
use yew::prelude::*;

use super::{Msg, Props};
use crate::RouterState;
use yew::virtual_dom::VNode;

/// An anchor tag Component that when clicked, will navigate to the provided route.
///
/// Alias to RouterAnchor.
#[deprecated(note = "Has been renamed to RouterAnchor")]
pub type RouterLink<T> = RouterAnchor<T>;

/// An anchor tag Component that when clicked, will navigate to the provided route.
#[derive(Debug)]
pub struct RouterAnchor<SW: Switch + PartialEq + Clone + 'static, STATE: RouterState = ()> {
    router: RouteAgentDispatcher<STATE>,
    _marker: PhantomData<SW>,
}

impl<SW: Switch + PartialEq + Clone + 'static, STATE: RouterState> Component
    for RouterAnchor<SW, STATE>
{
    type Message = Msg;
    type Properties = Props<SW>;

    fn create(_: &Context<Self>) -> Self {
        let router = RouteAgentDispatcher::new();
        RouterAnchor {
            _marker: Default::default(),
            router,
        }
    }

    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
        match msg {
            Msg::Clicked => {
                let route = Route::from(ctx.props().route.clone());
                self.router.send(RouteRequest::ChangeRoute(route));
                false
            }
        }
    }

    fn view(&self, ctx: &Context<Self>) -> VNode {
        #[cfg(feature = "std_web")]
        use stdweb::web::event::IEvent;

        let route: Route<STATE> = Route::from(ctx.props().route.clone());

        #[cfg(feature = "std_web")]
        let cb = ctx.link().callback(|event: ClickEvent| {
            event.prevent_default();
            Msg::Clicked
        });
        #[cfg(feature = "web_sys")]
        let cb = ctx.link().callback(|event: MouseEvent| {
            event.prevent_default();
            Msg::Clicked
        });

        html! {
            <a
                class={ctx.props().classes.clone()}
                onclick={cb}
                disabled={ctx.props().disabled}
                href={route.route}
            >
                {
                    #[allow(deprecated)]
                    &ctx.props().text
                }
                {ctx.props().children.iter().collect::<VNode>()}
            </a>
        }
    }
}