1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
import type { HTMLAttributes } from "corvos/plugins/jsx.ts";
import { Icon } from "$/ui/objects/Icon.tsx";
import { nav } from "../../data/nav.ts";
import { ActionButton } from "../objects/ActionButton.tsx";
import { Navbar } from "../objects/Navbar.tsx";
import { NavbarItem } from "../objects/NavbarItem.tsx";
import { Logo } from "./Logo.tsx";
export type Props = HTMLAttributes<"header"> & {
"url": string;
"mode"?: "compact" | "none";
"at-end"?: boolean;
"hidden"?: boolean;
"sm"?: JSX.Element;
"end"?: JSX.Element;
"children"?: JSX.Element;
};
export const SiteHeader = ({
children,
sm,
url,
mode,
"at-end": atEnd,
hidden,
end,
class: cls,
...props
}: Props) => {
const navItems = nav.map((item) => ({
...item,
selected: new RegExp(`^${item.url.replace("/#", "/")}`).test(url),
}));
const parent = navItems
.filter((item) => item.url !== url)
.reduce(
(parent: (typeof navItems)[number] | undefined, item) =>
item.selected && item.url.length > (parent?.url.length ?? 0) ? item : parent,
undefined,
);
const selected = navItems.reduce(
(sel, item) => (item.selected && item.url.length > sel.url.length ? item : sel),
{
icon: "",
label: "Back",
selected: true,
url: "/",
},
);
const variant = atEnd ? "static-white" : undefined;
return (
<header
class:list={[
"c-site-header",
"l-media",
{ "c-site-header--end": atEnd, "c-site-header--hidden": hidden },
cls,
]}
{...props}
>
<Logo class="c-site-header__logo l-media__block" variant={variant} />
{mode !== "none" && (
<>
<Navbar aria-label="Mainmenu" class="c-site-header__nav l-media__block" variant={variant}>
{mode === "compact" ? (
<NavbarItem
href={selected.url}
pre={<Icon icon="arrow-left" variant="bold" />}
selected
>
{selected.label}
</NavbarItem>
) : (
navItems
.filter((item) => item.url !== "/" && !item.hidden)
.map((item) => (
<NavbarItem as="a" href={item.url} selected={item.selected}>
{item.label}
</NavbarItem>
))
)}
</Navbar>
{parent && (
<ActionButton
align-block
class="c-site-header__back l-media__block"
href={parent.url}
icon={<Icon icon="arrow-left" variant="bold" />}
level="quiet"
pill
/>
)}
</>
)}
{children}
{sm && <div class="c-site-header__slot c-site-header__slot--sm">{sm}</div>}
{end && (
<>
<div class="c-site-header__spacer" />
<div class="c-site-header__slot c-site-header__slot--end">{end}</div>
</>
)}
<Logo
class="c-site-header__logo c-site-header__logo--sm l-media__block"
size="sm"
variant={variant}
/>
</header>
);
};
|