Automatically highlighting the active part in e.g. a menu hierarchy can already be done manually by making the menu or individual links implement AfterNavigationObserver and then manually toggle a css classname or an attribute.
In the general case, menu items can be represented by any kind of component and there can also be arbitrary logic for when a section is considered to be active. In practice, the menu items are usually RouterLink components and the hierarchy is either defined based on the URL structure or sharing a common RouterLayout (though in most cases the topmost layout is shared among the entire application).
We could add helper API to RouterLink for the common cases and ensure the documentation also contains an example of how this is done manually.
Added to the backlog
Some ideas on what the API in RouterLink could look like:
// Low level flexible API based on BiPredicate<RouterLink, AfterNavigationEvent>
someLink.setHighlightCondition((link, event) -> event.getLocation().getPath().startsWith("foo"));
// Helper for creating conditions
someLink.setHighlightCondition(HighlightConditions.sameLocation()); // This could be used by default?
someLink.setHighlightCondition(HighlightConditions.locationPrefix("foo"));
someLink.setHighlightCondition(HighlightConditions.locationPrefix()); // Uses the URL of this link as the prefix
someLink.setHighlightCondition(HighlightConditions.hasLayout(SomeLayout.class));
// Configuring how the highlight is represented in the DOM
someLink.setHighlightClassName("link-active"); // default is null
someLink.setHighlightAttribute("link-active"); // default is "active"
Edit: Renamed APIs to use highlight instead of active
The name setActive sounds like having it as false means that it is disabled and will not give events.
Does it actually disable the link or is it just a styling?
My assumption is that it only affects styling. The link would still be usable.
Any other ideas on the naming?
setHighlightCondition or setStyleCondition
for a setStyleCondition it could be usable as someLink.setStyleCondition(StyleCondition, String activeClassName) or the like so you could have different styles for different conditions.
Being forced to explicitly define a classname with no default available sounds like boilerplate that is only there to support a quite theoretical case of having multiple conditions. It's always possible to achieve the same result with an explicit AfterNavigationObserver, so this helper API doesn't have to cover all potential cases.
I'll change my proposal to use highlight instead of active.
How should the RouterLink be notified of the AfterNavigationEvent? Can it implement AfterNavigationObserver or just @Route-annotated components can?
Anything that is currently attached to the component tree will receive navigation events if they implement the appropriate interface.
As a reminder for e.g. documentation examples, this is how I'm using #3526 with Tabs:
RouterLink fooLink = new RouterLink("Foo", Foo.class);
Tab fooTab = new Tab(fooLink);
Tabs tabs = new Tabs(fooTab);
fooLink.setHighlightAction((link, highlight) -> {
if (highlight) tabs.setSelectedTab(fooTab);
});
Most helpful comment
Some ideas on what the API in
RouterLinkcould look like:Edit: Renamed APIs to use
highlightinstead ofactive