Angular Labs LABS

A common task in our applications is to visually highlight the navigation link that corresponds to the current route.

In this recipe, you’ll learn how to implement it, from basic to advanced techniques based on your application’s needs.

Note

As a reminder if you are not familiar with the routerLink directive, it is a directive that allows you to navigate to a different route. In Angular, except for navigating to an external URL, you should always use the routerLink directive.

The routerLink is currently used in the opened file in the editor. Each link will unlock learning a new concept and how to use it.

Simple navigation

Let’s start with the simplest case: the About link. By clicking on it, the page will navigate to the /about route and display the content of the AboutComponent, as defined in the route file:

export const routes = [
{
path: "/about",
component: AboutComponent,
},
];

Now let’s visually highlight the About link when it is active.

The routerActiveLink directive is a directive that allows you to highlight the navigation link that corresponds to the current route. It’s always used in conjunction with the routerLink directive.

It even consumes info from the related routerLink to get its link and apply the active state if needed:

constructor(@Optional() private link?: RouterLink) {
// ...
}
private hasActiveLinks(): boolean {
const isActiveCheckFn = this.isLinkActive(this.router);
return (this.link && isActiveCheckFn(this.link)) || this.links.some(isActiveCheckFn);
}

Based on this condition, the directive will apply css classes to the HTML tag it’s applied to.

this.classes.forEach((c) => {
if (hasActiveLinks) {
this.renderer.addClass(this.element.nativeElement, c);
} else {
this.renderer.removeClass(this.element.nativeElement, c);
}
});

The related css classes are defined by passing a value to the routerActiveLink directive:

<a routerLink="/about" routerActiveLink="active">About</a>

You can also pass a list of classes, either as an array or a string, separated by spaces:

<a
routerLink="/about"
[routerActiveLink]="['active' 'active-link']"
>About</a>
<a
routerLink="/about"
routerActiveLink="active active-link"
>About</a>
Warning

Passing an array will require to use data binding, surrounding the directive with square brackets.

<a
routerLink="/about"
[routerActiveLink]="['active' 'active-link']"
>About</a>

Advanced navigation

  1. Import the component into your MDX file:

    import { Steps } from "@astrojs/starlight/components";
  2. Wrap <Steps> around your ordered list items.

  • astro.config.mjs
  • package.json
  • Directorysrc
    • Directorycomponents
      • Header.astro
      • Title.astro
    • Directorypages/

To kick things off, we have prepared a small demo lesson for you, where we’ll dive into the concept of event handling in JavaScript. Our task is to resuscitate a lifeless counter app by introducing the crucial element of interactivity: event listeners.

Let’s look at the preview on the right for a moment and try to click on the button that says counter is 0. We’ll notice that it doesn’t work.

In the code for counter.js, which you can find on the right, we have a setupCounter function responsible for initializing our counter app. However, a crucial component is missing: an event listener for the button.

Event listeners are essential in web development as they enable our applications to respond to user actions. In this case, we need to listen for clicks on the button to increment the counter.

To address this, we’ll call the addEventListener to attach a click event listener to the button element. When a click is detected, we’ll execute a callback function that increments the counter and updates the innerHTML accordingly.

code.js
export function setupCounter(element) {
let counter = 0;
const setCounter = (count) => {
counter = count;
element.innerHTML = `count is ${counter}`;
};
element.addEventListener("click", () => setCounter(counter + 1));
setCounter(0);
}

This gives you a sneak peak of the TutorialKit experience, demonstrating what it’s capable of.

Happy writing!

Powered by WebContainers
Files
Preparing Environment
  • Installing dependencies
  • Starting http server