A versatile React navigation component with unlimited multi-level dropdowns, four alignment options, mobile responsiveness, and customizable styling. Perfect for modern web applications.
npm install asafarim-navlinksbash
Run the demo locally
pnpm run demo
`
!Simple Navigation with Basic Links
$3
- Deep Nesting: See multi-level dropdown menus in action (5+ levels deep)
- Four Alignment Options: Left, right, top, and bottom dropdown positioning
- Interactive Examples: Try different navigation styles and configurations
- Code Samples: Ready-to-use code snippets for each feature
- Visual Guide: Clear visualization of all component capabilities
!Complex Navigation Structure with Multiple Levels
Multi-level dropdown menus with unlimited nesting support
!Different Alignment Options for Dropdown Positioning
Four different alignment options for dropdown positioning
📦 Installation
`bash
npm
npm install asafarim-navlinks
yarn
yarn add asafarim-navlinks
pnpm
pnpm add asafarim-navlinks
`
🎪 Quick Start
`tsx
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 (
);
}
`
🎨 Examples
$3
`tsx
const basicLinks: NavLinkType[] = [
{ label: 'Home', href: '/' },
{ label: 'About', href: '/about' },
{ label: 'Contact', href: '/contact' }
];
`
$3
`tsx
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' }
]
}
]
}
];
`
$3
`tsx
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' }
];
`
$3
`tsx
const emojiLinks: NavLinkType[] = [
{ label: 'Home', href: '/', emoji: '🏠' },
{ label: 'Products', href: '/products', emoji: '📦' },
{ label: 'Support', href: '/support', emoji: '🎧' }
];
`
$3
`tsx
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' }
]
}
];
`
$3
`tsx
const logoLinks: NavLinkType[] = [
{
label: 'Brand',
href: '/',
svgLogoIcon: {
src: '/logo.svg',
alt: 'Company Logo',
width: 40,
height: 40,
caption: 'MyBrand'
}
},
{ label: 'Products', href: '/products' }
];
`
$3
`tsx
// Automatic mobile detection and responsive behavior
links={mobileNavLinks}
baseLinkStyle={{
display: 'flex',
flexWrap: 'wrap' // Allows wrapping on smaller screens
}}
/>
// With collapsible mobile menu (hamburger menu)
links={mobileNavLinks}
enableMobileCollapse={true}
/>
// Force mobile behavior for testing
links={mobileNavLinks}
isMobile={true}
enableMobileCollapse={true}
/>
`
#### Mobile Features:
- Automatic Detection: Responsive breakpoint at 768px with automatic hamburger menu
- Smart Behavior: Hamburger menu appears automatically on mobile devices
- Animated Cross Icon: Professional hamburger-to-cross animation when menu opens
- Touch-Friendly: Larger touch targets and proper spacing
- Collapsible Menu: Hamburger menu automatically enabled on mobile screens
- Vertical Stacking: Navigation items stack vertically on mobile
- Simplified Dropdowns: Dropdowns appear below instead of to the side
$3
#### Automatic Mobile Detection (Recommended)
`tsx
// Automatically shows hamburger menu on mobile devices
links={mobileNavLinks}
baseLinkStyle={{
display: 'flex',
gap: '20px' // Adjusts automatically for mobile
}}
/>
`
#### Manual Mobile Control
`tsx
// Force mobile behavior for testing
links={mobileNavLinks}
isMobile={true}
enableMobileCollapse={true}
/>
// Disable mobile collapse even on mobile
links={mobileNavLinks}
enableMobileCollapse={false}
/>
`
📝 Component Props
$3
| 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 |
$3
`typescript
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;
};
}
`
🎨 Styling and Customization
$3
The component uses CSS modules with default styling that can be easily overridden:
`css
/ 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;
}
`
`tsx
links={links}
className="custom-nav"
/>
`
$3
You can apply inline styles directly to the component:
`tsx
links={links}
baseLinkStyle={{
fontSize: '16px',
fontWeight: 'bold',
padding: '12px 16px'
}}
subLinkStyle={{
backgroundColor: '#2c3e50',
minWidth: '220px'
}}
/>
`
$3
The component is built with responsive design in mind. You can further enhance responsiveness with your own CSS:
`css
@media (max-width: 768px) {
.custom-nav ul li {
display: block;
width: 100%;
}
.custom-nav ul ul {
position: static;
display: none;
}
}
`
🌟 Advanced Usage
$3
All dropdowns are hidden by default and only appear when hovering over their parent item. This behavior works consistently across all nesting levels:
`tsx
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' }
]
}
]
}
]
}
];
`
$3
The component supports four different alignment options for dropdown positioning:
#### Left-Aligned Navigation (Default)
`tsx
links={navData}
isLeftAligned={true}
/>
`
#### Right-Aligned Navigation
`tsx
links={navData}
isRightAligned={true}
baseLinkStyle={{ justifyContent: 'flex-end' }}
/>
`
#### Top-Aligned Navigation
`tsx
links={navData}
isTopAligned={true}
/>
`
#### Bottom-Aligned Navigation (Default)
`tsx
links={navData}
isBottomAligned={true}
/>
`
$3
You can combine horizontal and vertical alignment for custom positioning:
`tsx
// Dropdowns appear above and slide to the right
links={navLinks}
isTopAligned={true}
isRightAligned={true}
/>
// Dropdowns appear below and slide to the left
links={navLinks}
isBottomAligned={true}
isLeftAligned={true}
/>
`
$3
`tsx
function Navigation() {
const leftLinks = [
{ label: 'Home', href: '/', iconLeft: 'fas fa-home' }
];
const rightLinks = [
{ label: 'Login', href: '/login', iconRight: 'fas fa-sign-in-alt' }
];
return (
);
}
`
$3
`tsx
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)
// Right aligned - nested dropdowns appear to the right
// Top aligned - dropdowns appear above parent items
// Bottom aligned - dropdowns appear below parent items (default)
`
$3
All dropdowns are hidden by default and only appear when hovering over their parent item. This behavior works consistently across all nesting levels:
`tsx
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' }
]
}
]
}
]
}
];
`
📖 Full Example
`tsx
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 (
Welcome to My App
);
}
export default App;
`
🛠️ Development
$3
`bash
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
`
$3
`bash
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
`
👥 Contributing
Contributions are welcome! Here's how you can contribute:
1. Fork the repository
2. Create your feature branch (git checkout -b feature/amazing-feature)
3. Commit your changes (git commit -m 'Add some amazing feature')
4. Push to the branch (git push origin feature/amazing-feature)
5. Open a Pull Request
Please make sure to update tests as appropriate.
📄 License
This project is licensed under the MIT License - see the MIT_License file for details.
👨💻 Author
Ali Safari - @AliSafari-IT
---
Made with ❤️ for the React community
⚠️ Troubleshooting
$3
If your dropdowns aren't opening on hover, check:
1. Make sure there are no CSS conflicts in your project overriding the hover behavior
2. Verify that your navigation data structure is correct with properly nested subNav arrays
3. Try increasing the CSS specificity in your custom styles with !important flags
$3
If your dropdowns are not positioned correctly:
1. Check if alignment props (isLeftAligned, isRightAligned, isTopAligned, isBottomAligned) need to be adjusted
2. Ensure the parent container has position: relative
3. Add higher z-index values if dropdowns are appearing behind other elements
4. For edge cases, consider combining alignment options (e.g., isTopAligned={true} with isRightAligned={true}`)