1.0.0 • Published 1 year ago

ngx-router-outlet-class v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

NgxRouterOutletClass

A directive to add CSS class(es) to the activated/attached component's host element (hereinafter, the route element) of a router-outlet.

Reason

Ever wonder why the class(es) set on router-outlet is not applied to the route element?

This is because, in Angular, the router-outlet is not directly replaced by the route element, while in some other frameworks, the route element replaces the router outlet/view placeholder. In Angular, the route element is inserted next to the router-outlet.

You may wish to add a uniform class(es) to each route element based on the overall layout and styling to form a uniform look for your application regardless of the route's path. It would be less work if you could bind class(es) to router-outlet and add the class(es) on the fly to each route element instead of adding class(es) to them individually.

This directive adds class binding to the router-outlet to the route element. It is a workaround for the missing functionality.

Usage

Simply install and import the module.

Then set or bind a string to the componentClass attribute of the router-outlet element, just like you would do to the class attribute of any native element. The directive will automatically add the class(es) to the route element.

A dynamicClassGetter function attribute is also provided to get the dynamic class(es) for the route element. This function should take the activated component as the only parameter and return the class(es) as a string.

Install

npm install ngx-router-outlet-class

Import

import { NgxRouterOutletClassModule } from 'ngx-router-outlet-class';

@NgModule({
  imports: [
    NgxRouterOutletClassModule,
  ],
})
export class AppModule {
}

Use

Component Class Binding

You can simply set the componentClass attribute to a string, which will be added to the route element's class list.

  • Static class(es)
<router-outlet componentClass="content-container"></router-outlet>
  • Dynamic class(es)
<router-outlet [componentClass]="componentClass" #myOutlet="outlet"></router-outlet>
class AppComponent {

  @ViewChild('myOutlet') myOutlet: RouterOutlet;

  get componentClass() {
    return `content-container ${
      this.myOutlet.component?.isAboutComponent
        ? 'theme-aero'
        : 'theme-violet'
    }`;
  }

}

High Performance Dynamic Class(es)

Performance has already been taken into consideration when handling bound value changes.

But in the dynamic component class binding above, there is still a performance issue, since the addition and deletion of class(es) happens not only on change of the bound value, but also (inside the directive) on change of the component.

Use dynamicClassGetter function attribute to solve the issue, with componentClass used for static or less changeable class(es) only.

This function is only called by the directive when the component changes, making it a high-performance way to get and apply the component-specific class(es).

Here's an example of how to use it:

<router-outlet [dynamicClassGetter]="myClassGetter"></router-outlet>
class AppComponent {

  myClassGetter(component: any) {
    return component?.isAbout
      ? 'theme-aero'
      : 'theme-violet';
  }

}

Limitation

Because the private property activated of RouterOutlet is used in the directive, there is no guarantee that the directive will work in the future versions of Angular.

Upvote My Feature Request

If you find this workaround helpful, please vote my feature request for the Angular team, then we may have built-in functionality in the future.

1.0.0

1 year ago

0.0.6

1 year ago

0.0.5

1 year ago

0.0.4

1 year ago

0.0.3

1 year ago

0.0.2

1 year ago

0.0.1

1 year ago