npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ngx-material-navigation

v18.1.1

Published

Builds material navigation elements like a combined navbar and sidenav or footers based on the supplied configuration data. Will automatically move elements from the navbar to the sidenav at the provided breakpoints.

Downloads

167

Readme

NgxMaterialNavigation

Builds material navigation elements like a combined navbar and sidenav or footers based on the supplied configuration data. Will automatically move elements from the navbar to the sidenav at the provided breakpoints.

Supports nested menus and brings functionality which allow you to extract angular routes from an Configuration if you want to define the routes directly there.

Table of Contents

Requirements

This package relies on the angular material library to render its components.

Basic Usage

Define your configuration

import { NavbarRow, NavRoute } from 'ngx-material-navigation';

/**
 * The configuration consists of multiple NavbarRows.
 * This is needed if you want to have a toolbar with multiple rows.
 * 
 * In most cases you probably only define one NavbarRow in this array.
 * 
 * You can also provide a generic type for any angular routes in the elements.
 * This is helpful if you want to have type safety when using the routes data property.
 * Or when you want to enforce that a title/path etc. is required on every route.
*/
export const navbarRows: NavbarRow<NavRoute>[] = [
    {
        elements: [
            {
                type: NavElementTypes.IMAGE_WITH_INTERNAL_LINK,
                url: 'https://www.my-great-website.de/my-great-picture.png',
                link: {
                    route: 'home',
                },
                collapse: 'never'
            },
            {
                type: NavElementTypes.TITLE_WITH_INTERNAL_LINK,
                title: 'Showcase Project',
                link: {
                    route: 'home'
                },
                collapse: 'sm'
            },
            {
                type: NavElementTypes.INTERNAL_LINK,
                name: 'Home',
                route: { // This can also just be a string.
                    title: 'Home',
                    path: 'home',
                    loadChildren: () => import('./components/home/home.module').then(m => m.HomeModule)
                },
                collapse: 'md'
            },
            {
                type: NavElementTypes.MENU,
                name: 'Menu',
                elements: [
                    {
                        type: NavElementTypes.INTERNAL_LINK,
                        name: 'menu item #1',
                        route: 'menu-item/1'
                    },
                    {
                        type: NavElementTypes.INTERNAL_LINK,
                        name: 'menu item #2',
                        route: 'menu-item/2'
                    }
                ],
                position: 'center',
                collapse: 'md'
            },
            {
                type: NavElementTypes.BUTTON,
                name: 'Reload the page',
                action: () => location.reload(),
                position: 'right',
                collapse: 'sm'
            }
        ]
    }
];

Extract the angular routes

:warning: Optional: You only need this if you want to define your angular routes inside the NavbarRows.

// Define any additional routes that are not defined in the NavbarRows.
const extraRoute: NavRoute = {
    title: '404 Page not found',
    path: '**',
    component: NgxMatNavigationNotFoundComponent,
    data: { // this is type safe
        pageNotFoundConfig: {
            homeRoute: '/home'
        }
    }
};
// Extract the angular routes from the given configuration. This can be used in the app.routing.module.ts
export const routes: NavRoute[] = NavUtilities.getAngularRoutes<NavRoute>(navbarRows, [extraRoute]);

Use the elements

In app.component.html:

<ngx-mat-navigation-navbar [minHeight]="70" [minSidenavWidth]="'30%'" [minHeightOtherElements]="70" [navbarRows]="navbarRows">
    <!-- The content of your app needs to be put inside the navbar -->
    <router-outlet></router-outlet>
</ngx-mat-navigation-navbar>

<app-footer [minHeight]="70"></app-footer>

Please note that all of your content needs to be put inside the navbar. This is needed to put it inside the mat-sidenav-content.

The minHeight and minHeightOtherElements is needed internally to set the min-height of the content accordingly.

Actions and conditions

In your navigation data you can define actions that are executed when a button is clicked. You can also define a condition function which defines whether or not the navigation element should be visible:

...
{
    type: 'button',
    name: 'Reload the page',
    action: () => location.reload(),
    condition: conditionWithInjection,
    position: 'right',
    collapse: 'sm'
}
...

When the above button is clicked the current window gets reloaded. For the isUserLoggedIn-function this is a bit more tricky, as normally injections only work inside an angular context. We work around this by using the EnvironmentInjector, however THIS REQUIRES YOU TO DEFINE ANY CONDITION AS AN EXTRA FUNCTION (at least if you want to use injections).

// This will work:
...
{
    type: 'button',
    name: 'Reload the page',
    action: () => location.reload(),
    condition: conditionWithInjection,
    position: 'right',
    collapse: 'sm'
}
...

function conditionWithInjection(): boolean {
    const router = inject(Router);
    console.log(router.url);
    return true;
}
// This wont work:
...
{
    type: 'button',
    name: 'Reload the page',
    action: () => inject(Router).url.length > 10,
    condition: conditionWithInjection,
    position: 'right',
    collapse: 'sm'
}
...

Dynamic Anchors

This library supports adding anchors (different sections the user can scroll to) dynamically to the navbar.

First, define anchor elements in your routes configuration:

{
    type: NavElementTypes.INTERNAL_LINK,
    name: 'Scrolling',
    route: {
        title: 'Scrolling',
        path: 'scrolling',
        loadComponent: () => import('./components/scrolling/scrolling.component').then(m => m.ScrollingComponent),
        data: {
            anchors: [
                {
                    name: 'Bottom',
                    fragment: 'bottom',
                    icon: 'fas fa-home'
                },
                {
                    name: 'Middle',
                    fragment: 'middle'
                }
            ]
        }
    },
    collapse: 'md'
}

On the scrolling component there need to be elements with the ids "bottom" and "middle".

Then configure your routing options:

const routerOptions: ExtraOptions = {
    scrollPositionRestoration: 'enabled',
    onSameUrlNavigation: 'reload',
    anchorScrolling: 'enabled'
};

@NgModule({
    imports: [RouterModule.forRoot(routes, routerOptions)],
    exports: [RouterModule]
})
export class AppRoutingModule { }

If you want to enable smooth scrolling you can add html { scroll-behavior: smooth; } to your styles.scss.

:warning: No anchor toolbar is shown:

The NgxMatNavigationService handles getting the anchor toolbar from the route configuration by subscribing to router.events.

Usually the navbar is used in your app.component.html, which means the service gets initialized and everything should work out of the box. But it could be possible that route navigation happens without the service being initialized.

In that case you need to add the following to your app.module.ts provider array:

{
   provide: APP_INITIALIZER,
   useFactory: () => {
       return () => {};
   },
   deps: [NgxMatNavigationService],
   multi: true
}

Custom Components

You have the option to easily add custom components if the provided components don't fully cover your requirements.

Create the custom component

The only restriction for the component is that it needs to extends NgxMatNavigationBaseNavElementComponent:

import { NavElementTypes, NgxMatNavigationBaseNavElementComponent } from 'ngx-material-navigation';

@Component({
    selector: 'app-custom',
    templateUrl: './custom.component.html',
    styleUrls: ['./custom.component.scss']
})
export class CustomComponent extends NgxMatNavigationBaseNavElementComponent<NavElementTypes.CUSTOM> {}

Use it in your routes

import { NavElementTypes } from 'ngx-material-navigation';

...
{
    type: NavElementTypes.CUSTOM,
    component: CustomComponent
},
...

NavRoute

/**
 * An opinionated model of the Angular Route.
 * This makes the title and path attributes required.
 * It also adds the option to use a generic for the route data.
 */
export interface NavRoute<DataType extends Data = DefaultNavRouteDataType> extends Route {
    title: string | Type<Resolve<string>> | ResolveFn<string>,
    path: string,
    data?: DataType
}

/**
 * The default data type for a nav route.
 * Will be used if no generic is provided.
 */
export interface DefaultNavRouteDataType extends Data {
    /**
     * The configuration for the 404 page not found component.
     */
    pageNotFoundConfig?: PageNotFoundConfig
}

NgxMatNavigationNotFoundComponent

This is a simple 404-Error Page that can be used in your routing:

import { PageNotFoundConfig, NavRoute, NgxMatNavigationNotFoundComponent } from 'ngx-material-navigation';

const pageNotFoundConfig: PageNotFoundConfig = {
    title?: string,
    message?: string,
    buttonLabel?: string,
    homeRoute?: string
}

const pageNotFoundRoute: NavRoute = {
    title: '404 Page not found',
    path: '**',
    component: NgxMatNavigationNotFoundComponent,
    data: {
        // this is optional for overriding the default values. When using NavRoute this is also type safe.
        pageNotFoundConfig: pageNotFoundConfig
    }
};