@sofidevo/astro-dynamic-header 1.0.31 → 1.0.32
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 +71 -74
- package/package.json +2 -2
- package/src/Header.astro +47 -11
- package/src/NavMenu.astro +19 -19
package/README.md
CHANGED
|
@@ -4,13 +4,13 @@ A dynamic, responsive header component for Astro projects that can switch betwee
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
7
|
+
- **Dynamic Styles**: Switch between floating and fullscreen header layouts
|
|
8
|
+
- **Fully Responsive**: Mobile-first design with hamburger menu
|
|
9
|
+
- **Multi-level Dropdowns**: Support for nested navigation menus
|
|
10
|
+
- **Slot Support**: Customizable slots for desktop header and mobile panel content
|
|
11
|
+
- **TypeScript Support**: Full type safety and IntelliSense
|
|
12
|
+
- **Customizable**: Extensive customization options for colors, sizes, and behavior
|
|
13
|
+
- **Astro Optimized**: Built specifically for Astro framework
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
### Live demo
|
|
@@ -126,7 +126,10 @@ const menuItems = [
|
|
|
126
126
|
| `headerType` | `"floating" \| "fullscreen"` | `"floating"` | Header layout style |
|
|
127
127
|
| `logoSrc` | `string` | `"/logo.png"` | Logo image source |
|
|
128
128
|
| `logoAlt` | `string` | `"Logo"` | Logo alt text |
|
|
129
|
-
| `logoWidth` | `string` | `"
|
|
129
|
+
| `logoWidth` | `string` | `"55px"` | Logo width |
|
|
130
|
+
| `logoText` | `string` | `"Your logo text"` | Text displayed next to the logo |
|
|
131
|
+
| `logoTextSize` | `string` | `"1em"` | Font size for logo text |
|
|
132
|
+
| `logoTextColor` | `string` | `"#ffffff"` | Color for logo text |
|
|
130
133
|
| `homeUrl` | `string` | `"/"` | Home page URL |
|
|
131
134
|
| `menuItems` | `MenuItemType[]` | `[]` | Navigation menu items |
|
|
132
135
|
| `backgroundColor` | `string` | `"#0d0d0dcc"` | Header background color |
|
|
@@ -145,18 +148,24 @@ interface MenuItemType {
|
|
|
145
148
|
|
|
146
149
|
## Slots Support
|
|
147
150
|
|
|
148
|
-
The Header component provides
|
|
151
|
+
The Header component provides a flexible slot system that allows you to add additional content:
|
|
149
152
|
|
|
150
153
|
### Available Slots
|
|
151
154
|
|
|
152
155
|
| Slot Name | Location | Visibility | Description |
|
|
153
|
-
|
|
154
|
-
| `
|
|
155
|
-
|
|
156
|
+
|-----------|----------|------------|-----------|
|
|
157
|
+
| `actions` | Header & Mobile panel | Responsive visibility | Add action buttons (login, signup, etc.) that appear in both desktop and mobile |
|
|
158
|
+
|
|
159
|
+
### Actions Slot Behavior
|
|
160
|
+
|
|
161
|
+
The `actions` slot is intelligent and automatically manages visibility:
|
|
162
|
+
- **Desktop (≥768px)**: Shows actions in the main header after navigation
|
|
163
|
+
- **Mobile (<768px)**: Shows same actions inside the mobile menu panel
|
|
164
|
+
- **Automatic hiding**: Desktop version is hidden on mobile, mobile version is hidden on desktop
|
|
156
165
|
|
|
157
166
|
### Slot Examples
|
|
158
167
|
|
|
159
|
-
#### Using
|
|
168
|
+
#### Using the Actions Slot
|
|
160
169
|
|
|
161
170
|
```astro
|
|
162
171
|
---
|
|
@@ -168,32 +177,20 @@ const menuItems = [
|
|
|
168
177
|
];
|
|
169
178
|
---
|
|
170
179
|
|
|
171
|
-
<!-- Adding content only to desktop header -->
|
|
172
180
|
<Header
|
|
173
181
|
headerType="floating"
|
|
174
182
|
logoSrc="/logo.png"
|
|
183
|
+
logoText="My Company"
|
|
175
184
|
menuItems={menuItems}
|
|
176
185
|
>
|
|
177
|
-
<
|
|
178
|
-
</
|
|
179
|
-
|
|
180
|
-
<!-- Adding content only to mobile panel -->
|
|
181
|
-
<Header
|
|
182
|
-
headerType="fullscreen"
|
|
183
|
-
logoSrc="/logo.png"
|
|
184
|
-
menuItems={menuItems}
|
|
185
|
-
>
|
|
186
|
-
<div slot="slot-panel" class="mobile-footer">
|
|
187
|
-
<p>© 2024 My Company</p>
|
|
188
|
-
<div class="social-links">
|
|
189
|
-
<a href="/twitter">Twitter</a>
|
|
190
|
-
<a href="/linkedin">LinkedIn</a>
|
|
191
|
-
</div>
|
|
186
|
+
<div slot="actions">
|
|
187
|
+
<button class="login-btn">Login</button>
|
|
188
|
+
<button class="signup-btn">Sign Up</button>
|
|
192
189
|
</div>
|
|
193
190
|
</Header>
|
|
194
191
|
```
|
|
195
192
|
|
|
196
|
-
####
|
|
193
|
+
#### Complete Example with All Props
|
|
197
194
|
|
|
198
195
|
```astro
|
|
199
196
|
---
|
|
@@ -210,64 +207,64 @@ const menuItems = [
|
|
|
210
207
|
headerType="fullscreen"
|
|
211
208
|
logoSrc="/logo.png"
|
|
212
209
|
logoAlt="My Company"
|
|
213
|
-
logoWidth="
|
|
210
|
+
logoWidth="60px"
|
|
211
|
+
logoText="My Company"
|
|
212
|
+
logoTextSize="1.2em"
|
|
213
|
+
logoTextColor="#ffffff"
|
|
214
214
|
homeUrl="/"
|
|
215
215
|
menuItems={menuItems}
|
|
216
216
|
backgroundColor="#000000dd"
|
|
217
217
|
backdropBlur="blur(15px)"
|
|
218
218
|
zIndex={100}
|
|
219
219
|
>
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
</button>
|
|
224
|
-
|
|
225
|
-
<!-- Content for mobile panel -->
|
|
226
|
-
<div slot="slot-panel" class="mobile-extras">
|
|
227
|
-
<button class="mobile-cta">Download App</button>
|
|
228
|
-
<div class="mobile-contact">
|
|
229
|
-
<p>Call us: +1 (555) 123-4567</p>
|
|
230
|
-
<p>Email: info@company.com</p>
|
|
231
|
-
</div>
|
|
220
|
+
<div slot="actions" class="header-actions">
|
|
221
|
+
<button class="btn btn-outline">Login</button>
|
|
222
|
+
<button class="btn btn-primary">Get Started</button>
|
|
232
223
|
</div>
|
|
233
224
|
</Header>
|
|
234
225
|
```
|
|
235
226
|
|
|
236
|
-
####
|
|
237
|
-
|
|
238
|
-
The `slot-desktop` is visible on both desktop and mobile by default. If you want to hide it on mobile, use CSS:
|
|
227
|
+
#### Styling Action Buttons
|
|
239
228
|
|
|
240
229
|
```css
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
.
|
|
244
|
-
|
|
245
|
-
}
|
|
230
|
+
.header-actions {
|
|
231
|
+
display: flex;
|
|
232
|
+
gap: 0.5em;
|
|
233
|
+
align-items: center;
|
|
246
234
|
}
|
|
247
235
|
|
|
248
|
-
|
|
249
|
-
.
|
|
250
|
-
|
|
236
|
+
.btn {
|
|
237
|
+
padding: 0.5em 1em;
|
|
238
|
+
border: none;
|
|
239
|
+
border-radius: 6px;
|
|
240
|
+
cursor: pointer;
|
|
241
|
+
font-weight: 500;
|
|
242
|
+
text-decoration: none;
|
|
243
|
+
display: inline-flex;
|
|
244
|
+
align-items: center;
|
|
245
|
+
transition: all 0.2s ease;
|
|
251
246
|
}
|
|
252
247
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
248
|
+
.btn-outline {
|
|
249
|
+
background: transparent;
|
|
250
|
+
color: #ffffff;
|
|
251
|
+
border: 1px solid #ffffff;
|
|
257
252
|
}
|
|
258
|
-
```
|
|
259
253
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
```
|
|
254
|
+
.btn-outline:hover {
|
|
255
|
+
background: #ffffff;
|
|
256
|
+
color: #000000;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.btn-primary {
|
|
260
|
+
background: #00ffff;
|
|
261
|
+
color: #000000;
|
|
262
|
+
}
|
|
270
263
|
|
|
264
|
+
.btn-primary:hover {
|
|
265
|
+
background: #00cccc;
|
|
266
|
+
}
|
|
267
|
+
```
|
|
271
268
|
## Header Types
|
|
272
269
|
|
|
273
270
|
### Floating Header
|
|
@@ -348,10 +345,10 @@ If you encounter import errors, try these solutions:
|
|
|
348
345
|
|
|
349
346
|
### Compatibility
|
|
350
347
|
|
|
351
|
-
-
|
|
352
|
-
-
|
|
353
|
-
-
|
|
354
|
-
-
|
|
348
|
+
- Astro 4.x and 5.x
|
|
349
|
+
- SSG Projects (Static Site Generation)
|
|
350
|
+
- SSR Projects (Server-Side Rendering)
|
|
351
|
+
- Hybrid Projects (output: 'hybrid')
|
|
355
352
|
|
|
356
353
|
## Live Examples
|
|
357
354
|
|
|
@@ -401,4 +398,4 @@ MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
|
401
398
|
|
|
402
399
|
## Support
|
|
403
400
|
|
|
404
|
-
If you find this package helpful, please consider giving it a
|
|
401
|
+
If you find this package helpful, please consider giving it a star on GitHub!
|
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.32",
|
|
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",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
},
|
|
64
64
|
"repository": {
|
|
65
65
|
"type": "git",
|
|
66
|
-
"url": "
|
|
66
|
+
"url": "https://github.com/SofiDevO/astro-dynamic-header"
|
|
67
67
|
},
|
|
68
68
|
"bugs": {
|
|
69
69
|
"url": "https://github.com/SofiDevO/astro-dynamic-header/issues"
|
package/src/Header.astro
CHANGED
|
@@ -5,9 +5,14 @@ import MobileNav from "./MobileNav.astro";
|
|
|
5
5
|
|
|
6
6
|
export interface Props {
|
|
7
7
|
headerType?: "floating" | "fullscreen";
|
|
8
|
+
// properties for logo
|
|
8
9
|
logoSrc?: string;
|
|
9
10
|
logoAlt?: string;
|
|
10
11
|
logoWidth?: string;
|
|
12
|
+
logoText?: string;
|
|
13
|
+
logoTextSize?: string;
|
|
14
|
+
logoTextColor?: string;
|
|
15
|
+
// properties for navigation
|
|
11
16
|
homeUrl?: string;
|
|
12
17
|
menuItems?: Array<{
|
|
13
18
|
link: string;
|
|
@@ -21,6 +26,7 @@ export interface Props {
|
|
|
21
26
|
}>;
|
|
22
27
|
}>;
|
|
23
28
|
}>;
|
|
29
|
+
// styles
|
|
24
30
|
backgroundColor?: string;
|
|
25
31
|
backdropBlur?: string;
|
|
26
32
|
zIndex?: number;
|
|
@@ -31,6 +37,9 @@ const {
|
|
|
31
37
|
logoSrc = "/logo.png",
|
|
32
38
|
logoAlt = "Logo",
|
|
33
39
|
logoWidth = "55px",
|
|
40
|
+
logoText = "Your logo text",
|
|
41
|
+
logoTextSize = "1em",
|
|
42
|
+
logoTextColor = "#ffffff",
|
|
34
43
|
homeUrl = "/",
|
|
35
44
|
menuItems = [],
|
|
36
45
|
backgroundColor = "#0d0d0dcc",
|
|
@@ -84,20 +93,25 @@ const {
|
|
|
84
93
|
|
|
85
94
|
<div class={`header__container header__container--${headerType}`} style={`z-index: ${zIndex};`}>
|
|
86
95
|
<header class={`header header--${headerType}`} style={`background-color: ${backgroundColor}; backdrop-filter: ${backdropBlur}; -webkit-backdrop-filter: ${backdropBlur};`}>
|
|
87
|
-
<a href={homeUrl}>
|
|
96
|
+
<a class="logo__container" href={homeUrl}>
|
|
88
97
|
<img class="header__logo" src={logoSrc} alt={logoAlt} style={`width: ${logoWidth};`} />
|
|
98
|
+
{logoText && <span class="header__logo-text" style={`color: ${logoTextColor}; font-size: ${logoTextSize};`}>{logoText}</span>}
|
|
89
99
|
</a>
|
|
90
100
|
<NavMenu menuItems={menuItems} />
|
|
91
|
-
<
|
|
101
|
+
<div class="actions-desktop">
|
|
102
|
+
<slot name="actions" />
|
|
103
|
+
</div>
|
|
92
104
|
<HamburgerButton />
|
|
93
105
|
<MobileNav menuItems={menuItems} type={headerType}>
|
|
94
|
-
<
|
|
106
|
+
<div class="actions-mobile" slot="slot-panel">
|
|
107
|
+
<slot name="actions" />
|
|
108
|
+
</div>
|
|
95
109
|
</MobileNav>
|
|
96
110
|
|
|
97
111
|
</header>
|
|
98
112
|
</div>
|
|
99
113
|
|
|
100
|
-
<style is:inline>
|
|
114
|
+
<style is:inline >
|
|
101
115
|
/* Base styles for header container */
|
|
102
116
|
.header__container {
|
|
103
117
|
width: 100%;
|
|
@@ -115,7 +129,7 @@ const {
|
|
|
115
129
|
|
|
116
130
|
/* Floating header container styles */
|
|
117
131
|
.header__container--floating {
|
|
118
|
-
padding: .
|
|
132
|
+
padding: .5em;
|
|
119
133
|
}
|
|
120
134
|
|
|
121
135
|
/* Fullscreen header container styles */
|
|
@@ -129,11 +143,11 @@ const {
|
|
|
129
143
|
align-items: center;
|
|
130
144
|
width: 100%;
|
|
131
145
|
justify-content: space-between;
|
|
132
|
-
padding:
|
|
146
|
+
padding: 1em 2em;
|
|
133
147
|
|
|
134
148
|
@media (width < 768px) {
|
|
135
149
|
align-self: flex-end;
|
|
136
|
-
padding: 0.
|
|
150
|
+
padding: 0.4em;
|
|
137
151
|
margin: 0 auto;
|
|
138
152
|
}
|
|
139
153
|
}
|
|
@@ -142,7 +156,7 @@ const {
|
|
|
142
156
|
.header--floating {
|
|
143
157
|
max-width: 1100px;
|
|
144
158
|
border-radius: 20px;
|
|
145
|
-
padding: .
|
|
159
|
+
padding: .7em 1em;
|
|
146
160
|
|
|
147
161
|
@media (width < 768px) {
|
|
148
162
|
max-width: 95%;
|
|
@@ -152,19 +166,41 @@ const {
|
|
|
152
166
|
/* Fullscreen header styles */
|
|
153
167
|
.header--fullscreen {
|
|
154
168
|
border-radius: 0;
|
|
155
|
-
padding:
|
|
169
|
+
padding: 1em 2em;
|
|
156
170
|
|
|
157
171
|
@media (width < 768px) {
|
|
158
172
|
max-width: 100%;
|
|
159
|
-
padding: 0.
|
|
173
|
+
padding: 0.8em 1em;
|
|
160
174
|
}
|
|
161
175
|
}
|
|
162
176
|
|
|
177
|
+
.logo__container {
|
|
178
|
+
display: flex;
|
|
179
|
+
align-items: center;
|
|
180
|
+
text-decoration: none;
|
|
181
|
+
& span{
|
|
182
|
+
font-weight: 600;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
163
185
|
.header__logo {
|
|
164
|
-
margin-right:
|
|
186
|
+
margin-right: 1em;
|
|
165
187
|
object-fit: contain;
|
|
166
188
|
}
|
|
167
189
|
|
|
190
|
+
/* Actions visibility control */
|
|
191
|
+
.actions-desktop {
|
|
192
|
+
@media (width < 768px) {
|
|
193
|
+
display: none;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.actions-mobile {
|
|
198
|
+
margin-top: 20px;
|
|
199
|
+
@media (width >= 768px) {
|
|
200
|
+
display: none;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
168
204
|
/* Adjust transform for fullscreen header */
|
|
169
205
|
.header--fullscreen .mobile-header__menu.is-active {
|
|
170
206
|
transform: translate(0%);
|
package/src/NavMenu.astro
CHANGED
|
@@ -86,7 +86,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
86
86
|
|
|
87
87
|
const isPositionedLeft =
|
|
88
88
|
(subsubmenu as HTMLElement).style.left === "-100%";
|
|
89
|
-
const transformDirection = isPositionedLeft ? "-
|
|
89
|
+
const transformDirection = isPositionedLeft ? "-32px" : "32px";
|
|
90
90
|
|
|
91
91
|
const currentTransform = (subsubmenu as HTMLElement).style.transform;
|
|
92
92
|
if (currentTransform && currentTransform.includes("translateX")) {
|
|
@@ -202,10 +202,10 @@ const pagePathname = Astro.url.pathname;
|
|
|
202
202
|
|
|
203
203
|
.menu__link {
|
|
204
204
|
text-decoration: none;
|
|
205
|
-
padding: 0.
|
|
205
|
+
padding: 0.5em ;
|
|
206
206
|
display: flex;
|
|
207
207
|
align-items: center;
|
|
208
|
-
gap: 0.
|
|
208
|
+
gap: 0.8em;
|
|
209
209
|
color: color-mix(in srgb, var(--light-spot-color, #00ffff) 30%, white 70%);
|
|
210
210
|
position: relative;
|
|
211
211
|
}
|
|
@@ -244,9 +244,9 @@ const pagePathname = Astro.url.pathname;
|
|
|
244
244
|
border: 0.5px solid #3e1c71;
|
|
245
245
|
position: absolute;
|
|
246
246
|
flex-direction: column;
|
|
247
|
-
gap: 0.
|
|
248
|
-
padding:
|
|
249
|
-
border-radius:
|
|
247
|
+
gap: 0.4em;
|
|
248
|
+
padding: 1em;
|
|
249
|
+
border-radius: 10px;
|
|
250
250
|
transition: transform 0.3s ease-in-out;
|
|
251
251
|
pointer-events: none;
|
|
252
252
|
opacity: 0;
|
|
@@ -266,7 +266,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
266
266
|
align-items: center;
|
|
267
267
|
width: 100%;
|
|
268
268
|
height: 64px;
|
|
269
|
-
border-radius:
|
|
269
|
+
border-radius: 6px;
|
|
270
270
|
color: #fff;
|
|
271
271
|
color: var(--color-tertiary, #fff);
|
|
272
272
|
}
|
|
@@ -278,7 +278,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
278
278
|
|
|
279
279
|
.submenu__item--secondary a,
|
|
280
280
|
.submenu__item--tertiary a {
|
|
281
|
-
padding:
|
|
281
|
+
padding: 26px;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
.submenu__item--secondary a:hover,
|
|
@@ -288,18 +288,18 @@ const pagePathname = Astro.url.pathname;
|
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
.submenu {
|
|
291
|
-
padding: 0.
|
|
292
|
-
right: -
|
|
291
|
+
padding: 0.9em;
|
|
292
|
+
right: calc(50% - 80px);
|
|
293
293
|
}
|
|
294
294
|
|
|
295
295
|
.submenu::after {
|
|
296
296
|
content: "";
|
|
297
297
|
position: absolute;
|
|
298
|
-
top: -
|
|
298
|
+
top: -4em;
|
|
299
299
|
width: 100%;
|
|
300
300
|
z-index: -3;
|
|
301
301
|
pointer-events: none;
|
|
302
|
-
height:
|
|
302
|
+
height: 10em;
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
.subsubmenu {
|
|
@@ -312,22 +312,22 @@ const pagePathname = Astro.url.pathname;
|
|
|
312
312
|
.subsubmenu::before {
|
|
313
313
|
content: "";
|
|
314
314
|
position: absolute;
|
|
315
|
-
top: -
|
|
315
|
+
top: -4em;
|
|
316
316
|
z-index: -1;
|
|
317
317
|
pointer-events: none;
|
|
318
|
-
height:
|
|
319
|
-
width:
|
|
320
|
-
height:
|
|
318
|
+
height: 10em;
|
|
319
|
+
width: 20em;
|
|
320
|
+
height: 14em;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
.subsubmenu::after {
|
|
324
324
|
content: "";
|
|
325
325
|
position: absolute;
|
|
326
326
|
top: -14px;
|
|
327
|
-
right:
|
|
327
|
+
right: 3em;
|
|
328
328
|
width: 100%;
|
|
329
329
|
z-index: -3;
|
|
330
|
-
height:
|
|
330
|
+
height: 21em;
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
.submenu li {
|
|
@@ -337,7 +337,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
337
337
|
.menu__item:hover > .submenu {
|
|
338
338
|
opacity: 1;
|
|
339
339
|
pointer-events: all;
|
|
340
|
-
transform: translateY(1.
|
|
340
|
+
transform: translateY(1.4em);
|
|
341
341
|
}
|
|
342
342
|
|
|
343
343
|
.menu__item:hover > .submenu::after {
|