📱(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:
@@ -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}>
|
||||
|
||||
1
src/frontend/apps/impress/src/stores/index.ts
Normal file
1
src/frontend/apps/impress/src/stores/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './useResponsiveStore';
|
||||
61
src/frontend/apps/impress/src/stores/useResponsiveStore.tsx
Normal file
61
src/frontend/apps/impress/src/stores/useResponsiveStore.tsx
Normal 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);
|
||||
};
|
||||
},
|
||||
}));
|
||||
Reference in New Issue
Block a user