AstralHalo/src/components/Navbar.astro
HPCesia 8a8bf19e35 build(deps): upgrade TailwindCSS to v4
- Upgrade TailwindCSS to v4
- Upgrade daisyUI to v5 beta.
- Delete the PostCSS TailwindCSS compatibility layer.
- Delete Sass dependency because TailwindCSS v4 will generate nested CSS, so we don't need Sass anymore.
2025-02-07 21:39:05 +08:00

151 lines
5.0 KiB
Plaintext

---
import { navbarConfig } from '@/config';
import { i18n } from '@i18n/translation';
import { Icon } from 'astro-icon/components';
import Button from './widgets/Button.astro';
import DarkModeButton from './widgets/DarkModeButton.astro';
interface Props {
title?: string;
lang?: string;
}
let { title } = Astro.props;
if (!title) title = 'Astral Halo';
---
<div class="drawer drawer-end">
<input id="sidebar-drawer" type="checkbox" class="drawer-toggle" />
<div class="drawer-content flex flex-col">
<!-- Navbar -->
<div
id="navbar"
class="navbar bg-base-200/50 fixed z-20 flex h-16 w-full items-center backdrop-blur-md"
>
<div class="navbar-start">
<Button id="site-name" href="/" class="group btn-ghost">
<span class="text-xl font-bold duration-300 group-hover:opacity-0">{title}</span>
<Icon
name="material-symbols:home-rounded"
class="absolute text-3xl opacity-0 duration-300 group-hover:opacity-100"
/>
</Button>
</div>
<nav class="join navbar-center max-md:hidden">
{
navbarConfig.navbarCenterItems.map((item) => (
<Button
{...('href' in item && item.href && { href: item.href })}
title={i18n(item.text)}
class="btn-ghost join-item"
>
<span class="text-xl tracking-wide">{i18n(item.text)}</span>
</Button>
))
}
</nav>
<div class="navbar-end">
<div class="flex max-md:hidden">
{
navbarConfig.navbarRightItems.onlyWide.map((item) => (
<Button
class="nav-menu-item btn-circle btn-ghost"
{...('href' in item && item.href && { href: item.href })}
title={i18n(item.text)}
{...('onclick' in item &&
item.onclick &&
(typeof item.onclick === 'string'
? { onclick: item.onclick }
: { id: 'nav-' + item.onclick.id }))}
>
<Icon name={item.icon} class="text-2xl" />
</Button>
))
}
</div>
<div class="flex">
{
navbarConfig.navbarRightItems.always.map((item) => (
<Button
class="nav-menu-item btn-circle btn-ghost"
{...('href' in item && item.href && { href: item.href })}
title={i18n(item.text)}
{...('onclick' in item &&
item.onclick &&
(typeof item.onclick === 'string'
? { onclick: item.onclick }
: { id: 'nav-' + item.onclick.id }))}
>
<Icon name={item.icon} class="text-2xl" />
</Button>
))
}
</div>
<div class="md:hidden">
<label for="sidebar-drawer" class="btn btn-circle btn-ghost">
<Icon name="material-symbols:menu-rounded" class="text-2xl" />
</label>
</div>
</div>
</div>
<div id="navbar-placeholder" class="pt-20"></div>
<!-- Page Content -->
<slot />
</div>
<div class="drawer-side z-50">
<!-- Sidebar -->
<label for="sidebar-drawer" class="drawer-overlay"></label>
<ul class="menu bg-base-200 min-h-full w-[min(calc(100%-3rem),20rem)] p-4">
<li><DarkModeButton class="btn-ghost text-xl" showText={true} /></li>
{
navbarConfig.navbarCenterItems.map((item) => (
<li>
<Button
{...('href' in item && item.href && { href: item.href })}
title={i18n(item.text)}
class="btn-ghost"
>
<span class="text-xl">{i18n(item.text)}</span>
</Button>
</li>
))
}
{
navbarConfig.navbarRightItems.onlyWide.map((item) => (
<li>
<Button
{...('href' in item && item.href && { href: item.href })}
title={i18n(item.text)}
{...('onclick' in item &&
item.onclick &&
(typeof item.onclick === 'string'
? { onclick: item.onclick }
: { id: 'side-' + item.onclick.id }))}
class="btn-ghost"
>
<Icon name={item.icon} class="text-2xl" />
<span class="text-xl">{i18n(item.text)}</span>
</Button>
</li>
))
}
</ul>
</div>
</div>
<script>
import { navbarConfig } from '@/config';
const rightItems = [
navbarConfig.navbarRightItems.onlyWide,
navbarConfig.navbarRightItems.always,
].flat();
document.addEventListener('astro:page-load', () => {
rightItems.forEach((item) => {
if ('onclick' in item && item.onclick && typeof item.onclick !== 'string') {
const element = document.getElementById('nav-' + item.onclick.id);
if (element) element.addEventListener('click', item.onclick.function);
}
});
});
</script>