Files
automaker/apps/ui/src/hooks/use-media-query.ts
webdevcody d98cae124f feat: enhance sidebar functionality for mobile and compact views
- Introduced a floating toggle button for mobile to show/hide the sidebar when collapsed.
- Updated sidebar behavior to completely hide on mobile when the new mobileSidebarHidden state is true.
- Added logic to conditionally render sidebar components based on screen size using the new useIsCompact hook.
- Enhanced SidebarHeader to include close and expand buttons for mobile views.
- Refactored CollapseToggleButton to hide in compact mode.
- Implemented HeaderActionsPanel for mobile actions in various views, improving accessibility and usability on smaller screens.

These changes improve the user experience on mobile devices by providing better navigation options and visibility controls.
2026-01-16 22:27:19 -05:00

68 lines
1.9 KiB
TypeScript

import { useState, useEffect, useRef } from 'react';
/**
* Hook to detect if a media query matches
* @param query - The media query string (e.g., '(max-width: 768px)')
* @returns boolean indicating if the media query matches
*/
export function useMediaQuery(query: string): boolean {
const [matches, setMatches] = useState(() => {
if (typeof window === 'undefined') return false;
return window.matchMedia(query).matches;
});
// Track if this is the initial mount to avoid redundant setMatches call
const isInitialMount = useRef(true);
useEffect(() => {
if (typeof window === 'undefined') return;
const mediaQuery = window.matchMedia(query);
const handleChange = (e: MediaQueryListEvent) => {
setMatches(e.matches);
};
// Only sync state when query changes after initial mount
// (initial mount already has correct value from useState initializer)
if (isInitialMount.current) {
isInitialMount.current = false;
} else {
setMatches(mediaQuery.matches);
}
// Listen for changes
mediaQuery.addEventListener('change', handleChange);
return () => {
mediaQuery.removeEventListener('change', handleChange);
};
}, [query]);
return matches;
}
/**
* Hook to detect if the device is mobile (screen width <= 768px)
* @returns boolean indicating if the device is mobile
*/
export function useIsMobile(): boolean {
return useMediaQuery('(max-width: 768px)');
}
/**
* Hook to detect if the device is tablet or smaller (screen width <= 1024px)
* @returns boolean indicating if the device is tablet or smaller
*/
export function useIsTablet(): boolean {
return useMediaQuery('(max-width: 1024px)');
}
/**
* Hook to detect compact layout (screen width <= 1240px)
* Used for collapsing top bar controls into mobile menu
* @returns boolean indicating if compact layout should be used
*/
export function useIsCompact(): boolean {
return useMediaQuery('(max-width: 1240px)');
}