diff --git a/src/App.tsx b/src/App.tsx index 2a7e9a7..7620b21 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,6 +3,7 @@ import styles from "./App.module.css"; import ColorPicker from "./components/ColorPicker/ColorPicker"; import ColorValues from "./components/ColorValues/ColorValues"; import { LeftMenu, RightMenu } from "./components/SideMenu"; +import { useMediaQuery } from "./providers/hooks"; import clsx from "clsx"; // Menu Button Components @@ -133,22 +134,29 @@ function MobileContent({ }: MenuStateProps) { const toggleRightMenu = () => setIsRightMenuOpen(!isRightMenuOpen); const toggleLeftMenu = () => setIsLeftMenuOpen(!isLeftMenuOpen); + const { isMobilePortrait, isMobileLandscape } = useMediaQuery(); return (
- + {isMobilePortrait && ( + + )} - + {isMobileLandscape && ( + + )} - + {isMobileLandscape && ( + + )} - - + {!isDesktop && ( + + )} + + {isDesktop && } ); } diff --git a/src/main.tsx b/src/main.tsx index eff7ccc..8a87d96 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,9 +2,12 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import "./index.css"; import App from "./App.tsx"; +import { MediaQueryProvider } from "./providers"; createRoot(document.getElementById("root")!).render( - + + + , ); diff --git a/src/providers/MediaQueryProvider.tsx b/src/providers/MediaQueryProvider.tsx new file mode 100644 index 0000000..9dec320 --- /dev/null +++ b/src/providers/MediaQueryProvider.tsx @@ -0,0 +1,77 @@ +import { createContext, useState, useEffect } from "react"; +import type { ReactNode } from "react"; + +enum ViewportMode { + DESKTOP = "desktop", + MOBILE_LANDSCAPE = "mobile-landscape", + MOBILE_PORTRAIT = "mobile-portrait", +} + +interface MediaQueryContextType { + viewportMode: ViewportMode; + isDesktop: boolean; + isMobileLandscape: boolean; + isMobilePortrait: boolean; +} + +const MediaQueryContext = createContext( + undefined, +); + +function MediaQueryProvider({ children }: { children: ReactNode }) { + const [viewportMode, setViewportMode] = useState( + ViewportMode.DESKTOP, + ); + + useEffect(() => { + const desktopQuery = window.matchMedia( + "(min-width: 992px), (min-width: 568px) and (max-width: 991px) and (orientation: portrait)", + ); + const mobileLandscapeQuery = window.matchMedia( + "(min-width: 568px) and (max-width: 991px) and (orientation: landscape)", + ); + const mobilePortraitQuery = window.matchMedia("(max-width: 567px)"); + + const updateViewportMode = () => { + if (desktopQuery.matches) { + setViewportMode(ViewportMode.DESKTOP); + } else if (mobileLandscapeQuery.matches) { + setViewportMode(ViewportMode.MOBILE_LANDSCAPE); + } else if (mobilePortraitQuery.matches) { + setViewportMode(ViewportMode.MOBILE_PORTRAIT); + } + }; + + updateViewportMode(); + + desktopQuery.addEventListener("change", updateViewportMode); + mobileLandscapeQuery.addEventListener("change", updateViewportMode); + mobilePortraitQuery.addEventListener("change", updateViewportMode); + + return () => { + desktopQuery.removeEventListener("change", updateViewportMode); + mobileLandscapeQuery.removeEventListener("change", updateViewportMode); + mobilePortraitQuery.removeEventListener("change", updateViewportMode); + }; + }, []); + + const isDesktop = viewportMode === ViewportMode.DESKTOP; + const isMobileLandscape = viewportMode === ViewportMode.MOBILE_LANDSCAPE; + const isMobilePortrait = viewportMode === ViewportMode.MOBILE_PORTRAIT; + + return ( + + {children} + + ); +} + +export default MediaQueryProvider; +export { MediaQueryContext }; diff --git a/src/providers/hooks.ts b/src/providers/hooks.ts new file mode 100644 index 0000000..7f280ba --- /dev/null +++ b/src/providers/hooks.ts @@ -0,0 +1,12 @@ +import { useContext } from "react"; +import { MediaQueryContext } from "./MediaQueryProvider"; + +function useMediaQuery() { + const context = useContext(MediaQueryContext); + if (context === undefined) { + throw new Error("useMediaQuery must be used within a MediaQueryProvider"); + } + return context; +} + +export { useMediaQuery }; diff --git a/src/providers/index.ts b/src/providers/index.ts new file mode 100644 index 0000000..62a9952 --- /dev/null +++ b/src/providers/index.ts @@ -0,0 +1,3 @@ +import MediaQueryProvider from "./MediaQueryProvider"; + +export { MediaQueryProvider }; diff --git a/tsconfig.app.json b/tsconfig.app.json index c9ccbd4..9c8a3c4 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -19,7 +19,6 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, diff --git a/tsconfig.node.json b/tsconfig.node.json index 9728af2..d9aa8a8 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -17,7 +17,6 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true },