实现响应式导航栏组件
This commit is contained in:
@@ -1,11 +1,154 @@
|
||||
import Provider from '@/app/(home)/@header/_client/provider'
|
||||
'use client'
|
||||
import UserCenter from '@/components/composites/user-center'
|
||||
import {useClientStore, useProfileStore} from '@/app/stores'
|
||||
import {buttonVariants} from '@/components/ui/button'
|
||||
import {
|
||||
Navigation,
|
||||
NavigationIndicator,
|
||||
NavigationLink,
|
||||
NavigationLinkItem,
|
||||
NavigationGroup,
|
||||
NavigationTriggerItem,
|
||||
NavigationMenuViewport,
|
||||
} from '@/components/ui/navigation-menu'
|
||||
import Wrap from '@/components/wrap'
|
||||
import {merge} from '@/lib/utils'
|
||||
import {useState, useCallback, useEffect, useContext} from 'react'
|
||||
import Image from 'next/image'
|
||||
import logo from '@/assets/logo.webp'
|
||||
import ProductMenu, {Domestic} from '@/app/(home)/@header/_client/product'
|
||||
import SolutionMenu from '@/app/(home)/@header/_client/solution'
|
||||
import HelpMenu from '@/app/(home)/@header/_client/help'
|
||||
import {MenuIcon} from 'lucide-react'
|
||||
|
||||
export type HeaderProps = {}
|
||||
|
||||
export default async function Header(props: HeaderProps) {
|
||||
export default function Header(props: HeaderProps) {
|
||||
// ======================
|
||||
// 背景显示状态
|
||||
// ======================
|
||||
|
||||
const [expand, setExpand] = useState(false)
|
||||
const [scroll, setScroll] = useState(false)
|
||||
const handleScroll = useCallback(() => {
|
||||
setScroll(window.scrollY > 48)
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
setScroll(window.scrollY > 48)
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
}
|
||||
}, [handleScroll])
|
||||
|
||||
// ======================
|
||||
// 移动端
|
||||
// ======================
|
||||
|
||||
const lg = useClientStore(state => state.breakpoint.lg)
|
||||
|
||||
// ======================
|
||||
// render
|
||||
// ======================
|
||||
|
||||
return (
|
||||
<header className="fixed top-0 w-full z-10">
|
||||
<Provider/>
|
||||
<header
|
||||
data-expand={expand}
|
||||
data-scroll={scroll}
|
||||
data-effect={expand || scroll}
|
||||
className="group/header w-full fixed left-0 top-0 z-20"
|
||||
>
|
||||
<Navigation
|
||||
onValueChange={(value) => {
|
||||
setExpand(!!value)
|
||||
}}
|
||||
>
|
||||
<div className={merge(
|
||||
`transition-[background-color,backdrop-filter,box-shadow] duration-200 ease-in-out`,
|
||||
`bg-transparent backdrop-blur-none shadow-none`,
|
||||
`group-data-[effect=true]/header:bg-card/90`,
|
||||
`group-data-[effect=true]/header:backdrop-blur-sm`,
|
||||
`group-data-[scroll=true]/header:shadow-lg`,
|
||||
)}>
|
||||
<Wrap className={merge('h-14 md:h-16 flex justify-between items-stretch')}>
|
||||
<div className="flex items-stretch lg:flex-row-reverse">
|
||||
{lg ? (
|
||||
<NavigationGroup className="gap-0 flex">
|
||||
<NavigationLinkItem href="/" text="首页"/>
|
||||
|
||||
<NavigationTriggerItem text="产品订购" className="h-80">
|
||||
<ProductMenu/>
|
||||
</NavigationTriggerItem>
|
||||
|
||||
<NavigationTriggerItem text="业务场景" className="h-80">
|
||||
<SolutionMenu/>
|
||||
</NavigationTriggerItem>
|
||||
|
||||
<NavigationTriggerItem text="帮助中心" className="h-80">
|
||||
<HelpMenu/>
|
||||
</NavigationTriggerItem>
|
||||
|
||||
<NavigationLinkItem href="/" text="企业服务"/>
|
||||
<NavigationLinkItem href="/" text="推广返利"/>
|
||||
|
||||
<NavigationIndicator/>
|
||||
</NavigationGroup>
|
||||
) : (
|
||||
<NavigationGroup className="flex">
|
||||
<NavigationTriggerItem
|
||||
suffix={false}
|
||||
text={<MenuIcon/>}
|
||||
className={merge(
|
||||
`flex flex-col items-start gap-6`,
|
||||
)}
|
||||
>
|
||||
<ProductMenu/>
|
||||
|
||||
<SolutionMenu/>
|
||||
|
||||
<HelpMenu/>
|
||||
|
||||
<NavigationLink href="/" text="企业服务"/>
|
||||
<NavigationLink href="/" text="推广返利"/>
|
||||
</NavigationTriggerItem>
|
||||
</NavigationGroup>
|
||||
)}
|
||||
|
||||
<NavigationLink href="/" text={<Image src={logo} alt="logo" height={36}/>}/>
|
||||
</div>
|
||||
<AccountRegion/>
|
||||
</Wrap>
|
||||
</div>
|
||||
|
||||
<NavigationMenuViewport className={merge(
|
||||
`bg-card/90 backdrop-blur-sm shadow-lg`,
|
||||
`transition-[padding,opacity,max-height]`,
|
||||
`group-data-[expand=false]/header:delay-[0s,0s,0.2s] group-data-[expand=true]/header:delay-0`,
|
||||
`p-0 group-data-[expand=true]/header:py-4`,
|
||||
`opacity-0 group-data-[effect=true]/header:opacity-100`,
|
||||
`max-h-0 group-data-[effect=true]/header:max-h-[calc(100vh-56px)] overflow-auto`,
|
||||
)}/>
|
||||
</Navigation>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
||||
function AccountRegion() {
|
||||
const profile = useProfileStore(state => state.profile)
|
||||
|
||||
return (
|
||||
<div className="self-center">
|
||||
{profile ? (
|
||||
<UserCenter profile={profile}/>
|
||||
) : (
|
||||
<NavigationLink
|
||||
href="/login"
|
||||
text="登录 / 注册"
|
||||
classNameOverride={buttonVariants({
|
||||
theme: 'gradient',
|
||||
className: 'h-10 lg:h-12',
|
||||
})}/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user