active_class prop for Router
This commit is contained in:
1 parent
1080ffe52d
commit
9a23ee4612
6 files changed
+52
-8
No files matched your search
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in new issue
Block a user