📱(frontend) add hook store useResponsiveStore

useResponsiveStore is a hook store that provides
the current screen size and the current device type.
This commit is contained in:
Anthony LC
2024-09-26 13:08:48 +02:00
committed by Anthony LC
parent f081f7826a
commit 399cf893ad
3 changed files with 73 additions and 0 deletions

View File

@@ -1,8 +1,10 @@
import { CunninghamProvider } from '@openfun/cunningham-react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useEffect } from 'react';
import { useCunninghamTheme } from '@/cunningham';
import '@/i18n/initI18n';
import { useResponsiveStore } from '@/stores/';
import { Auth } from './auth/';
@@ -25,6 +27,15 @@ const queryClient = new QueryClient({
export function AppProvider({ children }: { children: React.ReactNode }) {
const { theme } = useCunninghamTheme();
const initializeResizeListener = useResponsiveStore(
(state) => state.initializeResizeListener,
);
useEffect(() => {
const cleanupResizeListener = initializeResizeListener();
return cleanupResizeListener;
}, [initializeResizeListener]);
return (
<QueryClientProvider client={queryClient}>
<CunninghamProvider theme={theme}>

View File

@@ -0,0 +1 @@
export * from './useResponsiveStore';

View File

@@ -0,0 +1,61 @@
import { create } from 'zustand';
export type ScreenSize = 'small-mobile' | 'mobile' | 'tablet' | 'desktop';
export interface UseResponsiveStore {
isMobile: boolean;
isSmallMobile: boolean;
screenSize: ScreenSize;
screenWidth: number;
setScreenSize: (size: ScreenSize) => void;
initializeResizeListener: () => () => void;
}
const initialState = {
isMobile: false,
isSmallMobile: false,
screenSize: 'desktop' as ScreenSize,
screenWidth: 0,
};
export const useResponsiveStore = create<UseResponsiveStore>((set) => ({
isMobile: initialState.isMobile,
isSmallMobile: initialState.isSmallMobile,
screenSize: initialState.screenSize,
screenWidth: initialState.screenWidth,
setScreenSize: (size: ScreenSize) => set(() => ({ screenSize: size })),
initializeResizeListener: () => {
const resizeHandler = () => {
const width = window.innerWidth;
if (width < 560) {
set({
screenSize: 'small-mobile',
isMobile: true,
isSmallMobile: true,
});
} else if (width < 768) {
set({ screenSize: 'mobile', isMobile: true, isSmallMobile: false });
} else if (width >= 768 && width < 1024) {
set({ screenSize: 'tablet', isMobile: false, isSmallMobile: false });
} else {
set({ screenSize: 'desktop', isMobile: false, isSmallMobile: false });
}
set({ screenWidth: width });
};
const debouncedResizeHandler = () => {
setTimeout(() => {
resizeHandler();
}, 300);
};
window.addEventListener('resize', debouncedResizeHandler);
resizeHandler();
return () => {
window.removeEventListener('resize', debouncedResizeHandler);
};
},
}));