Side Navigation Block
The SideNavigation Component is a fully customizable and accessible side navigation menu built with React and TypeScript. It provides a complete navigation interface with modern design patterns, mobile-responsive behavior, floating and fixed modes, and flexible customization options.
π Installationβ
npm install @nodeblocks/frontend-side-navigation-block
π Usageβ
import {SideNavigation} from '@nodeblocks/frontend-side-navigation-block';
- Basic Usage
- Advanced Usage
function BasicSideNavigation() { const [isMenuOpen, setIsMenuOpen] = useState(false); const navigationHeader = { icon: 'home' as const, text: 'Home', href: '#home', }; const navigationLinks = [ {icon: 'dashboard' as const, text: 'Dashboard', href: '#dashboard'}, {icon: 'shopping_cart' as const, text: 'Products', href: '#products'}, {icon: 'reorder' as const, text: 'Orders', href: '#orders'}, {icon: 'settings' as const, text: 'Settings', href: '#settings'}, {icon: 'help' as const, text: 'Support', href: '#support'}, ]; return ( <SideNavigation isFloating={true} isMenuOpen={isMenuOpen} setIsMenuOpen={setIsMenuOpen} header={navigationHeader} links={navigationLinks}> <SideNavigation.Links /> </SideNavigation> ); }
function AdvancedSideNavigation() { const [isMenuOpen, setIsMenuOpen] = useState(false); const navigationHeader = { icon: 'home' as const, text: 'Home', href: '#home', }; const navigationLinks = [ {icon: 'π' as const, text: 'Dashboard', href: '#dashboard', color: '#007bff'}, {icon: 'ποΈ' as const, text: 'Products', href: '#products', color: '#007bff'}, {icon: 'π¦' as const, text: 'Orders', href: '#orders', color: '#007bff'}, {icon: 'βοΈ' as const, text: 'Settings', href: '#settings', color: '#007bff'}, {icon: 'π¬' as const, text: 'Support', href: '#support', color: '#007bff'}, ]; return ( <SideNavigation isFloating={true} isMenuOpen={isMenuOpen} setIsMenuOpen={setIsMenuOpen} header={navigationHeader} links={[]} // will use inside the override function > {({defaultBlocks, defaultBlockOrder}) => { return { blocks: { ...defaultBlocks, // π§ Rich Navigation Links with full component override links: { ...defaultBlocks.links, props: { ...defaultBlocks.links.props, className: 'custom-links', children: ( <nav style={{ display: 'flex', flexDirection: 'column', gap: '8px', padding: '20px', background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', minHeight: '100vh', width: isMenuOpen ? '280px' : '60px', transition: 'all 0.3s ease', position: 'relative', overflow: 'hidden', }} > {/* Header Section */} <div style={{ display: 'flex', alignItems: 'center', gap: '12px', padding: '16px 12px', backgroundColor: 'rgba(255, 255, 255, 0.1)', borderRadius: '12px', marginBottom: '20px', backdropFilter: 'blur(10px)', border: '1px solid rgba(255, 255, 255, 0.2)', }} > <div style={{ width: '40px', height: '40px', backgroundColor: '#fff', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '1.2rem', color: '#667eea', fontWeight: 'bold', boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)', }} > π </div> {isMenuOpen && ( <div style={{color: 'white'}}> <div style={{fontWeight: 'bold', fontSize: '1.1rem'}}>My App</div> <div style={{fontSize: '0.8rem', opacity: 0.8}}>Welcome back!</div> </div> )} </div> {/* Navigation Links */} <div style={{display: 'flex', flexDirection: 'column', gap: '6px'}}> {navigationLinks.map((item, index) => ( <a key={index} href={item.href} style={{ display: 'flex', alignItems: 'center', gap: '15px', padding: '14px 16px', borderRadius: '10px', textDecoration: 'none', color: 'white', transition: 'all 0.3s ease', backgroundColor: 'rgba(255, 255, 255, 0.1)', border: '1px solid rgba(255, 255, 255, 0.1)', backdropFilter: 'blur(10px)', }} onMouseEnter={e => { e.currentTarget.style.backgroundColor = item.color; e.currentTarget.style.transform = 'translateX(8px)'; //@ts-expect-error - color is not a valid property e.currentTarget.style.boxShadow = `0 4px 15px ${item.color}40`; }} onMouseLeave={e => { e.currentTarget.style.backgroundColor = 'rgba(255, 255, 255, 0.1)'; e.currentTarget.style.transform = 'translateX(0)'; e.currentTarget.style.boxShadow = 'none'; }} > <div style={{ fontSize: '1.4rem', minWidth: '24px', textAlign: 'center', }} > {item.icon} </div> {isMenuOpen && ( <div style={{ fontSize: '0.95rem', fontWeight: '500', whiteSpace: 'nowrap', }} > {item.text} </div> )} </a> ))} </div> </nav> ), }, }, }, blockOrder: defaultBlockOrder, }; }} </SideNavigation> ); }
π§ Props Referenceβ
Main Component Propsβ
Prop | Type | Default | Description |
---|---|---|---|
isFloating | boolean | undefined | Whether the navigation should float over content (mobile-style) or be fixed in place |
isMenuOpen | boolean | undefined | Controls whether the navigation menu is open or closed |
setIsMenuOpen | (isMenuOpen: boolean) => void | Required | Function to control the menu open/close state |
header | { icon?: IconType; text?: ReactNode; href: string } | Required | Header link object with optional icon, text content, and href |
links | { icon?: IconType; text?: ReactNode; href: string }[] | Required | Array of navigation link objects with optional icons |
children | BlocksOverride | undefined | Function to override default blocks or add custom navigation components |
Sub-Componentsβ
The SideNavigation component provides several sub-components. All sub-components receive their default values from the main component's context and can override these values through props.
SideNavigation.Overlayβ
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | undefined | Custom content for the overlay |
setIsMenuOpen | (isMenuOpen: boolean) => void | From context | Function to control menu state when overlay is clicked |
Note: This component inherits all HTML div
element props.
SideNavigation.MenuButtonβ
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | <Icon icon="menu" /> | Custom content for the menu button (defaults to hamburger icon) |
isMenuOpen | boolean | From context | Current menu open state |
setIsMenuOpen | (isMenuOpen: boolean) => void | From context | Function to toggle menu state |
Note: This component inherits all HTML button
element props.
SideNavigation.Linksβ
Prop | Type | Default | Description |
---|---|---|---|
children | ReactNode | Default links rendering | Custom content to override default links rendering |
header | { icon?: IconType; text?: ReactNode; href: string } | From context | Header link object to display |
links | { icon?: IconType; text?: ReactNode; href: string }[] | From context | Array of navigation links to display |
Note: This component inherits all HTML nav
element props.
π§ TypeScript Supportβ
Full TypeScript support with comprehensive type definitions:
import {SideNavigation} from '@nodeblocks/frontend-side-navigation-block';
import {ComponentProps, ReactNode} from 'react';
// Main component interface
interface SideNavigationProps extends Omit<ComponentProps<'aside'>, 'children'> {
isFloating?: boolean;
isMenuOpen?: boolean;
setIsMenuOpen: (isMenuOpen: boolean) => void;
header: { icon?: string; text?: ReactNode; href: string };
links: { icon?: string; text?: ReactNode; href: string }[];
}
// Usage example with comprehensive typing
interface CustomNavigationData {
headerItem: { icon?: string; text?: ReactNode; href: string };
menuItems: { icon?: string; text?: ReactNode; href: string }[];
isResponsive: boolean;
onMenuToggle: (isOpen: boolean) => void;
}
const NavigationComponent = ({headerItem, menuItems, isResponsive, onMenuToggle}: CustomNavigationData) => {
const [isOpen, setIsOpen] = useState(false);
const handleMenuToggle = (isMenuOpen: boolean) => {
setIsOpen(isMenuOpen);
onMenuToggle(isMenuOpen);
};
return (
<SideNavigation
isFloating={isResponsive}
isMenuOpen={isOpen}
setIsMenuOpen={handleMenuToggle}
header={headerItem}
links={menuItems}
onClick={e => console.log('Navigation clicked')}>
<SideNavigation.Links />
</SideNavigation>
);
};
Built with β€οΈ using React, TypeScript, and modern web standards.