From 1a62c07e8c8ab0dc94c8662847e91de920a37c94 Mon Sep 17 00:00:00 2001 From: dididy Date: Wed, 17 Nov 2021 22:42:08 +0900 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20slide=20=ED=82=A4=ED=94=84=EB=A0=88?= =?UTF-8?q?=EC=9E=84=20mixin=EC=9D=84=20=EC=B6=94=EA=B0=80=ED=95=9C?= =?UTF-8?q?=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/styles/_mixin.scss | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/assets/styles/_mixin.scss b/src/assets/styles/_mixin.scss index acaeff5..d0224c8 100644 --- a/src/assets/styles/_mixin.scss +++ b/src/assets/styles/_mixin.scss @@ -50,6 +50,28 @@ $mobile: 'screen and (max-width: 758px)'; } } +@mixin slide_keyframes { + @keyframes slidein { + from { + width: 150px; + } + + to { + width: 300px; + } + } + + @keyframes slideout { + from { + width: 300px; + } + + to { + width: 150px; + } + } +} + @mixin modal_wrapper { @include flex_col(); position: fixed; @@ -73,7 +95,7 @@ $mobile: 'screen and (max-width: 758px)'; -moz-user-select: -moz-none; -webkit-user-select: none; -khtml-user-select: none; - user-select:none; + user-select: none; } // * $bgc: background-color (e.g. #fff) From 3f76d39d8848dbd180af68b56e9f9db2d630a1a0 Mon Sep 17 00:00:00 2001 From: dididy Date: Wed, 17 Nov 2021 22:44:37 +0900 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=EC=8A=AC=EB=9D=BC=EC=9D=B4=EB=93=9C?= =?UTF-8?q?=20=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=EA=B3=BC=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=B2=98=EB=A6=AC=EB=A5=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/IdeaPage/IdeaPage.module.scss | 23 ++++++++++++++ src/pages/IdeaPage/index.tsx | 41 ++++++++++++++++++++++--- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/pages/IdeaPage/IdeaPage.module.scss b/src/pages/IdeaPage/IdeaPage.module.scss index 3416ac6..8b93fc1 100644 --- a/src/pages/IdeaPage/IdeaPage.module.scss +++ b/src/pages/IdeaPage/IdeaPage.module.scss @@ -23,6 +23,29 @@ .searchArea { @include flex_row(flex-end); + .ideaPageSeachbar { + @include slide_keyframes; + + input { + width: 150px; + } + + &.isInputFocusOut { + input { + animation-duration: 0.2s; + animation-name: slideout; + } + } + + &.isInputFocus { + input { + width: 300px; + animation-duration: 0.2s; + animation-name: slidein; + } + } + } + svg { cursor: pointer; padding: 0px 5.5px; diff --git a/src/pages/IdeaPage/index.tsx b/src/pages/IdeaPage/index.tsx index 204e6ec..dab2185 100644 --- a/src/pages/IdeaPage/index.tsx +++ b/src/pages/IdeaPage/index.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import cn from 'classnames'; import styles from './IdeaPage.module.scss'; import Search from '@src/assets/Search.svg'; @@ -12,7 +12,7 @@ import IdeaCardContainer from '@src/components/Idea/IdeaCardContainer'; import { useAuth } from '@src/hooks/useUserQuery'; import Typography from '@src/components/common/Typography'; import { setIdea, useAppDispatch, useIdeaState } from '@src/store'; -import Input from '@src/components/common/Input'; +import Input, { ParentRef } from '@src/components/common/Input'; import { useQueryClient } from 'react-query'; import HashTagBanner from '@src/components/HashTagBanner'; import { useGetHashTags } from '@src/hooks/useHashTagQuery'; @@ -26,12 +26,16 @@ interface IdeaPageProps { const IdeaPage = ({ handleToTop }: IdeaPageProps) => { const { search } = useIdeaState(); const [isFilterOpen, setIsFilterOpen] = useState(false); + const [isInputFocus, setIsInputFocus] = useState(false); const queryClient = useQueryClient(); const { isDone, sort } = useIdeaState(); const dispatch = useAppDispatch(); const { data: isAuth } = useAuth(); const { data: hashTagInfos, isSuccess: isHashTagSuccess } = useGetHashTags(); + const wrapperRef = useRef(null); + const searchRef = useRef({} as ParentRef); + const { isModalVisible: isAlertVisible, modalMessage: alertMessage, @@ -45,6 +49,18 @@ const IdeaPage = ({ handleToTop }: IdeaPageProps) => { hideModal: hideIdeaForm, } = useModalControl(); + useEffect(() => { + document.addEventListener('click', handleClickOutside, true); + return () => + document.removeEventListener('click', handleClickOutside, true); + }, []); + + const handleClickOutside = ({ target }: MouseEvent) => { + if (!wrapperRef.current?.contains(target as HTMLDivElement)) { + setIsFilterOpen(false); + } + }; + return (
@@ -55,7 +71,7 @@ const IdeaPage = ({ handleToTop }: IdeaPageProps) => {
setIsFilterOpen((prev) => !prev)} /> {isFilterOpen && ( - <> +
- +
)} - + { + setIsInputFocus(true); + searchRef.current.focus(); + }} + /> dispatch(setIdea({ search: e.target.value.split(' ') })) } value={search?.join(' ')} + onFocus={() => { + setIsFilterOpen(false); + setIsInputFocus(true); + }} + onBlur={() => setIsInputFocus(false)} />
From e8f89ffa8090eb33d1f0f64551f0d4cb901c58e0 Mon Sep 17 00:00:00 2001 From: dididy Date: Wed, 17 Nov 2021 22:52:53 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=EC=82=AC=EC=9D=B4=EB=93=9C=20?= =?UTF-8?q?=EA=B2=80=EC=83=89=20=EC=8A=AC=EB=9D=BC=EC=9D=B4=EB=93=9C=20?= =?UTF-8?q?=EC=95=A0=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=EA=B3=BC=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=B2=98=EB=A6=AC=EB=A5=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/SidePage/SidePage.module.scss | 30 +++++++++++++++++- src/pages/SidePage/index.tsx | 42 ++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/pages/SidePage/SidePage.module.scss b/src/pages/SidePage/SidePage.module.scss index 6e82ce2..e16aea0 100644 --- a/src/pages/SidePage/SidePage.module.scss +++ b/src/pages/SidePage/SidePage.module.scss @@ -18,7 +18,7 @@ backdrop-filter: blur(30px); z-index: 100; - + &.isGithubVisible { z-index: 0; } @@ -30,6 +30,34 @@ .searchArea { @include flex_row(flex-end); + .sideFilter { + @include flex_row(); + gap: 5px; + } + + .sidePageSeachbar { + @include slide_keyframes; + + input { + width: 150px; + } + + &.isInputFocusOut { + input { + animation-duration: 0.2s; + animation-name: slideout; + } + } + + &.isInputFocus { + input { + width: 300px; + animation-duration: 0.2s; + animation-name: slidein; + } + } + } + svg { cursor: pointer; padding: 0px 5.5px; diff --git a/src/pages/SidePage/index.tsx b/src/pages/SidePage/index.tsx index 928a102..a8f9a95 100644 --- a/src/pages/SidePage/index.tsx +++ b/src/pages/SidePage/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; import cn from 'classnames'; import styles from './SidePage.module.scss'; @@ -21,7 +21,7 @@ import { import Dropdown, { ListsEachObject } from '@src/components/Dropdown'; import Typography from '@src/components/common/Typography'; import { setSide, useAppDispatch, useSideState } from '@src/store'; -import Input from '@src/components/common/Input'; +import Input, { ParentRef } from '@src/components/common/Input'; import { useAuth } from '@src/hooks/useUserQuery'; import { useLocation } from 'react-router-dom'; import { GuideText } from '@src/constant/enums'; @@ -42,9 +42,14 @@ const SidePage = ({ handleToTop }: SidePageProps) => { }, [status]); const [isFilterOpen, setIsFilterOpen] = useState(false); + const [isInputFocus, setIsInputFocus] = useState(false); const dispatch = useAppDispatch(); const { isRecruiting, sort } = useSideState(); + + const wrapperRef = useRef(null); + const searchRef = useRef({} as ParentRef); + const { isModalVisible: isAlertVisible, modalMessage: alertMessage, @@ -63,6 +68,18 @@ const SidePage = ({ handleToTop }: SidePageProps) => { const { data: organizationData } = useGetOrganization(); const { data: skillsData } = useGetSkills(); + useEffect(() => { + document.addEventListener('click', handleClickOutside, true); + return () => + document.removeEventListener('click', handleClickOutside, true); + }, []); + + const handleClickOutside = ({ target }: MouseEvent) => { + if (!wrapperRef.current?.contains(target as HTMLDivElement)) { + setIsFilterOpen(false); + } + }; + return (
@@ -78,7 +95,7 @@ const SidePage = ({ handleToTop }: SidePageProps) => {
setIsFilterOpen((prev) => !prev)} /> {isFilterOpen && ( - <> +
{ - +
)} - + { + setIsInputFocus(true); + searchRef.current.focus(); + }} + /> dispatch(setSide({ search: e.target.value.split(' ') })) } + onFocus={() => { + setIsFilterOpen(false); + setIsInputFocus(true); + }} + onBlur={() => setIsInputFocus(false)} />