118 lines
2.8 KiB
TypeScript
118 lines
2.8 KiB
TypeScript
import { useEffect, useCallback, useState } from 'react';
|
|
|
|
/**
|
|
* Hook centralisé pour la gestion du scroll du body
|
|
* Factorisation de la logique répétée dans plusieurs composants
|
|
*/
|
|
export const useBodyScrollLock = (isLocked: boolean) => {
|
|
useEffect(() => {
|
|
const originalStyle = document.body.style.overflow;
|
|
|
|
if (isLocked) {
|
|
document.body.style.overflow = 'hidden';
|
|
} else {
|
|
document.body.style.overflow = originalStyle || 'unset';
|
|
}
|
|
|
|
return () => {
|
|
document.body.style.overflow = originalStyle || 'unset';
|
|
};
|
|
}, [isLocked]);
|
|
};
|
|
|
|
/**
|
|
* Hook pour gérer les événements de redimensionnement avec debounce
|
|
*/
|
|
export const useResizeEvent = (callback: () => void, breakpoint: number = 768, delay: number = 100) => {
|
|
useEffect(() => {
|
|
let timeoutId: NodeJS.Timeout;
|
|
|
|
const handleResize = () => {
|
|
clearTimeout(timeoutId);
|
|
timeoutId = setTimeout(() => {
|
|
if (window.innerWidth >= breakpoint) {
|
|
callback();
|
|
}
|
|
}, delay);
|
|
};
|
|
|
|
window.addEventListener('resize', handleResize);
|
|
return () => {
|
|
window.removeEventListener('resize', handleResize);
|
|
clearTimeout(timeoutId);
|
|
};
|
|
}, [callback, breakpoint, delay]);
|
|
};
|
|
|
|
/**
|
|
* Hook pour les états de toggle simples (booléens)
|
|
*/
|
|
export const useToggle = (initialState: boolean = false) => {
|
|
const [state, setState] = useState(initialState);
|
|
|
|
const toggle = useCallback(() => setState(prev => !prev), []);
|
|
const setTrue = useCallback(() => setState(true), []);
|
|
const setFalse = useCallback(() => setState(false), []);
|
|
|
|
return {
|
|
state,
|
|
toggle,
|
|
setTrue,
|
|
setFalse,
|
|
setState
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Hook pour gérer les modales génériques
|
|
*/
|
|
export const useModal = <T = any>(initialState: T | null = null) => {
|
|
const [data, setData] = useState<T | null>(initialState);
|
|
|
|
const open = useCallback((newData: T) => {
|
|
setData(newData);
|
|
}, []);
|
|
|
|
const close = useCallback(() => {
|
|
setData(null);
|
|
}, []);
|
|
|
|
const isOpen = data !== null;
|
|
|
|
return {
|
|
data,
|
|
open,
|
|
close,
|
|
isOpen
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Hook pour la navigation entre sections avec scroll smooth
|
|
*/
|
|
export const useNavigation = () => {
|
|
const scrollToSection = useCallback((sectionId: string) => {
|
|
if (sectionId === 'home') {
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
} else if (sectionId === 'contact') {
|
|
window.location.href = 'mailto:contact@la-banquise.fr';
|
|
} else {
|
|
const element = document.getElementById(sectionId);
|
|
if (element) {
|
|
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
}
|
|
}
|
|
}, []);
|
|
|
|
const createNavHandler = useCallback((onClose?: () => void) => {
|
|
return (sectionId: string) => {
|
|
scrollToSection(sectionId);
|
|
onClose?.();
|
|
};
|
|
}, [scrollToSection]);
|
|
|
|
return {
|
|
scrollToSection,
|
|
createNavHandler
|
|
};
|
|
}; |