Skip to content

build: Tailwind CSS v3 → v4 마이그레이션#104

Merged
6-keem merged 2 commits into
mainfrom
chore/tailwind-v4
Jun 15, 2026
Merged

build: Tailwind CSS v3 → v4 마이그레이션#104
6-keem merged 2 commits into
mainfrom
chore/tailwind-v4

Conversation

@6-keem

@6-keem 6-keem commented Jun 15, 2026

Copy link
Copy Markdown
Member

관련 이슈

Closes #103

변경 내용

Tailwind CSS v3 → v4 마이그레이션. 안 쓰는 HeroUI 의존성도 함께 제거.

  • 공식 @tailwindcss/upgrade 적용: 디렉티브(@import 'tailwindcss'), 17개 컴포넌트의 유틸리티 클래스 rename(shadowshadow-sm, roundedrounded-sm, outline-noneoutline-hidden 등), v4 기본 border-color 변경 호환 shim
  • @config 레거시 모드로 기존 tailwind.config.js(HSL 색상 토큰·tailwindcss-animate) 유지 — 마이그레이션 리스크 최소화
  • PostCSS: tailwindcss+autoprefixer@tailwindcss/postcss (v4가 prefix 내장)
  • tailwind-merge v2 → v3: v2가 shadow-xs 등 v4 신규 클래스를 못 합쳐 cn() 머지가 깨지던 문제 해결
  • HeroUI 제거: src에서 import되지 않는 @heroui/{theme,system,switch} + config 참조 정리
  • dead CSS 삭제: 미사용 index.css/option.css 제거, shadcn components.json css 경로를 live 파일(shadow.css)로 갱신

Shadow DOM 호환 (핵심)

이 확장의 UI는 adoptedStyleSheets로 Shadow DOM에 주입되는데, 이 환경에서는 @property가 등록되지 않습니다. v4는 box-shadow·border·transform 등의 기본값과 inherits:false@property에 의존하므로, 그대로면 컨테이너 유틸리티(border-none·shadow-zinc)가 모든 카드로 상속 누수되어 인디케이터가 사라지고 그림자가 짙어지는 등 디자인이 깨집니다.

→ Tailwind가 이미 생성하는 * 변수 리셋 폴백(@Property 미지원 브라우저용, @supports로 비활성)을 무조건 적용시키는 PostCSS 플러그인(postcss/tw-property-fallback.js)을 추가해 해결. 동작 기반 매칭 + 미발견 시 경고로 견고성 확보. (참고: tailwindlabs/tailwindcss#16772)

@tailwindcss/vite(Vite 권장 경로) 대신 @tailwindcss/postcss를 유지한 이유: 위 Shadow DOM 픽스가 생성 CSS 후처리를 필요로 하며 PostCSS 파이프라인이 적합. PostCSS는 v4에서 deprecated 아님.

변경 유형

  • ⚙️ 빌드/CI (chore, ci)

체크리스트

  • 이 PR과 연결된 이슈가 존재합니다.
  • 로컬에서 npm run lintnpm run build 가 통과합니다.
  • 변경 사항을 직접 테스트했습니다. (LMS에서 좌측 인디케이터·그림자·카드 높이 육안 확인)
  • CodeRabbit / 리뷰어 피드백을 반영할 준비가 되어 있습니다.

후속 (별도 이슈)

  • 강의 카드 확장/축소 애니메이션 추가 (신규 feat)
  • Shadow DOM @property 워크어라운드는 TW/브라우저가 지원하면 제거

Summary by CodeRabbit

릴리스 노트

  • 스타일

    • 디자인 시스템 업그레이드로 UI 컴포넌트의 시각적 일관성 개선
    • 그림자, 아웃라인, 축소 클래스 등 스타일 세부 조정
    • 포커스 및 비활성 상태 시각 처리 개선
  • Refactor

    • CSS 파일 구조 정리 및 통합
    • 의존성 업데이트로 모던 UI 라이브러리 기반 전환
    • Shadow DOM 호환성 강화를 위한 폴백 메커니즘 추가

@6-keem 6-keem added chore 빌드/도구/설정 등 잡일 dependencies Pull requests that update a dependency file labels Jun 15, 2026
@6-keem 6-keem self-assigned this Jun 15, 2026
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 90cdbe7a-4c01-43da-bb55-15cc079cfb62

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Tailwind CSS를 v3에서 v4로 업그레이드한다. PostCSS 파이프라인을 재구성하고 Shadow DOM @property 폴백을 위한 신규 PostCSS 플러그인을 추가한다. CSS 진입점을 shadow.css로 통합하고, 전체 컴포넌트 클래스 문자열을 v4 문법(outline-hidden, shrink-0, data-disabled, origin-(...) 등)으로 전환하며 @heroui 의존성을 제거한다.

Changes

Tailwind CSS v3 → v4 마이그레이션

Layer / File(s) Summary
의존성 및 빌드 도구 설정
package.json, tailwind.config.js, postcss.config.js, components.json
@heroui/* 제거, tailwindcss v4·@tailwindcss/postcss 추가, autoprefixer 제거, tailwind-merge v3 상향, heroui() 플러그인 제거, PostCSS 구성을 배열 기반으로 전환하고 twPropertyFallback 플러그인 등록, CSS 참조 경로를 shadow.css로 교체.
Shadow DOM @property 폴백 PostCSS 플러그인
postcss/tw-property-fallback.js
@supports 게이트로 인해 Shadow DOM에서 Tailwind v4 @property 폴백이 적용되지 않는 문제를 해결하기 위해 신규 PostCSS 플러그인 추가. OnceExit에서 해당 게이트를 감지하면 supports 노드를 언랩하고, 미감지 시 경고를 출력한다.
CSS 진입점 통합 및 shadow.css 갱신
src/styles/shadow.css, src/styles/index.css, src/styles/option.css
index.css·option.css 전체 내용 삭제. shadow.css@import 'tailwindcss' + @config 방식으로 전환하고, border-color 기본값 재정의·button cursor 복원 규칙 추가 및 :host-context(.dark) 블록 제거.
Shadcn/Radix UI 컴포넌트 클래스 v4 전환
src/components/ui/button.tsx, src/components/ui/card.tsx, src/components/ui/border-trail.tsx, src/components/ui/context-menu.tsx, src/components/ui/dropdown-menu.tsx, src/components/ui/popover.tsx, src/components/ui/select.tsx
outline-noneoutline-hidden, data-[disabled]data-disabled, min-w-[8rem]min-w-32, origin-[...]origin-(...), shadowshadow-sm/shadow-xs, [mask-composite:intersect]mask-intersect, CSS 커스텀 프로퍼티 참조 문법을 v4 방식으로 전환.
앱 컴포넌트 클래스 v4 전환
src/i18n/LanguageSwitcher.tsx, src/popover/dashboard/components/*, src/popover/player/components/*
flex-shrink-0shrink-0, outline-noneoutline-hidden, backdrop-blur-smbackdrop-blur-xs, z-[9999]z-9999, bg-gradient-to-rbg-linear-to-r 등 v4 문법으로 전환. VodListCardHeaderspace-y-0 및 명시적 패딩 추가.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

style

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 Tailwind CSS v3에서 v4로의 마이그레이션이라는 주요 변경사항을 명확하고 간결하게 설명하고 있습니다.
Linked Issues check ✅ Passed PR의 모든 코드 변경사항이 #103의 요구사항을 충족합니다: tailwindcss v4 업그레이드, postcss.config.js 및 tailwind.config.js 마이그레이션, @tailwind@import 변환, 그리고 Shadow DOM 호환성을 위한 커스텀 PostCSS 플러그인 추가가 모두 구현되었습니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 Tailwind v4 마이그레이션 범위 내입니다: 의존성 업데이트, 설정 파일 변경, CSS 지시문 변환, utility 클래스명 업데이트, 그리고 Shadow DOM 호환성 처리 등이 모두 마이그레이션 작업에 직접 관련되어 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/tailwind-v4

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/popover/dashboard/components/VodList.tsx (1)

79-82: CardHeader 컴포넌트가 v4 호환으로 업데이트되지 않았습니다.

src/components/ui/card.tsx의 CardHeader는 여전히 기본값으로 space-y-1.5 p-6을 적용하고 있습니다. 따라서 VodList에서 space-y-0과 명시적 패딩(px-5 pt-5 pb-3)을 추가하여 이를 오버라이드하는 것이 필수적입니다.

CardHeader 컴포넌트 자체를 v4에 맞게 재설계하거나 더 유연하게 만드는 것을 검토하세요. 여러 곳에서 동일한 오버라이드가 필요한 경우라면 더욱 그렇습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/popover/dashboard/components/VodList.tsx` around lines 79 - 82, The
CardHeader component in src/components/ui/card.tsx applies hardcoded default
classes space-y-1.5 and p-6 which are causing VodList to need explicit overrides
(space-y-0 and custom padding px-5 pt-5 pb-3). Refactor the CardHeader component
to make the spacing and padding properties more flexible by either removing the
hardcoded defaults, accepting className props that properly override defaults,
or updating the defaults to be v4-compatible. This will eliminate the need for
consumers like VodList to override the same values repeatedly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/styles/shadow.css`:
- Line 3: The `@config` directive in src/styles/shadow.css is valid Tailwind v4
syntax but stylelint's scss/at-rule-no-unknown rule from the extended
stylelint-config-standard-scss does not recognize it, causing lint errors. Open
.stylelintrc.json and locate the rules section, then add an exception for the
scss/at-rule-no-unknown rule that ignores the config at-rule by specifying
ignoreAtRules with config as an exempted at-rule. This will allow the `@config`
directive to pass linting without errors.
- Around line 22-23: The selector [role='button']:not(:disabled) fails to
properly exclude disabled state for custom elements because the :disabled
pseudo-class only applies to native form elements. Since the codebase uses the
data-disabled attribute on UI components (dropdown-menu, select, context-menu),
modify the [role='button']:not(:disabled) selector to use
[role='button']:not([data-disabled]) instead to correctly exclude elements with
the data-disabled attribute from receiving the pointer cursor style.

---

Nitpick comments:
In `@src/popover/dashboard/components/VodList.tsx`:
- Around line 79-82: The CardHeader component in src/components/ui/card.tsx
applies hardcoded default classes space-y-1.5 and p-6 which are causing VodList
to need explicit overrides (space-y-0 and custom padding px-5 pt-5 pb-3).
Refactor the CardHeader component to make the spacing and padding properties
more flexible by either removing the hardcoded defaults, accepting className
props that properly override defaults, or updating the defaults to be
v4-compatible. This will eliminate the need for consumers like VodList to
override the same values repeatedly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7010a488-4ba4-4ba0-8de5-d04839742e6e

📥 Commits

Reviewing files that changed from the base of the PR and between 9469cae and 714b1be.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json, !package-lock.json
📒 Files selected for processing (26)
  • components.json
  • package.json
  • postcss.config.js
  • postcss/tw-property-fallback.js
  • src/components/ui/border-trail.tsx
  • src/components/ui/button.tsx
  • src/components/ui/card.tsx
  • src/components/ui/context-menu.tsx
  • src/components/ui/dropdown-menu.tsx
  • src/components/ui/popover.tsx
  • src/components/ui/select.tsx
  • src/i18n/LanguageSwitcher.tsx
  • src/popover/dashboard/components/DashboardHeader.tsx
  • src/popover/dashboard/components/FilterItem.tsx
  • src/popover/dashboard/components/InfoBubble.tsx
  • src/popover/dashboard/components/NotificationBubble.tsx
  • src/popover/dashboard/components/Setting.tsx
  • src/popover/dashboard/components/VodList.tsx
  • src/popover/player/components/PlayerIframe.tsx
  • src/popover/player/components/PlayerPopoverContent.tsx
  • src/popover/player/components/PlayerPopoverTrigger.tsx
  • src/popover/player/components/SortableItem.tsx
  • src/styles/index.css
  • src/styles/option.css
  • src/styles/shadow.css
  • tailwind.config.js
💤 Files with no reviewable changes (2)
  • src/styles/option.css
  • src/styles/index.css

Comment thread src/styles/shadow.css
Comment thread src/styles/shadow.css Outdated
@6-keem 6-keem merged commit f9f0ec0 into main Jun 15, 2026
4 checks passed
@6-keem 6-keem deleted the chore/tailwind-v4 branch June 15, 2026 10:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore 빌드/도구/설정 등 잡일 dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore: Tailwind CSS v3 → v4 마이그레이션

1 participant