@ovyn/menu
v1.1.6
Published
`@ovyn/menu` is a modern, responsive navigation menu component library for Angular applications built with Angular Signals, PrimeNG, and Tailwind CSS. It supports horizontal top navigation, vertical left sidebar rails, responsive mobile drawers, role-base
Readme
@ovyn/menu
@ovyn/menu is a modern, responsive navigation menu component library for Angular applications built with Angular Signals, PrimeNG, and Tailwind CSS. It supports horizontal top navigation, vertical left sidebar rails, responsive mobile drawers, role-based visibility filtering, and rich template customization.
Features
- Flexible Layouts: Switch seamlessly between horizontal top bar (
location: 'top') and vertical sidebar (location: 'left'). - Responsive Mobile Drawer: Automatically collapses into a hamburger icon and mobile drawer (
p-drawer) below the configured breakpoint (defaults to768px). - Submenus & Hierarchical Navigation: Popover dropdowns for top bar menus and expandable accordions for sidebar navigation.
- Security & Role-based Visibility: Native integration with
provideMenuSecurityto evaluate link visibility based on user roles and permissions. - Customizable Templates: Custom
#logo,#actions(user profile, settings), and#contenttemplate slots with smart fallbacks (p-image,<router-outlet />). - Signal-driven State: Reactive configuration via
MenuConfigServicewith Angular signals. - Tailwind & PrimeNG Theming: Custom CSS tokens and PrimeNG preset configuration for colors, heights, and panel styling.
Installation
Install @ovyn/menu via your package manager:
yarn add @ovyn/menu
# or
npm install @ovyn/menuPeer Dependencies
Ensure your project has the required peer dependencies installed:
yarn add @angular/core @angular/common @angular/cdk @angular/router primeng @primeuix/themes tailwindcss-primeuiSetup & Styles
Include the menu theme stylesheet in your project's angular.json styles or root styles.css:
/* src/styles.css */
@import '@ovyn/menu/styles/menu-theme.css';Or in angular.json:
"styles": [
"node_modules/@ovyn/menu/styles/menu-theme.css",
"src/styles.css"
]Usage
1. Configure Menu Providers
You can register the menu configuration globally in app.config.ts or scoped to a specific route/component:
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideMenu, provideMenuSecurity } from '@ovyn/menu';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
// Optional security provider for role checking
provideMenuSecurity({
hasRole: (role: string) => role === 'user',
}),
// Menu configuration (supports static object or factory function with security provider)
provideMenu((security) => ({
location: 'top', // 'top' | 'left'
collapseBreakpoint: 768,
logoSrc: 'assets/logo.png',
links: [
{ label: 'Home', icon: 'pi pi-home', route: '/' },
{
label: 'Admin',
icon: 'pi pi-shield',
route: '/admin',
visible: security.hasRole('admin'),
},
{
label: 'Projects',
icon: 'pi pi-folder',
children: [
{ label: 'Active', route: '/projects/active' },
{ label: 'Archived', route: '/projects/archived', badge: 3 },
],
},
],
userActions: [
{
label: 'Profile',
icon: 'pi pi-user',
route: '/profile',
},
{
label: 'Settings',
icon: 'pi pi-cog',
route: '/settings',
},
],
})),
],
};2. Add Component to Template
Import MMenu in your standalone component and place <m-menu> in the template:
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { MMenu, MMenuItem } from '@ovyn/menu';
@Component({
selector: 'app-root',
imports: [MMenu, RouterOutlet, MMenuItem],
template: `
<m-menu>
<!-- Optional: Custom action bar items -->
<ng-template #actions let-userActions>
@for (action of userActions; track action.label) {
<menu-item [link]="action" location="top" />
}
</ng-template>
<!-- Optional: Custom content wrapper (defaults to <router-outlet />) -->
<ng-template #content>
<router-outlet />
</ng-template>
</m-menu>
`,
})
export class AppComponent {}API Reference
Configuration Types
MenuConfig
| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| location | 'top' \| 'left' | 'top' | Main navigation layout position. |
| links | MenuLink[] | [] | List of navigation links and nested children. |
| collapseBreakpoint | number | 768 | Screen width (in pixels) below which the menu switches to mobile drawer. |
| logoSrc | string | undefined | URL/path of the logo image displayed in the header/sidebar. |
| userActions | MenuLink[] | [] | Links or actions exposed to the #actions template slot. |
MenuLink
| Property | Type | Description |
| :--- | :--- | :--- |
| label | string | Display text for the item. |
| icon | string (optional) | PrimeIcons CSS class (e.g., 'pi pi-home'). |
| route | string \| string[] (optional) | Angular router link destination. |
| badge | string \| number (optional) | Badge counter or label tag. |
| disabled | boolean (optional) | Disables interaction when true. |
| visible | boolean (optional) | Conditionally displays/hides the menu item. |
| children | MenuLink[] (optional) | Nested items (rendered as popover dropdown in top mode or accordion in left mode). |
Template Slots (MMenu)
<m-menu> provides customizable content template slots:
#logo: Custom brand template replacing the defaultp-image/ text logo.#actions: Custom actions slot on the right (top bar) or bottom (sidebar), receivinguserActionsin the template context (let-userActions).#content: Main application view outlet (defaults to<router-outlet />).
Dynamic State with MenuConfigService
Inject MenuConfigService to inspect or modify the menu state at runtime:
import { Component, inject } from '@angular/core';
import { MenuConfigService } from '@ovyn/menu';
@Component({ ... })
export class MyComponent {
private menuConfigService = inject(MenuConfigService);
// Signals
readonly location = this.menuConfigService.location;
readonly isCollapsed = this.menuConfigService.collapsed;
toggleLayout() {
this.menuConfigService.setLocation(
this.location() === 'top' ? 'left' : 'top'
);
}
}CSS Variables & Theming
The library defines CSS custom properties that can be overridden in your stylesheets or via PrimeNG theme presets:
:root {
--m-menu-bar-height: 4rem;
--m-menu-rail-width: 16rem;
--m-menu-bg: linear-gradient(90deg, #63c1c9 0%, #82c9a0 45%, #bdd977 100%);
--m-menu-fg: #ffffff;
--m-menu-item-radius: 0.5rem;
--m-menu-item-pad-x: 0.75rem;
--m-menu-item-pad-y: 0.5rem;
--m-menu-item-hover: rgb(255 255 255 / 0.15);
--m-menu-item-active: rgb(255 255 255 / 0.24);
--m-menu-panel-bg: #1e293b;
--m-menu-panel-fg: #f1f5f9;
--m-menu-panel-radius: 0.75rem;
}Building
To build the library:
ng build menuThe compiled output will be generated in dist/menu.
License
MIT © Flavian Ovyn
