94 lines
2.1 KiB
Plaintext
94 lines
2.1 KiB
Plaintext
/**
|
|
* useHover Hook
|
|
* 用于检测鼠标悬停状态,仅在桌面端(Web)生效
|
|
* 在移动端返回默认值 false
|
|
*/
|
|
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
import { Platform } from 'react-native';
|
|
|
|
interface UseHoverOptions {
|
|
enterDelay?: number;
|
|
leaveDelay?: number;
|
|
}
|
|
|
|
interface UseHoverReturn {
|
|
isHovered: boolean;
|
|
hoverProps: {
|
|
onMouseEnter: () => void;
|
|
onMouseLeave: () => void;
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 检测当前是否在 Web 平台
|
|
*/
|
|
const isWeb = Platform.OS === 'web';
|
|
|
|
/**
|
|
* useHover Hook
|
|
* @param options 配置选项
|
|
* @returns 悬停状态和事件处理器
|
|
*/
|
|
export function useHover(options: UseHoverOptions = {}): UseHoverReturn {
|
|
const { enterDelay = 0, leaveDelay = 0 } = options;
|
|
const [isHovered, setIsHovered] = useState(false);
|
|
const enterTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
const leaveTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
|
|
// 清理定时器
|
|
useEffect(() => {
|
|
return () => {
|
|
if (enterTimeoutRef.current) {
|
|
clearTimeout(enterTimeoutRef.current);
|
|
}
|
|
if (leaveTimeoutRef.current) {
|
|
clearTimeout(leaveTimeoutRef.current);
|
|
}
|
|
};
|
|
}, []);
|
|
|
|
const handleMouseEnter = useCallback(() => {
|
|
if (!isWeb) return;
|
|
|
|
if (leaveTimeoutRef.current) {
|
|
clearTimeout(leaveTimeoutRef.current);
|
|
leaveTimeoutRef.current = null;
|
|
}
|
|
|
|
if (enterDelay > 0) {
|
|
enterTimeoutRef.current = setTimeout(() => {
|
|
setIsHovered(true);
|
|
}, enterDelay);
|
|
} else {
|
|
setIsHovered(true);
|
|
}
|
|
}, [enterDelay]);
|
|
|
|
const handleMouseLeave = useCallback(() => {
|
|
if (!isWeb) return;
|
|
|
|
if (enterTimeoutRef.current) {
|
|
clearTimeout(enterTimeoutRef.current);
|
|
enterTimeoutRef.current = null;
|
|
}
|
|
|
|
if (leaveDelay > 0) {
|
|
leaveTimeoutRef.current = setTimeout(() => {
|
|
setIsHovered(false);
|
|
}, leaveDelay);
|
|
} else {
|
|
setIsHovered(false);
|
|
}
|
|
}, [leaveDelay]);
|
|
|
|
return {
|
|
isHovered,
|
|
hoverProps: {
|
|
onMouseEnter: handleMouseEnter,
|
|
onMouseLeave: handleMouseLeave,
|
|
},
|
|
};
|
|
}
|
|
|
|
export default useHover;
|