diff --git a/components/header/header.css b/components/header/header.css
new file mode 100644
index 0000000..fa33252
--- /dev/null
+++ b/components/header/header.css
@@ -0,0 +1,66 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+:root {
+ --header-height: 8rem;
+ --header-height-scrolled: 4.5rem;
+}
+
+@layer base {
+ header.scrolled {
+ height: var(--header-height-scrolled);
+
+ @apply border-border;
+ @apply bg-background;
+ }
+
+ .menuBtn {
+ --size: 1.5rem;
+ --duration: 250ms;
+
+ position: relative;
+ transform: rotate(0deg);
+ transition: var(--duration) * 2 ease-in-out;
+ }
+
+ .menuBtn > span {
+ display: block;
+ height: calc(var(--size) / 4);
+ left: 0;
+ opacity: 1;
+ position: absolute;
+ transform: rotate(0deg);
+ transition: var(--duration) ease-in-out;
+ width: var(--size);
+
+ @apply bg-foreground;
+ }
+
+ .menuBtn span:nth-child(1) {
+ top: 0;
+ }
+
+ .menuBtn span:nth-child(2) {
+ top: calc(var(--size) / 4 + var(--size) / 8);
+ }
+
+ .menuBtn span:nth-child(3) {
+ top: calc(var(--size) / 2 + var(--size) / 4);
+ }
+
+ .menuBtn.opened span:nth-child(1) {
+ top: calc(var(--size) / 4 + var(--size) / 8);
+ transform: rotate(135deg);
+ }
+
+ .menuBtn.opened span:nth-child(2) {
+ left: -60px;
+ opacity: 0;
+ }
+
+ .menuBtn.opened span:nth-child(3) {
+ top: calc(var(--size) / 4 + var(--size) / 8);
+ transform: rotate(-135deg);
+ }
+}
diff --git a/components/header/index.tsx b/components/header/index.tsx
new file mode 100644
index 0000000..2547522
--- /dev/null
+++ b/components/header/index.tsx
@@ -0,0 +1,20 @@
+import Logo from "./logo";
+import Nav from "./menu";
+import Sidebar from "./sidebar";
+import JumpToContent from "./util/jumpToContent";
+import HeaderWrapper from "./util/wrapper";
+
+export default function Header() {
+ return (
+ <>
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/components/header/logo.tsx b/components/header/logo.tsx
new file mode 100644
index 0000000..0dc308b
--- /dev/null
+++ b/components/header/logo.tsx
@@ -0,0 +1,28 @@
+"use client";
+import BaseLogo from "@/components/logo";
+import { useSidebarContext } from "@/context/sidebar";
+import { env } from "@/env/client";
+import { cn } from "@/lib/utils";
+
+export default function Logo() {
+ const sidebar = useSidebarContext();
+ return (
+ <>
+
+
+ /
+ {env.NEXT_PUBLIC_SITE_NAME}
+
+ >
+ );
+}
diff --git a/components/header/menu/index.tsx b/components/header/menu/index.tsx
new file mode 100644
index 0000000..34ee9de
--- /dev/null
+++ b/components/header/menu/index.tsx
@@ -0,0 +1,53 @@
+"use client";
+// import Link from "next/link";
+// import { usePathname } from "next/navigation";
+
+import {
+ NavigationMenu,
+ //NavigationMenuItem,
+ //NavigationMenuLink,
+ NavigationMenuList,
+ //navigationMenuTriggerStyle,
+} from "@/components/ui/navigation-menu";
+// import { cn } from "@/lib/utils";
+
+export default function Nav() {
+ // const router = usePathname();
+ return (
+ <>
+
+
+ {/*
+ Item One
+
+ Link
+
+ */}
+ {/*
+
+
+ Archive
+
+
+ */}
+ {/*
+
+
+ What's Trendy
+
+
+ */}
+
+
+ >
+ );
+}
diff --git a/components/header/sidebar/index.tsx b/components/header/sidebar/index.tsx
new file mode 100644
index 0000000..4a4c171
--- /dev/null
+++ b/components/header/sidebar/index.tsx
@@ -0,0 +1,21 @@
+import Nav from "./nav";
+import TopBar from "./topbar";
+import BackDrop from "./util/backdrop";
+import InnerWrapper from "./util/innerWrapper";
+import { MenuButton } from "./util/menuButton";
+
+export default function Sidebar() {
+ return (
+ <>
+
+
+
+ {/* */}
+
+
+
+
+
+ >
+ );
+}
diff --git a/components/header/sidebar/nav/index.tsx b/components/header/sidebar/nav/index.tsx
new file mode 100644
index 0000000..402f53a
--- /dev/null
+++ b/components/header/sidebar/nav/index.tsx
@@ -0,0 +1,34 @@
+"use client";
+import { FaBoxArchive, FaFileLines } from "react-icons/fa6";
+
+import LogOut from "./logout";
+import Privacy from "./privacy";
+import SidebarItem from "./sidebarItem";
+export default function Nav() {
+ return (
+ <>
+
+ >
+ );
+}
diff --git a/components/header/sidebar/nav/logout.tsx b/components/header/sidebar/nav/logout.tsx
new file mode 100644
index 0000000..fecd2eb
--- /dev/null
+++ b/components/header/sidebar/nav/logout.tsx
@@ -0,0 +1,57 @@
+"use client";
+import { type KeyboardEventHandler, useState } from "react";
+
+import { useSidebarContext } from "@/context/sidebar";
+import { cn } from "@/lib/utils";
+
+export default function LogOut() {
+ const [isLoggedIn] = useState(false);
+ const sidebar = useSidebarContext();
+ const trapFocus: KeyboardEventHandler = (e) => {
+ if (e.code === "Tab" && sidebar.btnInSidebarRef.current) {
+ sidebar.isExpanded && sidebar.btnInSidebarRef.current.focus();
+ }
+ };
+ return (
+ <>
+ {isLoggedIn && (
+ <>
+
+
+ Logga Ut
+
+ >
+ )}
+ >
+ );
+}
diff --git a/components/header/sidebar/nav/privacy.tsx b/components/header/sidebar/nav/privacy.tsx
new file mode 100644
index 0000000..fd2fc8a
--- /dev/null
+++ b/components/header/sidebar/nav/privacy.tsx
@@ -0,0 +1,30 @@
+"use client";
+import { type KeyboardEventHandler, useState } from "react";
+import { FaPassport } from "react-icons/fa6";
+
+import { useSidebarContext } from "@/context/sidebar";
+
+import SidebarItem from "./sidebarItem";
+
+export default function Privacy() {
+ const sidebar = useSidebarContext();
+ const [isLoggedIn] = useState(false);
+ const trapFocus: KeyboardEventHandler = (e) => {
+ if (e.code === "Tab" && !e.shiftKey && sidebar.mainMenuBtnRef.current) {
+ e.preventDefault();
+ sidebar.isExpanded && sidebar.mainMenuBtnRef.current.focus();
+ }
+ };
+ return (
+ <>
+
+
+
+ >
+ );
+}
diff --git a/components/header/sidebar/nav/sidebarItem.tsx b/components/header/sidebar/nav/sidebarItem.tsx
new file mode 100644
index 0000000..568fba6
--- /dev/null
+++ b/components/header/sidebar/nav/sidebarItem.tsx
@@ -0,0 +1,67 @@
+"use client";
+import Link from "next/link";
+import { usePathname } from "next/navigation";
+import type { KeyboardEventHandler } from "react";
+
+import { useSidebarContext } from "@/context/sidebar";
+import { cn } from "@/lib/utils";
+
+export default function SidebarItem({
+ href,
+ classes = "",
+ text,
+ isLast = false,
+ onKeyDown,
+ children,
+}: {
+ href: string;
+ classes?: string;
+ text: string;
+ isLast?: boolean;
+ onKeyDown?: KeyboardEventHandler | undefined;
+ children?: React.ReactNode;
+}) {
+ const sidebar = useSidebarContext();
+ const pathname = usePathname();
+ let attr = {};
+ attr = {
+ tabIndex: sidebar.isExpanded ? 0 : -1,
+ onClick: () => sidebar.toggle(),
+ };
+ if (isLast) {
+ attr = {
+ ...attr,
+ onKeyDown,
+ };
+ }
+ return (
+ <>
+
+
+ {children}
+
+ {text}
+
+
+ >
+ );
+}
diff --git a/components/header/sidebar/topbar/index.tsx b/components/header/sidebar/topbar/index.tsx
new file mode 100644
index 0000000..5d154ee
--- /dev/null
+++ b/components/header/sidebar/topbar/index.tsx
@@ -0,0 +1,21 @@
+import { cn } from "@/lib/utils";
+
+import SearchButton from "./searchBtn";
+
+export default function TopBar() {
+ return (
+ <>
+
+
+ {/* */}
+
+ >
+ );
+}
diff --git a/components/header/sidebar/topbar/searchBtn.tsx b/components/header/sidebar/topbar/searchBtn.tsx
new file mode 100644
index 0000000..3323947
--- /dev/null
+++ b/components/header/sidebar/topbar/searchBtn.tsx
@@ -0,0 +1,33 @@
+export default function SearchButton() {
+ return (
+ <>
+ {/* */}
+
+ >
+ );
+}
diff --git a/components/header/sidebar/util/backdrop.tsx b/components/header/sidebar/util/backdrop.tsx
new file mode 100644
index 0000000..54bd500
--- /dev/null
+++ b/components/header/sidebar/util/backdrop.tsx
@@ -0,0 +1,20 @@
+"use client";
+import { useSidebarContext } from "@/context/sidebar";
+import { cn } from "@/lib/utils";
+
+export default function BackDrop() {
+ const sidebar = useSidebarContext();
+ return (
+ <>
+
+ >
+ );
+}
diff --git a/components/header/sidebar/util/innerMenuButton.tsx b/components/header/sidebar/util/innerMenuButton.tsx
new file mode 100644
index 0000000..661551f
--- /dev/null
+++ b/components/header/sidebar/util/innerMenuButton.tsx
@@ -0,0 +1,40 @@
+"use client";
+import { useSidebarContext } from "@/context/sidebar";
+import { cn } from "@/lib/utils";
+
+export default function InnerMenuButton() {
+ const sidebar = useSidebarContext();
+ return (
+ <>
+
+ >
+ );
+}
diff --git a/components/header/sidebar/util/innerWrapper.tsx b/components/header/sidebar/util/innerWrapper.tsx
new file mode 100644
index 0000000..4d5e3bf
--- /dev/null
+++ b/components/header/sidebar/util/innerWrapper.tsx
@@ -0,0 +1,56 @@
+"use client";
+import { useState } from "react";
+
+import { useSidebarContext } from "@/context/sidebar";
+import { cn } from "@/lib/utils";
+
+export default function InnerWrapper({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const sidebar = useSidebarContext();
+ const [touchStart, setTouchStart] = useState(0);
+ const [touchEnd, setTouchEnd] = useState(0);
+ //127 - 72 = 55 / 2 = 22 - 23
+ return (
+ <>
+
+ >
+ );
+}
diff --git a/components/header/sidebar/util/menuButton.tsx b/components/header/sidebar/util/menuButton.tsx
new file mode 100644
index 0000000..10005cd
--- /dev/null
+++ b/components/header/sidebar/util/menuButton.tsx
@@ -0,0 +1,52 @@
+"use client";
+import { forwardRef } from "react";
+
+import { useSidebarContext } from "@/context/sidebar";
+import { cn } from "@/lib/utils";
+
+type Props = JSX.IntrinsicElements["button"];
+
+type Ref = HTMLButtonElement;
+export const MenuButton = forwardRef[(function MenuButton() {
+ const sidebar = useSidebarContext();
+ return (
+ <>
+
+ >
+ );
+});
diff --git a/components/header/sidebar/util/swipearea.tsx b/components/header/sidebar/util/swipearea.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/components/header/util/jumpToContent.tsx b/components/header/util/jumpToContent.tsx
new file mode 100644
index 0000000..c3de3a2
--- /dev/null
+++ b/components/header/util/jumpToContent.tsx
@@ -0,0 +1,18 @@
+import { Button } from "@/components/ui/button";
+import { cn } from "@/lib/utils";
+
+export default function JumpToContent() {
+ return (
+ <>
+
+ >
+ );
+}
diff --git a/components/header/util/wrapper.tsx b/components/header/util/wrapper.tsx
new file mode 100644
index 0000000..ed5d25f
--- /dev/null
+++ b/components/header/util/wrapper.tsx
@@ -0,0 +1,53 @@
+"use client";
+import { useEffect } from "react";
+import { useInView } from "react-intersection-observer";
+
+import { useSidebarContext } from "@/context/sidebar";
+import { cn } from "@/lib/utils";
+
+import "@/components/header/header.css";
+
+export default function HeaderWrapper({
+ children,
+}: {
+ children: React.ReactNode;
+}) {
+ const { setIsAtTop } = useSidebarContext();
+ const { ref, inView } = useInView({
+ threshold: 0,
+ initialInView: true,
+ fallbackInView: false,
+ });
+
+ useEffect(() => {
+ setIsAtTop(inView);
+ }, [inView, setIsAtTop]);
+ return (
+ <>
+
+
+ >
+ );
+}
diff --git a/components/logo.tsx b/components/logo.tsx
new file mode 100644
index 0000000..21dbebd
--- /dev/null
+++ b/components/logo.tsx
@@ -0,0 +1,26 @@
+export default function Logo({
+ className = "",
+ length = 32,
+}: {
+ className?: string;
+ length?: number;
+}) {
+ return (
+ <>
+
+ >
+ );
+}
]