
Product
Rust Support Now in Beta
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
asafarim-navlinks
Advanced tools
A versatile React navigation component with unlimited multi-level dropdowns, four alignment options, mobile responsiveness, and customizable styling. Perfect for modern web applications.
Dynamic Navigation Links with Multi-Level Dropdowns and Icons for React Apps
A versatile and feature-rich React component for creating dynamic navigation bars with unlimited multi-level dropdown menus, icons, emojis, and flexible styling options. Perfect for modern web applications that require sophisticated navigation structures.
🎮 Interactive Online Demo - Experience all features in action directly in your browser!
# Run the demo locally
pnpm run demo
Multi-level dropdown menus with unlimited nesting support
Four different alignment options for dropdown positioning
# npm
npm install asafarim-navlinks
# yarn
yarn add asafarim-navlinks
# pnpm
pnpm add asafarim-navlinks
import React from 'react';
import NavLinks, { NavLinkType } from 'asafarim-navlinks';
const navData: NavLinkType[] = [
{
label: 'Home',
href: '/',
iconLeft: 'fas fa-home'
},
{
label: 'Products',
href: '/products',
iconLeft: 'fas fa-box',
subNav: [
{ label: 'Web Apps', href: '/web-apps' },
{ label: 'Mobile Apps', href: '/mobile-apps' }
]
},
{
label: 'About',
href: '/about',
emoji: '📖'
}
];
function App() {
return (
<nav>
<NavLinks links={navData} />
</nav>
);
}
const basicLinks: NavLinkType[] = [
{ label: 'Home', href: '/' },
{ label: 'About', href: '/about' },
{ label: 'Contact', href: '/contact' }
];
<NavLinks links={basicLinks} />
const nestedLinks: NavLinkType[] = [
{
label: 'Products',
href: '/products',
subNav: [
{ label: 'Software', href: '/software' },
{
label: 'Services',
href: '/services',
subNav: [
{
label: 'Consulting',
href: '/consulting',
subNav: [
{ label: 'Technical', href: '/technical' },
{ label: 'Business', href: '/business' }
]
},
{ label: 'Training', href: '/training' }
]
}
]
}
];
<NavLinks links={nestedLinks} />
const iconLinks: NavLinkType[] = [
{ label: 'Dashboard', href: '/dashboard', iconLeft: 'fas fa-tachometer-alt' },
{ label: 'Settings', href: '/settings', iconRight: 'fas fa-cog' },
{ label: 'Profile', href: '/profile', iconLeft: 'fas fa-user' }
];
<NavLinks links={iconLinks} />
const emojiLinks: NavLinkType[] = [
{ label: 'Home', href: '/', emoji: '🏠' },
{ label: 'Products', href: '/products', emoji: '📦' },
{ label: 'Support', href: '/support', emoji: '🎧' }
];
<NavLinks links={emojiLinks} />
const dropdownLinks: NavLinkType[] = [
{
label: 'Services',
href: '/services',
iconLeft: 'fas fa-concierge-bell',
subNav: [
{ label: 'Web Development', href: '/web-dev' },
{
label: 'Support',
href: '/support',
subNav: [
{ label: '24/7 Support', href: '/support-24-7' },
{ label: 'Documentation', href: '/docs' },
{ label: 'Community', href: '/community' }
]
},
{ label: 'Consulting', href: '/consulting' }
]
}
];
<NavLinks links={dropdownLinks} />
const logoLinks: NavLinkType[] = [
{
label: 'Brand',
href: '/',
svgLogoIcon: {
src: '/logo.svg',
alt: 'Company Logo',
width: 40,
height: 40,
caption: 'MyBrand'
}
},
{ label: 'Products', href: '/products' }
];
<NavLinks links={logoLinks} />
// Automatic mobile detection and responsive behavior
<NavLinks
links={mobileNavLinks}
baseLinkStyle={{
display: 'flex',
flexWrap: 'wrap' // Allows wrapping on smaller screens
}}
/>
// With collapsible mobile menu (hamburger menu)
<NavLinks
links={mobileNavLinks}
enableMobileCollapse={true}
/>
// Force mobile behavior for testing
<NavLinks
links={mobileNavLinks}
isMobile={true}
enableMobileCollapse={true}
/>
// Automatically shows hamburger menu on mobile devices
<NavLinks
links={mobileNavLinks}
baseLinkStyle={{
display: 'flex',
gap: '20px' // Adjusts automatically for mobile
}}
/>
// Force mobile behavior for testing
<NavLinks
links={mobileNavLinks}
isMobile={true}
enableMobileCollapse={true}
/>
// Disable mobile collapse even on mobile
<NavLinks
links={mobileNavLinks}
enableMobileCollapse={false}
/>
Prop | Type | Default | Description |
---|---|---|---|
links | NavLinkType[] | Required | Array of navigation link objects |
className | string | undefined | Custom CSS class for the navigation container |
baseLinkStyle | React.CSSProperties | undefined | Inline styles for top-level links |
subLinkStyle | React.CSSProperties | undefined | Inline styles for dropdown links |
isRightAligned | boolean | false | Right-align the dropdown menus |
isLeftAligned | boolean | false | Left-align the dropdown menus (nested dropdowns appear to the left) |
isBottomAligned | boolean | false | Position dropdowns below their parent items (default behavior) |
isTopAligned | boolean | false | Position dropdowns above their parent items |
isMobile | boolean | false | Force mobile behavior regardless of screen size |
enableMobileCollapse | boolean | false | Enable collapsible hamburger menu on mobile. Note: Hamburger menu automatically appears on mobile devices (≤768px) regardless of this setting |
interface NavLinkType {
label?: string; // Text label for the link
title?: string; // Title attribute (tooltip)
href: string; // URL for the link
iconLeft?: string; // Font Awesome class for left icon
iconRight?: string; // Font Awesome class for right icon
emoji?: string; // Emoji character
subNav?: NavLinkType[]; // Array of sub-navigation items
svgLogoIcon?: { // Custom SVG/logo configuration
src: string;
alt: string;
width?: number;
height?: number | string;
caption?: string;
style?: React.CSSProperties;
};
}
The component uses CSS modules with default styling that can be easily overridden:
/* In your CSS file */
.custom-nav ul li a {
color: #3498db !important;
font-weight: bold;
}
.custom-nav ul ul {
background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%) !important;
}
<NavLinks
links={links}
className="custom-nav"
/>
You can apply inline styles directly to the component:
<NavLinks
links={links}
baseLinkStyle={{
fontSize: '16px',
fontWeight: 'bold',
padding: '12px 16px'
}}
subLinkStyle={{
backgroundColor: '#2c3e50',
minWidth: '220px'
}}
/>
The component is built with responsive design in mind. You can further enhance responsiveness with your own CSS:
@media (max-width: 768px) {
.custom-nav ul li {
display: block;
width: 100%;
}
.custom-nav ul ul {
position: static;
display: none;
}
}
All dropdowns are hidden by default and only appear when hovering over their parent item. This behavior works consistently across all nesting levels:
const advancedNav: NavLinkType[] = [
{
label: 'Resources',
href: '#',
subNav: [
{
label: 'Documentation',
href: '/docs',
subNav: [
{
label: 'Components',
href: '/docs/components',
subNav: [
// This will appear when hovering on "Components"
{ label: 'Navigation', href: '/docs/components/navigation' }
]
}
]
}
]
}
];
The component supports four different alignment options for dropdown positioning:
<NavLinks
links={navData}
isLeftAligned={true}
/>
<NavLinks
links={navData}
isRightAligned={true}
baseLinkStyle={{ justifyContent: 'flex-end' }}
/>
<NavLinks
links={navData}
isTopAligned={true}
/>
<NavLinks
links={navData}
isBottomAligned={true}
/>
You can combine horizontal and vertical alignment for custom positioning:
// Dropdowns appear above and slide to the right
<NavLinks
links={navLinks}
isTopAligned={true}
isRightAligned={true}
/>
// Dropdowns appear below and slide to the left
<NavLinks
links={navLinks}
isBottomAligned={true}
isLeftAligned={true}
/>
function Navigation() {
const leftLinks = [
{ label: 'Home', href: '/', iconLeft: 'fas fa-home' }
];
const rightLinks = [
{ label: 'Login', href: '/login', iconRight: 'fas fa-sign-in-alt' }
];
return (
<nav style={{ display: 'flex', justifyContent: 'space-between' }}>
<NavLinks links={leftLinks} />
<NavLinks links={rightLinks} isRightAligned={true} />
</nav>
);
}
const alignmentLinks: NavLinkType[] = [
{
label: 'Services',
href: '#services',
subNav: [
{ label: 'Web Design', href: '#web-design' },
{ label: 'Development', href: '#development' }
]
}
];
// Left aligned - nested dropdowns appear to the left (default)
<NavLinks links={alignmentLinks} isLeftAligned={true} />
// Right aligned - nested dropdowns appear to the right
<NavLinks links={alignmentLinks} isRightAligned={true} />
// Top aligned - dropdowns appear above parent items
<NavLinks links={alignmentLinks} isTopAligned={true} />
// Bottom aligned - dropdowns appear below parent items (default)
<NavLinks links={alignmentLinks} isBottomAligned={true} />
All dropdowns are hidden by default and only appear when hovering over their parent item. This behavior works consistently across all nesting levels:
const advancedNav: NavLinkType[] = [
{
label: 'Resources',
href: '#',
subNav: [
{
label: 'Documentation',
href: '/docs',
subNav: [
{
label: 'Components',
href: '/docs/components',
subNav: [
// This will appear when hovering on "Components"
{ label: 'Navigation', href: '/docs/components/navigation' }
]
}
]
}
]
}
];
import React from 'react';
import NavLinks, { NavLinkType } from 'asafarim-navlinks';
const navigationData: NavLinkType[] = [
{
label: 'Home',
href: '/',
svgLogoIcon: {
src: '/logo.svg',
alt: 'Company Logo',
width: 30,
height: 30,
caption: 'MyApp'
}
},
{
label: 'Products',
href: '/products',
iconLeft: 'fas fa-cube',
subNav: [
{ label: 'Web Applications', href: '/web-apps', emoji: '🌐' },
{ label: 'Mobile Apps', href: '/mobile-apps', emoji: '📱' },
{
label: 'Enterprise Solutions',
href: '/enterprise',
emoji: '🏢',
subNav: [
{ label: 'CRM Systems', href: '/crm' },
{ label: 'ERP Solutions', href: '/erp' },
{ label: 'Custom Development', href: '/custom' }
]
}
]
},
{
label: 'Services',
href: '/services',
iconLeft: 'fas fa-concierge-bell',
subNav: [
{ label: 'Consulting', href: '/consulting' },
{ label: 'Support', href: '/support' },
{ label: 'Training', href: '/training' }
]
},
{
label: 'About',
href: '/about',
iconLeft: 'fas fa-info-circle'
},
{
label: 'Contact',
href: '/contact',
iconLeft: 'fas fa-envelope'
}
];
function App() {
return (
<div className="app">
<header className="header">
<nav className="navigation">
<NavLinks
links={navigationData}
baseLinkStyle={{
display: 'flex',
gap: '1rem',
listStyle: 'none',
margin: 0,
padding: 0
}}
subLinkStyle={{
backgroundColor: '#2c3e50',
padding: '0.5rem',
borderRadius: '4px',
minWidth: '200px'
}}
/>
</nav>
</header>
<main className="main-content">
<h1>Welcome to My App</h1>
</main>
</div>
);
}
export default App;
# Clone the repository
git clone https://github.com/AliSafari-IT/asafarim-navlinks.git
# Install dependencies
pnpm install
# Build the package
pnpm run build
# Run the demo
pnpm run demo
pnpm run build # Build the package
pnpm run demo # Run the demo
pnpm run demo:install # Install demo dependencies
pnpm run demo:build # Build the demo
pnpm run publishPublicly # Publish to npm
Contributions are welcome! Here's how you can contribute:
git checkout -b feature/amazing-feature
)git commit -m 'Add some amazing feature'
)git push origin feature/amazing-feature
)Please make sure to update tests as appropriate.
This project is licensed under the MIT License - see the MIT_License file for details.
Ali Safari - @AliSafari-IT
Made with ❤️ for the React community
If your dropdowns aren't opening on hover, check:
subNav
arrays!important
flagsIf your dropdowns are not positioned correctly:
isLeftAligned
, isRightAligned
, isTopAligned
, isBottomAligned
) need to be adjustedposition: relative
z-index
values if dropdowns are appearing behind other elementsisTopAligned={true}
with isRightAligned={true}
)If SVG or logo images aren't loading:
For better mobile support:
FAQs
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.
Product
Socket Fix 2.0 brings targeted CVE remediation, smarter upgrade planning, and broader ecosystem support to help developers get to zero alerts.
Security News
Socket CEO Feross Aboukhadijeh joins Risky Business Weekly to unpack recent npm phishing attacks, their limited impact, and the risks if attackers get smarter.