use crate::router::ToRoute;
use crate::router::context::use_router;
use silex_core::traits::RxGet;
use silex_dom::prelude::*;
use silex_html::a;
use silex_macros::component;
#[component]
pub fn Link<T: ToRoute + Clone + 'static>(
to: T,
#[chain] children: AnyView,
#[prop(into)]
#[chain(default)]
active_class: String,
) -> impl View {
let href = to.to_route();
let router_ctx = use_router();
let display_href = if let Some(ctx) = &router_ctx
&& !ctx.base_path.is_empty()
&& ctx.base_path != "/"
&& href.starts_with('/')
{
format!("{}{}", ctx.base_path.trim_end_matches('/'), href)
} else {
href.clone()
};
let is_active_class = if !active_class.is_empty()
&& let Some(router) = &router_ctx
{
let path_signal = router.path;
let href_for_rx = href.clone();
let class_name = active_class.clone();
let is_active = silex_core::rx! {
let current_path = path_signal.get();
if href_for_rx == "/" {
current_path == "/"
} else if current_path == href_for_rx {
true
} else if current_path.starts_with(&href_for_rx) {
if href_for_rx.ends_with('/') {
true
} else {
current_path.chars().nth(href_for_rx.len()) == Some('/')
}
} else {
false
}
};
Some((class_name, is_active))
} else {
None
};
let href_for_click = href.clone();
let router_for_click = router_ctx.clone();
a(children)
.attr("href", display_href)
.class(is_active_class)
.on_click(move |e: web_sys::MouseEvent| {
e.prevent_default();
if let Some(ctx) = &router_for_click {
ctx.navigator.push(href_for_click.as_str());
} else {
if let Some(window) = web_sys::window() {
let _ = window.location().set_href(&href_for_click);
}
}
})
}