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

[#570] [도서 검색] 도서 검색 결과 렌더링 시 search 헤더 숨기고 input sticky 적용 #589

Merged
merged 8 commits into from
May 20, 2024
2 changes: 1 addition & 1 deletion public/icons/discover.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion public/icons/group.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/app/book/[bookId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const BookTitle = ({ bookId }: { bookId: APIBook['bookId'] }) => {
};

const Heading = ({ text }: { text: string }) => (
<p className="text-xl font-bold">{text}</p>
<p className="font-subheading-bold">{text}</p>
);

const AddBookCommentButton = ({ bookId }: { bookId: APIBook['bookId'] }) => {
Expand Down
40 changes: 34 additions & 6 deletions src/app/book/search/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,36 @@ const BookSearchPage = () => {
const watchedKeyword = watch('searchValue');
const debouncedKeyword = useDebounceValue(watchedKeyword, 1000);

/* TopHeader가 사라졌을 때 input의 위치 top: 5.8rem */
const inputPositionClasses = watchedKeyword && 'sticky top-[5.8rem]';

return (
<>
<TopHeader text={'Discover'} />
<article className="flex max-h-[calc(100%-6rem)] w-full flex-col gap-[3rem]">
<div
className={`transition duration-500 ${
watchedKeyword
? '-translate-y-[5.8rem] opacity-0'
: 'translate-y-0 opacity-100'
}`}
>
<TopHeader text={'Discover'} />
</div>
<article
className={`flex w-full flex-col gap-[3rem] transition duration-500 ${
watchedKeyword ? '-translate-y-[5.8rem]' : 'translate-y-0'
}`}
>
<Input
inputStyle="line"
leftIconType="search"
placeholder="책 제목, 작가를 검색해보세요"
className={`z-10 bg-white ${inputPositionClasses}`}
{...register('searchValue')}
/>

{/** 최근 검색어 + 베스트 셀러 */}
<section
className={`flex flex-col gap-[1.6rem] ${watchedKeyword && 'hidden'}`}
className={`flex flex-col gap-[2rem] ${watchedKeyword && 'hidden'}`}
>
<SSRSafeSuspense fallback={<ContentsSkelton />}>
<RecentSearchResult
Expand All @@ -64,13 +80,13 @@ const BookSearchPage = () => {

{/** 도서 검색 결과 */}
{watchedKeyword && (
<section className="flex-grow overflow-y-scroll pb-[1rem]">
<Suspense fallback={<Loading fullpage />}>
<section className="flex-grow pb-[1rem]">
<Suspense fallback={<BookSearchLoading />}>
{watchedKeyword === debouncedKeyword ? (
<BookSearchResult queryKeyword={debouncedKeyword} />
) : (
/* 타이핑 중 debounce가 적용되어 keyword가 업데이트 되지 않는 경우에 Loading 컴포넌트로 대체 */
<Loading fullpage />
<BookSearchLoading />
)}
</Suspense>
</section>
Expand Down Expand Up @@ -144,6 +160,18 @@ const RecentSearchResult = ({
return <RecentSearchList keywords={keywords} onClick={onItemClick} />;
};

const BookSearchLoading = () => {
return (
/**
* Loading 컴포넌트가 화면 중앙에 올바르게 표시되도록 height가 존재하는 relative div 요소 추가
* 화면이 스크롤 되지 않는 크기: 100dvh - 23.3rem
*/
<div className="relative flex h-[calc(100dvh-23.3rem)]">
<Loading fullpage />
</div>
);
};

const ContentsSkelton = () => {
return (
<>
Expand Down
12 changes: 6 additions & 6 deletions src/app/bookshelf/[bookshelfId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ export default function UserBookShelfPage({
</TopNavigation.RightItem>
</TopNavigation>
<div className="mt-[0.8rem] flex flex-col gap-[0.8rem] pb-[2rem] pt-[1rem] font-bold">
<h1 className="text-[1.8rem]">
<h1 className="font-subheading-bold">
<span className="text-main-900">{data.userNickname}</span>
님의 책장
</h1>
<div className="flex items-center justify-between">
<span className="text-[1.4rem] text-[#939393]">
<span className="text-black-600 font-body2-regular">
{`${data.job.jobGroupKoreanName} • ${data.job.jobNameKoreanName}`}
</span>
<LikeButton
Expand Down Expand Up @@ -123,22 +123,22 @@ const BookShelfContent = ({
<BookShelfRow books={initialBookImageUrl} />
</div>
<div className="mt-[3.8rem] flex flex-col gap-[2rem] rounded-[4px] border border-[#CFCFCF] px-[1.7rem] py-[4rem]">
<p className="text-center text-md font-bold">
<p className="text-center font-body1-bold">
지금 로그인하면
<br />
책장에 담긴 모든 책을 볼 수 있어요!
</p>
<p className="text-center text-xs text-placeholder">
<p className="text-center text-placeholder font-body2-regular">
<span className="text-main-900">{userNickname}</span>님의 책장에서
다양한
<br />
인사이트를 얻을 수 있어요.
</p>
<Link href={KAKAO_OAUTH_LOGIN_URL}>
<Button colorScheme="kakao" size="full">
<div className="flex justify-center gap-[1rem]">
<div className="flex items-center justify-center gap-[1rem]">
<IconKakao width={16} height={'auto'} />
<span className="text-md font-normal">카카오 로그인</span>
<span className="font-body1-regular">카카오 로그인</span>
</div>
</Button>
</Link>
Expand Down
2 changes: 1 addition & 1 deletion src/app/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const ErrorPage = () => {
return (
<div className="absolute left-0 top-0 flex h-full w-full flex-col items-center justify-center gap-[2rem]">
<Image src="/images/loading.gif" width={230} height={160} alt="loading" />
<div className="text-2xl">
<div className="font-heading">
<span className="font-bold text-main-900">다독이</span>도 몰라요~ 왜
이래요~
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/app/group/[groupId]/join/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ const BookGroupJoinForm = ({ groupId }: { groupId: number }) => {
className="mt-[2.5rem] flex flex-col gap-[2.5rem]"
onSubmit={handleSubmit(submitJoinForm)}
>
<p className="whitespace-pre-line text-2xl font-bold leading-snug">
<p className="whitespace-pre-line !leading-snug font-subheading-bold">
{`문제를 맞추면
모임에 가입할 수 있어요`}
</p>
<div className="flex flex-col gap-[1.5rem]">
<p className="text-sm">{question}</p>
<p className="font-body2-regular">{question}</p>
<div className="flex flex-col gap-[0.5rem]">
<Input
{...register('answer', {
Expand Down
2 changes: 1 addition & 1 deletion src/app/group/[groupId]/not-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default function NotFound() {
return (
<div className="absolute left-0 top-0 flex h-full w-full flex-col items-center justify-center gap-[2rem]">
<Image src="/images/loading.gif" width={230} height={160} alt="loading" />
<p className="text-2xl">
<p className="font-heading">
<span className="font-bold text-main-900">다독이</span>가 길을 잃었어요.
</p>
<Link href="/group">
Expand Down
2 changes: 1 addition & 1 deletion src/app/group/[groupId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const DetailBookGroupPage = ({
export default DetailBookGroupPage;

const Heading = ({ text }: { text: string }) => (
<p className=" text-xl font-bold">{text}</p>
<p className="font-subheading-bold">{text}</p>
);

const PageSkeleton = () => (
Expand Down
2 changes: 1 addition & 1 deletion src/app/group/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const MyBookGroupList = () => {
const { data: myId } = useMyProfileId({ enabled: isAuthenticated });

return (
<section className="flex gap-[1rem] overflow-scroll">
<section className="flex gap-[1rem] overflow-y-hidden overflow-x-scroll pb-[1.5rem]">
{bookGroups.map(({ title, book, bookGroupId, owner }) => (
<SimpleBookGroupCard
key={bookGroupId}
Expand Down
5 changes: 4 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ const RootLayout = ({ children }: { children: React.ReactNode }) => {
<html lang="ko">
<head>
<title>다독다독</title>
<meta content="width=device-width, initial-scale=1" name="viewport" />
<meta
content="width=device-width, initial-scale=1, maximum-scale=1"
name="viewport"
/>
<link rel="icon" href="/favicon.ico" />
</head>
{/* @todo Chakra 제거시 app-layout 프로퍼티 제거. */}
Expand Down
2 changes: 1 addition & 1 deletion src/app/not-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const NotFound = () => {
return (
<div className="absolute left-0 top-0 flex h-full w-full flex-col items-center justify-center gap-[2rem]">
<Image src="/images/loading.gif" width={230} height={160} alt="loading" />
<div className="text-2xl">
<div className="font-heading">
<span className="font-bold text-main-900">다독이</span>가 길을 잃었어요.
</div>
<Button
Expand Down
20 changes: 13 additions & 7 deletions src/app/profile/me/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ const MyProfileForUnAuth = () => {
<div className="mb-[2rem] flex items-center gap-[1rem]">
<Avatar size="large" />
<div className="flex-grow">
<h2 className="text-lg font-bold">로그인 / 회원가입</h2>
<p className="text-sm text-placeholder">
<h2 className="pb-[0.2rem] font-subheading-bold">
로그인 / 회원가입
</h2>
<p className="text-placeholder font-body2-regular">
카카오로 3초만에 가입할 수 있어요.
</p>
</div>
Expand All @@ -54,21 +56,25 @@ const MyProfileForUnAuth = () => {
</div>
<div className="flex flex-col gap-[0.6rem]">
<div className="flex items-center justify-between">
<h3 className="text-lg font-bold">책장</h3>
<h3 className="font-body1-bold">책장</h3>
</div>
<BookShelf>
<div className="w-app pb-[2.5rem] pt-[2rem] shadow-[0px_20px_20px_-16px_#D1D1D1]">
<BookShelf.Background />
<div className="pb-[5.5rem] pt-[3rem] text-center">
<p className="text-sm text-placeholder">책장이 비었어요.</p>
<p className="text-placeholder font-body2-regular">
책장이 비었어요.
</p>
</div>
</div>
</BookShelf>
</div>
<div className="flex flex-col gap-[0.6rem]">
<h3 className="text-lg font-bold">참여한 모임</h3>
<h3 className="font-body1-bold">참여한 모임</h3>
<div className="pb-[5.5rem] pt-[5.5rem] text-center">
<p className="text-sm text-placeholder">참여 중인 모임이 없어요.</p>
<p className="text-placeholder font-body2-regular">
참여 중인 모임이 없어요.
</p>
</div>
</div>
</div>
Expand Down Expand Up @@ -101,7 +107,7 @@ const MyProfileForAuth = () => {
<ProfileInfo userId={USER_ID} />
<Link href="/profile/me/edit" className="w-full">
<Button colorScheme="main-light" size="full">
<span className="mr-[0.5rem] text-sm font-bold text-black-700">
<span className="mr-[0.5rem] text-black-700 font-body2-bold">
프로필 수정
</span>
</Button>
Expand Down
6 changes: 6 additions & 0 deletions src/styles/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
margin: 0 auto;
}

.sticky {
/* -webkit-sticky: Safari 브라우저 호환 */
position: -webkit-sticky;
position: sticky;
}
Comment on lines +35 to +39
Copy link
Member

Choose a reason for hiding this comment

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

👍


/* DatePicker Calendar 스타일링 */
input[type='date']::-webkit-calendar-picker-indicator {
background-image: none;
Expand Down
2 changes: 1 addition & 1 deletion src/v1/base/BottomNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const BottomNavigation = ({ pathname }: BottomNavigationProps) => {
}`}
>
<div className="h-[2.6rem] w-[2.6rem]">{icon}</div>
<p className="text-xs font-bold">{label}</p>
<p className="font-caption1-bold">{label}</p>
</button>
</Link>
))}
Expand Down
14 changes: 7 additions & 7 deletions src/v1/base/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@ type ButtonProps = PropsWithChildren<{
const getSizeClasses = (size: Size) => {
switch (size) {
case 'small': {
return 'text-sm px-[1.2rem] py-[0.6rem]';
return 'font-body2-bold px-[1.2rem] py-[0.6rem]';
}
case 'medium': {
return 'text-md px-[1.6rem] py-[0.8rem]';
return 'font-body1-bold px-[1.6rem] py-[0.8rem]';
}
case 'large': {
return 'text-lg px-[2.4rem] py-[1rem]';
return 'font-body1-bold px-[2.4rem] py-[1rem]';
}
case 'full': {
return 'text-lg px-[2.4rem] py-[1rem] w-full';
return 'font-body1-bold px-[2.4rem] py-[1rem] w-full';
}
default: {
// medium
return 'text-md px-[1.6rem] py-[0.8rem]';
return 'font-body1-bold px-[1.6rem] py-[0.8rem]';
}
}
};
Expand All @@ -41,7 +41,7 @@ const getSchemeClasses = (theme: ColorScheme, isFill: boolean) => {
: 'border-main-900 text-main-900';
}
case 'main-light': {
return 'border-transparent bg-main-600/[.18] text-main-900 font-normal';
return 'border-transparent bg-main-600/[.18] text-main-900 !font-normal';
}
case 'warning': {
return isFill
Expand All @@ -60,7 +60,7 @@ const getSchemeClasses = (theme: ColorScheme, isFill: boolean) => {
};

const BASE_BUTTON_CLASSES =
'cursor-pointer border-[0.1rem] leading-none inline-block font-bold focus:outline-none focus:ring-2';
'cursor-pointer border-[0.1rem] leading-none inline-block focus:outline-none focus:ring-2';

const Button = ({
size = 'medium',
Expand Down
6 changes: 3 additions & 3 deletions src/v1/base/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const DatePicker = (

return (
<label
className={`relative flex h-[3rem] max-w-[14rem] items-center justify-between gap-[0.5rem] bg-transparent ${disabledClasses}`}
className={`relative flex h-[3rem] max-w-[16rem] items-center justify-between gap-[0.5rem] bg-transparent ${disabledClasses}`}
htmlFor={name}
>
<div className="flex h-full min-w-0 flex-grow items-center">
Expand All @@ -69,8 +69,8 @@ const DatePicker = (
{...props}
/>
<p
className={`truncate text-sm ${
currentDate ? 'text-inherit' : 'text-placeholder'
className={`truncate font-body1-regular ${
currentDate ? 'text-black-700' : 'text-placeholder'
}`}
>
{currentDate
Expand Down
8 changes: 6 additions & 2 deletions src/v1/base/Drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,16 @@ const DrawerHeader = ({ children }: { children?: ReactNode }) => {
};

const DrawerContent = ({ children }: { children?: ReactNode }) => {
return <div className="w-full px-6 pt-6 text-md sm:px-8">{children}</div>;
return (
<div className="w-full px-6 pt-6 font-body1-regular sm:px-8">
{children}
</div>
);
};

const Title = ({ text }: { text?: string }) => {
return (
<h1 className="flex-grow truncate pl-[2.5rem] text-center text-md">
<h1 className="flex-grow truncate pl-[2.5rem] text-center font-body1-regular">
{text}
</h1>
);
Expand Down
2 changes: 1 addition & 1 deletion src/v1/base/ErrorMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const ErrorMessage = ({ children }: { children?: ReactNode }) => {
return (
<>
{children && (
<div className="flex items-center gap-[0.4rem] text-xs text-warning-800">
<div className="flex items-center gap-[0.4rem] text-warning-800 font-caption1-regular">
<div className="h-[1.2rem] w-[1.2rem]">
<IconWarningCircle />
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/v1/base/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ interface InputProps extends ComponentPropsWithoutRef<'input'> {
}

const FONT_SIZE_CLASSES = {
small: 'text-sm after:text-sm',
large: 'text-lg font-bold after:text-lg after:font-bold',
small: 'font-body1-regular after:font-body1-regular',
large: 'font-subheading-bold after:font-subheading-bold',
};

const getInputStyleClasses = (inputStyle: InputStyle) => {
Expand Down
2 changes: 1 addition & 1 deletion src/v1/base/InputLength.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const InputLength = ({
const textColor = isError ? 'text-warning-800 ' : 'text-main-900';

return (
<p className="text-xs">
<p className="font-caption1-regular">
<span className={textColor}>{currentLength ? currentLength : 0}</span>/
{maxLength}
</p>
Expand Down
Loading
Loading