放大产品中心菜单并适配 iPad 触控
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+50
-28
@@ -46,19 +46,19 @@ function isActive(item: NavItem): boolean {
|
||||
}
|
||||
|
||||
function getNavLinkClass(item: NavItem) {
|
||||
const baseClass = 'flex items-center gap-2 px-4 py-2.5 rounded-full font-medium transition-all duration-300';
|
||||
const baseClass = 'nav-link flex items-center gap-2 px-5 py-3 rounded-full text-base font-semibold transition-all duration-300 touch-manipulation select-none';
|
||||
if (isActive(item)) {
|
||||
return `${baseClass} bg-primary text-white shadow-md`;
|
||||
}
|
||||
return `${baseClass} text-gray-600 hover:text-primary hover:bg-primary/10`;
|
||||
return `${baseClass} text-gray-600`;
|
||||
}
|
||||
|
||||
function getMobileNavLinkClass(item: NavItem) {
|
||||
const baseClass = 'flex flex-col items-center justify-center py-2 px-2 min-w-[4.5rem] rounded-xl transition-all duration-300';
|
||||
const baseClass = 'flex flex-col items-center justify-center py-2.5 px-3 min-w-[5.5rem] rounded-xl transition-all duration-300 touch-manipulation select-none';
|
||||
if (isActive(item)) {
|
||||
return `${baseClass} bg-primary text-white`;
|
||||
}
|
||||
return `${baseClass} text-gray-600 hover:bg-primary/10`;
|
||||
return `${baseClass} text-gray-600`;
|
||||
}
|
||||
---
|
||||
|
||||
@@ -85,25 +85,25 @@ function getMobileNavLinkClass(item: NavItem) {
|
||||
<span>{item.label}</span>
|
||||
<i class="fa fa-angle-down text-xs ml-0.5 transition-transform duration-200" data-dropdown-chevron></i>
|
||||
</button>
|
||||
<div class="absolute top-full left-1/2 -translate-x-1/2 pt-2 opacity-0 invisible transition-all duration-200 z-50"
|
||||
<div class="absolute top-full left-1/2 -translate-x-1/2 pt-3 opacity-0 invisible transition-all duration-200 z-50"
|
||||
data-dropdown-panel role="menu">
|
||||
<div class="bg-white rounded-2xl shadow-xl border border-gray-100 p-3 w-[600px]">
|
||||
<div class="grid grid-cols-3 gap-2">
|
||||
<div class="bg-white rounded-2xl shadow-xl border border-gray-100 p-4 w-[760px]">
|
||||
<div class="grid grid-cols-3 gap-3">
|
||||
{item.children.map(child => (
|
||||
<a href={child.href} role="menuitem"
|
||||
class={`group flex items-center gap-3 px-3 py-2.5 rounded-lg transition-all ${
|
||||
class={`menu-item group flex items-center gap-3.5 px-4 py-3.5 rounded-xl transition-all touch-manipulation select-none ${
|
||||
child.id === activeNav
|
||||
? 'bg-primary text-white'
|
||||
: 'text-gray-700 hover:bg-primary/10 hover:text-primary'
|
||||
: 'text-gray-700'
|
||||
}`}>
|
||||
<span class={`w-9 h-9 rounded-lg flex items-center justify-center shrink-0 ${
|
||||
<span class={`menu-item-icon w-12 h-12 rounded-xl flex items-center justify-center shrink-0 transition-colors ${
|
||||
child.id === activeNav
|
||||
? 'bg-white/20 text-white'
|
||||
: 'bg-primary/10 text-primary group-hover:bg-primary group-hover:text-white'
|
||||
: 'bg-primary/10 text-primary'
|
||||
}`}>
|
||||
<i class={`fa ${child.icon} text-base`}></i>
|
||||
<i class={`fa ${child.icon} text-xl`}></i>
|
||||
</span>
|
||||
<span class="text-sm font-semibold whitespace-nowrap">{child.label}</span>
|
||||
<span class="text-base font-semibold whitespace-nowrap">{child.label}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
@@ -142,19 +142,19 @@ function getMobileNavLinkClass(item: NavItem) {
|
||||
class={getMobileNavLinkClass(item)}
|
||||
aria-haspopup="true" aria-expanded="false"
|
||||
data-mobile-dropdown-trigger>
|
||||
<i class={`fa ${item.icon} text-lg mb-1`}></i>
|
||||
<span class="text-xs font-medium whitespace-nowrap">{item.label}</span>
|
||||
<i class={`fa ${item.icon} text-xl mb-1`}></i>
|
||||
<span class="text-sm font-semibold whitespace-nowrap">{item.label}</span>
|
||||
</button>
|
||||
) : (
|
||||
<a href={item.href} class={getMobileNavLinkClass(item)}>
|
||||
<i class={`fa ${item.icon} text-lg mb-1`}></i>
|
||||
<span class="text-xs font-medium whitespace-nowrap">{item.label}</span>
|
||||
<i class={`fa ${item.icon} text-xl mb-1`}></i>
|
||||
<span class="text-sm font-semibold whitespace-nowrap">{item.label}</span>
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
<a href="/#contact-info" class="flex items-center justify-center py-2 px-3 bg-primary text-white rounded-xl min-w-[3rem] ml-1">
|
||||
<i class="fa fa-phone text-lg"></i>
|
||||
<a href="/#contact-info" class="flex items-center justify-center py-2.5 px-3.5 bg-primary text-white rounded-xl min-w-[3.25rem] ml-1.5">
|
||||
<i class="fa fa-phone text-xl"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -163,16 +163,16 @@ function getMobileNavLinkClass(item: NavItem) {
|
||||
<div id="mobile-product-panel"
|
||||
class="lg:hidden fixed left-0 right-0 z-30 bg-white shadow-xl border-b border-gray-200 transform -translate-y-full opacity-0 pointer-events-none transition-all duration-300"
|
||||
style="top: 108px;" role="menu">
|
||||
<div class="max-w-md mx-auto px-3 py-3 grid grid-cols-3 gap-2">
|
||||
<div class="max-w-lg mx-auto px-4 py-4 grid grid-cols-3 gap-3">
|
||||
{navItems.find(item => item.children)?.children?.map(child => (
|
||||
<a href={child.href} role="menuitem"
|
||||
class={`flex flex-col items-center gap-1.5 py-2.5 px-1 rounded-xl transition-colors ${
|
||||
class={`flex flex-col items-center gap-2 py-4 px-2 rounded-xl transition-colors touch-manipulation select-none ${
|
||||
child.id === activeNav
|
||||
? 'bg-primary text-white'
|
||||
: 'bg-primary/5 text-gray-700 hover:bg-primary/10'
|
||||
: 'bg-primary/5 text-gray-700'
|
||||
}`}>
|
||||
<i class={`fa ${child.icon} text-lg ${child.id === activeNav ? 'text-white' : 'text-primary'}`}></i>
|
||||
<span class={`text-[11px] font-semibold leading-tight text-center whitespace-nowrap ${child.id === activeNav ? 'text-white' : 'text-gray-700'}`}>{child.label}</span>
|
||||
<i class={`fa ${child.icon} text-2xl ${child.id === activeNav ? 'text-white' : 'text-primary'}`}></i>
|
||||
<span class={`text-sm font-semibold leading-tight text-center whitespace-nowrap ${child.id === activeNav ? 'text-white' : 'text-gray-700'}`}>{child.label}</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
@@ -182,8 +182,8 @@ function getMobileNavLinkClass(item: NavItem) {
|
||||
<div id="mobile-product-backdrop"
|
||||
class="lg:hidden fixed inset-0 z-20 bg-black/20 opacity-0 pointer-events-none transition-opacity duration-300"></div>
|
||||
|
||||
<!-- Spacer for mobile to prevent content overlap (header 3.5rem + nav 2.5rem) -->
|
||||
<div class="lg:hidden h-[6rem] transition-all duration-300"></div>
|
||||
<!-- Spacer for mobile to prevent content overlap (header ~3.5rem + nav ~4rem) -->
|
||||
<div class="lg:hidden h-[7.5rem] transition-all duration-300"></div>
|
||||
|
||||
<slot />
|
||||
<Footer />
|
||||
@@ -198,7 +198,7 @@ function getMobileNavLinkClass(item: NavItem) {
|
||||
(function() {
|
||||
var navContainer = document.getElementById('mobile-nav-container');
|
||||
var headerRow = document.getElementById('mobile-header-row');
|
||||
var spacer = document.querySelector('.lg\\:hidden.h-\\[6rem\\]');
|
||||
var spacer = document.querySelector('.lg\\:hidden.h-\\[7\\.5rem\\]');
|
||||
var lastScrollTop = 0;
|
||||
var scrollThreshold = 50;
|
||||
|
||||
@@ -239,7 +239,7 @@ function getMobileNavLinkClass(item: NavItem) {
|
||||
}
|
||||
// Restore spacer height
|
||||
if (spacer) {
|
||||
(spacer as HTMLElement).style.height = '6rem';
|
||||
(spacer as HTMLElement).style.height = '7.5rem';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,6 +379,28 @@ function getMobileNavLinkClass(item: NavItem) {
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hover effects only on real pointer devices (avoid sticky hover on iPad/touch) */
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.nav-link.text-gray-600:hover {
|
||||
color: var(--color-primary, #165DFF);
|
||||
background-color: rgb(22 93 255 / 0.1);
|
||||
}
|
||||
.menu-item.text-gray-700:hover {
|
||||
background-color: rgb(22 93 255 / 0.1);
|
||||
color: var(--color-primary, #165DFF);
|
||||
}
|
||||
.menu-item.text-gray-700:hover .menu-item-icon {
|
||||
background-color: var(--color-primary, #165DFF);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Active tap feedback for touch / iPad */
|
||||
.nav-link:active,
|
||||
.menu-item:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user