@ramiz4/ngx-multi-level-push-menu
TypeScript icon, indicating that this package has built-in type declarations

19.3.1 • Public • Published

NgxMultiLevelPushMenu

npm version License: MIT

A comprehensive Angular component for creating accessible, responsive multi-level push menus with extensive customization options.

See the changelog for recent changes.

Angular Compatibility

Library Version Angular Version
1.x.x 6.x - 8.x
2.x.x 9.x - 11.x
3.x.x - 12.x.x Not Available
13.x.x - 14.x.x 12.x - 14.x
16.x.x - 17.x.x 15.x - 17.x
18.x.x - 19.x.x 18.x - 19.x

Installation

npm i @ramiz4/ngx-multi-level-push-menu --save

Install dependencies

# For Font Awesome 4.x
npm i font-awesome --save

# OR for Font Awesome 5+/6+ (recommended for newer projects)
npm i @fortawesome/fontawesome-free --save

Usage

1. Update your angular.json

"styles": [
  "node_modules/@fortawesome/fontawesome-free/css/all.min.css",
  "styles.css"
],
"scripts": [],

2. Import the module

For NgModule-based applications:

import { NgxMultiLevelPushMenuModule, MultiLevelPushMenuService } from '@ramiz4/ngx-multi-level-push-menu';

@NgModule({
  imports: [
    // ...
    NgxMultiLevelPushMenuModule.forRoot(),
  ],
})
export class AppModule {}

For standalone applications (Angular 14+):

// In app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideMultiLevelPushMenu } from '@ramiz4/ngx-multi-level-push-menu';

export const appConfig: ApplicationConfig = {
  providers: [
    // ...other providers
    provideMultiLevelPushMenu(),
  ],
};
// In your component
import { Component } from '@angular/core';
import { MultiLevelPushMenuComponent } from '@ramiz4/ngx-multi-level-push-menu';

@Component({
  // ...
  standalone: true,
  imports: [MultiLevelPushMenuComponent],
})
export class AppComponent {
  // ...
}

3. Configure your component

You can use either SVG content directly or CSS classes from an icon library for your menu icons.

Option 1: Using SVG icons directly (recommended)

import { Component, OnInit } from '@angular/core';
import { MultiLevelPushMenuService, MultiLevelPushMenuOptions } from '@ramiz4/ngx-multi-level-push-menu';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent implements OnInit {
  options = new MultiLevelPushMenuOptions();

  constructor(private menuService: MultiLevelPushMenuService) {}

  ngOnInit() {
    // Menu configuration with SVG icons
    this.options.title = 'All Categories';

    // Define menu items with SVG icons
    this.options.menu = [
      {
        name: 'Home',
        // SVG home icon
        icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c0 2.7-.2 5.4-.5 8.1V472c0 22.1-17.9 40-40 40H456c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1H416 392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z"/></svg>',
        link: 'home',
      },
      {
        name: 'Products',
        // SVG shopping bag icon
        icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M160 112c0-35.3 28.7-64 64-64s64 28.7 64 64v48H160V112zm-48 48H48c-26.5 0-48 21.5-48 48V416c0 53 43 96 96 96H352c53 0 96-43 96-96V208c0-26.5-21.5-48-48-48H336V112C336 50.1 285.9 0 224 0S112 50.1 112 112v48zm24 48a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm152 24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z"/></svg>',
        items: [
          {
            name: 'Electronics',
            items: [
              { name: 'Smartphones', link: 'smartphones' },
              { name: 'Laptops', link: 'laptops' },
            ],
          },
        ],
      },
    ];

    // Set default back and group icons
    this.options.backItemIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path d="M9.4 278.6c-12.5-12.5-12.5-32.8 0-45.3l128-128c9.2-9.2 22.9-11.9 34.9-6.9s19.8 16.6 19.8 29.6l0 256c0 12.9-7.8 24.6-19.8 29.6s-25.7 2.2-34.9-6.9l-128-128z"/></svg>';
    this.options.groupIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path d="M246.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-9.2-9.2-22.9-11.9-34.9-6.9s-19.8 16.6-19.8 29.6l0 256c0 12.9-7.8 24.6-19.8 29.6s25.7 2.2 34.9-6.9l128-128z"/></svg>';

    // Optional: Set additional options
    this.options.mode = 'overlap';
    this.options.collapsed = false;
  }

  // Control methods
  collapseMenu(): void {
    this.menuService.collapse();
  }

  expandMenu(): void {
    this.menuService.expand();
  }
}

Option 2: Using CSS classes from an icon library

If you prefer using an icon library like Font Awesome, include it in your project and use CSS classes:

import { Component, OnInit } from '@angular/core';
import { MultiLevelPushMenuService, MultiLevelPushMenuOptions } from '@ramiz4/ngx-multi-level-push-menu';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent implements OnInit {
  options = new MultiLevelPushMenuOptions();

  constructor(private menuService: MultiLevelPushMenuService) {}

  ngOnInit() {
    // Menu configuration with Font Awesome icons
    this.options.title = 'All Categories';

    // Define menu items
    this.options.menu = [
      {
        name: 'Home',
        icon: 'fa fa-home',
        link: 'home',
      },
      {
        name: 'Products',
        icon: 'fa fa-shopping-bag',
        items: [
          {
            name: 'Electronics',
            items: [
              { name: 'Smartphones', link: 'smartphones' },
              { name: 'Laptops', link: 'laptops' },
            ],
          },
        ],
      },
    ];

    // Optional: Set additional options
    this.options.mode = 'overlap';
    this.options.collapsed = false;

    // Font Awesome icon classes for back and group icons
    this.options.backItemIcon = 'fa fa-angle-right';
    this.options.groupIcon = 'fa fa-angle-left';
  }

  // Control methods
  collapseMenu(): void {
    this.menuService.collapse();
  }

  expandMenu(): void {
    this.menuService.expand();
  }
}

4. Add to your template

<ramiz4-multi-level-push-menu [options]="options">
  <button (click)="collapseMenu()">Collapse Menu</button>
  <button (click)="expandMenu()">Expand Menu</button>
  <router-outlet></router-outlet>
</ramiz4-multi-level-push-menu>

5. Add styles (optional)

html,
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
}

Component API

Inputs

Name Type Default Description
options MultiLevelPushMenuOptions {} Configuration options

Outputs

Name Type Description
menuOpen EventEmitter Emitted when menu is opened
menuClose EventEmitter Emitted when menu is closed
itemClick EventEmitter Emitted when menu item is clicked
levelChange EventEmitter Emitted when menu level changes

Service API

The MultiLevelPushMenuService provides methods to control the menu programmatically:

Method Parameters Description
collapse() none Collapses the menu
expand() none Expands the menu
toggleMenu() none Toggles menu between states
openMenu() none Opens the menu
closeMenu() none Closes the menu
navigateToLevel(id) id: string Navigates to specific menu level
goBack() none Navigates to previous menu level

Options

// Default options
{
  collapsed: false,                   // Initialize menu collapsed
  menuID: 'multilevelpushmenu',       // ID for the menu
  wrapperClass: 'multilevelpushmenu_wrapper',
  menuInactiveClass: 'multilevelpushmenu_inactive',
  menu: [],                           // Menu structure
  menuWidth: 0,                       // Width of menu (integer, %, px, em)
  menuHeight: 0,                      // Height of menu
  backText: 'Back',                   // Text for back menu item
  backItemClass: 'backItemClass',     // CSS class for back item
  backItemIcon: '<svg>...</svg>',     // Icon for back item (SVG content or CSS class)
  groupIcon: '<svg>...</svg>',        // Icon for items with submenus (SVG content or CSS class)
  mode: 'overlap',                    // Menu sliding mode: overlap/cover
  overlapWidth: 40,                   // Width of menu overlap in px
  preventItemClick: true,             // Event callback per item click
  preventGroupItemClick: true,        // Event callback per group item click
  direction: 'ltr',                   // Direction: ltr/rtl
  fullCollapse: false,                // Hide base level when collapsed
  swipe: 'both'                       // Swipe support: both/touchscreen/desktop/none
}

Menu Structure

The menu structure follows this format:

{
  title: 'Menu Title',                // Title displayed at the top
  id: 'menuID',                       // Unique identifier
  icon: '<svg>...</svg>',             // Icon (SVG content or CSS class)
  items: [                            // Array of menu items
    {
      name: 'Home',                   // Display name
      id: 'home',                     // Unique identifier (optional)
      icon: '<svg>...</svg>',         // Icon (SVG content or CSS class)
      link: 'home',                   // Router link (optional)
      items: []                       // Child items (optional)
    }
  ]
}

Important: Each submenu should be defined directly within an items array. Don't add extra wrapper objects around menu items.

Features

  • Multi-level menu support with endless nesting
  • Expand/Collapse navigation with left/right swipe gestures
  • Support for both overlay and cover sliding modes
  • Flexible sizing options
  • Left-to-right and Right-to-left sliding directions
  • Flexible icon support - use SVG content directly or CSS classes from any icon library
  • Keyboard navigation and accessibility features
  • Customizable styling
  • Cross-browser compatibility
  • Angular Versions Support (6+)
  • AoT Compilation Support

Common Issues & Solutions

Menu not visible on init

If your menu is not visible initially, check:

  • Ensure options.collapsed is set to false
  • Verify CSS is properly loaded
  • Check console for errors

Submenu items not appearing

Ensure your menu structure is correct:

// Correct structure
{
  name: 'Products',
  items: [
    { name: 'Item 1' },
    { name: 'Item 2' }
  ]
}

// Incorrect structure
{
  name: 'Products',
  items: {
    item1: { name: 'Item 1' },
    item2: { name: 'Item 2' }
  }
}

Mobile Support

Configure the swipe behavior with the swipe option:

  • both: Support touch and mouse (default)
  • touchscreen: Support only touch
  • desktop: Support only mouse
  • none: Disable swipe support

Font Awesome Version Compatibility

This library supports two ways to provide icons:

  1. SVG content directly (recommended):

    • Better performance and accessibility
    • No external dependencies
    • Example: icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">...</svg>'
  2. CSS classes from icon libraries:

    • For Font Awesome 4.x: icon: 'fa fa-home'
    • For Font Awesome 5+: icon: 'fas fa-home'
    • Other icon libraries with similar class-based approaches

Accessibility

The component includes several accessibility enhancements:

  • ARIA attributes for screen readers
  • Keyboard navigation support
  • Focus management
  • Screen reader announcements for menu changes

Performance Considerations

For large menus, consider:

  • Lazy loading submenus
  • Using trackBy with *ngFor directives
  • Implementing virtual scrolling for very large menus

Demo

To view the demo:

git clone https://github.com/ramiz4/ngx-multi-level-push-menu.git
cd ngx-multi-level-push-menu
npm install
npm start

Then navigate to http://localhost:4200

/@ramiz4/ngx-multi-level-push-menu/

    Package Sidebar

    Install

    npm i @ramiz4/ngx-multi-level-push-menu

    Weekly Downloads

    22

    Version

    19.3.1

    License

    MIT

    Unpacked Size

    285 kB

    Total Files

    55

    Last publish

    Collaborators

    • ramiz4