@sofidevo/astro-dynamic-header 2.0.1 → 2.0.2
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 +38 -7
- package/package.json +1 -1
- package/src/HamburgerButton.astro +24 -9
- package/src/Header.astro +20 -0
- package/src/MobileNav.astro +80 -59
- package/src/NavMenu.astro +15 -0
- package/src/index.ts +122 -1
package/README.md
CHANGED
|
@@ -137,13 +137,44 @@ const theme = {
|
|
|
137
137
|
|
|
138
138
|
#### CustomClassNames
|
|
139
139
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
140
|
+
The `classNames` prop allows you to inject custom CSS classes (such as Tailwind CSS utility classes) into specific high-level elements of the Header component. This provides a bridge between the component's internal styles and your project's global styling system.
|
|
141
|
+
|
|
142
|
+
| Property | Target Element | Purpose & Common Use Cases |
|
|
143
|
+
| ----------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
144
|
+
| `container` | Outer `div` wrapping the header | **Positioning & Layout**: Use for `top-0`, `z-50`, `fixed`, or adjusting the `max-width` and `mx-auto` logic. |
|
|
145
|
+
| `header` | Inner `<header>` element | **Appearance**: The best place for shadows (`shadow-md`), borders (`border-b`), or custom transition durations. |
|
|
146
|
+
| `logo` | `<a>` tag surrounding the logo | **Interactions**: Add hover states, custom focus rings, or adjust the flex alignment of the logo group. |
|
|
147
|
+
| `logoText` | `<span>` tag containing the logo text | **Typography**: Override font weights, apply text shadows, or use specific tracking/leading classes. |
|
|
148
|
+
| `nav` | `div` wrapping the desktop navigation items | **Desktop Layout**: Adjust spacing between the logo and the menu, or add responsive visibility classes (`hidden md:flex`). |
|
|
149
|
+
|
|
150
|
+
##### Advanced Usage Examples
|
|
151
|
+
|
|
152
|
+
**Implementing a Premium Shadow & Border (Tailwind):**
|
|
153
|
+
Ideal for creating a modern "glass" effect with a subtle border and shadow that adapts to dark mode.
|
|
154
|
+
|
|
155
|
+
```astro
|
|
156
|
+
<Header
|
|
157
|
+
classNames={{
|
|
158
|
+
header: "shadow-xl border-b border-black/5 dark:border-white/10 transition-all duration-500",
|
|
159
|
+
container: "top-4 px-6"
|
|
160
|
+
}}
|
|
161
|
+
/>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Custom Typography for Logo & Nav Spacing:**
|
|
165
|
+
Perfect for matching the header with your brand's specific typography and layout requirements.
|
|
166
|
+
|
|
167
|
+
```astro
|
|
168
|
+
<Header
|
|
169
|
+
classNames={{
|
|
170
|
+
logoText: "tracking-tighter font-black italic uppercase",
|
|
171
|
+
nav: "ml-auto gap-8" /* Moves menu to the right and increases gap */
|
|
172
|
+
}}
|
|
173
|
+
/>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
> [!TIP]
|
|
177
|
+
> Since these classes are injected using Astro's `class:list`, you can also pass objects or arrays if you need conditional logic for your custom classes.
|
|
147
178
|
|
|
148
179
|
#### LogoConfig
|
|
149
180
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
export interface Props {
|
|
3
|
+
/** Override the default color of the hamburger lines */
|
|
3
4
|
color?: string;
|
|
4
5
|
}
|
|
5
6
|
|
|
6
|
-
const { color = "var(--color-hamburger-lines, #fff)" } =
|
|
7
|
+
const { color = "var(--text-color, var(--color-hamburger-lines, #fff))" } =
|
|
8
|
+
Astro.props;
|
|
7
9
|
---
|
|
8
10
|
|
|
9
11
|
<button
|
|
@@ -23,14 +25,16 @@ const { color = "var(--color-hamburger-lines, #fff)" } = Astro.props;
|
|
|
23
25
|
font: inherit;
|
|
24
26
|
overflow: visible;
|
|
25
27
|
margin: 0;
|
|
26
|
-
padding:
|
|
28
|
+
padding: 10px;
|
|
27
29
|
cursor: pointer;
|
|
28
30
|
transition-timing-function: linear;
|
|
29
31
|
transition-duration: 0.15s;
|
|
30
|
-
transition-property: opacity, filter;
|
|
32
|
+
transition-property: opacity, filter, border-color;
|
|
31
33
|
text-transform: none;
|
|
32
34
|
color: inherit;
|
|
33
|
-
border:
|
|
35
|
+
border: 1px solid
|
|
36
|
+
color-mix(in srgb, var(--text-color, #fff) 25%, transparent);
|
|
37
|
+
border-radius: 8px;
|
|
34
38
|
background-color: transparent;
|
|
35
39
|
|
|
36
40
|
@media screen and (max-width: 768px) {
|
|
@@ -61,7 +65,10 @@ const { color = "var(--color-hamburger-lines, #fff)" } = Astro.props;
|
|
|
61
65
|
.hamburger-inner,
|
|
62
66
|
.hamburger-inner::before,
|
|
63
67
|
.hamburger-inner::after {
|
|
64
|
-
background-color: var(
|
|
68
|
+
background-color: var(
|
|
69
|
+
--hamburger-color,
|
|
70
|
+
var(--color-hamburger-lines, #fff)
|
|
71
|
+
);
|
|
65
72
|
position: absolute;
|
|
66
73
|
width: 40px;
|
|
67
74
|
height: 4px;
|
|
@@ -88,12 +95,16 @@ const { color = "var(--color-hamburger-lines, #fff)" } = Astro.props;
|
|
|
88
95
|
}
|
|
89
96
|
|
|
90
97
|
.hamburger--collapse .hamburger-inner:before {
|
|
91
|
-
transition:
|
|
98
|
+
transition:
|
|
99
|
+
top 0.12s cubic-bezier(0.33333, 0.66667, 0.66667, 1) 0.2s,
|
|
100
|
+
transform 0.13s cubic-bezier(0.55, 0.055, 0.675, 0.19);
|
|
92
101
|
}
|
|
93
102
|
|
|
94
103
|
.hamburger--collapse .hamburger-inner:after {
|
|
95
104
|
top: -20px;
|
|
96
|
-
transition:
|
|
105
|
+
transition:
|
|
106
|
+
top 0.2s cubic-bezier(0.33333, 0.66667, 0.66667, 1) 0.2s,
|
|
107
|
+
opacity 0.1s linear;
|
|
97
108
|
}
|
|
98
109
|
|
|
99
110
|
/* Animation */
|
|
@@ -105,13 +116,17 @@ const { color = "var(--color-hamburger-lines, #fff)" } = Astro.props;
|
|
|
105
116
|
|
|
106
117
|
.hamburger--collapse.is-active .hamburger-inner:before {
|
|
107
118
|
top: 0;
|
|
108
|
-
transition:
|
|
119
|
+
transition:
|
|
120
|
+
top 0.1s cubic-bezier(0.33333, 0, 0.66667, 0.33333) 0.16s,
|
|
121
|
+
transform 0.13s cubic-bezier(0.215, 0.61, 0.355, 1) 0.25s;
|
|
109
122
|
transform: rotate(-90deg);
|
|
110
123
|
}
|
|
111
124
|
|
|
112
125
|
.hamburger--collapse.is-active .hamburger-inner:after {
|
|
113
126
|
top: 0;
|
|
114
|
-
transition:
|
|
127
|
+
transition:
|
|
128
|
+
top 0.2s cubic-bezier(0.33333, 0, 0.66667, 0.33333),
|
|
129
|
+
opacity 0.1s linear 0.22s;
|
|
115
130
|
opacity: 0;
|
|
116
131
|
}
|
|
117
132
|
</style>
|
package/src/Header.astro
CHANGED
|
@@ -11,11 +11,31 @@ import type {
|
|
|
11
11
|
} from "./index.js";
|
|
12
12
|
|
|
13
13
|
export interface Props {
|
|
14
|
+
/**
|
|
15
|
+
* Layout style.
|
|
16
|
+
* - "floating": Centered with max-width and rounded corners.
|
|
17
|
+
* - "fullscreen": Full width with no border radius.
|
|
18
|
+
* @default "floating"
|
|
19
|
+
*/
|
|
14
20
|
headerType?: "floating" | "fullscreen";
|
|
21
|
+
/**
|
|
22
|
+
* Theme behavior.
|
|
23
|
+
* - "light": Force light mode.
|
|
24
|
+
* - "dark": Force dark mode.
|
|
25
|
+
* - "auto": Detects .dark class on the root element.
|
|
26
|
+
* @default "auto"
|
|
27
|
+
*/
|
|
15
28
|
preset?: "light" | "dark" | "auto";
|
|
29
|
+
/** Logo configuration object (src, alt, text, etc.) */
|
|
16
30
|
logo?: LogoConfig;
|
|
31
|
+
/** Navigation links and structure. */
|
|
17
32
|
navigation?: NavConfig;
|
|
33
|
+
/** Custom theme overrides for light and dark modes. */
|
|
18
34
|
theme?: DualThemeConfig;
|
|
35
|
+
/**
|
|
36
|
+
* Custom CSS classes for specific internal elements.
|
|
37
|
+
* @example { header: "shadow-lg", nav: "ml-auto" }
|
|
38
|
+
*/
|
|
19
39
|
classNames?: CustomClassNames;
|
|
20
40
|
}
|
|
21
41
|
|
package/src/MobileNav.astro
CHANGED
|
@@ -2,9 +2,13 @@
|
|
|
2
2
|
import type { MenuItem, SecondaryMenuItem, TertiaryMenuItem } from "./index.js";
|
|
3
3
|
|
|
4
4
|
export interface Props {
|
|
5
|
+
/** Header type for styling: "floating" or "fullscreen" */
|
|
5
6
|
type?: "floating" | "fullscreen";
|
|
7
|
+
/** Array of menu items to display in the mobile menu */
|
|
6
8
|
menuItems?: MenuItem[];
|
|
9
|
+
/** Whether to show the home link (defaults to true) */
|
|
7
10
|
showHomeLink?: boolean;
|
|
11
|
+
/** Text for the home link (defaults to "Home") */
|
|
8
12
|
homeText?: string;
|
|
9
13
|
}
|
|
10
14
|
|
|
@@ -38,64 +42,73 @@ const pagePathname = Astro.url.pathname;
|
|
|
38
42
|
)
|
|
39
43
|
}
|
|
40
44
|
{
|
|
41
|
-
menuItems?.map((item: MenuItem) =>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
menuItems?.map((item: MenuItem) => {
|
|
46
|
+
const isActive = pagePathname === item.link;
|
|
47
|
+
return (
|
|
48
|
+
<li>
|
|
49
|
+
{item.submenu ? (
|
|
50
|
+
<details class="mobile-details" open={item.submenu.some(sub => pagePathname === sub.link)}>
|
|
51
|
+
<summary class:list={["menu__summary", { active: isActive }]}>
|
|
52
|
+
{item.text}
|
|
53
|
+
<iconify-icon
|
|
54
|
+
class="iconify-arrow"
|
|
55
|
+
icon="codicon:triangle-down"
|
|
56
|
+
width="15"
|
|
57
|
+
height="15"
|
|
58
|
+
style="color: var(--accent-color);"
|
|
59
|
+
/>
|
|
60
|
+
</summary>
|
|
61
|
+
<ol class="mobile-submenu">
|
|
62
|
+
{item?.submenu?.map((sub: SecondaryMenuItem) => {
|
|
63
|
+
const isSubActive = pagePathname === sub.link;
|
|
64
|
+
return (
|
|
65
|
+
<li>
|
|
66
|
+
{sub.submenu && sub.submenu.length > 0 ? (
|
|
67
|
+
<details class="mobile-details" open={sub.submenu.some(subsub => pagePathname === subsub.link)}>
|
|
68
|
+
<summary class:list={["menu__summary", { active: isSubActive }]}>
|
|
69
|
+
{sub.text}
|
|
70
|
+
<iconify-icon
|
|
71
|
+
class="iconify-arrow"
|
|
72
|
+
icon="codicon:triangle-down"
|
|
73
|
+
width="15"
|
|
74
|
+
height="15"
|
|
75
|
+
style="color: var(--accent-color);"
|
|
76
|
+
/>
|
|
77
|
+
</summary>
|
|
78
|
+
<ol class="mobile-subsubmenu">
|
|
79
|
+
{sub.submenu.map((subsub: TertiaryMenuItem) => {
|
|
80
|
+
const isSubSubActive = pagePathname === subsub.link;
|
|
81
|
+
return (
|
|
82
|
+
<li class="mobile-submenu__item secondary">
|
|
83
|
+
<a
|
|
84
|
+
class:list={["menu__link", "mobile-menu__link", { active: isSubSubActive }]}
|
|
85
|
+
href={subsub.link}
|
|
86
|
+
>
|
|
87
|
+
{subsub.text}
|
|
88
|
+
</a>
|
|
89
|
+
</li>
|
|
90
|
+
);
|
|
91
|
+
})}
|
|
92
|
+
</ol>
|
|
93
|
+
</details>
|
|
94
|
+
) : (
|
|
95
|
+
<a class:list={["menu__link", "mobile-menu__link", { active: isSubActive }]} href={sub.link}>
|
|
96
|
+
{sub.text}
|
|
97
|
+
</a>
|
|
98
|
+
)}
|
|
99
|
+
</li>
|
|
100
|
+
);
|
|
101
|
+
})}
|
|
102
|
+
</ol>
|
|
103
|
+
</details>
|
|
104
|
+
) : (
|
|
105
|
+
<a class:list={["mobile-menu__link", { active: isActive }]} href={item.link}>
|
|
46
106
|
{item.text}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
style="color: var(--accent-color);"
|
|
53
|
-
/>
|
|
54
|
-
</summary>
|
|
55
|
-
<ol class="mobile-submenu">
|
|
56
|
-
{item?.submenu?.map((sub: SecondaryMenuItem) => (
|
|
57
|
-
<li>
|
|
58
|
-
{sub.submenu && sub.submenu.length > 0 ? (
|
|
59
|
-
<details class="mobile-details">
|
|
60
|
-
<summary class="menu__summary">
|
|
61
|
-
{sub.text}
|
|
62
|
-
<iconify-icon
|
|
63
|
-
class="iconify-arrow"
|
|
64
|
-
icon="codicon:triangle-down"
|
|
65
|
-
width="15"
|
|
66
|
-
height="15"
|
|
67
|
-
style="color: var(--accent-color);"
|
|
68
|
-
/>
|
|
69
|
-
</summary>
|
|
70
|
-
<ol class="mobile-subsubmenu">
|
|
71
|
-
{sub.submenu.map((subsub: TertiaryMenuItem) => (
|
|
72
|
-
<li class="mobile-submenu__item secondary">
|
|
73
|
-
<a
|
|
74
|
-
class="menu__link mobile-menu__link"
|
|
75
|
-
href={subsub.link}
|
|
76
|
-
>
|
|
77
|
-
{subsub.text}
|
|
78
|
-
</a>
|
|
79
|
-
</li>
|
|
80
|
-
))}
|
|
81
|
-
</ol>
|
|
82
|
-
</details>
|
|
83
|
-
) : (
|
|
84
|
-
<a class="menu__link mobile-menu__link" href={sub.link}>
|
|
85
|
-
{sub.text}
|
|
86
|
-
</a>
|
|
87
|
-
)}
|
|
88
|
-
</li>
|
|
89
|
-
))}
|
|
90
|
-
</ol>
|
|
91
|
-
</details>
|
|
92
|
-
) : (
|
|
93
|
-
<a class="mobile-menu__link" href={item.link}>
|
|
94
|
-
{item.text}
|
|
95
|
-
</a>
|
|
96
|
-
)}
|
|
97
|
-
</li>
|
|
98
|
-
))
|
|
107
|
+
</a>
|
|
108
|
+
)}
|
|
109
|
+
</li>
|
|
110
|
+
);
|
|
111
|
+
})
|
|
99
112
|
}
|
|
100
113
|
</ol>
|
|
101
114
|
<slot name="slot-panel" />
|
|
@@ -122,7 +135,15 @@ const pagePathname = Astro.url.pathname;
|
|
|
122
135
|
}
|
|
123
136
|
|
|
124
137
|
a {
|
|
125
|
-
color:
|
|
138
|
+
color: color-mix(
|
|
139
|
+
in srgb,
|
|
140
|
+
var(--accent-color, #00ffff) 30%,
|
|
141
|
+
var(--text-color, #ffffff) 70%
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.active {
|
|
146
|
+
color: var(--accent-color, #00ffff) !important;
|
|
126
147
|
}
|
|
127
148
|
}
|
|
128
149
|
|
|
@@ -139,7 +160,7 @@ const pagePathname = Astro.url.pathname;
|
|
|
139
160
|
|
|
140
161
|
.mobile-menu li a {
|
|
141
162
|
border: solid 1px
|
|
142
|
-
color-mix(in srgb, var(--accent-color, #00ffff)
|
|
163
|
+
color-mix(in srgb, var(--accent-color, #00ffff) 15%, transparent);
|
|
143
164
|
border-radius: 4px;
|
|
144
165
|
width: 100%;
|
|
145
166
|
height: 4rem;
|
package/src/NavMenu.astro
CHANGED
|
@@ -2,8 +2,23 @@
|
|
|
2
2
|
import type { MenuItem, SecondaryMenuItem, TertiaryMenuItem } from "./index.js";
|
|
3
3
|
|
|
4
4
|
export interface Props {
|
|
5
|
+
/**
|
|
6
|
+
* Header type for styling.
|
|
7
|
+
* @example "floating"
|
|
8
|
+
*/
|
|
9
|
+
type?: "floating" | "fullscreen";
|
|
10
|
+
/** Array of menu items to display. */
|
|
5
11
|
menuItems?: MenuItem[];
|
|
12
|
+
/**
|
|
13
|
+
* Whether to show the home link in the menu.
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
6
16
|
showHomeLink?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Text for the home link.
|
|
19
|
+
* @default "Home"
|
|
20
|
+
*/
|
|
21
|
+
|
|
7
22
|
homeText?: string;
|
|
8
23
|
}
|
|
9
24
|
|
package/src/index.ts
CHANGED
|
@@ -1,71 +1,192 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Represents a menu item in the navigation.
|
|
5
|
+
*/
|
|
4
6
|
export interface MenuItemType {
|
|
7
|
+
/** The URL path for the link */
|
|
5
8
|
link: string;
|
|
9
|
+
/** The text label to display */
|
|
6
10
|
text: string;
|
|
11
|
+
/** Optional nested submenu items */
|
|
7
12
|
submenu?: MenuItemType[];
|
|
8
13
|
}
|
|
9
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Represents a third-level menu item.
|
|
17
|
+
*/
|
|
10
18
|
export interface TertiaryMenuItem {
|
|
19
|
+
/** The URL path for the link */
|
|
11
20
|
link: string;
|
|
21
|
+
/** The text label to display */
|
|
12
22
|
text: string;
|
|
13
23
|
}
|
|
14
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Represents a second-level menu item with optional nested tertiary items.
|
|
27
|
+
*/
|
|
15
28
|
export interface SecondaryMenuItem {
|
|
29
|
+
/** The URL path for the link */
|
|
16
30
|
link: string;
|
|
31
|
+
/** The text label to display */
|
|
17
32
|
text: string;
|
|
33
|
+
/** Optional nested tertiary menu items */
|
|
18
34
|
submenu?: TertiaryMenuItem[];
|
|
19
35
|
}
|
|
20
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Represents a top-level menu item with optional nested secondary items.
|
|
39
|
+
*/
|
|
21
40
|
export interface MenuItem {
|
|
41
|
+
/** The URL path for the link */
|
|
22
42
|
link: string;
|
|
43
|
+
/** The text label to display */
|
|
23
44
|
text: string;
|
|
45
|
+
/** Optional nested secondary menu items */
|
|
24
46
|
submenu?: SecondaryMenuItem[];
|
|
25
47
|
}
|
|
26
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Configuration for the site logo.
|
|
51
|
+
*/
|
|
27
52
|
export interface LogoConfig {
|
|
53
|
+
/**
|
|
54
|
+
* The URL of the logo image.
|
|
55
|
+
* @example "/assets/logo.png"
|
|
56
|
+
* @default "/logo.png"
|
|
57
|
+
*/
|
|
28
58
|
src?: string;
|
|
59
|
+
/** Alternative text for the logo image */
|
|
29
60
|
alt?: string;
|
|
61
|
+
/**
|
|
62
|
+
* CSS width for the logo.
|
|
63
|
+
* @example "150px" or "4rem"
|
|
64
|
+
* @default "55px"
|
|
65
|
+
*/
|
|
30
66
|
width?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Optional text to display next to the logo image.
|
|
69
|
+
* @example "My Awesome Site"
|
|
70
|
+
*/
|
|
31
71
|
text?: string;
|
|
72
|
+
/**
|
|
73
|
+
* CSS font-size for the logo text.
|
|
74
|
+
* @default "1em"
|
|
75
|
+
*/
|
|
32
76
|
textSize?: string;
|
|
77
|
+
/**
|
|
78
|
+
* CSS color for the logo text.
|
|
79
|
+
* If not provided, it will inherit from the theme's text color.
|
|
80
|
+
* @default "inherit"
|
|
81
|
+
*/
|
|
33
82
|
textColor?: string;
|
|
34
83
|
}
|
|
35
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Configuration for the main navigation.
|
|
87
|
+
*/
|
|
36
88
|
export interface NavConfig {
|
|
89
|
+
/**
|
|
90
|
+
* The URL for the home link.
|
|
91
|
+
* @default "/"
|
|
92
|
+
*/
|
|
37
93
|
homeUrl?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Array of top-level menu items.
|
|
96
|
+
* @example [{ link: "/about", text: "About Us" }]
|
|
97
|
+
*/
|
|
38
98
|
menuItems?: MenuItem[];
|
|
39
99
|
}
|
|
40
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Individual theme settings for a specific state (light/dark).
|
|
103
|
+
*/
|
|
41
104
|
export interface ThemeConfig {
|
|
105
|
+
/**
|
|
106
|
+
* Main background color. Supports hex, rgb, rgba, etc.
|
|
107
|
+
* @example "rgba(255, 255, 255, 0.9)"
|
|
108
|
+
*/
|
|
42
109
|
backgroundColor?: string;
|
|
110
|
+
/**
|
|
111
|
+
* Solid background color for submenus and mobile panels to ensure readability.
|
|
112
|
+
* @example "#ffffff"
|
|
113
|
+
*/
|
|
43
114
|
backgroundColorOpaque?: string;
|
|
115
|
+
/**
|
|
116
|
+
* CSS backdrop-filter blur value.
|
|
117
|
+
* @default "blur(20px)"
|
|
118
|
+
*/
|
|
44
119
|
backdropBlur?: string;
|
|
120
|
+
/**
|
|
121
|
+
* CSS z-index for the header container.
|
|
122
|
+
* @default 10
|
|
123
|
+
*/
|
|
45
124
|
zIndex?: number;
|
|
125
|
+
/**
|
|
126
|
+
* Primary text color for navigation and logo.
|
|
127
|
+
*/
|
|
46
128
|
textColor?: string;
|
|
129
|
+
/**
|
|
130
|
+
* Color for highlights, active states, underscores, and small borders.
|
|
131
|
+
*/
|
|
47
132
|
accentColor?: string;
|
|
48
133
|
}
|
|
49
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Combined theme configuration for both light and dark modes.
|
|
137
|
+
*/
|
|
50
138
|
export interface DualThemeConfig {
|
|
139
|
+
/** Settings applied when light mode is active. */
|
|
51
140
|
light?: ThemeConfig;
|
|
141
|
+
/** Settings applied when dark mode is active. */
|
|
52
142
|
dark?: ThemeConfig;
|
|
53
143
|
}
|
|
54
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Custom CSS class names for deep customization.
|
|
147
|
+
*/
|
|
55
148
|
export interface CustomClassNames {
|
|
149
|
+
/** Class for the outermost fixed container */
|
|
56
150
|
container?: string;
|
|
151
|
+
/** Class for the main header element */
|
|
57
152
|
header?: string;
|
|
153
|
+
/** Class for the logo anchor tag */
|
|
58
154
|
logo?: string;
|
|
155
|
+
/** Class for the logo span text */
|
|
59
156
|
logoText?: string;
|
|
157
|
+
/** Class for the desktop navigation wrapper */
|
|
60
158
|
nav?: string;
|
|
61
159
|
}
|
|
62
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Main properties for the Header component.
|
|
163
|
+
*/
|
|
63
164
|
export interface HeaderProps {
|
|
165
|
+
/**
|
|
166
|
+
* Layout style.
|
|
167
|
+
* - "floating": Centered with max-width and rounded corners.
|
|
168
|
+
* - "fullscreen": Full width with no border radius.
|
|
169
|
+
* @default "floating"
|
|
170
|
+
*/
|
|
64
171
|
headerType?: "floating" | "fullscreen";
|
|
172
|
+
/**
|
|
173
|
+
* Theme behavior.
|
|
174
|
+
* - "light": Force light mode.
|
|
175
|
+
* - "dark": Force dark mode.
|
|
176
|
+
* - "auto": Detects .dark class on the root element.
|
|
177
|
+
* @default "auto"
|
|
178
|
+
*/
|
|
65
179
|
preset?: "light" | "dark" | "auto";
|
|
180
|
+
/** Logo configuration object. */
|
|
66
181
|
logo?: LogoConfig;
|
|
182
|
+
/** Navigation links and structure. */
|
|
67
183
|
navigation?: NavConfig;
|
|
184
|
+
/** Custom theme overrides. See @interface DualThemeConfig */
|
|
68
185
|
theme?: DualThemeConfig;
|
|
186
|
+
/**
|
|
187
|
+
* Custom CSS classes for injecting utility classes (e.g., Tailwind).
|
|
188
|
+
* @example { header: "shadow-lg", logoText: "font-bold" }
|
|
189
|
+
*/
|
|
69
190
|
classNames?: CustomClassNames;
|
|
70
191
|
}
|
|
71
192
|
|