From c38c9398d0997d1fed09bc97b664d6dd1643ca74 Mon Sep 17 00:00:00 2001 From: sumi-0011 Date: Wed, 14 Jan 2026 09:42:01 +0900 Subject: [PATCH 01/85] refactor: tailwind setting migration --- apps/web/MIGRATION_STATUS.md | 153 +++ apps/web/package.json | 4 + apps/web/postcss.config.mjs | 9 + apps/web/src/app/[locale]/auth/page.tsx | 19 +- .../src/app/[locale]/auth/signOut/page.tsx | 17 +- apps/web/src/app/[locale]/error.tsx | 7 +- .../event/(christmas)/ChristmasCard.tsx | 14 +- .../[locale]/event/(christmas)/Snowflake.tsx | 16 +- .../app/[locale]/event/(christmas)/index.tsx | 63 +- .../event/(common)/BackgroundSection.tsx | 78 +- .../event/(common)/BackgroundSlider/Arrow.tsx | 56 +- .../BackgroundSlider/BackgroundSlider.tsx | 46 +- .../app/[locale]/event/(common)/CardList.tsx | 35 +- .../src/app/[locale]/event/(common)/Draw.tsx | 53 +- .../event/(common)/EventEndOverlay.tsx | 27 +- .../[locale]/event/(halloween)/Content.tsx | 97 +- .../event/(halloween)/HalloweenCard.tsx | 14 +- .../[locale]/event/(halloween)/KingGhost.tsx | 29 +- .../game/quiz/_components/BackGround.tsx | 20 +- .../CreateOrSolve/QuizTypeCard.tsx | 75 +- .../CreateOrSolve/SelectQuizType.tsx | 10 +- .../CreateOrSolve/SolveQuizConfirmDialog.tsx | 16 +- .../game/quiz/_components/MobileLayout.tsx | 104 +- .../create/_components/QuizCreateForm.tsx | 19 +- .../quiz/create/_components/QuizField.tsx | 25 +- .../quiz/create/_components/QuizTextArea.tsx | 88 +- .../app/[locale]/game/quiz/create/page.tsx | 41 +- apps/web/src/app/[locale]/game/quiz/page.tsx | 33 +- .../_components/done/CompleteAlertDialog.tsx | 61 +- .../_components/fail/FailAlertDialog.tsx | 63 +- .../notStarted/SelectCategorySection.tsx | 80 +- .../_components/solving/QuizProgressBar.tsx | 32 +- .../solving/SolvingQuizSection.tsx | 103 +- .../success/CorrectConfirmDialog.tsx | 60 +- .../(subpage)/[id]/CopyGuildImgButton.tsx | 4 +- .../(subpage)/[id]/GuildSliderContainer.tsx | 42 +- .../guild/(subpage)/[id]/MoreMenu.tsx | 2 +- .../[locale]/guild/(subpage)/[id]/layout.tsx | 51 +- .../[locale]/guild/(subpage)/[id]/page.tsx | 111 +-- .../[id]/setting/GuidlInfoFormClient.tsx | 108 +-- .../(subpage)/[id]/setting/GuildSetting.tsx | 6 +- .../[id]/setting/member/BannerGuildMember.tsx | 33 +- .../[id]/setting/member/MemberCard.tsx | 4 +- .../[id]/setting/member/WaitMemberCard.tsx | 7 +- .../(subpage)/[id]/setting/member/page.tsx | 25 +- .../guild/(subpage)/[id]/setting/pet/page.tsx | 11 +- .../guild/(subpage)/create/GuildCreate.tsx | 6 +- .../[locale]/guild/(subpage)/create/page.tsx | 13 +- .../guild/(subpage)/detail/GuildDetail.tsx | 40 +- .../guild/(subpage)/detail/[id]/join/page.tsx | 18 +- .../guild/(subpage)/detail/[id]/page.tsx | 4 +- .../guild/@modal/(.)detail/[id]/join/page.tsx | 11 +- .../guild/@modal/(.)detail/[id]/page.tsx | 16 +- .../[locale]/guild/_components/GuildCard.tsx | 76 +- .../_components/GuildModalPageLayout.tsx | 33 +- .../guild/_components/GuildPeopleList.tsx | 57 +- .../_components/GuildPetSelectDialog.tsx | 4 +- .../guild/_components/GuildSearch.tsx | 15 +- .../guild/_components/SelecableFormItem.tsx | 4 +- .../guild/_components/SelectPersonaList.tsx | 31 +- .../[locale]/guild/_components/SortSelect.tsx | 20 +- apps/web/src/app/[locale]/guild/layout.tsx | 22 +- apps/web/src/app/[locale]/guild/page.tsx | 103 +- .../laboratory/_component/ConfirmDialog.tsx | 25 +- .../laboratory/_component/FeedbackUpvote.tsx | 76 +- .../_component/LaboratoryLayout.tsx | 231 ++--- .../src/app/[locale]/laboratory/layout.tsx | 18 +- .../laboratory/multi-merge/MergeSlots.tsx | 54 +- .../laboratory/multi-merge/PersonaItem.tsx | 12 +- .../laboratory/multi-merge/PetGrid.tsx | 34 +- .../multi-merge/SelectionSummary.tsx | 63 +- .../laboratory/multi-merge/client.tsx | 7 +- .../[locale]/laboratory/multi-merge/styles.ts | 138 +-- apps/web/src/app/[locale]/laboratory/page.tsx | 266 ++--- .../laboratory/property-pet-sell/page.tsx | 61 +- .../AvailablePetSection/AnimalCardList.tsx | 12 +- .../AvailablePetSection/AnimalSlider.style.ts | 72 +- .../AvailablePetSection/AnimalSlider.tsx | 27 +- .../AnimalSliderContainer.tsx | 55 +- .../AnimalSliderContainerMobile.tsx | 60 +- .../AvailablePetSection.style.ts | 137 +-- .../AvailablePetSection.tsx | 2 +- .../ChoosePetSection.style.ts | 50 +- .../ChoosePetSection/ChoosePetSection.tsx | 2 +- .../[locale]/landing/Footer/Footer.style.ts | 134 +-- .../app/[locale]/landing/Footer/Footer.tsx | 4 +- .../landing/Footer/TeammateProfile.style.ts | 84 +- .../HavePetWaySection.style.ts | 117 +-- .../HavePetWaySection/HavePetWaySection.tsx | 6 +- .../landing/MainSection/MainSection.style.ts | 102 +- .../landing/MainSection/MainSection.tsx | 2 +- .../landing/MainSection/MainSlider.style.ts | 67 +- .../landing/MainSection/MainSlider.tsx | 57 +- .../landing/MainSection/SliderItem.style.ts | 43 +- .../landing/MainSection/TopBanner.tsx | 87 +- .../GameConsole/GameConsole.tsx | 30 +- .../RankingSection/GameConsole/GameScreen.tsx | 35 +- .../GameConsole/PixelNoiseEffect.tsx | 25 +- .../GameConsole/SvgContainer.tsx | 25 +- .../MobileGameConsole/MobileGameConsole.tsx | 12 +- .../RankingSection/MobileRankingTable.tsx | 208 ++-- .../landing/RankingSection/RankingSection.tsx | 134 +-- .../landing/RankingSection/RankingTable.tsx | 179 +--- .../landing/RankingSection/TopPodium.tsx | 217 ++--- .../(github-custom)/FarmBackgroundSelect.tsx | 38 +- .../(github-custom)/FarmPersonaSelect.tsx | 53 +- .../mypage/(github-custom)/FarmType.tsx | 37 +- .../(github-custom)/LinePersonaSelect.tsx | 68 +- .../mypage/(github-custom)/LinePreview.tsx | 89 +- .../src/app/[locale]/mypage/PersonaList.tsx | 26 +- .../app/[locale]/mypage/ProfileSection.tsx | 206 ++-- apps/web/src/app/[locale]/mypage/layout.tsx | 126 +-- .../my-pet/(evolution)/EvolutionPersona.tsx | 34 +- .../my-pet/(evolution)/EvolutionResult.tsx | 79 +- .../mypage/my-pet/(merge)/MergePersona.tsx | 7 +- .../mypage/my-pet/(merge)/MergePreview.tsx | 46 +- .../mypage/my-pet/(merge)/MergeResult.tsx | 78 +- .../mypage/my-pet/SelectedPetTable.tsx | 95 +- .../my-pet/_components/PersonaBanner.tsx | 58 +- .../my-pet/_components/SelectPersonaList.tsx | 49 +- .../my-pet/_components/SpinningLoader.tsx | 30 +- .../src/app/[locale]/mypage/my-pet/page.tsx | 46 +- apps/web/src/app/[locale]/mypage/page.tsx | 61 +- apps/web/src/app/[locale]/not-found.tsx | 5 +- apps/web/src/app/[locale]/page.tsx | 3 +- .../app/[locale]/shop/_auction/Background.tsx | 80 +- .../shop/_auction/DefaultTabRight.tsx | 6 +- .../[locale]/shop/_auction/HistoryTable.tsx | 3 +- .../app/[locale]/shop/_auction/MySellList.tsx | 2 +- .../[locale]/shop/_auction/PersonaSearch.tsx | 115 +-- .../[locale]/shop/_auction/ProductTable.tsx | 2 +- .../shop/_auction/SellSection/EditModal.tsx | 51 +- .../shop/_auction/SellSection/PetList.tsx | 22 +- .../_auction/SellSection/SellInputRow.tsx | 76 +- .../shop/_auction/SellSection/SellSection.tsx | 29 +- .../src/app/[locale]/shop/_auction/Tab.tsx | 79 +- .../src/app/[locale]/shop/_auction/index.tsx | 73 +- .../[locale]/shop/_auction/table.styles.ts | 65 +- .../shop/_background/BackgroundSection.tsx | 122 +-- .../shop/_common/FloatingPointSection.tsx | 62 +- .../shop/_common/ShopTableMobileRow.tsx | 91 +- .../[locale]/shop/_petGotcha/CardFlipGame.tsx | 112 +-- .../app/[locale]/shop/_petGotcha/OnePet.tsx | 35 +- .../[locale]/shop/_petGotcha/PetGotcha.tsx | 101 +- .../shop/_petGotcha/TenCardFlipGame.tsx | 105 +- .../app/[locale]/shop/_petGotcha/TenPet.tsx | 45 +- apps/web/src/app/globals.css | 5 + apps/web/src/app/not-found.tsx | 5 +- .../src/components/AnimalCard/AnimalCard.tsx | 3 +- apps/web/src/components/AuthButton.tsx | 2 +- .../CardGame/FanDrawingGame/CardMotion.tsx | 18 +- .../FanDrawingGame/FanDrawingGame.tsx | 101 +- apps/web/src/components/CheckTime.tsx | 50 +- .../src/components/EmblaCarousel/Arrow.tsx | 58 +- .../EmblaCarousel/EmblaCarousel.tsx | 87 +- .../EmblaCarouselArrowButtons.tsx | 42 +- .../EmblaCarousel/EmblaCarouselDotButton.tsx | 51 +- apps/web/src/components/Error/ErrorPage.tsx | 50 +- .../web/src/components/Error/ErrorSection.tsx | 49 +- apps/web/src/components/GNB/DesktopGNB.tsx | 97 +- .../src/components/GNB/LanguageSelector.tsx | 109 +-- apps/web/src/components/GNB/MobileGNB.tsx | 109 +-- .../components/GNB/Notification/InboxList.tsx | 127 +-- .../GNB/Notification/Notification.tsx | 26 +- apps/web/src/components/Gitanimals.tsx | 4 +- .../src/components/Global/FeedbackForm.tsx | 109 +-- apps/web/src/components/Global/useDialog.tsx | 24 +- .../src/components/Guild/MemeberSlider.tsx | 9 +- apps/web/src/components/Input.tsx | 43 +- .../web/src/components/InterceptingDialog.tsx | 15 +- apps/web/src/components/Layout/TabBar.tsx | 46 +- .../src/components/MediaQuery/MediaQuery.tsx | 2 +- apps/web/src/components/PageModal/index.tsx | 33 +- .../src/components/Pagination/Pagination.tsx | 41 +- .../Pagination/PaginationServer.tsx | 37 +- apps/web/src/components/RouteModal.tsx | 21 +- apps/web/src/components/Select/Label.tsx | 38 +- apps/web/src/components/Select/Option.tsx | 38 +- apps/web/src/components/Select/Panel.tsx | 33 +- apps/web/src/components/Select/Root.tsx | 9 +- .../Slider/PerspectiveCenterSlider.tsx | 67 +- .../components/SortSelect/OrderTypeSelect.tsx | 2 +- .../SortSelect/SortDirectionSelect.tsx | 2 +- .../components/SortSelect/useSortSelect.tsx | 6 +- apps/web/src/components/Tabs/TabsList.tsx | 19 +- apps/web/src/components/Tabs/TabsTrigger.tsx | 43 +- apps/web/src/components/TextArea.tsx | 70 +- apps/web/src/styles/prevTextToken.ts | 12 +- apps/web/src/styles/scrollStyle.ts | 40 +- apps/web/tailwind.config.ts | 18 + packages/ui/tailwind/package.json | 74 ++ .../src/components/animation/SplitText.tsx | 138 +++ .../src/components/animation/index.ts | 2 + .../tailwind/src/components/card/CardBack.tsx | 36 + .../tailwind/src/components/card/GameCard.tsx | 108 +++ .../tailwind/src/components/card/constants.ts | 26 + .../ui/tailwind/src/components/card/index.ts | 4 + packages/ui/tailwind/src/components/index.ts | 3 + .../tailwind/src/components/ui/accordion.tsx | 63 ++ .../ui/tailwind/src/components/ui/button.tsx | 87 ++ .../tailwind/src/components/ui/checkbox.tsx | 34 + .../ui/tailwind/src/components/ui/dialog.tsx | 175 ++++ .../src/components/ui/dropdown-menu.tsx | 216 +++++ .../ui/tailwind/src/components/ui/index.ts | 12 + .../ui/tailwind/src/components/ui/label.tsx | 23 + .../src/components/ui/scroll-area.tsx | 47 + .../ui/tailwind/src/components/ui/select.tsx | 203 ++++ .../tailwind/src/components/ui/skeleton.tsx | 44 + .../tailwind/src/components/ui/textarea.tsx | 30 + .../tailwind/src/components/ui/textfield.tsx | 39 + .../ui/tailwind/src/components/ui/tooltip.tsx | 34 + packages/ui/tailwind/src/config.ts | 70 ++ packages/ui/tailwind/src/index.ts | 13 + packages/ui/tailwind/src/preset.ts | 35 + packages/ui/tailwind/src/theme/colors.ts | 66 ++ packages/ui/tailwind/src/theme/index.ts | 23 + packages/ui/tailwind/src/theme/keyframes.ts | 79 ++ packages/ui/tailwind/src/theme/screens.ts | 46 + packages/ui/tailwind/src/theme/typography.ts | 33 + packages/ui/tailwind/src/theme/zIndex.ts | 25 + packages/ui/tailwind/src/utils/cn.ts | 14 + packages/ui/tailwind/src/utils/index.ts | 1 + packages/ui/tailwind/tsconfig.json | 12 + packages/ui/tailwind/tsup.config.ts | 16 + pnpm-lock.yaml | 917 ++++++++++++++++-- 225 files changed, 5317 insertions(+), 7125 deletions(-) create mode 100644 apps/web/MIGRATION_STATUS.md create mode 100644 apps/web/postcss.config.mjs create mode 100644 apps/web/tailwind.config.ts create mode 100644 packages/ui/tailwind/package.json create mode 100644 packages/ui/tailwind/src/components/animation/SplitText.tsx create mode 100644 packages/ui/tailwind/src/components/animation/index.ts create mode 100644 packages/ui/tailwind/src/components/card/CardBack.tsx create mode 100644 packages/ui/tailwind/src/components/card/GameCard.tsx create mode 100644 packages/ui/tailwind/src/components/card/constants.ts create mode 100644 packages/ui/tailwind/src/components/card/index.ts create mode 100644 packages/ui/tailwind/src/components/index.ts create mode 100644 packages/ui/tailwind/src/components/ui/accordion.tsx create mode 100644 packages/ui/tailwind/src/components/ui/button.tsx create mode 100644 packages/ui/tailwind/src/components/ui/checkbox.tsx create mode 100644 packages/ui/tailwind/src/components/ui/dialog.tsx create mode 100644 packages/ui/tailwind/src/components/ui/dropdown-menu.tsx create mode 100644 packages/ui/tailwind/src/components/ui/index.ts create mode 100644 packages/ui/tailwind/src/components/ui/label.tsx create mode 100644 packages/ui/tailwind/src/components/ui/scroll-area.tsx create mode 100644 packages/ui/tailwind/src/components/ui/select.tsx create mode 100644 packages/ui/tailwind/src/components/ui/skeleton.tsx create mode 100644 packages/ui/tailwind/src/components/ui/textarea.tsx create mode 100644 packages/ui/tailwind/src/components/ui/textfield.tsx create mode 100644 packages/ui/tailwind/src/components/ui/tooltip.tsx create mode 100644 packages/ui/tailwind/src/config.ts create mode 100644 packages/ui/tailwind/src/index.ts create mode 100644 packages/ui/tailwind/src/preset.ts create mode 100644 packages/ui/tailwind/src/theme/colors.ts create mode 100644 packages/ui/tailwind/src/theme/index.ts create mode 100644 packages/ui/tailwind/src/theme/keyframes.ts create mode 100644 packages/ui/tailwind/src/theme/screens.ts create mode 100644 packages/ui/tailwind/src/theme/typography.ts create mode 100644 packages/ui/tailwind/src/theme/zIndex.ts create mode 100644 packages/ui/tailwind/src/utils/cn.ts create mode 100644 packages/ui/tailwind/src/utils/index.ts create mode 100644 packages/ui/tailwind/tsconfig.json create mode 100644 packages/ui/tailwind/tsup.config.ts diff --git a/apps/web/MIGRATION_STATUS.md b/apps/web/MIGRATION_STATUS.md new file mode 100644 index 00000000..1baf7c7c --- /dev/null +++ b/apps/web/MIGRATION_STATUS.md @@ -0,0 +1,153 @@ +# PandaCSS → Tailwind CSS 마이그레이션 진행 상황 + +**마지막 업데이트**: 2026-01-14 + +## 진행률 요약 + +- **시작 시점**: 162개 파일 (PandaCSS 임포트) +- **현재 남은 파일**: 24개 파일 +- **완료율**: 약 **85%** + +--- + +## 남은 작업 목록 + +### PandaCSS 패턴 임포트 (`from '_panda/'`) - 5개 파일 + +| 파일 | 상태 | 비고 | +|------|------|------| +| `src/app/[locale]/dev/page.tsx` | ⬜ 미완료 | dev 페이지 | +| `src/app/[locale]/dev/Client.tsx` | ⬜ 미완료 | dev 클라이언트 | +| `src/app/[locale]/dev/token/token.style.ts` | ⬜ 미완료 | 토큰 스타일 | +| `src/app/[locale]/dev/component/page.tsx` | ⬜ 미완료 | 컴포넌트 페이지 | +| `src/app/[locale]/laboratory/_component/AlertDialog.tsx` | ⬜ 미완료 | Alert 다이얼로그 | + +### UI-Panda 컴포넌트 임포트 (`from '@gitanimals/ui-panda'`) - 19개 파일 + +#### Landing 섹션 (3개) +| 파일 | 상태 | +|------|------| +| `src/app/[locale]/landing/MainSection/MainSection.tsx` | ⬜ 미완료 | +| `src/app/[locale]/landing/ChoosePetSection/ChoosePetSection.tsx` | ⬜ 미완료 | +| `src/app/[locale]/landing/AvailablePetSection/AvailablePetSection.tsx` | ⬜ 미완료 | + +#### Components (4개) +| 파일 | 상태 | +|------|------| +| `src/components/AnimalCard/AnimalCard.tsx` | ⬜ 미완료 | +| `src/components/SortSelect/SortDirectionSelect.tsx` | ⬜ 미완료 | +| `src/components/SortSelect/OrderTypeSelect.tsx` | ⬜ 미완료 | +| `src/components/MediaQuery/MediaQuery.tsx` | ⬜ 미완료 | + +#### Guild 페이지 (7개) +| 파일 | 상태 | +|------|------| +| `src/app/[locale]/guild/_components/SortSelect.tsx` | ⬜ 미완료 | +| `src/app/[locale]/guild/_components/GuildPetSelectDialog.tsx` | ⬜ 미완료 | +| `src/app/[locale]/guild/(subpage)/detail/[id]/page.tsx` | ⬜ 미완료 | +| `src/app/[locale]/guild/(subpage)/create/GuildCreate.tsx` | ⬜ 미완료 | +| `src/app/[locale]/guild/(subpage)/[id]/setting/member/MemberCard.tsx` | ⬜ 미완료 | +| `src/app/[locale]/guild/(subpage)/[id]/MoreMenu.tsx` | ⬜ 미완료 | +| `src/app/[locale]/guild/(subpage)/[id]/CopyGuildImgButton.tsx` | ⬜ 미완료 | + +#### Dev 페이지 (4개) +| 파일 | 상태 | +|------|------| +| `src/app/[locale]/dev/page.tsx` | ⬜ 미완료 | +| `src/app/[locale]/dev/Client.tsx` | ⬜ 미완료 | +| `src/app/[locale]/dev/token/page.tsx` | ⬜ 미완료 | +| `src/app/[locale]/dev/component/page.tsx` | ⬜ 미완료 | + +#### Laboratory (1개) +| 파일 | 상태 | +|------|------| +| `src/app/[locale]/laboratory/_component/AlertDialog.tsx` | ⬜ 미완료 | + +--- + +## 완료된 작업 + +### 백그라운드 에이전트 작업 결과 + +| 작업 ID | 내용 | 상태 | +|---------|------|------| +| ab99674 | Landing styles (6개 파일) | ✅ 완료 | +| a988b66 | Landing components | ✅ 완료 | +| abdd937 | Guild page files (8개 파일) | ✅ 완료 | +| aeebca2 | Event page files (12개 파일) | ✅ 완료 | +| a6a13a4 | Mypage files | ⚠️ Rate limit 중단 | +| a49d6dc | Ranking section | ⚠️ Rate limit 중단 | +| af69c09 | Quiz game files | ⚠️ Rate limit 중단 | +| a8ee052 | Guild subpage files | ⚠️ Rate limit 중단 | +| a1f8080 | Component files | ⚠️ Rate limit 중단 | + +### 수동 마이그레이션 완료 파일 +- `src/app/[locale]/error.tsx` +- `src/app/[locale]/auth/page.tsx` +- `src/app/[locale]/auth/signOut/page.tsx` +- `src/components/Pagination/PaginationServer.tsx` +- `src/components/Global/useDialog.tsx` +- `src/components/Global/FeedbackForm.tsx` (읽기만 완료) + +--- + +## 마이그레이션 패턴 참조 + +### 임포트 변환 +```typescript +// Before +import { css, cx } from '_panda/css'; +import { flex, center, grid } from '_panda/patterns'; +import { Flex, Box } from '_panda/jsx'; +import { Button, Dialog } from '@gitanimals/ui-panda'; + +// After +import { cn, Button, Dialog } from '@gitanimals/ui-tailwind'; +``` + +### 스타일 변환 예시 +```typescript +// Before (PandaCSS) +const style = css({ + display: 'flex', + alignItems: 'center', + gap: '8px', + textStyle: 'glyph16.regular', + color: 'white.white_75', + _mobile: { padding: '8px' }, +}); + +// After (Tailwind) +const style = cn( + 'flex items-center gap-2', + 'font-product text-glyph-16 text-white-white/75', + 'max-mobile:p-2' +); +``` + +### 색상 토큰 매핑 +| PandaCSS | Tailwind | +|----------|----------| +| `brand.canary` | `brand-canary` | +| `gray.gray_150` | `gray-150` | +| `white.white_75` | `white-white/75` | +| `black.black_50` | `black/50` | + +### 반응형 프리픽스 +| PandaCSS | Tailwind | +|----------|----------| +| `_mobile: {}` | `max-mobile:` | +| `_desktop: {}` | `desktop:` | + +--- + +## 최종 단계 (마이그레이션 완료 후) + +- [ ] 모든 파일 마이그레이션 완료 +- [ ] `pnpm build:web` 빌드 성공 확인 +- [ ] 시각적 회귀 테스트 +- [ ] PandaCSS 의존성 제거 + - `panda.config.ts` 삭제 + - `styled-system/` 디렉토리 삭제 + - `package.json`에서 PandaCSS 관련 의존성 제거 + - `tsconfig.json`에서 `_panda` 경로 제거 diff --git a/apps/web/package.json b/apps/web/package.json index 5780dc4d..69832768 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@air/react-drag-to-select": "^5.0.11", + "@gitanimals/ui-tailwind": "workspace:*", "@egjs/flicking-plugins": "^4.7.1", "@egjs/react-flicking": "^4.11.3", "@gitanimals/api": "workspace:*", @@ -61,6 +62,9 @@ }, "devDependencies": { "@chromatic-com/storybook": "^1.3.3", + "autoprefixer": "^10.4.21", + "postcss": "^8.5.6", + "tailwindcss": "^3.4.17", "@gitanimals/eslint-config": "workspace:*", "@gitanimals/typescript-config": "workspace:*", "@gitanimals/util-common": "workspace:*", diff --git a/apps/web/postcss.config.mjs b/apps/web/postcss.config.mjs new file mode 100644 index 00000000..2ef30fcf --- /dev/null +++ b/apps/web/postcss.config.mjs @@ -0,0 +1,9 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; + +export default config; diff --git a/apps/web/src/app/[locale]/auth/page.tsx b/apps/web/src/app/[locale]/auth/page.tsx index 36e6f25e..df6c3e48 100644 --- a/apps/web/src/app/[locale]/auth/page.tsx +++ b/apps/web/src/app/[locale]/auth/page.tsx @@ -1,7 +1,7 @@ 'use client'; import { useEffect } from 'react'; -import { center } from '_panda/patterns'; +import { cn } from '@gitanimals/ui-tailwind'; import { setRequestInterceptor, setResponseInterceptor } from '@gitanimals/api'; import { setRenderRequestInterceptor, setRenderResponseInterceptor } from '@gitanimals/api/src/_instance'; @@ -42,16 +42,7 @@ function JWTPage({ export default JWTPage; -const loadingContainerStyle = center({ - position: 'fixed', - top: 0, - left: 0, - right: 0, - bottom: 0, - backgroundColor: 'rgba(255, 255, 255, 0.8)', - zIndex: 'loading', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - fontSize: '36px', -}); +const loadingContainerStyle = cn( + 'fixed inset-0 bg-white/80 z-loading', + 'flex items-center justify-center text-[36px]' +); diff --git a/apps/web/src/app/[locale]/auth/signOut/page.tsx b/apps/web/src/app/[locale]/auth/signOut/page.tsx index d374d613..a27ccdb9 100644 --- a/apps/web/src/app/[locale]/auth/signOut/page.tsx +++ b/apps/web/src/app/[locale]/auth/signOut/page.tsx @@ -2,7 +2,6 @@ import { useEffect } from 'react'; import { signOut } from 'next-auth/react'; -import { css } from '_panda/css'; import { Loader2 } from 'lucide-react'; export default function SignOutPage() { @@ -11,21 +10,9 @@ export default function SignOutPage() { }, []); return ( -
+
{/* TODO: loading 애니메이션 추가 */} - +
); } diff --git a/apps/web/src/app/[locale]/error.tsx b/apps/web/src/app/[locale]/error.tsx index f0dd6f92..a9d3fe50 100644 --- a/apps/web/src/app/[locale]/error.tsx +++ b/apps/web/src/app/[locale]/error.tsx @@ -2,8 +2,7 @@ import { useEffect } from 'react'; import { useTranslations } from 'next-intl'; -import { css } from '_panda/css'; -import { Button } from '@gitanimals/ui-panda'; +import { Button } from '@gitanimals/ui-tailwind'; import { sendMessageToErrorChannel } from '@/apis/slack/sendMessage'; import { ErrorPage } from '@/components/Error/ErrorPage'; @@ -58,10 +57,10 @@ User: ${user?.id ? JSON.stringify(user) : 'NOT LOGGED IN'} return ( {t('want-to-report-error')}

} + paragraph={

{t('want-to-report-error')}

} onClickButton={onClickRetry} secondButtonElement={ -
+
diff --git a/apps/web/src/app/[locale]/event/(christmas)/ChristmasCard.tsx b/apps/web/src/app/[locale]/event/(christmas)/ChristmasCard.tsx index 5c6e1bf5..04ae4f46 100644 --- a/apps/web/src/app/[locale]/event/(christmas)/ChristmasCard.tsx +++ b/apps/web/src/app/[locale]/event/(christmas)/ChristmasCard.tsx @@ -1,8 +1,7 @@ 'use client'; import Image from 'next/image'; -import { css } from '_panda/css'; -import { NoRatingCard } from '@gitanimals/ui-panda'; +import { NoRatingCard } from '@gitanimals/ui-tailwind'; import { getPersonaImage } from '@/utils/image'; @@ -12,7 +11,7 @@ interface ChristmasCardProps { export function ChristmasCard({ type }: ChristmasCardProps) { return ( -
+
); } - -const containerStyle = css({ - '& .animal-card-type': { - color: '#000', - }, - '& .animal-card-rating': { - color: '#000', - }, -}); diff --git a/apps/web/src/app/[locale]/event/(christmas)/Snowflake.tsx b/apps/web/src/app/[locale]/event/(christmas)/Snowflake.tsx index eea9a0f2..f7041e53 100644 --- a/apps/web/src/app/[locale]/event/(christmas)/Snowflake.tsx +++ b/apps/web/src/app/[locale]/event/(christmas)/Snowflake.tsx @@ -1,6 +1,5 @@ 'use client'; -import { css } from '_panda/css'; import { motion } from 'framer-motion'; interface SnowflakeProps { @@ -13,7 +12,7 @@ interface SnowflakeProps { export function Snowflake({ delay, left, size, duration }: SnowflakeProps) { return ( ); } - -const snowflakeStyle = css({ - position: 'absolute', - backgroundColor: 'white', - borderRadius: '4px', - opacity: 0.8, - pointerEvents: 'none', - top: 0, - zIndex: 1, - _mobile: { - scale: 0.8, - }, -}); diff --git a/apps/web/src/app/[locale]/event/(christmas)/index.tsx b/apps/web/src/app/[locale]/event/(christmas)/index.tsx index 1edeec2b..7b658ab6 100644 --- a/apps/web/src/app/[locale]/event/(christmas)/index.tsx +++ b/apps/web/src/app/[locale]/event/(christmas)/index.tsx @@ -1,6 +1,4 @@ import Image from 'next/image'; -import { css } from '_panda/css'; -import { flex } from '_panda/patterns'; import { BackgroundSection } from '../(common)/BackgroundSection'; @@ -12,7 +10,7 @@ const bgTypes = ['GRASS_CHRISTMAS_TREE_FIELD', 'SNOW_GRASS_FIELD', 'SNOW_HOUSE_F export function ChristmasContent() { return ( <> -
+
{[...Array(20)].map((_, i) => ( -
+
gitanimals christmas event -

+

Christmas has come to Gitanimals
Draw Christmas pet for free! @@ -54,54 +52,3 @@ export function ChristmasContent() { ); } - -const descriptionStyle = css({ - color: 'white.white_90', - textStyle: 'glyph32.bold', - fontWeight: 400, - textAlign: 'center', - whiteSpace: 'pre-line', - marginTop: '60px', - marginBottom: '100px', - _mobile: { - textStyle: 'glyph16.regular', - fontSize: '16px', - marginTop: '20px', - marginBottom: '40px', - }, -}); - -const bgImageStyle = css({ - pointerEvents: 'none', -}); - -const containerStyle = flex({ - position: 'relative', - width: '100%', - height: '100%', - paddingTop: '211px', - zIndex: 2, - flexDirection: 'column', - paddingBottom: '280px', - _mobile: { - paddingTop: '110px', - paddingBottom: '200px', - }, -}); - -const logoImageStyle = css({ - objectFit: 'contain', - margin: '0 auto', - maxWidth: '80vw', - height: 'auto', - _mobile: { - maxWidth: '90vw', - }, -}); - -const bgContainerStyle = css({ - position: 'relative', - width: '100%', - minHeight: 'calc(100vh - 60px)', - overflow: 'hidden', -}); diff --git a/apps/web/src/app/[locale]/event/(common)/BackgroundSection.tsx b/apps/web/src/app/[locale]/event/(common)/BackgroundSection.tsx index ac5eea06..02ef87dc 100644 --- a/apps/web/src/app/[locale]/event/(common)/BackgroundSection.tsx +++ b/apps/web/src/app/[locale]/event/(common)/BackgroundSection.tsx @@ -2,10 +2,10 @@ 'use client'; import { useTranslations } from 'next-intl'; -import { css, cx } from '_panda/css'; +import { cn } from '@gitanimals/ui-tailwind'; import type { Background } from '@gitanimals/api'; import { renderUserQueries, shopQueries, useBuyBackground } from '@gitanimals/react-query'; -import { Button } from '@gitanimals/ui-panda'; +import { Button } from '@gitanimals/ui-tailwind'; import { wrap } from '@suspensive/react'; import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'; import { AxiosError } from 'axios'; @@ -76,8 +76,10 @@ export const BackgroundSection = wrap }; return ( -

-

Background

+
+

+ Background +

{backgroundList?.map((item) => ( -
+
+
{item.type}
-
{addNumberComma(item.price)} P
+
+ {addNumberComma(item.price)} P +
); } - -const sectionCss = css({ - position: 'relative', - display: 'flex', - flexDir: 'column', - alignItems: 'center', - padding: '120px 20px', - width: '100%', - background: 'linear-gradient(180deg, #FFF 0%, #A7DEF6 100%)', -}); - -const h2Css = css({ - textStyle: 'glyph82.bold', - color: 'black', - marginBottom: '80px', - - _mobile: { - textStyle: 'glyph40.bold', - marginBottom: '30px', - }, -}); - -const cardCss = css({ - width: '100%', - display: 'flex', - flexDir: 'column', - alignItems: 'center', - justifyContent: 'center', - position: 'relative', -}); - -const cardImageCss = css({ - width: '100%', - aspectRatio: '2 / 1', - bg: 'white', - position: 'relative', -}); - -const purchasedCardImageCss = css({ - filter: 'brightness(0.5)', - cursor: 'not-allowed', -}); - -const cardPointStyle = css({ - textStyle: 'glyph18.bold', - color: 'black.black_75', - border: '1px solid #99C7DB', - background: '#DDF2FB', - mt: '4px', - mb: '24px', - p: '4px 25px', - w: '100%', -}); diff --git a/apps/web/src/app/[locale]/event/(common)/BackgroundSlider/Arrow.tsx b/apps/web/src/app/[locale]/event/(common)/BackgroundSlider/Arrow.tsx index 9f234a55..306515bb 100644 --- a/apps/web/src/app/[locale]/event/(common)/BackgroundSlider/Arrow.tsx +++ b/apps/web/src/app/[locale]/event/(common)/BackgroundSlider/Arrow.tsx @@ -1,5 +1,5 @@ import Image from 'next/image'; -import { css, cx } from '_panda/css'; +import { cn } from '@gitanimals/ui-tailwind'; export function ArrowButton({ onClick, @@ -13,18 +13,11 @@ export function ArrowButton({ return ( ); } - -const arrowStyle = css({ - position: 'absolute', - top: '0', - bottom: '0', - margin: 'auto', - zIndex: 'floating', - - '& img': { - width: '100%', - height: '100%', - }, - - _mobile: { - bottom: '72px', - }, -}); - -const prevArrowStyle = cx( - arrowStyle, - css({ - left: '-62px', - _mobile: { - left: '-26px', - }, - }), -); - -const nextArrowStyle = cx( - arrowStyle, - css({ - right: '-62px', - _mobile: { - right: '-26px', - }, - }), -); diff --git a/apps/web/src/app/[locale]/event/(common)/BackgroundSlider/BackgroundSlider.tsx b/apps/web/src/app/[locale]/event/(common)/BackgroundSlider/BackgroundSlider.tsx index fbbb3f73..98f4827c 100644 --- a/apps/web/src/app/[locale]/event/(common)/BackgroundSlider/BackgroundSlider.tsx +++ b/apps/web/src/app/[locale]/event/(common)/BackgroundSlider/BackgroundSlider.tsx @@ -1,7 +1,6 @@ 'use client'; import { Children, useRef, useState } from 'react'; -import { css } from '_panda/css'; import type { ChangedEvent, FlickingOptions, FlickingProps } from '@egjs/react-flicking'; import Flicking from '@egjs/react-flicking'; import useIsMobile from '@gitanimals/react/src/hooks/useIsMobile/useIsMobile'; @@ -44,13 +43,13 @@ function BackgroundSlider({ children }: { children: React.ReactNode }) { }; return ( -
-
+
+
{Children.map(children, (child, idx) => ( -
+
{child}
))} @@ -60,43 +59,4 @@ function BackgroundSlider({ children }: { children: React.ReactNode }) { ); } -const containerStyle = css({ - width: '100%', - maxWidth: '1200px', - margin: '0 auto', - padding: '0 60px', - position: 'relative', - - _mobile: { - padding: '0 35px', - }, -}); - -const sliderContainerStyle = css({ - position: 'relative', - width: '100%', - marginTop: '20px', - - _mobile: { - marginTop: '0px', - }, -}); - -const sliderItemStyle = css({ - width: 'calc(50% - 10px)', // gap을 고려한 너비 - padding: '10px', - textAlign: 'center', - - '& img': { - width: '100%', - height: 'auto', - borderRadius: '8px', - }, - - '& p': { - marginTop: '10px', - fontSize: '16px', - }, -}); - export default BackgroundSlider; diff --git a/apps/web/src/app/[locale]/event/(common)/CardList.tsx b/apps/web/src/app/[locale]/event/(common)/CardList.tsx index 627253f7..58c0d875 100644 --- a/apps/web/src/app/[locale]/event/(common)/CardList.tsx +++ b/apps/web/src/app/[locale]/event/(common)/CardList.tsx @@ -1,7 +1,6 @@ 'use client'; import React, { useEffect, useState } from 'react'; -import { css } from '_panda/css'; import { AnimatePresence, motion } from 'framer-motion'; import { PerspectiveCenterSlider } from '@/components/Slider'; @@ -34,9 +33,9 @@ export function CardList({ renderCard, persona }: CardListProps) { }, []); return ( -
+
{[0, 1, 2].map((index) => ( -
+
{visibleCards[index].Element} @@ -55,38 +54,14 @@ export function CardList({ renderCard, persona }: CardListProps) { ); } -const cardContainerStyle = css({ - display: 'flex', - justifyContent: 'space-between', - width: '1000px', - maxWidth: '80vw', - margin: '0 auto', -}); - -const slotContainerStyle = css({ position: 'relative', width: '265px', height: '328px', overflow: 'hidden' }); - -const slotItemStyle = css({ - position: 'absolute', - width: '100%', - height: '100%', -}); - export function MobileCardList({ renderCard, persona }: CardListProps) { return ( -
+
{persona.map((type) => ( -
- {renderCard(type)} -
+
{renderCard(type)}
))}
); } - -const mobileCardListContainer = css({ - '& .slider-container': { - width: '100%', - }, -}); diff --git a/apps/web/src/app/[locale]/event/(common)/Draw.tsx b/apps/web/src/app/[locale]/event/(common)/Draw.tsx index 100d18c0..793ed432 100644 --- a/apps/web/src/app/[locale]/event/(common)/Draw.tsx +++ b/apps/web/src/app/[locale]/event/(common)/Draw.tsx @@ -4,11 +4,10 @@ import { useRef, useState } from 'react'; import { useParams } from 'next/navigation'; import { useSession } from 'next-auth/react'; import { useTranslations } from 'next-intl'; -import { css } from '_panda/css'; import { CustomException } from '@gitanimals/exception'; import { useOutsideClick } from '@gitanimals/react'; import { couponQueries, renderQueries, useUsingCoupon } from '@gitanimals/react-query'; -import { Button } from '@gitanimals/ui-panda'; +import { Button } from '@gitanimals/ui-tailwind'; import { wrap } from '@suspensive/react'; import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query'; import type { Variants } from 'framer-motion'; @@ -112,7 +111,7 @@ export const Draw = wrap.Suspense().on(({ renderCard, bonusEventCode, baseEventC <> ); }; export default QuizTypeCard; - -const cardStyle = css({ - position: 'relative', - display: 'flex', - alignItems: 'center', - gap: '12px', - width: '100%', - padding: '40px 24px', - backgroundColor: 'white.white_25', - borderRadius: '10px', -}); - -const disabledStyle = css({ - opacity: 0.5, - pointerEvents: 'none', -}); - -const imageStyle = css({ - flexShrink: 0, -}); - -const titleStyle = css({ - textStyle: 'glyph18.bold', - fontFamily: 'Product Sans', - fontWeight: 700, - color: 'white', - textAlign: 'left', -}); - -const descriptionStyle = css({ - textStyle: 'glyph14.regular', - fontFamily: 'Product Sans', - fontWeight: 400, - color: 'white.white_50', - wordBreak: 'keep-all', - textAlign: 'left', -}); - -const pointStyle = css({ - position: 'absolute', - top: '8px', - right: '8px', - padding: '2px 12px', - backgroundColor: 'black.black_25', - borderRadius: 'full', - textStyle: 'glyph12.regular', - fontWeight: 400, - color: 'white.white_75', -}); diff --git a/apps/web/src/app/[locale]/game/quiz/_components/CreateOrSolve/SelectQuizType.tsx b/apps/web/src/app/[locale]/game/quiz/_components/CreateOrSolve/SelectQuizType.tsx index 2265df23..b3463b06 100644 --- a/apps/web/src/app/[locale]/game/quiz/_components/CreateOrSolve/SelectQuizType.tsx +++ b/apps/web/src/app/[locale]/game/quiz/_components/CreateOrSolve/SelectQuizType.tsx @@ -2,7 +2,6 @@ import { useState } from 'react'; import { useTranslations } from 'next-intl'; -import { css } from '_panda/css'; import { wrap } from '@suspensive/react'; import { ROUTE } from '@/constants/route'; @@ -28,7 +27,7 @@ const SelectQuizType = wrap const t = useTranslations('Quiz'); return ( -
+
void; @@ -28,21 +26,17 @@ const SolveQuizConfirmDialog = ({ onConfirm, onClose, isOpen }: SolveQuizConfirm {t('solve-todays-quiz')} - - - - +
); }; export default SolveQuizConfirmDialog; - -const buttonStyle = css({ - width: '100%', -}); diff --git a/apps/web/src/app/[locale]/game/quiz/_components/MobileLayout.tsx b/apps/web/src/app/[locale]/game/quiz/_components/MobileLayout.tsx index 5c75116a..16ad37e4 100644 --- a/apps/web/src/app/[locale]/game/quiz/_components/MobileLayout.tsx +++ b/apps/web/src/app/[locale]/game/quiz/_components/MobileLayout.tsx @@ -1,7 +1,7 @@ import React from 'react'; import Image from 'next/image'; import { getTranslations } from 'next-intl/server'; -import { css } from '_panda/css'; +import { cn } from '@gitanimals/ui-tailwind'; import GNB from '@/components/GNB/GNB'; @@ -14,16 +14,38 @@ interface MobileLayoutProps { children: React.ReactNode; } +const getBackgroundPositionClass = (position?: string) => { + switch (position) { + case 'top': + return 'bg-top'; + case 'bottom': + return 'bg-bottom'; + case 'absolute': + case 'center': + default: + return 'bg-center'; + } +}; + export const MobileLayout = async ({ children, background }: MobileLayoutProps) => { const t = await getTranslations('HomePage'); return ( -
+
-
-
-
+
+
+
gitanimals-logo

{t('description')}

-
{children}
+
+ {children} +
); }; - -const layoutStyle = css({ - position: 'relative', - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - width: '100%', - height: '100%', - backgroundColor: 'black', - zIndex: 0, -}); - -const bodyContainerStyle = css({ - position: 'relative', - display: 'flex', - justifyContent: 'center', - width: '100%', - height: '100%', - minHeight: 'calc(100vh - var(--mobile-header-height))', -}); - -const backgroundStyle = (background?: MobileLayoutProps['background']) => - css({ - position: 'absolute', - width: '100%', - height: '100%', - backgroundPosition: background?.position ?? 'center', - backgroundSize: 'cover', - backgroundRepeat: 'no-repeat', - opacity: background?.opacity ?? 0.3, - pointerEvents: 'none', - }); - -const logoContainerStyle = css({ - position: 'sticky', - width: 'min(100vw, 475px)', - height: `calc(100vh - var(--mobile-header-height))`, - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - gap: '16px', - color: 'white', - fontSize: '18px', - - '@media (max-width: 950px)': { - display: 'none', - }, -}); - -const logoStyle = css({ - dropShadow: '0 0 10px rgba(0, 0, 0, 0.5)', -}); - -const contentStyle = css({ - position: 'relative', - zIndex: 1, - width: '100%', - maxWidth: '475px', - height: '100%', - minHeight: 'calc(100vh - var(--mobile-header-height))', - display: 'flex', - flexDirection: 'column', - justifyContent: 'flex-start', - alignItems: 'flex-start', -}); diff --git a/apps/web/src/app/[locale]/game/quiz/create/_components/QuizCreateForm.tsx b/apps/web/src/app/[locale]/game/quiz/create/_components/QuizCreateForm.tsx index ad1ab816..fba0e612 100644 --- a/apps/web/src/app/[locale]/game/quiz/create/_components/QuizCreateForm.tsx +++ b/apps/web/src/app/[locale]/game/quiz/create/_components/QuizCreateForm.tsx @@ -3,9 +3,8 @@ import React, { useState } from 'react'; import { useRouter } from 'next/navigation'; import { useLocale, useTranslations } from 'next-intl'; -import { css } from '_panda/css'; import { createQuiz } from '@gitanimals/api'; -import { Button } from '@gitanimals/ui-panda'; +import { Button } from '@gitanimals/ui-tailwind'; import { toast } from 'sonner'; import QuizField from '@/app/[locale]/game/quiz/create/_components/QuizField'; @@ -95,7 +94,7 @@ const QuizCreateForm = () => { }; return ( -
+ { } /> - @@ -158,15 +157,3 @@ const QuizCreateForm = () => { }; export default QuizCreateForm; - -const contentStyle = css({ - display: 'flex', - flexDirection: 'column', - gap: '24px', -}); - -const buttonStyle = css({ - width: '100%', - height: '40px', - marginTop: '70px', -}); diff --git a/apps/web/src/app/[locale]/game/quiz/create/_components/QuizField.tsx b/apps/web/src/app/[locale]/game/quiz/create/_components/QuizField.tsx index 3f24269d..d3a6a22f 100644 --- a/apps/web/src/app/[locale]/game/quiz/create/_components/QuizField.tsx +++ b/apps/web/src/app/[locale]/game/quiz/create/_components/QuizField.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { css } from '_panda/css'; interface Props { title: string; @@ -10,29 +9,11 @@ interface Props { const QuizField = ({ title, description, content }: Props) => { return (
-

{title}

-

{description}

-
{content}
+

{title}

+

{description}

+
{content}
); }; export default QuizField; - -const titleStyle = css({ - textStyle: 'glyph15.bold', - fontFamily: 'Product Sans', - fontWeight: 700, - color: 'white', -}); - -const descriptionStyle = css({ - textStyle: 'glyph14.regular', - fontFamily: 'Product Sans', - fontWeight: 400, - color: 'white.white_50', -}); - -const contentStyle = css({ - marginTop: '12px', -}); diff --git a/apps/web/src/app/[locale]/game/quiz/create/_components/QuizTextArea.tsx b/apps/web/src/app/[locale]/game/quiz/create/_components/QuizTextArea.tsx index 56a46fe0..7675be0b 100644 --- a/apps/web/src/app/[locale]/game/quiz/create/_components/QuizTextArea.tsx +++ b/apps/web/src/app/[locale]/game/quiz/create/_components/QuizTextArea.tsx @@ -1,7 +1,6 @@ import type { ChangeEvent, ComponentProps } from 'react'; import { useState } from 'react'; -import { css, cx } from '_panda/css'; -import { Flex } from '_panda/jsx'; +import { cn } from '@gitanimals/ui-tailwind'; import { customScrollStyle } from '@/styles/scrollStyle'; @@ -18,83 +17,32 @@ function QuizTextArea({ maxLength = 1000, ...props }: QuizTextAreaProps) { }; return ( -
+