From 516d53c3a6866b9d56e6051d3eb5dacb6181dc8d Mon Sep 17 00:00:00 2001 From: chysis Date: Tue, 30 Jul 2024 17:57:30 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20top=20button=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useTopButton.ts | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 frontend/src/hooks/useTopButton.ts diff --git a/frontend/src/hooks/useTopButton.ts b/frontend/src/hooks/useTopButton.ts new file mode 100644 index 000000000..97551b5be --- /dev/null +++ b/frontend/src/hooks/useTopButton.ts @@ -0,0 +1,39 @@ +import { useState, useEffect } from 'react'; + +const TOP_BUTTON_DISPLAY_THRESHOLD = 500; + +interface UseTopButtonResult { + showTopButton: boolean; + scrollToTop: () => void; +} + +const useTopButton = (): UseTopButtonResult => { + const [showTopButton, setShowTopButton] = useState(false); + + useEffect(() => { + const handleShowTopButton = () => { + if (window.scrollY > TOP_BUTTON_DISPLAY_THRESHOLD) { + setShowTopButton(true); + } else { + setShowTopButton(false); + } + }; + + window.addEventListener('scroll', handleShowTopButton); + + return () => { + window.removeEventListener('scroll', handleShowTopButton); + }; + }, []); + + const scrollToTop = () => { + window.scrollTo({ + top: 0, + behavior: 'smooth', + }); + }; + + return { showTopButton, scrollToTop }; +}; + +export default useTopButton; From 67844fdf2d7fca4d83df9c263fafb522a18b24f0 Mon Sep 17 00:00:00 2001 From: chysis Date: Tue, 30 Jul 2024 17:58:49 +0900 Subject: [PATCH 2/6] =?UTF-8?q?design:=20top=20button=20UI=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/assets/upperArrow.svg | 3 +++ .../src/components/common/TopButton/index.tsx | 18 +++++++++++++ .../src/components/common/TopButton/style.ts | 26 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 frontend/src/assets/upperArrow.svg create mode 100644 frontend/src/components/common/TopButton/index.tsx create mode 100644 frontend/src/components/common/TopButton/style.ts diff --git a/frontend/src/assets/upperArrow.svg b/frontend/src/assets/upperArrow.svg new file mode 100644 index 000000000..0852c8f29 --- /dev/null +++ b/frontend/src/assets/upperArrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/components/common/TopButton/index.tsx b/frontend/src/components/common/TopButton/index.tsx new file mode 100644 index 000000000..5894bf43f --- /dev/null +++ b/frontend/src/components/common/TopButton/index.tsx @@ -0,0 +1,18 @@ +import UpperArrow from '@/assets/upperArrow.svg'; +import useTopButton from '@/hooks/useTopButton'; + +import * as S from './style'; + +const TopButton = () => { + const { showTopButton, scrollToTop } = useTopButton(); + + if (!showTopButton) return null; + + return ( + + + + ); +}; + +export default TopButton; diff --git a/frontend/src/components/common/TopButton/style.ts b/frontend/src/components/common/TopButton/style.ts new file mode 100644 index 000000000..8b56b7633 --- /dev/null +++ b/frontend/src/components/common/TopButton/style.ts @@ -0,0 +1,26 @@ +import styled from '@emotion/styled'; + +export const TopButton = styled.button` + position: fixed; + right: 5rem; + bottom: 5rem; + + display: flex; + align-items: center; + justify-content: center; + + width: 5rem; + height: 5rem; + + color: ${({ theme }) => theme.colors.white}; + + background-color: ${({ theme }) => theme.colors.primary}; + filter: drop-shadow(0 0 0.2rem ${({ theme }) => theme.colors.primary}); + border: 0.2rem solid ${({ theme }) => theme.colors.primary}; + border-radius: 100%; +`; + +export const ArrowImage = styled.img` + width: 3rem; + height: 3rem; +`; From 9674ad255a1f2a12db733eb049951ffe9c225e07 Mon Sep 17 00:00:00 2001 From: chysis Date: Tue, 30 Jul 2024 17:59:19 +0900 Subject: [PATCH 3/6] =?UTF-8?q?chore:=20=EA=B0=81=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=A7=88=EB=8B=A4=20top=20button=EC=9D=B4=20=EB=B3=B4?= =?UTF-8?q?=EC=97=AC=EC=A7=80=EB=8F=84=EB=A1=9D=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/layouts/PageLayout/index.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/components/layouts/PageLayout/index.tsx b/frontend/src/components/layouts/PageLayout/index.tsx index f3b235609..0949206d2 100644 --- a/frontend/src/components/layouts/PageLayout/index.tsx +++ b/frontend/src/components/layouts/PageLayout/index.tsx @@ -1,11 +1,14 @@ import { PropsWithChildren } from 'react'; +import { TopButton } from '@/components/common'; + import * as S from './styles'; const PageLayout = ({ children }: PropsWithChildren) => { return ( {children} + ); }; From 13702fa951eb70281cd16896cc8f263a2146c8b9 Mon Sep 17 00:00:00 2001 From: chysis Date: Tue, 30 Jul 2024 17:59:49 +0900 Subject: [PATCH 4/6] =?UTF-8?q?chore:=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20default=EB=A1=9C=20export=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/common/index.tsx b/frontend/src/components/common/index.tsx index dbcb4a5cd..3052e49a4 100644 --- a/frontend/src/components/common/index.tsx +++ b/frontend/src/components/common/index.tsx @@ -5,4 +5,5 @@ export { default as ProjectImg } from './ProjectImg'; export { default as ReviewDate } from './ReviewDate'; export { default as ReviewComment } from './ReviewComment'; export { default as MultilineTextViewer } from './MultilineTextViewer'; +export { default as TopButton } from './TopButton'; export * from './modals'; From 54b5cfee47764b47ccfccbb05c511faab6e298df Mon Sep 17 00:00:00 2001 From: chysis Date: Wed, 31 Jul 2024 00:39:15 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor:=20handler=EB=A5=BC=20useEffect=20?= =?UTF-8?q?=EC=99=B8=EB=B6=80=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useTopButton.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/src/hooks/useTopButton.ts b/frontend/src/hooks/useTopButton.ts index 97551b5be..fe924c832 100644 --- a/frontend/src/hooks/useTopButton.ts +++ b/frontend/src/hooks/useTopButton.ts @@ -10,15 +10,15 @@ interface UseTopButtonResult { const useTopButton = (): UseTopButtonResult => { const [showTopButton, setShowTopButton] = useState(false); - useEffect(() => { - const handleShowTopButton = () => { - if (window.scrollY > TOP_BUTTON_DISPLAY_THRESHOLD) { - setShowTopButton(true); - } else { - setShowTopButton(false); - } - }; + const handleShowTopButton = () => { + if (window.scrollY > TOP_BUTTON_DISPLAY_THRESHOLD) { + setShowTopButton(true); + } else { + setShowTopButton(false); + } + }; + useEffect(() => { window.addEventListener('scroll', handleShowTopButton); return () => { From 372861ce5ff37ca9754e648257678c5960959c7d Mon Sep 17 00:00:00 2001 From: chysis Date: Wed, 31 Jul 2024 14:25:14 +0900 Subject: [PATCH 6/6] =?UTF-8?q?chore:=20svg=20import=20=EC=BB=A8=EB=B2=A4?= =?UTF-8?q?=EC=85=98=EC=97=90=20=EB=A7=9E=EC=B6=94=EC=96=B4=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/common/TopButton/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/common/TopButton/index.tsx b/frontend/src/components/common/TopButton/index.tsx index 5894bf43f..b22accba2 100644 --- a/frontend/src/components/common/TopButton/index.tsx +++ b/frontend/src/components/common/TopButton/index.tsx @@ -1,4 +1,4 @@ -import UpperArrow from '@/assets/upperArrow.svg'; +import UpperArrowIcon from '@/assets/upperArrow.svg'; import useTopButton from '@/hooks/useTopButton'; import * as S from './style'; @@ -10,7 +10,7 @@ const TopButton = () => { return ( - + ); };