ngx-router-outlet-class
Version:
A directive to add CSS class(es) to the activated/attached component's host element (hereinafter, the `route element`) of a router-outlet.
128 lines (84 loc) • 3.76 kB
Markdown
# 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
```bash
npm install ngx-router-outlet-class
```
### Import
```typescript
import { NgxRouterOutletClassModule } from 'ngx-router-outlet-class';
({
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)
```html
<router-outlet componentClass="content-container"></router-outlet>
```
* Dynamic class(es)
```html
<router-outlet [componentClass]="componentClass" #myOutlet="outlet"></router-outlet>
```
```typescript
class AppComponent {
('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:
```html
<router-outlet [dynamicClassGetter]="myClassGetter"></router-outlet>
```
```typescript
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](https://github.com/angular/angular/issues/49483)
for the Angular team, then we may have built-in functionality in the future.