yew_router_nested/components/
router_button.rs

1//! A component wrapping a `<button>` tag that changes the route.
2use crate::{
3    agent::{RouteAgentDispatcher, RouteRequest},
4    route::Route,
5    Switch,
6};
7use std::marker::PhantomData;
8use yew::prelude::*;
9
10use super::{Msg, Props};
11use crate::RouterState;
12use yew::virtual_dom::VNode;
13
14/// Changes the route when clicked.
15#[derive(Debug)]
16pub struct RouterButton<SW: Switch + PartialEq + Clone + 'static, STATE: RouterState = ()> {
17    router: RouteAgentDispatcher<STATE>,
18    _marker: PhantomData<SW>,
19}
20
21impl<SW: Switch + PartialEq + Clone + 'static, STATE: RouterState> Component
22    for RouterButton<SW, STATE>
23{
24    type Message = Msg;
25    type Properties = Props<SW>;
26
27    fn create(_: &Context<Self>) -> Self {
28        let router = RouteAgentDispatcher::new();
29        RouterButton {
30            _marker: Default::default(),
31            router,
32        }
33    }
34
35    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
36        match msg {
37            Msg::Clicked => {
38                let route = Route::from(ctx.props().route.clone());
39                self.router.send(RouteRequest::ChangeRoute(route));
40                false
41            }
42        }
43    }
44
45    fn view(&self, ctx: &Context<Self>) -> VNode {
46        #[cfg(feature = "std_web")]
47        let cb = ctx.link().callback(|event: ClickEvent| {
48            event.prevent_default();
49            Msg::Clicked
50        });
51        #[cfg(feature = "web_sys")]
52        let cb = ctx.link().callback(|event: MouseEvent| {
53            event.prevent_default();
54            Msg::Clicked
55        });
56        html! {
57            <button
58                class={ctx.props().classes.clone()}
59                onclick={cb}
60                disabled={ctx.props().disabled}
61            >
62                {
63                    #[allow(deprecated)]
64                    &ctx.props().text
65                }
66                {ctx.props().children.iter().collect::<VNode>()}
67            </button>
68        }
69    }
70}