UNPKG

create-react-tailwind-app-router

Version:

A starter template package for React applications with React Router, Tailwind CSS, and Prettier using Vite. Supports both JavaScript and TypeScript templates.

190 lines (177 loc) 7.06 kB
/** * Navigation Bar Component * * A responsive navigation component that provides site-wide navigation. * This component demonstrates several important React and accessibility patterns: * * Key Features: * - Active link highlighting using React Router * - Theme-aware design with dark/light mode support * - Dark/Light mode toggle integration * - Responsive design with Tailwind CSS * - Accessibility-friendly navigation structure * - Hover states and smooth transitions * - Clean, reusable helper functions * * React Patterns Demonstrated: * - useLocation hook for route-aware components * - Context API integration for theme management * - Conditional CSS classes with template literals * - Component composition with React Router Link * - Helper function extraction for cleaner code * * Learning Points: * - How to create navigation that responds to route changes * - Theme integration with global state management * - Best practices for conditional styling in React * - Semantic HTML for accessibility (nav, role attributes) * - CSS transitions for better user experience */ import { Link, useLocation } from 'react-router-dom' import { useAppContext } from '../../context/AppContext' import ThemeToggle from '../ui/ThemeToggle' function Navbar() { // useLocation hook gives us access to the current route // This is a React Router hook that returns the current location object // We use this to determine which navigation link should be highlighted as "active" const location = useLocation() // Access theme state from global context const { state } = useAppContext() const { theme } = state /** * Helper function to determine if a navigation link is active * * This pattern is common in navigation components - extract logic into * small, focused functions for better readability and reusability. * * @param {string} path - The path to check against current location * @returns {boolean} True if the current path matches the given path */ const isActive = path => { return location.pathname === path } return ( <nav className={`shadow-lg transition-colors duration-300 ${ theme === 'dark' ? 'bg-gray-800' : 'bg-white' }`} role="navigation" // Accessibility: explicitly define this as navigation aria-label="Main navigation" // Screen reader description > <div className='container mx-auto px-4'> <div className='flex justify-between items-center py-4'> {/* Logo/Brand Section */} <Link to='/' className={`text-xl font-bold transition-colors ${ theme === 'dark' ? 'text-white hover:text-blue-400' : 'text-gray-800 hover:text-blue-600' }`} aria-label="Go to homepage" // Accessibility: describe link purpose > React Tailwind App </Link> {/* Navigation Links and Theme Toggle Section */} <div className='flex items-center space-x-4'> {/* Navigation Links */} <div className='flex space-x-4'> {/* Home Link Pattern Explanation: - Use template literals for dynamic class names - Conditional operator (ternary) for active vs inactive styles - Theme-aware styling for both active and inactive states - Consistent spacing and typography across all links */} <Link to='/' className={` px-3 py-2 rounded-md text-sm font-medium transition-colors ${isActive('/') ? 'bg-blue-500 text-white' // Active state styles (same for both themes) : theme === 'dark' ? 'text-gray-300 hover:bg-gray-700 hover:text-white' // Dark theme inactive : 'text-gray-700 hover:bg-gray-100' // Light theme inactive } `} aria-current={isActive('/') ? 'page' : undefined} // Accessibility: indicate current page > Home </Link> {/* About Link */} <Link to='/about' className={` px-3 py-2 rounded-md text-sm font-medium transition-colors ${isActive('/about') ? 'bg-blue-500 text-white' : theme === 'dark' ? 'text-gray-300 hover:bg-gray-700 hover:text-white' : 'text-gray-700 hover:bg-gray-100' } `} aria-current={isActive('/about') ? 'page' : undefined} > About </Link> {/* Contact Link */} <Link to='/contact' className={` px-3 py-2 rounded-md text-sm font-medium transition-colors ${isActive('/contact') ? 'bg-blue-500 text-white' : theme === 'dark' ? 'text-gray-300 hover:bg-gray-700 hover:text-white' : 'text-gray-700 hover:bg-gray-100' } `} aria-current={isActive('/contact') ? 'page' : undefined} > Contact </Link> </div> {/* Theme Toggle Component */} <ThemeToggle /> </div> </div> </div> </nav> ) } /** * CSS Classes Explained: * * Navigation Container: * - bg-white: White background * - shadow-lg: Large shadow for depth * * Layout: * - container mx-auto: Centered container with max-width * - px-4: Horizontal padding * - flex justify-between items-center: Space between logo and nav items * - py-4: Vertical padding * * Links: * - px-3 py-2: Padding for click targets (accessibility) * - rounded-md: Medium border radius * - text-sm font-medium: Typography styling * - transition-colors: Smooth color transitions on hover/focus * * Active States: * - bg-blue-500 text-white: Blue background with white text for active links * - text-gray-700 hover:bg-gray-100: Gray text with light hover background for inactive links * * Accessibility Features: * - role="navigation": Explicit navigation landmark * - aria-label: Descriptive label for screen readers * - aria-current="page": Indicates the current page to assistive technology * - Proper semantic HTML structure with nav element * * Performance Considerations: * - useLocation is called once per render, not per link * - Helper function prevents code duplication * - CSS transitions provide smooth UX without JavaScript */ export default Navbar