From fb8214e9a9f5528096b21e80950c71f25b0f1c95 Mon Sep 17 00:00:00 2001 From: "DESKTOP-O9GP521\\J" Date: Tue, 27 Apr 2021 19:28:05 +0900 Subject: [PATCH 1/4] [Fix]: modal width fixed --- sidedish/src/component/ItemDetail/DetailModal.jsx | 2 +- sidedish/src/component/ItemDetail/ItemDetail.jsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sidedish/src/component/ItemDetail/DetailModal.jsx b/sidedish/src/component/ItemDetail/DetailModal.jsx index 78835b095..0f3253d1f 100644 --- a/sidedish/src/component/ItemDetail/DetailModal.jsx +++ b/sidedish/src/component/ItemDetail/DetailModal.jsx @@ -109,7 +109,7 @@ const DetailModal = ({ detailData, loading, title, badge }) => { export default DetailModal; export const ModalStyle = styled.div` - width: 70%; + width: 50%; height: 95%; background-color: white; display: flex; diff --git a/sidedish/src/component/ItemDetail/ItemDetail.jsx b/sidedish/src/component/ItemDetail/ItemDetail.jsx index 2df1f8822..4612c4eec 100644 --- a/sidedish/src/component/ItemDetail/ItemDetail.jsx +++ b/sidedish/src/component/ItemDetail/ItemDetail.jsx @@ -49,9 +49,9 @@ const StyleModal = styled.div` .closeBtn { position: fixed; - left: 86%; + left: 76%; font-size: 24px; - top: 36px; + top: 20px; color: white; } `; From e4f6553002f838621771f1fff9be880983aad25a Mon Sep 17 00:00:00 2001 From: "DESKTOP-O9GP521\\J" Date: Tue, 27 Apr 2021 23:53:09 +0900 Subject: [PATCH 2/4] [WIP]: prop bubbling with useRef --- sidedish/src/component/Carousel/Carousel.jsx | 38 ++++-------- .../src/component/ItemDetail/DetailModal.jsx | 5 ++ .../src/component/ItemDetail/ItemDetail.jsx | 13 +++- .../src/component/SlideDish/SlideDish.jsx | 59 +++++++++++++++---- 4 files changed, 79 insertions(+), 36 deletions(-) diff --git a/sidedish/src/component/Carousel/Carousel.jsx b/sidedish/src/component/Carousel/Carousel.jsx index 7d00c76ff..4bf919a45 100644 --- a/sidedish/src/component/Carousel/Carousel.jsx +++ b/sidedish/src/component/Carousel/Carousel.jsx @@ -1,8 +1,8 @@ -import React, { useRef, useState } from 'react'; +import React, { useState, forwardRef, useImperativeHandle } from 'react'; import styled from 'styled-components'; -import { IoChevronBackSharp, IoChevronForwardSharp } from 'react-icons/io5'; -const Carousel = ({ children, itemWidth, maxItem, skipItem, animationTime }) => { +const Carousel = forwardRef(({ children, itemWidth, maxItem, skipItem, animationTime }, ref) => { + console.log(ref); const [locationX, setLocationX] = useState(0); const [currIdx, setCurrIdx] = useState(0); const [leftItem, setLeftItem] = useState(); @@ -23,6 +23,15 @@ const Carousel = ({ children, itemWidth, maxItem, skipItem, animationTime }) => setLeftItem(newLeftItem - possibleMove); }; + useImperativeHandle( + ref, + () => ({ + handleClickPrev, + handleClickNext, + }), + [handleClickPrev, handleClickNext] + ); + return ( currIdx={currIdx} leftItem={leftItem} > -
{children}
-
); -}; +}); export default Carousel; @@ -52,23 +59,4 @@ export const StyledCarousel = styled.div` transition: ${({ animationTime }) => `transform ${animationTime}s`}; transform: ${({ locationX }) => `translateX(${locationX}px)`}; } - .arrow { - position: absolute; - font-size: 2rem; - top: 40%; - } - .leftArrow { - left: -50px; - opacity: ${({ currIdx }) => (currIdx === 0 ? '0.3' : '1')}; - } - .leftArrow:hover { - color: ${({ currIdx }) => currIdx !== 0 && 'red'}; - } - .rightArrow { - right: -50px; - opacity: ${({ leftItem }) => (leftItem === 0 ? '0.3' : '1')}; - } - .rightArrow :hover { - color: ${({ leftItem }) => leftItem !== 0 && 'red'}; - } `; diff --git a/sidedish/src/component/ItemDetail/DetailModal.jsx b/sidedish/src/component/ItemDetail/DetailModal.jsx index 0f3253d1f..158bbab8f 100644 --- a/sidedish/src/component/ItemDetail/DetailModal.jsx +++ b/sidedish/src/component/ItemDetail/DetailModal.jsx @@ -114,6 +114,11 @@ export const ModalStyle = styled.div` background-color: white; display: flex; flex-direction: column; + + .error_center { + justify-content: center; + align-items: center; + } `; const Top = styled.div` diff --git a/sidedish/src/component/ItemDetail/ItemDetail.jsx b/sidedish/src/component/ItemDetail/ItemDetail.jsx index 4612c4eec..5da778781 100644 --- a/sidedish/src/component/ItemDetail/ItemDetail.jsx +++ b/sidedish/src/component/ItemDetail/ItemDetail.jsx @@ -24,7 +24,9 @@ const ItemDetail = ({ id, toggleModal, title, badge }) => { {detailData ? ( ) : ( - 데이터가 없습니다. + + 😢불러올 데이터가 없습니다😢 + )}
X @@ -36,6 +38,15 @@ const ItemDetail = ({ id, toggleModal, title, badge }) => { export default ItemDetail; +const ErrorStyle = styled.div` + height: 100%; + display: flex; + justify-content: center; + align-items: center; + font-size: 32px; + font-weight: bold; +`; + const StyleModal = styled.div` position: fixed; display: flex; diff --git a/sidedish/src/component/SlideDish/SlideDish.jsx b/sidedish/src/component/SlideDish/SlideDish.jsx index a5b8332b3..6632693ad 100644 --- a/sidedish/src/component/SlideDish/SlideDish.jsx +++ b/sidedish/src/component/SlideDish/SlideDish.jsx @@ -1,11 +1,13 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import styled from 'styled-components'; import DishItem from 'component/DishItem/DishItem'; import { URL } from 'util/data'; import useFetch from 'hooks/useFetch'; import Carousel from 'component/Carousel/Carousel'; +import { IoChevronBackSharp, IoChevronForwardSharp } from 'react-icons/io5'; const SlideDish = ({ category }) => { + const ref = useRef(); const { data: slideData, loading, error } = useFetch({ url: URL[category]() }); const slideCategory = slideData && @@ -17,15 +19,27 @@ const SlideDish = ({ category }) => { ) : (
모두가 좋아하는 든든한 메인요리
- - {slideCategory} - +
+ ref.current.handleClickPrev()} + className="leftArrow arrow" + /> + + {slideCategory} + + + ref.current.handleClickNext()} + className="rightArrow arrow" + /> +
); }; @@ -35,9 +49,34 @@ export default SlideDish; const SlideContainer = styled.div` min-width: 1280px; position: relative; + + .arrow { + position: absolute; + font-size: 2rem; + top: 40%; + } + + .slide_wrapper { + width: 100%; + display: flex; + overflow: hidden; + } + .carouselWrapper { min-width: 1280px; } + .leftArrow { + left: -50px; + } + .leftArrow:hover { + color: red; + } + .rightArrow { + right: -50px; + } + .rightArrow :hover { + color: red; + } `; const Header = styled.div` From 8823563b6a488ad2df12c31b2c45a0bd3e05559b Mon Sep 17 00:00:00 2001 From: "DESKTOP-O9GP521\\J" Date: Wed, 28 Apr 2021 18:09:24 +0900 Subject: [PATCH 3/4] [WIP]: carousel simplify --- sidedish/src/component/Carousel/Carousel.jsx | 26 +++++++++++++------ .../src/component/Carousel/CarouselItem.jsx | 18 +++++++++++++ sidedish/src/component/DishItem/DishItem.jsx | 3 +-- .../src/component/SlideDish/SlideDish.jsx | 21 +++++++-------- 4 files changed, 47 insertions(+), 21 deletions(-) create mode 100644 sidedish/src/component/Carousel/CarouselItem.jsx diff --git a/sidedish/src/component/Carousel/Carousel.jsx b/sidedish/src/component/Carousel/Carousel.jsx index 4bf919a45..1825f6507 100644 --- a/sidedish/src/component/Carousel/Carousel.jsx +++ b/sidedish/src/component/Carousel/Carousel.jsx @@ -1,11 +1,12 @@ -import React, { useState, forwardRef, useImperativeHandle } from 'react'; +import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } from 'react'; import styled from 'styled-components'; +import CarouselItem from 'component/Carousel/CarouselItem'; -const Carousel = forwardRef(({ children, itemWidth, maxItem, skipItem, animationTime }, ref) => { - console.log(ref); +const Carousel = forwardRef(({ children, maxItem, skipItem, animationTime }, ref) => { const [locationX, setLocationX] = useState(0); const [currIdx, setCurrIdx] = useState(0); const [leftItem, setLeftItem] = useState(); + const [itemWidth, setItemWidth] = useState(0); const handleClickPrev = () => { const possibleMove = currIdx >= skipItem ? skipItem : currIdx; @@ -16,6 +17,7 @@ const Carousel = forwardRef(({ children, itemWidth, maxItem, skipItem, animation const handleClickNext = () => { const totalItemCount = children.length; + // console.log(currIdx); const newLeftItem = totalItemCount - (currIdx + maxItem); const possibleMove = newLeftItem >= skipItem ? skipItem : newLeftItem; setLocationX(locationX - itemWidth * possibleMove); @@ -32,6 +34,16 @@ const Carousel = forwardRef(({ children, itemWidth, maxItem, skipItem, animation [handleClickPrev, handleClickNext] ); + const CarouselItems = () => { + return children ? ( + children.map((child) => { + return ; + }) + ) : ( +
children 없음
+ ); + }; + return ( -
-
{children}
+
+
); @@ -51,10 +63,8 @@ export default Carousel; export const StyledCarousel = styled.div` position: relative; - .carouselWrapper { + .container { overflow: hidden; - } - .carouselList { display: flex; transition: ${({ animationTime }) => `transform ${animationTime}s`}; transform: ${({ locationX }) => `translateX(${locationX}px)`}; diff --git a/sidedish/src/component/Carousel/CarouselItem.jsx b/sidedish/src/component/Carousel/CarouselItem.jsx new file mode 100644 index 000000000..4b46ad045 --- /dev/null +++ b/sidedish/src/component/Carousel/CarouselItem.jsx @@ -0,0 +1,18 @@ +import React, { useRef, forwardRef, useEffect, useState, useImperativeHandle } from 'react'; +// import styled from 'styled-components'; + +const CarouselItem = ({ item, setItemWidth }) => { + const targetRef = useRef(); + + useEffect(() => { + setItemWidth(targetRef.current.offsetWidth); + }, []); + + return ( + <> +
{item}
+ + ); +}; + +export default CarouselItem; diff --git a/sidedish/src/component/DishItem/DishItem.jsx b/sidedish/src/component/DishItem/DishItem.jsx index baad4763d..ed0c76177 100644 --- a/sidedish/src/component/DishItem/DishItem.jsx +++ b/sidedish/src/component/DishItem/DishItem.jsx @@ -17,7 +17,6 @@ const DishItem = ({ const toggleModal = () => { setShowDetail((showDetail) => !showDetail); - console.log('modal is toggled'); }; const handleMouseEnter = () => setIsHover(true); @@ -69,7 +68,7 @@ export default DishItem; const StyledDishItem = styled.div` width: ${({ size }) => (size === 'L' ? '384px' : '308px')}; height: ${({ size }) => (size === 'L' ? '540px' : '456px')}; - margin-right: ${({ size }) => size === 'M' && '16px'}; + margin-right: ${({ size }) => size === 'M' && '16px'}; // 얘를 지우고 캐로셀 안에서 작동이 되게 .imgContainer { position: relative; } diff --git a/sidedish/src/component/SlideDish/SlideDish.jsx b/sidedish/src/component/SlideDish/SlideDish.jsx index 6632693ad..4ab586168 100644 --- a/sidedish/src/component/SlideDish/SlideDish.jsx +++ b/sidedish/src/component/SlideDish/SlideDish.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from 'react'; +import React, { useState, useEffect, useLayoutEffect, useRef } from 'react'; import styled from 'styled-components'; import DishItem from 'component/DishItem/DishItem'; import { URL } from 'util/data'; @@ -8,11 +8,19 @@ import { IoChevronBackSharp, IoChevronForwardSharp } from 'react-icons/io5'; const SlideDish = ({ category }) => { const ref = useRef(); + const { data: slideData, loading, error } = useFetch({ url: URL[category]() }); const slideCategory = slideData && slideData.body.map((item) => ); + const settings = { + ref: ref, + maxItem: 4, // 얘도 settings 에서 제외해보자~ 먼저 maxItem이 어떤식으로 Carousel에 필요한지 알아야 + skipItem: 3, + animationTime: 0.5, + }; + if (error) throw Error(error); return loading ? (
Loading...
@@ -24,16 +32,7 @@ const SlideDish = ({ category }) => { onClick={() => ref.current.handleClickPrev()} className="leftArrow arrow" /> - - {slideCategory} - + {slideCategory} ref.current.handleClickNext()} From 67f2db4a568bcda24758761f5c1e3a180256b4bf Mon Sep 17 00:00:00 2001 From: "DESKTOP-O9GP521\\J" Date: Thu, 29 Apr 2021 10:39:03 +0900 Subject: [PATCH 4/4] [WIP]: merging --- sidedish/src/component/Carousel/Carousel.jsx | 26 +++++++------- sidedish/src/component/Main/Main.jsx | 7 +++- .../src/component/SlideDish/SlideDish.jsx | 35 +++++++------------ 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/sidedish/src/component/Carousel/Carousel.jsx b/sidedish/src/component/Carousel/Carousel.jsx index 1825f6507..230538ab1 100644 --- a/sidedish/src/component/Carousel/Carousel.jsx +++ b/sidedish/src/component/Carousel/Carousel.jsx @@ -2,11 +2,13 @@ import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } f import styled from 'styled-components'; import CarouselItem from 'component/Carousel/CarouselItem'; -const Carousel = forwardRef(({ children, maxItem, skipItem, animationTime }, ref) => { +const Carousel = forwardRef(({ children, skipItem, animationTime }, ref) => { + const currRef = useRef(); const [locationX, setLocationX] = useState(0); const [currIdx, setCurrIdx] = useState(0); const [leftItem, setLeftItem] = useState(); const [itemWidth, setItemWidth] = useState(0); + const maxItem = currRef.current && Math.floor(currRef.current.offsetWidth / itemWidth) + 1; const handleClickPrev = () => { const possibleMove = currIdx >= skipItem ? skipItem : currIdx; @@ -17,7 +19,7 @@ const Carousel = forwardRef(({ children, maxItem, skipItem, animationTime }, ref const handleClickNext = () => { const totalItemCount = children.length; - // console.log(currIdx); + console.log(currIdx); const newLeftItem = totalItemCount - (currIdx + maxItem); const possibleMove = newLeftItem >= skipItem ? skipItem : newLeftItem; setLocationX(locationX - itemWidth * possibleMove); @@ -34,15 +36,11 @@ const Carousel = forwardRef(({ children, maxItem, skipItem, animationTime }, ref [handleClickPrev, handleClickNext] ); - const CarouselItems = () => { - return children ? ( - children.map((child) => { - return ; - }) - ) : ( -
children 없음
- ); - }; + const carouselItems = + children && + children.map((child) => { + return ; + }); return ( -
- +
+ {carouselItems}
); @@ -62,9 +60,9 @@ export default Carousel; export const StyledCarousel = styled.div` position: relative; + overflow: hidden; .container { - overflow: hidden; display: flex; transition: ${({ animationTime }) => `transform ${animationTime}s`}; transform: ${({ locationX }) => `translateX(${locationX}px)`}; diff --git a/sidedish/src/component/Main/Main.jsx b/sidedish/src/component/Main/Main.jsx index 3995e334a..9b3447619 100644 --- a/sidedish/src/component/Main/Main.jsx +++ b/sidedish/src/component/Main/Main.jsx @@ -5,7 +5,12 @@ import MoreButton from 'component/atoms/MoreButton'; const Main = () => { const [slideDishCount, setSlideDishCount] = useState(1); - const slideDishes = ['main', 'soup', 'side']; + const slideDishes = [ + { path: 'main', title: '모두가 좋아하는 든든한 메인요리' }, + { path: 'soup', title: '정성이 담긴 뜨끈한 국물요리' }, + { path: 'side', title: '식탁을 풍성하게 하는 정갈한 밑반찬' }, + ]; + const slideDishList = slideDishes .slice(0, slideDishCount) .map((category, idx) => ); diff --git a/sidedish/src/component/SlideDish/SlideDish.jsx b/sidedish/src/component/SlideDish/SlideDish.jsx index 4ab586168..8325f4f3a 100644 --- a/sidedish/src/component/SlideDish/SlideDish.jsx +++ b/sidedish/src/component/SlideDish/SlideDish.jsx @@ -6,18 +6,17 @@ import useFetch from 'hooks/useFetch'; import Carousel from 'component/Carousel/Carousel'; import { IoChevronBackSharp, IoChevronForwardSharp } from 'react-icons/io5'; -const SlideDish = ({ category }) => { +const SlideDish = ({ category: { path, title } }) => { const ref = useRef(); - const { data: slideData, loading, error } = useFetch({ url: URL[category]() }); + const { data: slideData, loading, error } = useFetch({ url: URL[path]() }); const slideCategory = slideData && slideData.body.map((item) => ); const settings = { ref: ref, - maxItem: 4, // 얘도 settings 에서 제외해보자~ 먼저 maxItem이 어떤식으로 Carousel에 필요한지 알아야 - skipItem: 3, + skipItem: 2, animationTime: 0.5, }; @@ -26,19 +25,17 @@ const SlideDish = ({ category }) => {
Loading...
) : ( -
모두가 좋아하는 든든한 메인요리
-
- ref.current.handleClickPrev()} - className="leftArrow arrow" - /> - {slideCategory} +
{title}
+ ref.current.handleClickPrev()} + className="leftArrow arrow" + /> + {slideCategory} - ref.current.handleClickNext()} - className="rightArrow arrow" - /> -
+ ref.current.handleClickNext()} + className="rightArrow arrow" + />
); }; @@ -55,12 +52,6 @@ const SlideContainer = styled.div` top: 40%; } - .slide_wrapper { - width: 100%; - display: flex; - overflow: hidden; - } - .carouselWrapper { min-width: 1280px; }