-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/#269 qa #284
Feat/#269 qa #284
Changes from all commits
96eea95
188d8c3
eb1f8b7
fff4e10
d5645a8
420b5a8
5e5a6dd
91d474e
dae5a4e
7d3917e
c89019a
cf590be
6851615
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { PropsWithChildren } from "react"; | ||
|
||
import * as St from "./style"; | ||
|
||
type HeadlessCTAButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>; | ||
|
||
const HeadlessCTAButton = (props: PropsWithChildren<HeadlessCTAButtonProps>) => { | ||
const { children, ...buttonProps } = props; | ||
|
||
return ( | ||
<St.CTAButtonWrapper> | ||
<St.CTAButton {...buttonProps}>{children}</St.CTAButton> | ||
</St.CTAButtonWrapper> | ||
); | ||
}; | ||
|
||
export default HeadlessCTAButton; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,14 @@ | ||
import { LocationType } from "../../../types/cardCollection"; | ||
import { GTM_CLASS_NAME } from "../../../util/const/gtm"; | ||
import useNavigateCardCollection, { | ||
NavigateCardCollectionAllType, | ||
} from "../../@common/hooks/useNavigateCardCollection"; | ||
import { St } from "./style"; | ||
import useNavigateCardCollection, { NavigateCardCollectionAllType } from "../hooks/useNavigateCardCollection"; | ||
import HeadlessCTAButton from "./HeadlessCTAButton"; | ||
|
||
export default function CTABtn() { | ||
const navigateCardCollection = useNavigateCardCollection(LocationType.ALL) as NavigateCardCollectionAllType; | ||
|
||
return ( | ||
<St.Button type="button" onClick={() => navigateCardCollection()} className={GTM_CLASS_NAME.mainCTABtn}> | ||
<HeadlessCTAButton type="button" onClick={() => navigateCardCollection()} className={GTM_CLASS_NAME.mainCTABtn}> | ||
대화주제 추천 바로가기 | ||
</St.Button> | ||
</HeadlessCTAButton> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import styled from "styled-components"; | ||
|
||
export const CTAButtonWrapper = styled.div` | ||
position: fixed; | ||
bottom: 0rem; | ||
left: 50%; | ||
transform: translate(-50%, 0); | ||
|
||
width: 100%; | ||
${({ theme }) => theme.media.desktop` | ||
width: 36rem; | ||
`}; | ||
height: 9.6rem; | ||
|
||
display: flex; | ||
flex-direction: column; | ||
justify-content: flex-end; | ||
|
||
padding: 0 0.8rem 0.8rem; | ||
|
||
background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, white 40.63%); | ||
|
||
z-index: 10; | ||
`; | ||
|
||
export const CTAButton = styled.button` | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
|
||
width: 100%; | ||
height: 5.6rem; | ||
|
||
background-color: ${({ theme }) => theme.newColors.gray900}; | ||
border-radius: 0.8rem; | ||
|
||
backdrop-filter: blur(0.6rem); | ||
color: ${({ theme }) => theme.newColors.white}; | ||
${({ theme }) => theme.newFonts.btn1}; | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { useEffect, useRef, useState } from "react"; | ||
|
||
const useScrollPosition = () => { | ||
const lastScrollPositionRef = useRef(0); | ||
const [isScrollingDown, setIsScrollingDown] = useState(true); | ||
const [isScrollTop, setIsScrollTop] = useState(true); | ||
|
||
useEffect(() => { | ||
const scrollHandler = () => { | ||
const currentScrollPosition = window.scrollY; | ||
|
||
setIsScrollTop(currentScrollPosition < 20); | ||
setIsScrollingDown(lastScrollPositionRef.current < currentScrollPosition); | ||
Comment on lines
+12
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분에 값이 어떻게 들어가는건지 궁금합니다!!👀👀 그나저나 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 스크롤된 정도가 20 이하면, isScrollTop 상태이고 하지만 이 훅.. 사용하지 않습니다 ㅋㅋㅋ intersectionObeserver로 첫 카드 넘어갈 때 헤더가 바뀌는 방식으로 바꾸었어요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아하!!! 이해했어요💡 어쩐지 없드라😎😎 |
||
|
||
lastScrollPositionRef.current = currentScrollPosition; | ||
}; | ||
|
||
window.addEventListener("scroll", scrollHandler); | ||
|
||
return () => { | ||
window.removeEventListener("scroll", scrollHandler); | ||
}; | ||
}, []); | ||
|
||
return { | ||
isScrollingDown, | ||
isScrollTop, | ||
}; | ||
}; | ||
|
||
export default useScrollPosition; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,42 @@ | ||
import "swiper/swiper.css"; | ||
|
||
import { forwardRef } from "react"; | ||
import { Swiper, SwiperSlide } from "swiper/react"; | ||
|
||
import { CardList } from "../../../types/cardCollection"; | ||
import Card from "../Card"; | ||
import LastCard from "../Card/LastCard"; | ||
import useCardSwiper from "../hooks/useCardSwiper"; | ||
import St from "./style"; | ||
|
||
interface CardSliderProps { | ||
openLoginModalHandler: () => void; | ||
cardLists: CardList[]; | ||
firstCardObsvRef: React.RefObject<HTMLDivElement>; | ||
lastCardObsvRef: React.RefObject<HTMLDivElement>; | ||
} | ||
|
||
const CardSlider = forwardRef(function CardSlider(props: CardSliderProps, ref: React.ForwardedRef<HTMLDivElement>) { | ||
const { openLoginModalHandler, cardLists } = props; | ||
const CardSlider = (props: CardSliderProps) => { | ||
const { openLoginModalHandler, cardLists, firstCardObsvRef, lastCardObsvRef } = props; | ||
const { swiperSettings } = useCardSwiper(); | ||
|
||
return ( | ||
<St.Wrapper> | ||
<Swiper {...swiperSettings} className="swiper"> | ||
{cardLists.map((cardList) => ( | ||
<Swiper {...swiperSettings}> | ||
{cardLists.map((cardList, idx) => ( | ||
<SwiperSlide key={cardList._id}> | ||
<Card openLoginModalHandler={openLoginModalHandler} {...cardList} /> | ||
<Card | ||
openLoginModalHandler={openLoginModalHandler} | ||
{...cardList} | ||
firstCardObsvRef={idx === 0 ? firstCardObsvRef : undefined} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. undefined 대신 null은 어떠신지요?-? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. null 은 object 타입으로, "값이 비어있음을 나타내는 유효한 값"이라고 생각해요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아무것도 아님을 표현하는 거였군용!!🤩 저는 값이 없음을 표현하는 줄 알고 제안해봤습니다:) |
||
/> | ||
</SwiperSlide> | ||
))} | ||
<SwiperSlide> | ||
<LastCard ref={ref} /> | ||
<LastCard ref={lastCardObsvRef} /> | ||
</SwiperSlide> | ||
</Swiper> | ||
</St.Wrapper> | ||
); | ||
}); | ||
}; | ||
|
||
export default CardSlider; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { useState } from "react"; | ||
|
||
import useIntersectionObserver from "../../@common/hooks/useIntersectionObserver"; | ||
|
||
const useHeaderChange = () => { | ||
const [isDefaultHeader, setIsDefaultHeader] = useState(true); | ||
|
||
const intersectionObserverRef = useIntersectionObserver( | ||
(entry) => { | ||
if (entry.isIntersecting) { | ||
setIsDefaultHeader(true); | ||
return; | ||
} | ||
setIsDefaultHeader(false); | ||
}, | ||
{ threshold: 0.5 }, | ||
); | ||
|
||
return { isDefaultHeader, intersectionObserverRef }; | ||
}; | ||
|
||
export default useHeaderChange; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
변수명에
Headless
이거 왜 들어간 걸까요?! 궁금쓰!!There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HeadlessUI 에 고안해서 작성했어요! 이는 쉽게 말해 비즈니스 로직(동작)이 전혀 없이 스타일링 로직만 보여줌을 말합니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HeadlessUI 함 찾아볼게요:) 친절한 설명 감사합니당😆👍