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

디자인 시스템 적용 및 반응형처리 #8

Merged
merged 9 commits into from
Feb 17, 2025
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"next": "15.1.3",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"sonner": "^1.7.4",
"tailwind-merge": "^2.6.0",
"zustand": "^5.0.2"
},
Expand Down
20 changes: 12 additions & 8 deletions src/app/(routes)/test/page.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
"use client"

import Button from "@/components/Button"
import Footer from "@/components/Footer"
import Header from "@/components/Header"
import Input from "@/components/Input"
import MemeTypeButton from "@/components/MemeTypeButton"
import MoreViewButton from "@/components/MoreViewButton"
import SearchInput from "@/components/SearchInput"
import TagButton from "@/components/TagButton"
import TagSmallButton from "@/components/TagSmallButton"
import Textarea from "@/components/Textarea"
import ThumbnailCard from "@/components/ThumbnailCard"
import { useToast } from "@/store/toast"
import { COLORS } from "@/styles/colors"
import { Heart, Search, Type } from "lucide-react"
import { toast } from "sonner"

export default function TestPage() {
const { showToast } = useToast()

return (
<section className="mx-[20px] my-[80px] flex flex-col gap-[12px]">
<button onClick={() => showToast({ text: "테스트", type: "warning" })}>auto close Toast</button>
<button onClick={() => showToast({ text: "테스트", type: "success", autoClose: false })}>Toast</button>
<Header />
<Footer />
<button onClick={() => toast.success("삭제가 완료되었습니다!")}>토스트 메세지</button>
<MemeTypeButton
title="텍스트밈"
Icon={Type}
Expand All @@ -28,8 +30,10 @@ export default function TestPage() {
<article className="flex gap-[12px]">
<TagButton title="키워드" onClick={() => console.log("TagButton1 클릭")} />
<TagButton title="ㄱ키워드" variant="colored" onClick={() => console.log("TagButton2 클릭")} />
<TagSmallButton title="ㄱ키워드" onClick={() => console.log("TagSmallButton1 클릭")} />
<TagSmallButton title="ㄱ키워드" variant="colored" onClick={() => console.log("TagSmallButton2 클릭")} />
</article>
<Button className="w-[120px] text-white">컬렉션 1</Button>
<Button className="w-[120px] text-gray-scale-100">컬렉션 1</Button>
<article className="flex gap-[12px]">
<Input placeholder="컬렉션 이름을 검색해주세요" />
<Input placeholder="메모 내용을 입력해주세요" className="border-none" />
Expand All @@ -47,8 +51,8 @@ export default function TestPage() {
<SearchInput placeholder="아이콘 없는 검색 Input" onSearch={() => console.log("검색 이벤트!")} />
</article>
<article className="flex gap-[12px]">
<Textarea />
<Textarea className="border-none" />
<Textarea placeholder="메모를 입력해주세요" />
<Textarea placeholder="메모를 입력해주세요" className="border-none" />
</article>
<article className="flex gap-[12px]">
<ThumbnailCard
Expand Down
19 changes: 5 additions & 14 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
import Toast from "@/components/Toast"
import NewToast from "@/components/NewToast"
import { Pretendard } from "@/fonts"
import "@/styles/globals.css"
import "@/styles/reset.css"
import { cn } from "@/utils/cn"
import type { Metadata } from "next"
import { Geist, Geist_Mono } from "next/font/google"

const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"]
})

const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"]
})

export const metadata: Metadata = {
title: "Create Next App",
Expand All @@ -26,10 +17,10 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body className={`${geistSans.variable} ${geistMono.variable} text-white antialiased`}>
<body className={cn(Pretendard.variable)}>
<div id="toastPortal" />
<Toast />
{children}
<NewToast />
</body>
</html>
)
Expand Down
2 changes: 1 addition & 1 deletion src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function Button({ children, ...buttonProps }: Params) {
return (
<button
{...buttonProps}
className={cn("w-fit rounded-lg bg-primary-400 p-2 font-semibold text-dark", buttonProps.className)}
className={cn("w-fit rounded-[8px] bg-primary-400 p-[8px] text-gray-scale-900", buttonProps.className)}
>
{children}
</button>
Expand Down
11 changes: 11 additions & 0 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Image from "next/image"

export default function Footer() {
return (
<section>
<article className="relative h-[20px] w-[120px]">
<Image src={"/kakao.png"} alt="logo" fill />
</article>
</section>
)
}
26 changes: 26 additions & 0 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Search } from "lucide-react"
import Image from "next/image"
import Button from "@/components/Button"
import { COLORS } from "@/styles/colors"

export default function Header() {
// Todo 세션체크해서 닉네임, 버튼 조건부 렌더링
return (
// lg:px-[120px]
<section className="flex h-[94px] w-full items-end justify-between px-[16px] py-[12px] md:h-auto md:items-center md:px-[24px] md:py-[8px]">
<article className="relative h-[24px] w-[120px]">
<Image src={"/kakao.png"} alt="logo" fill />
</article>
<article className="flex flex-row-reverse items-center gap-[24px] md:flex md:flex-row">
<div className="flex items-center gap-[8px]">
<div className="relative h-[24px] w-[24px]">
<Image src={"/cat.png"} alt="profile-image" fill className="rounded-full" />
</div>
<p className="hidden text-h3-r md:flex">유저 닉네임이 들어가요</p>
</div>
<Search size={24} color={COLORS.PRIMARY} />
<Button className="hidden bg-primary-300 px-[24px] py-[4px] text-h2-sb md:flex">로그인</Button>
</article>
</section>
)
}
4 changes: 2 additions & 2 deletions src/components/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import type { InputHTMLAttributes } from "react"

export default function Input(props: InputHTMLAttributes<HTMLInputElement>) {
return (
<section className="relative flex w-fit items-center">
<section className="relative flex w-full items-center">
<input
{...props}
className={cn(
"w-fit rounded-lg border border-primary-400 bg-gray-scale-800 p-4 font-semibold outline-none placeholder:text-gray",
"w-full rounded-[8px] border border-primary-400 bg-gray-scale-800 px-[16px] py-[12px] text-gray-scale-100 outline-none placeholder:text-gray-scale-400",
props.className
)}
/>
Expand Down
4 changes: 2 additions & 2 deletions src/components/MemeTypeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ export default function MemeTypeButton({ title, Icon, iconProps, ...buttonProps
return (
<Button
{...buttonProps}
className={cn("flex w-[224px] items-center gap-[12px] rounded-lg bg-primary-400 p-2", buttonProps.className)}
className={cn("flex w-[224px] items-center gap-[12px] rounded-[8px] bg-primary-400 p-2", buttonProps.className)}
>
{!!Icon && <Icon {...iconProps} />}
<p className="font-bold text-dark">{title}</p>
<p className="text-h2-b text-gray-scale-900">{title}</p>
</Button>
)
}
4 changes: 2 additions & 2 deletions src/components/MoreViewButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ export default function MoreViewButton({ title, Icon = ArrowRight, iconProps, ..
<Button
{...buttonProps}
className={cn(
"relative flex w-full cursor-pointer items-center justify-between rounded-lg border border-primary-400 bg-gray-scale-700 p-2 px-4 text-white",
"relative flex w-full cursor-pointer items-center justify-between rounded-[8px] border border-primary-400 bg-gray-scale-700 px-[16px] py-[8px] text-h2-sb text-gray-scale-100",
buttonProps.className
)}
>
<p className="font-semibold">{title}</p>
<p>{title}</p>
<Icon {...iconProps} />
</Button>
)
Expand Down
20 changes: 20 additions & 0 deletions src/components/NewToast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"use client"
import { Toaster } from "sonner"

export default function NewToast() {
return (
<Toaster
duration={3000}
className="font-pretendard flex items-center justify-center"
position="bottom-center"
// offset={{ left: 0, right: 0 }}
mobileOffset={{ left: 0, right: 0, bottom: 20 }}
toastOptions={{
classNames: {
toast:
"bg-primary-300 drop-shadow-toast backdrop-blur-lg border-none text-h2-m max-w-[280px] sm:max-w-[340px] justify-self-center p-[8px]"
}
}}
/>
)
}
6 changes: 3 additions & 3 deletions src/components/SearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ export default function SearchInput({ onSearch, Icon, iconProps, ...props }: Par
}

return (
<section className="relative flex w-fit items-center">
<section className="relative flex w-full items-center">
<input
{...props}
onKeyDown={handleKeyDown}
className={cn(
"w-full rounded-lg border border-primary-400 bg-gray-scale-800 p-4 font-semibold outline-none placeholder:text-gray",
"w-full rounded-[8px] border border-primary-400 bg-gray-scale-800 px-[16px] py-[12px] font-semibold outline-none placeholder:text-gray-scale-400",
Icon && "pr-10",
props.className
)}
/>
{Icon && <IconButton onClick={onSearch} className="absolute end-2" Icon={Icon} iconProps={iconProps} />}
{Icon && <IconButton onClick={onSearch} className="absolute end-[8px]" Icon={Icon} iconProps={iconProps} />}
</section>
)
}
6 changes: 4 additions & 2 deletions src/components/TagButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ export default function TagButton({ title, variant = "default", ...buttonProps }
<Button
{...buttonProps}
className={cn(
"w-fit rounded-lg bg-gray-scale-700 p-2 px-4 text-white",
variant === "colored" && "border border-primary-400 font-semibold text-primary-300",
"w-fit rounded-[8px] bg-gray-scale-700 px-[16px] py-[8px]",
variant === "colored"
? "border border-primary-400 text-h2-m text-primary-300"
: "text-h2-sb text-gray-scale-200",
buttonProps.className
)}
>
Expand Down
23 changes: 23 additions & 0 deletions src/components/TagSmallButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { cn } from "@/utils/cn"
import type { ButtonHTMLAttributes } from "react"
import Button from "./Button"

interface Params extends ButtonHTMLAttributes<HTMLButtonElement> {
title: string
variant?: "default" | "colored"
}

export default function TagSmallButton({ title, variant = "default", ...buttonProps }: Params) {
return (
<Button
{...buttonProps}
className={cn(
"w-fit rounded-[8px] bg-gray-scale-700 p-[8px] text-h3-m",
variant === "colored" ? "border border-primary-400 text-primary-300" : "text-gray-scale-200",
buttonProps.className
)}
>
<p>{title}</p>
</Button>
)
}
4 changes: 2 additions & 2 deletions src/components/Textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import type { TextareaHTMLAttributes } from "react"

export default function Textarea(props: TextareaHTMLAttributes<HTMLTextAreaElement>) {
return (
<section className="relative flex w-fit items-center">
<section className="relative flex w-full items-center">
<textarea
{...props}
className={cn(
"w-fit resize-none rounded-lg border border-primary-400 bg-gray-scale-800 p-4 font-semibold outline-none placeholder:text-gray",
"w-full resize-none rounded-[16px] border border-primary-400 bg-gray-scale-800 px-[16px] py-[12px] text-h3-r text-gray-scale-100 outline-none placeholder:text-gray-scale-400",
props.className
)}
/>
Expand Down
4 changes: 2 additions & 2 deletions src/components/ThumbnailCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ export default function ThumbnailCard({
return (
<section
className={cn(
"relative flex h-fit w-[224px] flex-col gap-[24px] break-all rounded-lg bg-gray-scale-700 p-4",
"relative flex h-fit w-[224px] flex-col gap-[24px] break-all rounded-[8px] bg-gray-scale-700 p-[16px]",
like && "border border-primary drop-shadow-thumbnail"
)}
>
{Icon && <IconButton Icon={Icon} iconProps={iconProps} className="self-end" />}
{type === "text" && <p>{text}</p>}
{type === "image" && (
<Image src={url} alt={"meme-thumbnail"} width={224} height={0} className="rounded-md object-contain" />
<Image src={url} alt={"meme-thumbnail"} width={224} height={0} className="rounded-[8px] object-contain" />
)}
{type === "video" && <p>{url}</p>}
</section>
Expand Down
4 changes: 2 additions & 2 deletions src/components/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function Toast() {
<AnimatePresence>
{toast.isOpened && (
<motion.section
className="fixed bottom-0 flex w-full justify-center bg-dark/60 px-6 py-10 drop-shadow-toast backdrop-blur-lg"
className="bg-dark/60 fixed bottom-0 z-[100] flex w-full justify-center px-6 py-10 drop-shadow-toast backdrop-blur-lg"
initial={{ y: 50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
exit={{ y: 50, opacity: 0 }}
Expand All @@ -52,7 +52,7 @@ export default function Toast() {
</div>
{!toast.autoClose && (
<button
className="min-w-[148px] rounded-md bg-gray-scale-800 px-3 py-2 text-white hover:bg-gray-scale-700"
className="min-w-[148px] rounded-[8px] bg-gray-scale-800 px-[12px] py-[8px] text-gray-scale-100 hover:bg-gray-scale-700"
onClick={closeToast}
>
완료
Expand Down
Binary file added src/fonts/PretendardVariable.woff2
Binary file not shown.
8 changes: 8 additions & 0 deletions src/fonts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import localFont from "next/font/local"

export const Pretendard = localFont({
src: "../fonts/PretendardVariable.woff2",
variable: "--font-pretendard",
weight: "400 500 600 700",
display: "swap"
})
2 changes: 2 additions & 0 deletions src/styles/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ export const COLORS = {
GRAY_SCALE_700: "#343134",
GRAY_SCALE_800: "#222122",
GRAY_SCALE_900: "#171617",
COLOR_OPACITY_20: "#17151733",
COLOR_OPACITY_60: "#17161799",
SEMANTIC: "#FF2424"
}
4 changes: 3 additions & 1 deletion src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
@tailwind utilities;

:root {
--foreground: #f7f7f7;
--background: #171617;
}

body {
color: var(--foreground);
background: var(--background);
font-family: Arial, Helvetica, sans-serif;
font-family: var(--font-pretendard), sans-serif;
}
Loading