summaryrefslogtreecommitdiff
path: root/src/components/widgets/Header.astro
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/widgets/Header.astro')
-rw-r--r--src/components/widgets/Header.astro167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/components/widgets/Header.astro b/src/components/widgets/Header.astro
new file mode 100644
index 0000000..ff4a3aa
--- /dev/null
+++ b/src/components/widgets/Header.astro
@@ -0,0 +1,167 @@
+---
+import { Icon } from 'astro-icon/components';
+import Logo from '~/components/Logo.astro';
+import ToggleTheme from '~/components/common/ToggleTheme.astro';
+import ToggleMenu from '~/components/common/ToggleMenu.astro';
+import Button from '~/components/ui/Button.astro';
+
+import { getHomePermalink } from '~/utils/permalinks';
+import { trimSlash, getAsset } from '~/utils/permalinks';
+import type { CallToAction } from '~/types';
+
+interface Link {
+ text?: string;
+ href?: string;
+ ariaLabel?: string;
+ icon?: string;
+}
+
+interface MenuLink extends Link {
+ links?: Array<MenuLink>;
+}
+
+export interface Props {
+ id?: string;
+ links?: Array<MenuLink>;
+ actions?: Array<CallToAction>;
+ isSticky?: boolean;
+ isDark?: boolean;
+ isFullWidth?: boolean;
+ showToggleTheme?: boolean;
+ showRssFeed?: boolean;
+ position?: string;
+}
+
+const {
+ id = 'header',
+ links = [],
+ actions = [],
+ isSticky = false,
+ isDark = false,
+ isFullWidth = false,
+ showToggleTheme = false,
+ showRssFeed = false,
+ position = 'center',
+} = Astro.props;
+
+const currentPath = `/${trimSlash(new URL(Astro.url).pathname)}`;
+---
+
+<header
+ class:list={[
+ { sticky: isSticky, relative: !isSticky, dark: isDark },
+ 'top-0 z-40 flex-none mx-auto w-full border-b border-gray-50/0 transition-[opacity] ease-in-out',
+ ]}
+ {...isSticky ? { 'data-aw-sticky-header': true } : {}}
+ {...id ? { id } : {}}
+>
+ <div class="absolute inset-0"></div>
+ <div
+ class:list={[
+ 'relative text-default py-3 px-3 md:px-6 mx-auto w-full',
+ {
+ 'md:flex md:justify-between': position !== 'center',
+ },
+ {
+ 'md:grid md:grid-cols-3 md:items-center': position === 'center',
+ },
+ {
+ 'max-w-7xl': !isFullWidth,
+ },
+ ]}
+ >
+ <div class:list={[{ 'mr-auto rtl:mr-0 rtl:ml-auto': position === 'right' }, 'flex justify-between']}>
+ <a class="flex items-center" href={getHomePermalink()}>
+ <Logo />
+ </a>
+ <div class="flex items-center md:hidden">
+ <ToggleMenu />
+ </div>
+ </div>
+ <nav
+ class="items-center w-full md:w-auto hidden md:flex md:mx-5 text-default overflow-y-auto overflow-x-hidden md:overflow-y-visible md:overflow-x-auto md:justify-self-center"
+ aria-label="Main navigation"
+ >
+ <ul
+ class="flex flex-col md:flex-row md:self-center w-full md:w-auto text-xl md:text-[0.9375rem] tracking-[0.01rem] font-medium md:justify-center"
+ >
+ {
+ links.map(({ text, href, links }) => (
+ <li class={links?.length ? 'dropdown' : ''}>
+ {links?.length ? (
+ <>
+ <button
+ type="button"
+ class="hover:text-link dark:hover:text-white px-4 py-3 flex items-center whitespace-nowrap"
+ >
+ {text}{' '}
+ <Icon name="tabler:chevron-down" class="w-3.5 h-3.5 ml-0.5 rtl:ml-0 rtl:mr-0.5 hidden md:inline" />
+ </button>
+ <ul class="dropdown-menu md:backdrop-blur-md dark:md:bg-dark rounded md:absolute pl-4 md:pl-0 md:hidden font-medium md:bg-white/90 md:min-w-[200px] drop-shadow-xl">
+ {links.map(({ text: text2, href: href2 }) => (
+ <li>
+ <a
+ class:list={[
+ 'first:rounded-t last:rounded-b md:hover:bg-gray-100 hover:text-link dark:hover:text-white dark:hover:bg-gray-700 py-2 px-5 block whitespace-no-wrap',
+ { 'aw-link-active': href2 === currentPath },
+ ]}
+ href={href2}
+ >
+ {text2}
+ </a>
+ </li>
+ ))}
+ </ul>
+ </>
+ ) : (
+ <a
+ class:list={[
+ 'hover:text-link dark:hover:text-white px-4 py-3 flex items-center whitespace-nowrap',
+ { 'aw-link-active': href === currentPath },
+ ]}
+ href={href}
+ >
+ {text}
+ </a>
+ )}
+ </li>
+ ))
+ }
+ </ul>
+ </nav>
+ <div
+ class:list={[
+ { 'ml-auto rtl:ml-0 rtl:mr-auto': position === 'left' },
+ 'hidden md:self-center md:flex items-center md:mb-0 fixed w-full md:w-auto md:static justify-end left-0 rtl:left-auto rtl:right-0 bottom-0 p-3 md:p-0 md:justify-self-end',
+ ]}
+ >
+ <div class="items-center flex justify-between w-full md:w-auto">
+ <div class="flex">
+ {showToggleTheme && <ToggleTheme iconClass="w-6 h-6 md:w-5 md:h-5 md:inline-block" />}
+ {
+ showRssFeed && (
+ <a
+ class="text-muted dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center"
+ aria-label="RSS Feed"
+ href={getAsset('/rss.xml')}
+ >
+ <Icon name="tabler:rss" class="w-5 h-5" />
+ </a>
+ )
+ }
+ </div>
+ {
+ actions?.length ? (
+ <span class="ml-4 rtl:ml-0 rtl:mr-4">
+ {actions.map((btnProps) => (
+ <Button {...btnProps} class="ml-2 py-2.5 px-5.5 md:px-6 font-semibold shadow-none text-sm w-auto" />
+ ))}
+ </span>
+ ) : (
+ ''
+ )
+ }
+ </div>
+ </div>
+ </div>
+</header>