active_class prop for Router

This commit is contained in:
Maccesch committed 2022-03-13 16:35:28 +00:00
1 parent 1080ffe52d
commit 9a23ee4612
6 files changed
+52 -8

No files matched your search

+15 -4
View File
@@ -28,7 +28,9 @@ pub struct LinkProps<'a> {
/// Set the class added to the inner link when the current route is the same as the "to" route.
///
/// By default set to `"active"`.
/// To set all of the active classes inside a Router at the same time use the `active_class`
/// prop on the Router component. If both the Router prop as well as this prop are provided then
/// this one has precedence. By default set to `"active"`.
#[props(default, strip_option)]
pub active_class: Option<&'a str>,
@@ -97,13 +99,22 @@ pub fn Link<'a>(cx: Scope<'a, LinkProps<'a>>) -> Element {
let outerlink = (*autodetect && is_http) || *external;
let prevent_default = if outerlink { "" } else { "onclick" };
let active_class_name = match active_class {
Some(c) => (*c).into(),
None => {
let active_from_router = match svc {
Some(service) => service.cfg.active_class.clone(),
None => None,
};
active_from_router.unwrap_or("active".into())
}
};
let route = use_route(&cx);
let url = route.url();
let path = url.path();
let active = path == cx.props.to;
let active_class = active
.then(|| active_class.unwrap_or("active"))
.unwrap_or("");
let active_class = if active { active_class_name } else { "".into() };
cx.render(rsx! {
a {
+14 -3
View File
@@ -28,6 +28,13 @@ pub struct RouterProps<'a> {
/// This lets you easily implement redirects
#[props(default)]
pub onchange: EventHandler<'a, Arc<RouterCore>>,
/// Set the active class of all Link components contained in this router.
///
/// This is useful if you don't want to repeat the same `active_class` prop value in every Link.
/// By default set to `"active"`.
#[props(default, strip_option)]
pub active_class: Option<&'a str>,
}
/// A component that conditionally renders children based on the current location of the app.
@@ -40,9 +47,13 @@ pub fn Router<'a>(cx: Scope<'a, RouterProps<'a>>) -> Element {
let svc = cx.use_hook(|_| {
let (tx, mut rx) = futures_channel::mpsc::unbounded::<RouteEvent>();
let base_url = cx.props.base_url.map(|s| s.to_string());
let svc = RouterCore::new(tx, RouterCfg { base_url });
let svc = RouterCore::new(
tx,
RouterCfg {
base_url: cx.props.base_url.map(|s| s.to_string()),
active_class: cx.props.active_class.map(|s| s.to_string()),
},
);
cx.spawn({
let svc = svc.clone();