Files
blitzkit/packages/website/src/components/Navbar.astro
T

259 lines
6.5 KiB
Plaintext
Raw Normal View History

2024-09-15 14:51:01 -05:00
---
2025-09-13 21:54:43 -05:00
import { assertSecret } from "@blitzkit/core";
2024-09-15 14:51:01 -05:00
import {
Cross1Icon,
DiscordLogoIcon,
GearIcon,
HamburgerMenuIcon,
2025-09-13 21:54:43 -05:00
} from "@radix-ui/react-icons";
import { Box, Code, Flex, IconButton, Link } from "@radix-ui/themes";
import { TOOLS } from "../constants/tools";
import { resolveBranchName } from "../core/blitzkit/branches";
import { getStrings } from "../core/i18n/getStrings";
import { Var } from "../core/radix/var";
import { LinkI18n } from "./LinkI18n";
2024-09-15 14:51:01 -05:00
2025-05-06 21:30:35 -05:00
export interface Props {
integrated?: boolean;
}
2025-07-27 15:36:46 -05:00
const { integrated = false } = Astro.props;
2025-09-13 21:54:43 -05:00
const toolsFiltered = TOOLS.filter((tool) => !tool.href && !tool.disabled);
2024-12-27 14:01:59 -06:00
const { locale } = Astro.params;
2025-01-06 20:09:11 -06:00
const branchName = resolveBranchName(locale);
const isBranchNamed = branchName !== undefined;
const strings = getStrings(locale);
2024-09-15 14:51:01 -05:00
---
<style>
2025-05-06 13:29:40 -05:00
.navbar,
.padder {
transition-duration: 1s;
}
body.no-navbar .navbar {
transform: translateY(-100%);
}
body.no-navbar .padder {
height: 0;
}
2025-09-13 21:54:43 -05:00
.navbar[data-expanded="false"] *[data-expanded] {
2024-11-12 21:34:49 -06:00
display: none;
}
2024-09-15 14:51:01 -05:00
2025-09-13 21:54:43 -05:00
.navbar[data-expanded="true"] {
2025-04-03 13:00:23 -05:00
height: 100%;
}
2025-09-13 21:54:43 -05:00
.navbar[data-expanded="false"][data-integrated="false"] .content {
2025-04-24 20:07:17 -05:00
background-color: var(--black-a8);
backdrop-filter: blur(4rem);
2025-05-16 18:01:10 -05:00
box-shadow: var(--shadow-3);
2025-04-24 20:07:17 -05:00
}
2025-09-13 21:54:43 -05:00
.navbar[data-expanded="true"] .content {
2025-04-24 20:07:17 -05:00
background-color: var(--gray-1);
}
2025-09-13 21:54:43 -05:00
.navbar[data-expanded="true"] *[data-closed] {
2024-11-12 21:34:49 -06:00
display: none;
2024-09-15 14:51:01 -05:00
}
</style>
<script>
2025-09-13 21:54:43 -05:00
const navbar = document.querySelector<HTMLDivElement>(".navbar");
const hamburger = document.querySelector<HTMLButtonElement>(".hamburger");
2024-09-15 14:51:01 -05:00
2025-09-13 21:54:43 -05:00
navbar?.addEventListener("click", () => {
navbar.dataset.expanded = "false";
2024-09-15 14:51:01 -05:00
});
2025-09-13 21:54:43 -05:00
hamburger?.addEventListener("click", (event) => {
2025-04-03 12:15:08 -05:00
if (!navbar) return;
2024-09-15 14:51:01 -05:00
event.stopPropagation();
2025-09-13 21:54:43 -05:00
navbar.dataset.expanded = `${navbar.dataset.expanded === "false"}`;
2024-09-15 14:51:01 -05:00
});
</script>
2025-05-06 21:30:35 -05:00
{
!integrated && (
2025-09-13 21:54:43 -05:00
<Box className="padder" height={{ initial: "3.5rem", sm: "3rem" }} />
2025-05-06 21:30:35 -05:00
)
}
2024-09-15 14:51:01 -05:00
2025-04-03 12:15:08 -05:00
<Flex
direction="column"
align="center"
data-expanded="false"
2025-07-27 15:36:46 -05:00
data-integrated={`${integrated}`}
2025-04-03 12:15:08 -05:00
className="navbar"
width="100%"
top="0"
position="fixed"
style={{
zIndex: 1,
2025-09-13 21:54:43 -05:00
backdropFilter: "blur(4rem)",
2025-04-03 12:15:08 -05:00
}}
>
<Flex
2025-04-24 20:07:17 -05:00
className="content"
2025-04-03 12:15:08 -05:00
width="100%"
2025-09-13 21:54:43 -05:00
p={{ initial: "4", sm: "3" }}
2025-04-03 12:15:08 -05:00
direction="column"
2025-04-03 12:45:33 -05:00
align="center"
2025-09-13 21:54:43 -05:00
style={{ backgroundColor: integrated ? undefined : Var("gray-1") }}
2025-04-03 12:15:08 -05:00
>
2025-04-03 12:45:33 -05:00
<Flex gap="4" direction="column" maxWidth="80rem" width="100%">
<Flex align="center">
<LinkI18n
{locale}
color="gray"
highContrast
href="/"
underline="hover"
weight="medium"
>
<Flex align="center" gap="1">
BlitzKit
{
isBranchNamed && (
<Code color="gray" size="1" variant="outline">
{branchName}
</Code>
)
}
</Flex>
</LinkI18n>
<Box flexGrow="1" />
<Flex
align="center"
2025-09-13 21:54:43 -05:00
gap={{ initial: "4", md: "6" }}
display={{ initial: "none", sm: "flex" }}
2025-04-03 12:45:33 -05:00
justify="center"
className="tools"
>
2024-09-15 14:51:01 -05:00
{
2025-04-20 21:27:00 -05:00
toolsFiltered.map((tool) => {
2025-05-15 23:44:20 -05:00
const selected = Astro.url.pathname.includes(`/${tool.id}`);
2025-04-03 12:45:33 -05:00
const toolStrings =
strings.website.tools[
2025-09-13 21:54:43 -05:00
(tool.strings ??
2025-04-03 12:45:33 -05:00
tool.id) as keyof typeof strings.website.tools
];
2025-09-13 21:54:43 -05:00
if (toolStrings === undefined) console.log(tool.id);
2025-04-03 12:45:33 -05:00
return (
<LinkI18n
{locale}
2025-09-13 21:54:43 -05:00
weight={selected ? "medium" : "regular"}
2025-04-03 12:45:33 -05:00
color="gray"
highContrast={selected}
size="2"
2025-05-15 23:44:20 -05:00
href={`/${tool.id}`}
2025-04-03 12:45:33 -05:00
underline="hover"
>
{toolStrings.name}
</LinkI18n>
);
})
2024-09-15 14:51:01 -05:00
}
</Flex>
2025-04-03 12:45:33 -05:00
<Box flexGrow="1" />
<Flex align="center" gap="4">
<Link
2025-09-13 21:54:43 -05:00
style={{ display: "flex", alignContent: "center" }}
2025-04-03 12:45:33 -05:00
color="gray"
href="https://discord.gg/nDt7AjGJQH"
underline="none"
target="_blank"
>
<DiscordLogoIcon width="1em" height="1em" />
</Link>
<LinkI18n
{locale}
2025-09-13 21:54:43 -05:00
style={{ display: "flex", alignContent: "center" }}
2025-04-03 12:45:33 -05:00
color="gray"
href="/settings"
underline="none"
>
<GearIcon width="1em" height="1em" />
</LinkI18n>
<!-- <NavbarAccount client:idle /> -->
2025-09-13 21:54:43 -05:00
<Flex align="center" display={{ initial: "flex", sm: "none" }}>
2025-04-03 12:45:33 -05:00
<IconButton variant="ghost" color="gray" className="hamburger">
<Cross1Icon data-expanded />
<HamburgerMenuIcon data-closed />
</IconButton>
</Flex>
</Flex>
</Flex>
2024-09-15 14:51:01 -05:00
2025-04-03 12:15:08 -05:00
<Flex
2025-04-03 12:45:33 -05:00
direction="column"
data-expanded
gap="3"
2025-09-13 21:54:43 -05:00
display={{ initial: "flex", sm: "none" }}
2024-11-24 20:30:42 -06:00
>
{
2025-04-03 12:45:33 -05:00
toolsFiltered.map((tool) => {
2025-01-06 20:09:11 -06:00
const toolStrings =
strings.website.tools[
2025-09-13 21:54:43 -05:00
(tool.strings ?? tool.id) as keyof typeof strings.website.tools
2025-01-06 20:09:11 -06:00
];
2024-09-15 14:51:01 -05:00
2024-11-24 20:30:42 -06:00
return (
2025-04-03 12:45:33 -05:00
<Link
2025-04-03 12:15:08 -05:00
color="gray"
2025-04-03 12:45:33 -05:00
highContrast
2025-09-13 21:54:43 -05:00
style={{ display: "contents" }}
2025-05-15 23:44:20 -05:00
href={`/${tool.id}`}
2024-09-15 14:51:01 -05:00
>
2025-04-03 12:45:33 -05:00
<Box
style={{
2025-09-13 21:54:43 -05:00
borderRadius: Var("radius-2"),
2025-07-27 20:07:47 -05:00
backgroundImage: `url(/assets/images/tools/${tool.id}.webp)`,
2025-09-13 21:54:43 -05:00
backgroundSize: "200%",
backgroundPosition: "right center",
2025-04-03 12:45:33 -05:00
}}
>
<Flex
py="4"
justify="end"
flexGrow="1"
style={{
2025-09-13 21:54:43 -05:00
background: `linear-gradient(90deg, transparent, ${Var("gray-1")} 90%)`,
2025-04-03 12:45:33 -05:00
}}
>
{toolStrings.name}
</Flex>
</Box>
</Link>
2024-11-24 20:30:42 -06:00
);
})
}
2025-04-03 12:15:08 -05:00
</Flex>
</Flex>
2024-09-15 14:51:01 -05:00
</Flex>
2025-04-03 12:15:08 -05:00
<Box
data-expanded
flexGrow="1"
width="100%"
2025-09-13 21:54:43 -05:00
display={{ initial: "block", sm: "none" }}
2025-04-03 12:15:08 -05:00
style={{
2025-09-13 21:54:43 -05:00
backgroundColor: Var("black-a7"),
backdropFilter: "blur(0.5rem)",
WebkitBackdropFilter: "blur(0.5rem)",
2025-04-03 12:15:08 -05:00
}}
/>
2024-09-15 14:51:01 -05:00
</Flex>