Skip to content
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

Merged
merged 13 commits into from
May 5, 2023
17 changes: 17 additions & 0 deletions src/@components/@common/CTABtn/HeadlessCTAButton.tsx
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>) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

변수명에 Headless 이거 왜 들어간 걸까요?! 궁금쓰!!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HeadlessUI 에 고안해서 작성했어요! 이는 쉽게 말해 비즈니스 로직(동작)이 전혀 없이 스타일링 로직만 보여줌을 말합니다!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HeadlessUI 함 찾아볼게요:) 친절한 설명 감사합니당😆👍

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>
);
}
40 changes: 40 additions & 0 deletions src/@components/@common/CTABtn/style.ts
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};
`;
2 changes: 1 addition & 1 deletion src/@components/@common/Header/HeaderMinVer/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Link as LinkComponent } from "react-router-dom";
import styled from "styled-components";

const Header = styled.header`
position: absolute;
position: sticky;
top: 0;
left: 0;
right: 0;
Expand Down
5 changes: 1 addition & 4 deletions src/@components/@common/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useLocation } from "react-router-dom";

import { IcHamburger, IcLogo } from "../../../asset/icon";
import { routePaths } from "../../../core/routes/path";
import { GTM_CLASS_NAME } from "../../../util/const/gtm";
Expand All @@ -8,11 +6,10 @@ import MenuBar from "../MenuBar";
import * as St from "./style";

export default function Header() {
const { pathname } = useLocation();
const { isModalOpen, toggleModal } = useModal();

return (
<St.HeaderWrapper iscardview={pathname === routePaths.CardCollection}>
<St.HeaderWrapper>
<St.Link to={routePaths.Main} className={GTM_CLASS_NAME.mainPiickleLogo}>
<IcLogo aria-label="피클" />
</St.Link>
Expand Down
6 changes: 3 additions & 3 deletions src/@components/@common/Header/style.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Link as LinkRouter } from "react-router-dom";
import styled from "styled-components";

export const HeaderWrapper = styled.header<{ iscardview: boolean }>`
export const HeaderWrapper = styled.header`
display: flex;
position: ${({ iscardview }) => (iscardview ? "absolute" : "sticky")};
position: sticky;
top: 0;
align-items: center;
justify-content: space-between;
Expand All @@ -13,7 +13,7 @@ export const HeaderWrapper = styled.header<{ iscardview: boolean }>`
width: 100%;
height: 5.2rem;

background-color: ${({ theme, iscardview }) => (iscardview ? "transparent" : theme.colors.white)};
background-color: ${({ theme }) => theme.colors.white};

z-index: 10;
`;
Expand Down
9 changes: 6 additions & 3 deletions src/@components/@common/LoginModal/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const Container = styled.section`
align-items: center;
gap: 6rem;

margin-top: 6.9rem;
margin-top: 6.4rem;
height: 13.6rem;
`;

Expand All @@ -25,13 +25,12 @@ export const Buttons = styled.div`
width: 100%;

display: flex;
gap: 0.1rem;

height: 5.8em;
`;

export const Button = styled.button`
flex: 1;
width: 100%;

display: flex;
justify-content: center;
Expand All @@ -42,4 +41,8 @@ export const Button = styled.button`
${({ theme }) => theme.newFonts.btn1};
color: ${({ theme }) => theme.newColors.gray100};
background: ${({ theme }) => theme.newColors.gray900};

&:first-child {
margin-right: 0.1rem;
}
`;
10 changes: 8 additions & 2 deletions src/@components/@common/Modal/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ import styled, { keyframes } from "styled-components";
export const Root = styled.div`
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;

width: 100vw;
${({ theme }) => theme.media.desktop`
width: 36rem;
`};
height: 100vh;
height: calc(var(--vh, 1vh) * 100);
min-height: -webkit-fill-available;

z-index: 10;

background-color: rgb(0, 0, 0, 0.5);
Expand Down
31 changes: 31 additions & 0 deletions src/@components/@common/hooks/useScrollPosition.ts
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분에 값이 어떻게 들어가는건지 궁금합니다!!👀👀

그나저나 isScrollingDown, isScrollTop 변수명 대박인데요? 세심한 사람✨✨

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스크롤된 정도가 20 이하면, isScrollTop 상태이고
이전 스크롤 정도보다 현재 스크롤 정도가 크다면 isScrollingDown 상태입니다!

하지만 이 훅.. 사용하지 않습니다 ㅋㅋㅋ intersectionObeserver로 첫 카드 넘어갈 때 헤더가 바뀌는 방식으로 바꾸었어요
해당 훅은 이후에 쓰일까 남겨두었습니다!

Copy link
Contributor

Choose a reason for hiding this comment

The 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;
5 changes: 3 additions & 2 deletions src/@components/CardCollectionPage/Card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,16 @@ interface LoginCheckProps {
content: string;
isBookmark: boolean;
tags: string[];
firstCardObsvRef?: React.RefObject<HTMLDivElement>;
}

const Card = (props: LoginCheckProps) => {
const { _id, content, isBookmark, tags, openLoginModalHandler } = props;
const { _id, content, isBookmark, tags, openLoginModalHandler, firstCardObsvRef } = props;

const { isBookmarked, handleClickBookmark } = useCardBookmark(isBookmark, openLoginModalHandler);

return (
<St.Card className={GTM_CLASS_NAME.cardSwipe}>
<St.Card ref={firstCardObsvRef} className={GTM_CLASS_NAME.cardSwipe}>
<St.Container>
<St.ContentWrapper className={GTM_CLASS_NAME.cardSwipe}>{content}</St.ContentWrapper>
<St.TagsWrapper>
Expand Down
4 changes: 2 additions & 2 deletions src/@components/CardCollectionPage/Card/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styled from "styled-components";
const Card = styled.article`
position: relative;

margin: 0.8rem;
margin: 0 0.8rem 0.8rem;
height: 100%;

border: 0.1rem solid ${({ theme }) => theme.colors.gray200};
Expand All @@ -26,7 +26,7 @@ const Container = styled.div`
const ContentWrapper = styled.p`
text-align: center;

word-break: keep-all;
white-space: pre-wrap;

${({ theme }) => theme.newFonts.body1};
color: ${({ theme }) => theme.newColors.gray900};
Expand Down
22 changes: 14 additions & 8 deletions src/@components/CardCollectionPage/CardSlider/index.tsx
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}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undefined 대신 null은 어떠신지요?-?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null 은 object 타입으로, "값이 비어있음을 나타내는 유효한 값"이라고 생각해요
따라서 아에 아무것도 아님을 표현하기 위해 undefined로 작성해보았어요!

Copy link
Contributor

Choose a reason for hiding this comment

The 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;
3 changes: 1 addition & 2 deletions src/@components/CardCollectionPage/CardSlider/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ import styled from "styled-components";
const Wrapper = styled.section`
position: relative;
height: 100%;
padding-top: 3.3rem;

& .swiper {
width: 100%;
height: 100%;
}

& .swiper-slide {
height: calc((100% + 3.3rem) * 0.75);
height: calc((100% + 3.3rem) * 0.77);
}

& .swiper-slide:last-child {
Expand Down
22 changes: 22 additions & 0 deletions src/@components/CardCollectionPage/hooks/useHeaderChange.ts
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;
Loading