From c26fb54dd740cdc357c5c631b6f6a6ee956f4ce9 Mon Sep 17 00:00:00 2001 From: VyVu Date: Wed, 8 May 2024 12:22:18 +0700 Subject: [PATCH] Responsive --- src/app/@main/layout.tsx | 10 +++++++--- src/app/globals.css | 1 + src/app/layout.tsx | 11 ++++++++++- src/lib/useMediaQuery.ts | 23 +++++++++++++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 src/lib/useMediaQuery.ts diff --git a/src/app/@main/layout.tsx b/src/app/@main/layout.tsx index 09fa426..4a8d01b 100644 --- a/src/app/@main/layout.tsx +++ b/src/app/@main/layout.tsx @@ -1,4 +1,7 @@ -export default async function MainLayout({ +'use client'; +import { useMediaQuery } from '@/lib/useMediaQuery'; + +export default function MainLayout({ summary, projects, skills, @@ -9,14 +12,15 @@ export default async function MainLayout({ skills: React.ReactNode; certificates: React.ReactNode; }) { + const isMobile = useMediaQuery(); return (
{summary} - {projects} + {isMobile ? skills : projects}
- {skills} + {isMobile ? projects : skills} {certificates}
diff --git a/src/app/globals.css b/src/app/globals.css index e3bedec..417fe2f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -24,6 +24,7 @@ body { rgb(var(--background-end-rgb)) ) rgb(var(--background-start-rgb)); + overflow-x: hidden; } @layer utilities { diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 62a2ce5..2567312 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -22,10 +22,19 @@ export default function RootLayout({ return ( -
+
{header} {main} {footer} + {/*
diff --git a/src/lib/useMediaQuery.ts b/src/lib/useMediaQuery.ts new file mode 100644 index 0000000..0dc0080 --- /dev/null +++ b/src/lib/useMediaQuery.ts @@ -0,0 +1,23 @@ +import { useState, useCallback, useEffect } from 'react'; + +/** + * isMatches is undefined before hook effect + * @param width to make max-width media query. Default is 767 + * @returns {undefined | boolean} Is media query matches. Undefined if there is no window reference yet + */ +export const useMediaQuery = (width = 767): undefined | boolean => { + const [isMatches, setIsMatches] = useState(false); + const onChange = useCallback( + () => + setIsMatches(window.matchMedia(`(max-width: ${width}px)`).matches), + [width], + ); + + useEffect(() => { + onChange(); + window.addEventListener('resize', onChange); + return () => window.removeEventListener('resize', onChange); + }, [onChange]); + + return isMatches; +};