UNPKG

@sofidevo/astro-dynamic-header

Version:

A dynamic Astro header component that switches between floating and fullscreen styles

395 lines (311 loc) 9.27 kB
# @sofidevo/astro-dynamic-header A dynamic, responsive header component for Astro projects that can switch between floating and fullscreen styles with multi-level dropdown navigation support. ## Features - 🎨 **Dynamic Styles**: Switch between floating and fullscreen header layouts - 📱 **Fully Responsive**: Mobile-first design with hamburger menu - 🎯 **Multi-level Dropdowns**: Support for nested navigation menus - **Slot Support**: Customizable slots for desktop header and mobile panel content - �🚀 **TypeScript Support**: Full type safety and IntelliSense - 🎨 **Customizable**: Extensive customization options for colors, sizes, and behavior - **Astro Optimized**: Built specifically for Astro framework ### Live demo [https://base-astro-psi.vercel.app/fullscreen-demo](https://base-astro-psi.vercel.app/fullscreen-demo) ## Installation ```bash npm i @sofidevo/astro-dynamic-header ``` ## Quick Start ### Basic Usage ```astro --- // Option 1: Import from direct subpath (recommended) import Header from '@sofidevo/astro-dynamic-header/Header'; // Option 2: Import from main entry point with types import { HeaderProps, type MenuItemType } from '@sofidevo/astro-dynamic-header'; const menuItems = [ { link: '/about', text: 'About' }, { link: '/contact', text: 'Contact' }, ]; --- <Header headerType="floating" logoSrc="/logo.png" menuItems={menuItems} /> ``` ### TypeScript Configuration To ensure imports work correctly in your Astro project, make sure your `tsconfig.json` has the appropriate configuration: ```json { "compilerOptions": { "moduleResolution": "bundler", "allowImportingTsExtensions": true, "strict": true, "noEmit": true, "jsx": "preserve" }, "extends": "astro/tsconfigs/strict" } ``` ### Advanced Usage ```astro --- import Header from '@sofidevo/astro-dynamic-header/Header'; import type { MenuItemType } from '@sofidevo/astro-dynamic-header'; const menuItems = [ { link: '#', text: 'Services', submenu: [ { link: '#', text: 'Web Development', submenu: [ { link: '/web/frontend', text: 'Frontend' }, { link: '/web/backend', text: 'Backend' }, { link: '/web/fullstack', text: 'Full Stack' }, ], }, { link: '/design', text: 'Design' }, { link: '/consulting', text: 'Consulting' }, ], }, { link: '/about', text: 'About' }, { link: '/contact', text: 'Contact' }, ]; --- <Header headerType="fullscreen" logoSrc="/logo.png" logoAlt="My Company" logoWidth="150px" homeUrl="/" menuItems={menuItems} backgroundColor="#000000dd" backdropBlur="blur(15px)" zIndex={100} /> ``` ## Component Props ### Header Component | Prop | Type | Default | Description | |------|------|---------|-------------| | `headerType` | `"floating" \| "fullscreen"` | `"floating"` | Header layout style | | `logoSrc` | `string` | `"/logo.png"` | Logo image source | | `logoAlt` | `string` | `"Logo"` | Logo alt text | | `logoWidth` | `string` | `"120px"` | Logo width | | `homeUrl` | `string` | `"/"` | Home page URL | | `menuItems` | `MenuItemType[]` | `[]` | Navigation menu items | | `backgroundColor` | `string` | `"#0d0d0dcc"` | Header background color | | `backdropBlur` | `string` | `"blur(20px)"` | Backdrop filter blur | | `zIndex` | `number` | `10` | CSS z-index value | ### Menu Item Structure ```typescript interface MenuItemType { link: string; text: string; submenu?: MenuItemType[]; } ``` ## Slots Support The Header component provides two customizable slots that allow you to add additional content: ### Available Slots | Slot Name | Location | Visibility | Description | |-----------|----------|------------|-------------| | `slot-desktop` | Header (desktop & mobile) | Always visible | Add content to the main header area | | `slot-panel` | Mobile navigation panel | Mobile only | Add content to the mobile menu panel | ### Slot Examples #### Using Individual Slots ```astro --- import Header from '@sofidevo/astro-dynamic-header/Header'; const menuItems = [ { link: '/about', text: 'About' }, { link: '/contact', text: 'Contact' }, ]; --- <!-- Adding content only to desktop header --> <Header headerType="floating" logoSrc="/logo.png" menuItems={menuItems} > <button slot="slot-desktop" class="cta-button">Get Started</button> </Header> <!-- Adding content only to mobile panel --> <Header headerType="fullscreen" logoSrc="/logo.png" menuItems={menuItems} > <div slot="slot-panel" class="mobile-footer"> <p>© 2024 My Company</p> <div class="social-links"> <a href="/twitter">Twitter</a> <a href="/linkedin">LinkedIn</a> </div> </div> </Header> ``` #### Using Both Slots Together ```astro --- import Header from '@sofidevo/astro-dynamic-header/Header'; const menuItems = [ { link: '/about', text: 'About' }, { link: '/services', text: 'Services' }, { link: '/contact', text: 'Contact' }, ]; --- <Header headerType="fullscreen" logoSrc="/logo.png" logoAlt="My Company" logoWidth="150px" homeUrl="/" menuItems={menuItems} backgroundColor="#000000dd" backdropBlur="blur(15px)" zIndex={100} > <!-- Content for desktop header --> <button slot="slot-desktop" class="cta-button"> Sign Up </button> <!-- Content for mobile panel --> <div slot="slot-panel" class="mobile-extras"> <button class="mobile-cta">Download App</button> <div class="mobile-contact"> <p>Call us: +1 (555) 123-4567</p> <p>Email: info@company.com</p> </div> </div> </Header> ``` #### Responsive Slot Behavior The `slot-desktop` is visible on both desktop and mobile by default. If you want to hide it on mobile, use CSS: ```css /* Hide desktop slot on mobile devices */ @media (width < 768px) { .cta-button { display: none; } } /* Or create responsive variants */ .desktop-only { display: block; } @media (width < 768px) { .desktop-only { display: none; } } ``` ```astro <Header menuItems={menuItems}> <button slot="slot-desktop" class="cta-button desktop-only"> Desktop CTA </button> <div slot="slot-panel"> <button class="mobile-cta">Mobile CTA</button> </div> </Header> ``` ## Header Types ### Floating Header - Centered with max-width constraint - Rounded corners - Padding around container - Perfect for modern, card-like designs ### Fullscreen Header - Full viewport width - No border radius - Edge-to-edge design - Ideal for traditional website layouts ## Styling and Customization The component uses CSS custom properties that you can override: ```css :root { --light-spot-color: #00ffff; --color-tertiary: #ffffff; --color-hamburger-lines: #ffffff; } ``` ## TypeScript Support Full TypeScript support with exported interfaces: ```typescript import type { MenuItemType, HeaderProps, NavMenuProps, MobileNavProps, HamburgerButtonProps } from '@sofidevo/astro-dynamic-header'; ``` ## Browser Support - All modern browsers - Mobile responsive design - Supports CSS `backdrop-filter` - Graceful degradation for older browsers ## Troubleshooting ### Import Issues If you encounter import errors, try these solutions: 1. **Use direct subpath import:** ```astro import Header from '@sofidevo/astro-dynamic-header/Header'; ``` 2. **Verify TypeScript configuration:** ```json // tsconfig.json { "compilerOptions": { "moduleResolution": "bundler", // or "nodenext" "allowImportingTsExtensions": true } } ``` 3. **Import types separately:** ```astro --- import Header from '@sofidevo/astro-dynamic-header/Header'; import type { MenuItemType } from '@sofidevo/astro-dynamic-header'; --- ``` ### Compatibility - Astro 4.x and 5.x - SSG Projects (Static Site Generation) - SSR Projects (Server-Side Rendering) - Hybrid Projects (output: 'hybrid') ## Live Examples Visit our demo website to see the component in action with interactive examples and complete documentation. ## Testing This project includes a comprehensive test suite with 34 tests covering all critical functionality. ### Running Tests ```bash # Run all tests npm test # Run tests in watch mode npm run test:watch # Run tests with coverage report npm run test:coverage ``` ### Test Coverage The test suite covers: #### Component Logic Tests - **Header Component** (4 tests): Hamburger controller functionality, menu toggle behavior - **HamburgerButton Component** (10 tests): Button states, responsive behavior, accessibility - **MobileNav Component** (7 tests): Dropdown structure, nested submenus, conditional rendering - **NavMenu Component** (6 tests): Dynamic positioning, submenu interactions, viewport adjustments #### Integration Tests (7 tests) - Component interaction flows - Responsive behavior between mobile/desktop - Keyboard navigation and accessibility - Menu state management during navigation ### Test Technologies - **Vitest**: Fast testing framework - **jsdom**: DOM simulation for component testing - **TypeScript**: Type-safe test writing ## License MIT License - see the [LICENSE](./LICENSE) file for details. ## Support If you find this package helpful, please consider giving it a on GitHub!