Folo/apps/server/client/components/layout/header/index.tsx

110 lines
3.5 KiB
TypeScript

import { siteConfig } from "@client/configs"
import { openInFollowApp } from "@client/lib/helper"
import { Logo } from "@follow/components/icons/logo.jsx"
import { Button } from "@follow/components/ui/button/index.jsx"
import { Kbd } from "@follow/components/ui/kbd/Kbd.jsx"
import { cn } from "@follow/utils/utils"
import type { MotionValue } from "framer-motion"
import { useMotionValueEvent, useScroll } from "framer-motion"
import * as React from "react"
import { useState } from "react"
import { useHotkeys } from "react-hotkeys-hook"
import { Link } from "react-router-dom"
const useMotionValueToState = (value: MotionValue<number>) => {
const [state, setState] = useState(value.get())
useMotionValueEvent(value, "change", (v) => setState(v))
return state
}
function Container({ className, ...props }: React.ComponentPropsWithoutRef<"div">) {
return (
<div
className={cn(
"mx-auto w-full max-w-[var(--container-max-width)] px-4 sm:px-6 lg:px-8",
className,
)}
{...props}
/>
)
}
const HeaderWrapper: Component = (props) => {
const { scrollY } = useScroll()
const scrollYState = useMotionValueToState(scrollY)
const showOverlay = scrollYState > 100
return (
<header
className={cn(
"fixed inset-x-0 top-0 z-50 flex h-[80px] w-full items-center px-4 duration-200 lg:px-10",
showOverlay && "h-[60px] border-b",
)}
>
<div
className={cn(
"absolute inset-0 transform-gpu [-webkit-backdrop-filter:saturate(180%)_blur(20px)] [backdrop-filter:saturate(180%)_blur(20px)] [backface-visibility:hidden]",
"bg-[var(--bg-opacity)] duration-200 [border-bottom:1px_solid_rgb(187_187_187_/_20%)]",
)}
style={{
opacity: showOverlay ? 1 : 0,
}}
/>
{props.children}
</header>
)
}
export const Header = () => {
const handleToApp = () => {
openInFollowApp(
"",
() => {
window.open(siteConfig.appUrl, "_blank")
},
true,
)
}
useHotkeys("l", handleToApp)
return (
<HeaderWrapper>
<Container>
<nav className="relative flex justify-between">
<div className="flex items-center md:gap-x-12">
<Link className="flex items-center gap-4" to="/">
<Logo className="h-8 w-auto" />
<p className="font-default text-xl font-semibold">{APP_NAME}</p>
</Link>
</div>
<div className="flex items-center gap-4">
<Button
className="flex size-9 rounded-full border-neutral-300 bg-transparent hover:border-zinc-400 dark:border-neutral-700 dark:hover:border-zinc-600 md:w-auto md:px-2"
variant="outline"
>
<a
href={siteConfig.repoUrl}
className="flex items-center gap-2"
target="_blank"
rel="noopener noreferrer"
>
<span className="i-simple-icons-github size-4" />
<span className="hidden md:inline">Star on GitHub</span>
</a>
</Button>
<Button
buttonClassName="hidden lg:block cursor-pointer !text-accent-content"
onClick={handleToApp}
>
Open app
<Kbd className="kbd-xs !leading-0 !dark:bg-zinc-200 ml-2 size-5 scale-[0.85] rounded-sm !border-transparent !bg-zinc-50 !font-mono text-black">
L
</Kbd>
</Button>
</div>
</nav>
</Container>
</HeaderWrapper>
)
}