Compare commits
2 Commits
826805a0cc
...
2a41465de0
| Author | SHA1 | Date |
|---|---|---|
|
|
2a41465de0 | |
|
|
fc6b0d3a7c |
|
|
@ -1,6 +1,6 @@
|
||||||
import { Search } from 'lucide-react';
|
import { Search } from 'lucide-react';
|
||||||
import React, { useState,useEffect} from 'react';
|
import React, { useState,useEffect} from 'react';
|
||||||
|
import { Button } from '@/ui/button';
|
||||||
interface MenuItem {
|
interface MenuItem {
|
||||||
label: string;
|
label: string;
|
||||||
key: string;
|
key: string;
|
||||||
|
|
@ -29,15 +29,15 @@ export function TopNav({
|
||||||
const [internalActiveKey, setInternalActiveKey] = useState('home');
|
const [internalActiveKey, setInternalActiveKey] = useState('home');
|
||||||
const currentActiveKey = externalActiveKey !== undefined ? externalActiveKey : internalActiveKey;
|
const currentActiveKey = externalActiveKey !== undefined ? externalActiveKey : internalActiveKey;
|
||||||
const [searchKeyword, setSearchKeyword] = useState('');
|
const [searchKeyword, setSearchKeyword] = useState('');
|
||||||
const [activeIndex, setActiveIndex] = useState(0);
|
// const [activeIndex, setActiveIndex] = useState(0);
|
||||||
const [prevIndex, setPrevIndex] = useState(0);
|
// const [prevIndex, setPrevIndex] = useState(0);
|
||||||
|
|
||||||
// 监听激活项变化,更新索引和动画方向
|
// 监听激活项变化,更新索引和动画方向
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
const currentIndex = menuItems.findIndex(item => item.key === currentActiveKey);
|
// const currentIndex = menuItems.findIndex(item => item.key === currentActiveKey);
|
||||||
setPrevIndex(activeIndex);
|
// setPrevIndex(activeIndex);
|
||||||
setActiveIndex(currentIndex);
|
// setActiveIndex(currentIndex);
|
||||||
}, [currentActiveKey, menuItems, activeIndex]);
|
// }, [currentActiveKey, menuItems, activeIndex]);
|
||||||
|
|
||||||
const handleSearchSubmit = (e: React.FormEvent) => {
|
const handleSearchSubmit = (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
@ -52,61 +52,53 @@ export function TopNav({
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-20 flex items-center justify-center px-8 bg-white">
|
// 将组件宽度调整为1514px,并保持居中
|
||||||
|
<div className="h-20 w-[1514px] mx-auto flex items-center px-8 bg-white border-t-16 border-b-16 border-[#1f79bf]">
|
||||||
{/* 搜索框与导航菜单组合 */}
|
{/* 搜索框与导航菜单组合 */}
|
||||||
<div className="flex items-center space-x-4">
|
<div className="flex items-center justify-start w-full gap-5">
|
||||||
{/* 搜索框 */}
|
{/* 搜索框 */}
|
||||||
<form onSubmit={handleSearchSubmit} className="relative">
|
|
||||||
<div className="relative">
|
<div className="relative overflow-hidden bg-gray-100 ">
|
||||||
<input
|
<Button variant="default" className="absolute rounded-none right-0 top-1/2 transform -translate-y-1/2 bg-[#1f79bf] hover:bg-[#1a68a0] text-white border-0 "
|
||||||
type="text"
|
onClick={handleSearchSubmit}
|
||||||
|
|
||||||
|
>
|
||||||
|
<Search className="w-5 h-5" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<input type="text"
|
||||||
|
placeholder='请输入关键词'
|
||||||
value={searchKeyword}
|
value={searchKeyword}
|
||||||
onChange={(e) => setSearchKeyword(e.target.value)}
|
onChange={(e) => setSearchKeyword(e.target.value)}
|
||||||
placeholder="搜索..."
|
className="pl-5 pr-4 py-2 text-sm h-full border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent w-64 transition-all duration-200 hover:shadow-sm" />
|
||||||
className="pl-10 pr-4 py-2 text-sm border border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent w-64 transition-all duration-200 hover:shadow-sm"
|
|
||||||
/>
|
|
||||||
<span className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400">
|
|
||||||
<Search className="w-5 h-5" />
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
|
|
||||||
{/* 导航菜单 */}
|
{/* 导航菜单 */}
|
||||||
<ul className="flex space-x-8 relative">
|
<ul className="flex space-x-20 relative">
|
||||||
{/* 滑动背景层 */}
|
{menuItems.map((item) => {
|
||||||
<div
|
|
||||||
className="absolute inset-y-0 z-0 transition-all duration-500 ease-out"
|
|
||||||
style={{
|
|
||||||
left: `${activeIndex * (100 / menuItems.length)}%`,
|
|
||||||
width: `${100 / menuItems.length}%`,
|
|
||||||
clipPath: 'polygon(0% 0%, 80% 0%, 100% 100%, 20% 100%)', // 向左倾斜的平行四边形
|
|
||||||
background: 'linear-gradient(135deg, #3b82f6 0%, #1d4ed8 100%)',
|
|
||||||
transform: `translateX(${(prevIndex - activeIndex) * 100}%)`,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{menuItems.map((item, index) => {
|
|
||||||
const isActive = currentActiveKey === item.key;
|
const isActive = currentActiveKey === item.key;
|
||||||
return (
|
return (
|
||||||
<li
|
<li key={item.key} className="relative">
|
||||||
key={item.key}
|
|
||||||
className="relative z-10"
|
|
||||||
style={{ width: `${100 / menuItems.length}%` }}
|
|
||||||
>
|
|
||||||
<button
|
<button
|
||||||
onClick={() => handleItemClick(item)}
|
onClick={() => handleItemClick(item)}
|
||||||
className={`w-full h-full px-4 py-2 text-2xl transition-all duration-300 ${
|
className={`px-4 py-2 text-2xl font-extralight transition-all duration-500 relative z-10 ${
|
||||||
isActive
|
isActive ? 'text-white' : 'text-gray-600 hover:font-bold'
|
||||||
? 'text-white' // 激活状态文字颜色
|
|
||||||
: 'text-gray-600 hover:text-black cursor-pointer' // 非激活状态样式
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{item.label}
|
{/* 激活状态背景层 */}
|
||||||
|
{isActive && (
|
||||||
|
<span className="absolute inset-0 bg-gradient-to-br from-blue-500 to-blue-700 transform skew-x-12 rounded-none z-0"></span>
|
||||||
|
)}
|
||||||
|
<span className="relative z-20">{item.label}</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue