From b39692b02fef5026f0d9af1c5cb52efc35ba7e1c Mon Sep 17 00:00:00 2001 From: Andy Hong Date: Tue, 30 Dec 2025 16:27:39 +0900 Subject: [PATCH 01/12] =?UTF-8?q?perf:=20=ED=8F=B0=ED=8A=B8=20=EB=A1=9C?= =?UTF-8?q?=EB=94=A9=20=EB=B0=A9=EC=8B=9D=20=EC=B5=9C=EC=A0=81=ED=99=94=20?= =?UTF-8?q?=EB=B0=8F=20preconnect=20=EC=B6=94=EA=B0=80=20(#6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 7 ++++++- src/styles/fonts.css | 1 - src/styles/index.css | 1 - 3 files changed, 6 insertions(+), 3 deletions(-) delete mode 100644 src/styles/fonts.css diff --git a/index.html b/index.html index dc243c95..fc453bc0 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,12 @@ - ttorang-frontend + 또랑 + +
diff --git a/src/styles/fonts.css b/src/styles/fonts.css deleted file mode 100644 index 2c2e7242..00000000 --- a/src/styles/fonts.css +++ /dev/null @@ -1 +0,0 @@ -@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css'); diff --git a/src/styles/index.css b/src/styles/index.css index e5706ed8..1da34e2c 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -1,5 +1,4 @@ @import "tailwindcss"; -@import "./fonts.css"; @import "./theme.css"; @import "./typography.css"; From 85b168c56a8c58766dffd5e962ea7a98f0eb396c Mon Sep 17 00:00:00 2001 From: Andy Hong Date: Tue, 30 Dec 2025 16:28:56 +0900 Subject: [PATCH 02/12] =?UTF-8?q?feat:=20=ED=97=A4=EB=8D=94=20=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=95=84=EC=9B=83=20=EA=B5=AC=ED=98=84=20(#6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/layout/Header.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/components/layout/Header.tsx diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx new file mode 100644 index 00000000..9dd91d49 --- /dev/null +++ b/src/components/layout/Header.tsx @@ -0,0 +1,13 @@ +import type { ReactNode } from 'react'; + +interface HeaderProps { + children?: ReactNode; +} + +export function Header({ children }: HeaderProps) { + return ( +
+ {children} +
+ ); +} From 28aba23f08973fbd74549d22f5b50114770fc344 Mon Sep 17 00:00:00 2001 From: Andy Hong Date: Tue, 30 Dec 2025 17:01:07 +0900 Subject: [PATCH 03/12] =?UTF-8?q?feat:=20GNB=20=EB=A9=94=EB=89=B4=20?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EA=B5=AC=ED=98=84=20(#6?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 활성/비활성 상태 전환 시 layout shift 방지를 위해 투명 테두리 적용 - 스크린 리더 지원을 위한 aria 속성 추가 --- src/components/layout/GNB.tsx | 39 ++++++++++++++++++++++++++++++++ src/components/layout/Layout.tsx | 17 ++++++++++++++ src/components/layout/index.ts | 3 +++ 3 files changed, 59 insertions(+) create mode 100644 src/components/layout/GNB.tsx create mode 100644 src/components/layout/Layout.tsx create mode 100644 src/components/layout/index.ts diff --git a/src/components/layout/GNB.tsx b/src/components/layout/GNB.tsx new file mode 100644 index 00000000..86e0dfc7 --- /dev/null +++ b/src/components/layout/GNB.tsx @@ -0,0 +1,39 @@ +export type Tab = 'slide' | 'video' | 'insight'; + +interface GNBProps { + activeTab?: Tab; + onTabChange?: (tab: Tab) => void; +} + +const TABS: { key: Tab; label: string }[] = [ + { key: 'slide', label: '슬라이드' }, + { key: 'video', label: '영상' }, + { key: 'insight', label: '인사이트' }, +]; + +export function GNB({ activeTab = 'slide', onTabChange }: GNBProps) { + return ( + + ); +} diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx new file mode 100644 index 00000000..00626d28 --- /dev/null +++ b/src/components/layout/Layout.tsx @@ -0,0 +1,17 @@ +import type { ReactNode } from 'react'; + +import { Header } from './Header'; + +interface LayoutProps { + children?: ReactNode; + header: ReactNode; +} + +export function Layout({ children, header }: LayoutProps) { + return ( +
+
{header}
+
{children}
+
+ ); +} diff --git a/src/components/layout/index.ts b/src/components/layout/index.ts new file mode 100644 index 00000000..ee6726a4 --- /dev/null +++ b/src/components/layout/index.ts @@ -0,0 +1,3 @@ +export { GNB, type Tab } from './GNB'; +export { Header } from './Header'; +export { Layout } from './Layout'; From 19eb47f3ce69e0f87292ed0beb334cb0e50e1e5a Mon Sep 17 00:00:00 2001 From: Andy Hong Date: Tue, 30 Dec 2025 17:09:50 +0900 Subject: [PATCH 04/12] =?UTF-8?q?style:=20props=20=EC=9E=AC=EC=A0=95?= =?UTF-8?q?=EB=A0=AC=20(#6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit header가 children 앞에 오는게 더 자연스럽게 느껴져서 옮겼습니다. --- src/components/layout/Layout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index 00626d28..1517a961 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -3,8 +3,8 @@ import type { ReactNode } from 'react'; import { Header } from './Header'; interface LayoutProps { - children?: ReactNode; header: ReactNode; + children?: ReactNode; } export function Layout({ children, header }: LayoutProps) { From 3d6d8d74ce48bc5d0d0e3a4630c8a4cd017d6e52 Mon Sep 17 00:00:00 2001 From: Andy Hong Date: Tue, 30 Dec 2025 17:14:35 +0900 Subject: [PATCH 05/12] =?UTF-8?q?chore:=20ESLint=20parserOptions.project?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80=20(#6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .eslintrc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index 7df4352d..480ad3c1 100644 --- a/.eslintrc +++ b/.eslintrc @@ -18,7 +18,8 @@ "sourceType": "module", "ecmaFeatures": { "jsx": true - } + }, + "project": "./tsconfig.app.json" }, "plugins": ["@typescript-eslint", "react", "react-hooks", "react-refresh", "check-file"], "settings": { From 9c376553eb36b34d55c7aea437a1aca006977ec9 Mon Sep 17 00:00:00 2001 From: Andy Hong Date: Tue, 30 Dec 2025 17:14:46 +0900 Subject: [PATCH 06/12] =?UTF-8?q?refactor:=20=ED=83=AD=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EB=B0=8F=20=ED=83=80=EC=9E=85=20=EC=83=81?= =?UTF-8?q?=EC=88=98=ED=99=94=20(#6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SSoT 원칙에 의거하여 탭 데이터(TABS)와 타입(Tab)을 분리하였습니다. --- src/components/layout/GNB.tsx | 8 +------- src/components/layout/index.ts | 3 ++- src/constants/navigation.ts | 7 +++++++ 3 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 src/constants/navigation.ts diff --git a/src/components/layout/GNB.tsx b/src/components/layout/GNB.tsx index 86e0dfc7..726f29da 100644 --- a/src/components/layout/GNB.tsx +++ b/src/components/layout/GNB.tsx @@ -1,16 +1,10 @@ -export type Tab = 'slide' | 'video' | 'insight'; +import { TABS, type Tab } from '../../constants/navigation'; interface GNBProps { activeTab?: Tab; onTabChange?: (tab: Tab) => void; } -const TABS: { key: Tab; label: string }[] = [ - { key: 'slide', label: '슬라이드' }, - { key: 'video', label: '영상' }, - { key: 'insight', label: '인사이트' }, -]; - export function GNB({ activeTab = 'slide', onTabChange }: GNBProps) { return (