77 lines
2.0 KiB
TypeScript
77 lines
2.0 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
|
|
/**
|
|
* Hook to detect media query matches
|
|
* @param query - CSS media query string
|
|
* @returns boolean indicating if the query matches
|
|
*/
|
|
export function useMediaQuery(query: string): boolean {
|
|
const [matches, setMatches] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const mediaQuery = window.matchMedia(query);
|
|
|
|
// Set initial value
|
|
setMatches(mediaQuery.matches);
|
|
|
|
// Create event listener
|
|
const handler = (event: MediaQueryListEvent) => {
|
|
setMatches(event.matches);
|
|
};
|
|
|
|
// Add listener
|
|
mediaQuery.addEventListener('change', handler);
|
|
|
|
// Cleanup
|
|
return () => mediaQuery.removeEventListener('change', handler);
|
|
}, [query]);
|
|
|
|
return matches;
|
|
}
|
|
|
|
/**
|
|
* Hook to detect current breakpoint
|
|
* @returns current breakpoint name
|
|
*/
|
|
export function useBreakpoint() {
|
|
const isXs = useMediaQuery('(max-width: 639px)');
|
|
const isSm = useMediaQuery('(min-width: 640px) and (max-width: 767px)');
|
|
const isMd = useMediaQuery('(min-width: 768px) and (max-width: 1023px)');
|
|
const isLg = useMediaQuery('(min-width: 1024px) and (max-width: 1279px)');
|
|
const isXl = useMediaQuery('(min-width: 1280px) and (max-width: 1535px)');
|
|
const is2Xl = useMediaQuery('(min-width: 1536px)');
|
|
|
|
if (isXs) return 'xs';
|
|
if (isSm) return 'sm';
|
|
if (isMd) return 'md';
|
|
if (isLg) return 'lg';
|
|
if (isXl) return 'xl';
|
|
if (is2Xl) return '2xl';
|
|
|
|
return 'lg'; // default
|
|
}
|
|
|
|
/**
|
|
* Hook to detect if viewport is mobile size
|
|
* @returns boolean indicating if viewport is mobile
|
|
*/
|
|
export function useIsMobile(): boolean {
|
|
return useMediaQuery('(max-width: 767px)');
|
|
}
|
|
|
|
/**
|
|
* Hook to detect if viewport is tablet size
|
|
* @returns boolean indicating if viewport is tablet
|
|
*/
|
|
export function useIsTablet(): boolean {
|
|
return useMediaQuery('(min-width: 768px) and (max-width: 1023px)');
|
|
}
|
|
|
|
/**
|
|
* Hook to detect if viewport is desktop size
|
|
* @returns boolean indicating if viewport is desktop
|
|
*/
|
|
export function useIsDesktop(): boolean {
|
|
return useMediaQuery('(min-width: 1024px)');
|
|
}
|