添加了导航栏的鼠标悬停效果

This commit is contained in:
2026-03-24 20:53:31 +08:00
parent cf466a3959
commit ecc3d088a5
5 changed files with 289 additions and 31 deletions

View File

@@ -19,6 +19,7 @@ import type { TabName, NavItemConfig } from '../infrastructure/navigation/types'
import { NAVIGATION_CONSTANTS } from '../infrastructure/navigation/types';
import { colors, shadows } from '../theme';
import { useNavigationState } from '../infrastructure/navigation/hooks/useNavigationState';
import { useHover } from '../hooks/useHover';
// 导入屏幕
import { HomeScreen } from '../screens/home';
@@ -41,6 +42,66 @@ interface DesktopNavigatorProps {
unreadCount?: number;
}
// 单个导航项组件,支持悬停效果
interface NavItemProps {
item: NavItemConfig;
isActive: boolean;
isCollapsed: boolean;
showBadge: boolean;
unreadCount: number;
onPress: () => void;
}
const NavItem: React.FC<NavItemProps> = ({
item,
isActive,
isCollapsed,
showBadge,
unreadCount,
onPress,
}) => {
const { isHovered, hoverProps } = useHover();
return (
<TouchableOpacity
style={[
styles.sidebarItem,
isActive && styles.sidebarItemActive,
isHovered && !isActive && styles.sidebarItemHovered,
isCollapsed && styles.sidebarItemCollapsed,
]}
onPress={onPress}
activeOpacity={0.7}
{...hoverProps}
>
<View style={[
styles.sidebarIconContainer,
isHovered && !isActive && styles.sidebarIconContainerHovered,
]}>
<MaterialCommunityIcons
name={isActive ? (item.icon as any) : (item.iconOutline as any)}
size={24}
color={isActive ? colors.primary.main : isHovered ? colors.primary.main : colors.text.secondary}
/>
{showBadge && (
<View style={styles.badge}>
<Text style={styles.badgeText}>{unreadCount > 99 ? '99+' : unreadCount}</Text>
</View>
)}
</View>
{!isCollapsed && (
<Text style={[
styles.sidebarLabel,
isActive && styles.sidebarLabelActive,
isHovered && !isActive && styles.sidebarLabelHovered,
]}>
{item.label}
</Text>
)}
</TouchableOpacity>
);
};
export function DesktopNavigator({ unreadCount = 0 }: DesktopNavigatorProps) {
const insets = useSafeAreaInsets();
const { currentTab, isCollapsed, setCurrentTab, toggleCollapse, setIsReady } = useNavigationState();
@@ -103,34 +164,15 @@ export function DesktopNavigator({ unreadCount = 0 }: DesktopNavigatorProps) {
const showBadge = item.name === 'MessageTab' && unreadCount > 0;
return (
<TouchableOpacity
<NavItem
key={item.name}
style={[
styles.sidebarItem,
isActive && styles.sidebarItemActive,
isCollapsed && styles.sidebarItemCollapsed,
]}
item={item}
isActive={isActive}
isCollapsed={isCollapsed}
showBadge={showBadge}
unreadCount={unreadCount}
onPress={() => handleTabChange(item.name)}
activeOpacity={0.7}
>
<View style={styles.sidebarIconContainer}>
<MaterialCommunityIcons
name={isActive ? item.icon : item.iconOutline}
size={24}
color={isActive ? colors.primary.main : colors.text.secondary}
/>
{showBadge && (
<View style={styles.badge}>
<Text style={styles.badgeText}>{unreadCount > 99 ? '99+' : unreadCount}</Text>
</View>
)}
</View>
{!isCollapsed && (
<Text style={[styles.sidebarLabel, isActive && styles.sidebarLabelActive]}>
{item.label}
</Text>
)}
</TouchableOpacity>
/>
);
})}
</ScrollView>
@@ -201,6 +243,9 @@ const styles = StyleSheet.create({
sidebarItemActive: {
backgroundColor: `${colors.primary.main}15`,
},
sidebarItemHovered: {
backgroundColor: `${colors.primary.main}08`,
},
sidebarItemCollapsed: {
justifyContent: 'center',
paddingHorizontal: 0,
@@ -213,6 +258,9 @@ const styles = StyleSheet.create({
justifyContent: 'center',
borderRadius: 12,
},
sidebarIconContainerHovered: {
backgroundColor: `${colors.primary.main}10`,
},
sidebarLabel: {
fontSize: 15,
fontWeight: '500',
@@ -224,6 +272,9 @@ const styles = StyleSheet.create({
color: colors.primary.main,
fontWeight: '600',
},
sidebarLabelHovered: {
color: colors.primary.main,
},
collapseButton: {
flexDirection: 'row',
alignItems: 'center',