@sofidevo/astro-dynamic-header 1.0.26 → 1.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -163
- package/package.json +5 -11
- package/src/Header.astro +4 -5
- package/src/MobileNav.astro +1 -2
- package/src/NavMenu.astro +8 -7
package/README.md
CHANGED
|
@@ -7,8 +7,7 @@ A dynamic, responsive header component for Astro projects that can switch betwee
|
|
|
7
7
|
- 🎨 **Dynamic Styles**: Switch between floating and fullscreen header layouts
|
|
8
8
|
- 📱 **Fully Responsive**: Mobile-first design with hamburger menu
|
|
9
9
|
- 🎯 **Multi-level Dropdowns**: Support for nested navigation menus
|
|
10
|
-
-
|
|
11
|
-
- �🚀 **TypeScript Support**: Full type safety and IntelliSense
|
|
10
|
+
- 🚀 **TypeScript Support**: Full type safety and IntelliSense
|
|
12
11
|
- 🎨 **Customizable**: Extensive customization options for colors, sizes, and behavior
|
|
13
12
|
- ⚡ **Astro Optimized**: Built specifically for Astro framework
|
|
14
13
|
|
|
@@ -133,131 +132,6 @@ interface MenuItemType {
|
|
|
133
132
|
}
|
|
134
133
|
```
|
|
135
134
|
|
|
136
|
-
## Slots Support
|
|
137
|
-
|
|
138
|
-
The Header component provides two customizable slots that allow you to add additional content:
|
|
139
|
-
|
|
140
|
-
### Available Slots
|
|
141
|
-
|
|
142
|
-
| Slot Name | Location | Visibility | Description |
|
|
143
|
-
|-----------|----------|------------|-------------|
|
|
144
|
-
| `slot-desktop` | Header (desktop & mobile) | Always visible | Add content to the main header area |
|
|
145
|
-
| `slot-panel` | Mobile navigation panel | Mobile only | Add content to the mobile menu panel |
|
|
146
|
-
|
|
147
|
-
### Slot Examples
|
|
148
|
-
|
|
149
|
-
#### Using Individual Slots
|
|
150
|
-
|
|
151
|
-
```astro
|
|
152
|
-
---
|
|
153
|
-
import Header from '@sofidevo/astro-dynamic-header/Header';
|
|
154
|
-
|
|
155
|
-
const menuItems = [
|
|
156
|
-
{ link: '/about', text: 'About' },
|
|
157
|
-
{ link: '/contact', text: 'Contact' },
|
|
158
|
-
];
|
|
159
|
-
---
|
|
160
|
-
|
|
161
|
-
<!-- Adding content only to desktop header -->
|
|
162
|
-
<Header
|
|
163
|
-
headerType="floating"
|
|
164
|
-
logoSrc="/logo.png"
|
|
165
|
-
menuItems={menuItems}
|
|
166
|
-
>
|
|
167
|
-
<button slot="slot-desktop" class="cta-button">Get Started</button>
|
|
168
|
-
</Header>
|
|
169
|
-
|
|
170
|
-
<!-- Adding content only to mobile panel -->
|
|
171
|
-
<Header
|
|
172
|
-
headerType="fullscreen"
|
|
173
|
-
logoSrc="/logo.png"
|
|
174
|
-
menuItems={menuItems}
|
|
175
|
-
>
|
|
176
|
-
<div slot="slot-panel" class="mobile-footer">
|
|
177
|
-
<p>© 2024 My Company</p>
|
|
178
|
-
<div class="social-links">
|
|
179
|
-
<a href="/twitter">Twitter</a>
|
|
180
|
-
<a href="/linkedin">LinkedIn</a>
|
|
181
|
-
</div>
|
|
182
|
-
</div>
|
|
183
|
-
</Header>
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
#### Using Both Slots Together
|
|
187
|
-
|
|
188
|
-
```astro
|
|
189
|
-
---
|
|
190
|
-
import Header from '@sofidevo/astro-dynamic-header/Header';
|
|
191
|
-
|
|
192
|
-
const menuItems = [
|
|
193
|
-
{ link: '/about', text: 'About' },
|
|
194
|
-
{ link: '/services', text: 'Services' },
|
|
195
|
-
{ link: '/contact', text: 'Contact' },
|
|
196
|
-
];
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
<Header
|
|
200
|
-
headerType="fullscreen"
|
|
201
|
-
logoSrc="/logo.png"
|
|
202
|
-
logoAlt="My Company"
|
|
203
|
-
logoWidth="150px"
|
|
204
|
-
homeUrl="/"
|
|
205
|
-
menuItems={menuItems}
|
|
206
|
-
backgroundColor="#000000dd"
|
|
207
|
-
backdropBlur="blur(15px)"
|
|
208
|
-
zIndex={100}
|
|
209
|
-
>
|
|
210
|
-
<!-- Content for desktop header -->
|
|
211
|
-
<button slot="slot-desktop" class="cta-button">
|
|
212
|
-
Sign Up
|
|
213
|
-
</button>
|
|
214
|
-
|
|
215
|
-
<!-- Content for mobile panel -->
|
|
216
|
-
<div slot="slot-panel" class="mobile-extras">
|
|
217
|
-
<button class="mobile-cta">Download App</button>
|
|
218
|
-
<div class="mobile-contact">
|
|
219
|
-
<p>Call us: +1 (555) 123-4567</p>
|
|
220
|
-
<p>Email: info@company.com</p>
|
|
221
|
-
</div>
|
|
222
|
-
</div>
|
|
223
|
-
</Header>
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
#### Responsive Slot Behavior
|
|
227
|
-
|
|
228
|
-
The `slot-desktop` is visible on both desktop and mobile by default. If you want to hide it on mobile, use CSS:
|
|
229
|
-
|
|
230
|
-
```css
|
|
231
|
-
/* Hide desktop slot on mobile devices */
|
|
232
|
-
@media (width < 768px) {
|
|
233
|
-
.cta-button {
|
|
234
|
-
display: none;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/* Or create responsive variants */
|
|
239
|
-
.desktop-only {
|
|
240
|
-
display: block;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
@media (width < 768px) {
|
|
244
|
-
.desktop-only {
|
|
245
|
-
display: none;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
```astro
|
|
251
|
-
<Header menuItems={menuItems}>
|
|
252
|
-
<button slot="slot-desktop" class="cta-button desktop-only">
|
|
253
|
-
Desktop CTA
|
|
254
|
-
</button>
|
|
255
|
-
<div slot="slot-panel">
|
|
256
|
-
<button class="mobile-cta">Mobile CTA</button>
|
|
257
|
-
</div>
|
|
258
|
-
</Header>
|
|
259
|
-
```
|
|
260
|
-
|
|
261
135
|
## Header Types
|
|
262
136
|
|
|
263
137
|
### Floating Header
|
|
@@ -272,6 +146,27 @@ The `slot-desktop` is visible on both desktop and mobile by default. If you want
|
|
|
272
146
|
- Edge-to-edge design
|
|
273
147
|
- Ideal for traditional website layouts
|
|
274
148
|
|
|
149
|
+
## Individual Components
|
|
150
|
+
|
|
151
|
+
You can also import and use components individually:
|
|
152
|
+
|
|
153
|
+
```astro
|
|
154
|
+
---
|
|
155
|
+
// Import individual components
|
|
156
|
+
import NavMenu from '@sofidevo/astro-dynamic-header/NavMenu';
|
|
157
|
+
import MobileNav from '@sofidevo/astro-dynamic-header/MobileNav';
|
|
158
|
+
import HamburgerButton from '@sofidevo/astro-dynamic-header/HamburgerButton';
|
|
159
|
+
|
|
160
|
+
// Or use the .astro extension explicitly
|
|
161
|
+
import NavMenu from '@sofidevo/astro-dynamic-header/NavMenu.astro';
|
|
162
|
+
import MobileNav from '@sofidevo/astro-dynamic-header/MobileNav.astro';
|
|
163
|
+
import HamburgerButton from '@sofidevo/astro-dynamic-header/HamburgerButton.astro';
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
<NavMenu menuItems={menuItems} showHomeLink={true} homeText="Home" />
|
|
167
|
+
<MobileNav menuItems={menuItems} accentColor="#00ffff" />
|
|
168
|
+
<HamburgerButton color="#ffffff" />
|
|
169
|
+
```
|
|
275
170
|
|
|
276
171
|
## Styling and Customization
|
|
277
172
|
|
|
@@ -347,43 +242,9 @@ If you encounter import errors, try these solutions:
|
|
|
347
242
|
|
|
348
243
|
Visit our demo website to see the component in action with interactive examples and complete documentation.
|
|
349
244
|
|
|
350
|
-
##
|
|
351
|
-
|
|
352
|
-
This project includes a comprehensive test suite with 34 tests covering all critical functionality.
|
|
353
|
-
|
|
354
|
-
### Running Tests
|
|
355
|
-
|
|
356
|
-
```bash
|
|
357
|
-
# Run all tests
|
|
358
|
-
npm test
|
|
359
|
-
|
|
360
|
-
# Run tests in watch mode
|
|
361
|
-
npm run test:watch
|
|
362
|
-
|
|
363
|
-
# Run tests with coverage report
|
|
364
|
-
npm run test:coverage
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
### Test Coverage
|
|
368
|
-
|
|
369
|
-
The test suite covers:
|
|
370
|
-
|
|
371
|
-
#### Component Logic Tests
|
|
372
|
-
- **Header Component** (4 tests): Hamburger controller functionality, menu toggle behavior
|
|
373
|
-
- **HamburgerButton Component** (10 tests): Button states, responsive behavior, accessibility
|
|
374
|
-
- **MobileNav Component** (7 tests): Dropdown structure, nested submenus, conditional rendering
|
|
375
|
-
- **NavMenu Component** (6 tests): Dynamic positioning, submenu interactions, viewport adjustments
|
|
376
|
-
|
|
377
|
-
#### Integration Tests (7 tests)
|
|
378
|
-
- Component interaction flows
|
|
379
|
-
- Responsive behavior between mobile/desktop
|
|
380
|
-
- Keyboard navigation and accessibility
|
|
381
|
-
- Menu state management during navigation
|
|
245
|
+
## Contributing
|
|
382
246
|
|
|
383
|
-
|
|
384
|
-
- **Vitest**: Fast testing framework
|
|
385
|
-
- **jsdom**: DOM simulation for component testing
|
|
386
|
-
- **TypeScript**: Type-safe test writing
|
|
247
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
387
248
|
|
|
388
249
|
## License
|
|
389
250
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sofidevo/astro-dynamic-header",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.27",
|
|
4
4
|
"description": "A dynamic Astro header component that switches between floating and fullscreen styles",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -27,10 +27,7 @@
|
|
|
27
27
|
"build": "astro build",
|
|
28
28
|
"dev": "astro dev",
|
|
29
29
|
"check": "astro check",
|
|
30
|
-
"check:watch": "astro check --watch"
|
|
31
|
-
"test": "vitest run",
|
|
32
|
-
"test:watch": "vitest",
|
|
33
|
-
"test:coverage": "vitest run --coverage"
|
|
30
|
+
"check:watch": "astro check --watch"
|
|
34
31
|
},
|
|
35
32
|
"keywords": [
|
|
36
33
|
"astro",
|
|
@@ -53,12 +50,8 @@
|
|
|
53
50
|
},
|
|
54
51
|
"devDependencies": {
|
|
55
52
|
"@astrojs/check": "^0.9.0",
|
|
56
|
-
"@types/jsdom": "^21.1.7",
|
|
57
|
-
"@vitest/coverage-v8": "^3.2.4",
|
|
58
53
|
"astro": "^5.12.8",
|
|
59
|
-
"
|
|
60
|
-
"typescript": "^5.0.0",
|
|
61
|
-
"vitest": "^3.2.4"
|
|
54
|
+
"typescript": "^5.0.0"
|
|
62
55
|
},
|
|
63
56
|
"repository": {
|
|
64
57
|
"type": "git",
|
|
@@ -67,5 +60,6 @@
|
|
|
67
60
|
"bugs": {
|
|
68
61
|
"url": "https://github.com/SofiDevO/astro-dynamic-header/issues"
|
|
69
62
|
},
|
|
70
|
-
"homepage": "https://
|
|
63
|
+
"homepage": "https://github.com/SofiDevO/astro-dynamic-header#readme",
|
|
64
|
+
"demo": "https://base-astro-psi.vercel.app/fullscreen-demo"
|
|
71
65
|
}
|
package/src/Header.astro
CHANGED
|
@@ -88,11 +88,10 @@ const {
|
|
|
88
88
|
<img class="header__logo" src={logoSrc} alt={logoAlt} style={`width: ${logoWidth};`} />
|
|
89
89
|
</a>
|
|
90
90
|
<NavMenu menuItems={menuItems} />
|
|
91
|
-
<slot
|
|
91
|
+
<slot/>
|
|
92
92
|
<HamburgerButton />
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
</MobileNav>
|
|
93
|
+
|
|
94
|
+
<MobileNav menuItems={menuItems} type={headerType} />
|
|
96
95
|
|
|
97
96
|
</header>
|
|
98
97
|
</div>
|
|
@@ -115,7 +114,7 @@ const {
|
|
|
115
114
|
|
|
116
115
|
/* Floating header container styles */
|
|
117
116
|
.header__container--floating {
|
|
118
|
-
padding:
|
|
117
|
+
padding: 16px;
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
/* Fullscreen header container styles */
|
package/src/MobileNav.astro
CHANGED
|
@@ -110,7 +110,6 @@ const pagePathname = Astro.url.pathname;
|
|
|
110
110
|
))
|
|
111
111
|
}
|
|
112
112
|
</ol>
|
|
113
|
-
<slot name="slot-panel" />
|
|
114
113
|
</nav>
|
|
115
114
|
|
|
116
115
|
<style>
|
|
@@ -123,7 +122,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
123
122
|
width: 104vw;
|
|
124
123
|
height: 100dvh;
|
|
125
124
|
position: fixed;
|
|
126
|
-
|
|
125
|
+
top: -16px;
|
|
127
126
|
left: 0;
|
|
128
127
|
background: #151515;
|
|
129
128
|
z-index: 20;
|
package/src/NavMenu.astro
CHANGED
|
@@ -63,7 +63,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
63
63
|
const rect = subsubmenu.getBoundingClientRect();
|
|
64
64
|
|
|
65
65
|
if (rect.right > viewportWidth) {
|
|
66
|
-
(subsubmenu as HTMLElement).style.left = "-
|
|
66
|
+
(subsubmenu as HTMLElement).style.left = "-200%";
|
|
67
67
|
(subsubmenu as HTMLElement).style.right = "auto";
|
|
68
68
|
const leftRect = subsubmenu.getBoundingClientRect();
|
|
69
69
|
|
|
@@ -190,6 +190,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
.menu {
|
|
193
|
+
padding: 1rem;
|
|
193
194
|
list-style: none;
|
|
194
195
|
display: flex;
|
|
195
196
|
align-items: center;
|
|
@@ -202,7 +203,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
202
203
|
|
|
203
204
|
.menu__link {
|
|
204
205
|
text-decoration: none;
|
|
205
|
-
padding: 0.5rem ;
|
|
206
|
+
padding: 0.5rem 1rem;
|
|
206
207
|
display: flex;
|
|
207
208
|
align-items: center;
|
|
208
209
|
gap: 0.8rem;
|
|
@@ -213,7 +214,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
213
214
|
@media screen and (min-width: 768px) {
|
|
214
215
|
.menu__link::after {
|
|
215
216
|
position: absolute;
|
|
216
|
-
top:
|
|
217
|
+
top: 25px;
|
|
217
218
|
left: 0;
|
|
218
219
|
content: "";
|
|
219
220
|
width: 100%;
|
|
@@ -264,7 +265,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
264
265
|
justify-content: space-between;
|
|
265
266
|
align-items: center;
|
|
266
267
|
width: 100%;
|
|
267
|
-
height:
|
|
268
|
+
height: 4rem;
|
|
268
269
|
border-radius: 0.4rem;
|
|
269
270
|
color: #fff;
|
|
270
271
|
color: var(--color-tertiary, #fff);
|
|
@@ -277,7 +278,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
277
278
|
|
|
278
279
|
.submenu__item--secondary a,
|
|
279
280
|
.submenu__item--tertiary a {
|
|
280
|
-
padding:
|
|
281
|
+
padding: 2rem;
|
|
281
282
|
}
|
|
282
283
|
|
|
283
284
|
.submenu__item--secondary a:hover,
|
|
@@ -287,7 +288,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
287
288
|
}
|
|
288
289
|
|
|
289
290
|
.submenu {
|
|
290
|
-
padding:
|
|
291
|
+
padding: 1rem;
|
|
291
292
|
right: -23px;
|
|
292
293
|
}
|
|
293
294
|
|
|
@@ -336,7 +337,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
336
337
|
.menu__item:hover > .submenu {
|
|
337
338
|
opacity: 1;
|
|
338
339
|
pointer-events: all;
|
|
339
|
-
transform: translateY(
|
|
340
|
+
transform: translateY(2.5rem);
|
|
340
341
|
}
|
|
341
342
|
|
|
342
343
|
.menu__item:hover > .submenu::after {
|