Skip to content

feat: Tailwind CSS v4 への移行(Hub は Tailwind を廃止) - #500

Merged
ujiro99 merged 18 commits into
dev-1.4.0from
feat/tailwindcss-v4
Oct 21, 2026
Merged

ujiro99 merged 18 commits into
dev-1.4.0from
feat/tailwindcss-v4

Conversation

@ujiro99

@ujiro99 ujiro99 commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Closes #497

概要

拡張機能を Tailwind CSS v4 に移行し、Hub では Tailwind CSS(と shadcn/ui)を使うのをやめます。
方針と手順の詳細は docs/design/tailwindcss-v4-migration.md にあります。

content script はユーザーのページ上で動くので、ユーザーのページに影響を与えず、ユーザーのページからも影響を受けないことを前提に設計しています。

変更内容

Extension

  • 設定方式の変更
    • @tailwindcss/vite と、CSS の中で設定を書く方式(@theme)に移行しました。
    • tailwind.config.js と postcss.config.cjs は削除しました。
  • 依存パッケージの変更
    • tailwindcss-animate を tw-animate-css に置き換えました。
    • tailwind-merge を v3 に上げました(shared パッケージも同様)。
  • rem を使わない
    • サイズの値はすべて px にしました(余白の基準 --spacing、文字サイズ --text-*、幅 --container-*、角丸 --radius-*)。これで、ユーザーのページの root font-size が UI に影響しなくなります。
    • 画面幅の区切り(--breakpoint-*)も v3 と同じ px で定義しました。rem のままだと、Chrome の既定の文字サイズ設定に連動してしまうためです。
    • content script の CSS に rem(と rlh などページの root 要素に連動する単位)が含まれていたら、ビルドが失敗するようにしました(findRemUsages)。検査する CSS が見つからない場合もビルドを失敗させます。
  • Shadow DOM 内で @property が効かない問題への対策
    • Chrome は Shadow DOM の中の @property を無視します。そこで、@property で決めている初期値を、優先度の最も低い @layer properties に通常の変数として書き出す PostCSS プラグインを自作しました(postcss-shadow-dom-properties)。
    • CSS は分割されたまま shadow root に注入されるため、レイヤーを使う各ファイルの先頭で @layer properties; を宣言し、注入の順番に関係なく最も優先度の低いレイヤーになるようにしています。
    • ユーザーのページの document.head には何も追加しません。
  • テーマの色は @theme inline で定義しました。v4 の既定のやり方では、ユーザースタイルで指定した色が反映されなくなる退行(E2E-72)があり、それを直すためです。
  • クラスを探すファイルの範囲を src(テストを除く)に限りました。AGENTS.md などの説明文から、不要なクラスが作られないようにするためです。
  • クラス名の変更
    • v4 で名前が変わったクラスを書き換えました(rounded を rounded-sm に、bg-gradient-to-r を bg-linear-to-r に、など)。
    • @apply を使う CSS Modules には @reference を追加しました。

Hub

  • Tailwind CSS、PostCSS、shadcn/ui とその依存パッケージを削除し、普通の CSS(全体用の CSS と CSS Modules)に置き換えました。
  • e2e テストが使うテストページは、DOM 構造を変えずにスタイルだけ置き換えました。

e2e

  • E2E_HUB_BASE_URL を指定すると、デプロイ済みの hub への通信をローカルでビルドした hub に向けられるようにしました(e2e/utils/hubRoute.ts)。手順は packages/hub/AGENTS.md にあります。
    • ローカルに無い JS/CSS などのファイルはデプロイ済みの hub から取得します(拡張が自分で開く録画画面のため)。ページ(HTML)がローカルに無い場合は 404 を返し、テストが失敗するようにしています。

その他

  • 必要な Node のバージョンを 20 以上に上げました(Tailwind v4 の要件)。

検証結果

  • ビルド・型チェック・lint・テスト
    • リポジトリのルートで全パッケージのビルドが通りました。
    • 型チェック(tsc)が通りました。
    • lint はエラーが 0 件で、警告は移行前と同じ件数でした。
    • ユニットテストは extension の 1,523 件と hub の 33 件がすべて通りました。
  • v3 との見た目の比較
    • 選択時のメニューは画素単位で一致しました。
    • options page とオンボーディング画面の差は、画像のにじみとアニメーションの途中の違いだけでした。
  • root font-size を 62.5% にしたページでも、メニューのサイズは変わりませんでした。
  • e2e(v4 版の拡張と、ローカルで配信した新しい hub の組み合わせ)
    • 81 件成功、7 件失敗、5 件スキップでした。
    • 失敗した 7 件は main(v3)でも同じく失敗しました。
      • Cloudflare 認証が必要なテスト 4 件(E2E-90/91/92/94)は、この環境に認証用の秘密情報が無いためです。
      • 外部の検索サイトの応答を確かめるテスト 3 件(百度・Naver・Yandex)は、相手サイト側の問題です。

注意点

  • この PR の CI で走る e2e は、デプロイ済みの古いテストページを使います。新しい Hub を本番で確かめるには、マージして GitHub Pages へのデプロイが終わった後に e2e を走らせる必要があります。
  • content script に入る CSS は約 65KB から約 85KB に増えます。

🤖 Generated with Claude Code

https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU

ujiro99 and others added 11 commits October 19, 2026 08:49
The hub only serves the e2e test page and static data files, so a CSS
framework brings no benefit. Replace Tailwind classes with plain CSS
(globals.css + CSS Modules) and shadcn/ui components with native
elements, keeping the test page DOM that e2e relies on unchanged.

Also add E2E_HUB_BASE_URL to route the deployed hub to a local build so
hub changes can be verified with e2e before deploying.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
- postcss-shadow-dom-properties: declare the initial values of
  @property-registered custom properties inside the stylesheet, since
  Chrome ignores @Property in shadow trees (needed by Tailwind CSS v4)
- findRemUsages: detect rem units, which follow the user's page root
  font-size inside the content script's Shadow DOM

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
- Use @tailwindcss/vite and move the theme from tailwind.config.js to
  CSS (@theme); replace tailwindcss-animate with tw-animate-css and
  update tailwind-merge to v3
- Redefine every rem-based token in px (--spacing: 4px, text, container,
  radius) so the content script UI doesn't follow the user's page root
  font-size, and fail the build if content script CSS contains rem
- Apply the Shadow DOM @Property fallback via PostCSS
- Rename utilities for v4 (shadow, rounded, outline-hidden, ...), add
  @reference to CSS modules using @apply, and restore v3 defaults
  (placeholder color, button cursor)
- Ignore 'Request context disposed' in the e2e hub route helper

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
…canning

- Use @theme inline for tokens that reference runtime CSS variables.
  With a plain @theme, --color-background was resolved on :root/:host,
  so the popup's per-element --background override (user styles) no
  longer changed bg-background (e2e E2E-72)
- Scan only src/ (excluding tests) for class names; plain text in docs
  generated unused rem-based utilities

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
Windows opened by the extension (e.g. the PageAction recorder) load the
deployed HTML because their navigation can't be intercepted; forwarding
its hashed assets to the local build returned 404 and broke the page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
…olation

- Declare `@layer properties` at the top of every CSS file that uses layers,
  so it stays the lowest-priority layer whatever the chunk injection order.
- Fail the build when no content script CSS could be checked for rem, and
  also detect uppercase REM and other root-relative units (rlh, rex, ...).
- Define breakpoints in px as in v3, so media queries don't follow the
  browser's default font-size setting.
- e2e: return the local 404 for missing hub pages instead of falling back to
  the deployed hub, and match the base path on a segment boundary.
- Fix a lint error in the cn() test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

移行に伴う表示とスタイル分離の退行が残っているためです。

2 open issues
What changed in this PR

概要
Issue #497 に対応し、拡張機能を Tailwind CSS v4 へ移行するとともに、静的配信・テスト用途の Hub から Tailwind を撤去する変更です。

変更:

  • 拡張機能のテーマ・クラス名・ビルド設定を v4 に移行し、Shadow DOM 対応とルート相対単位の検査を追加。
  • Hub の UI を通常の CSS と CSS Modules に置換。
  • ローカル Hub を使う E2E 転送、関連テスト、移行資料を追加。

懸念点
承認前に対応が必要な動作上の問題が残っています。

改善提案
指摘箇所を修正し、表示とスタイル分離の回帰確認をお願いします。

File Description
yarn.lock 移行後の依存関係を反映
tailwind.config.js 共通 v3 設定を削除
packages/​shared/​package.json tailwind-merge を v3 に更新
packages/​hub/​vitest.config.ts 削除済み設定の除外指定を整理
packages/​hub/​tailwind.config.ts Hub の Tailwind 設定を削除
packages/​hub/​src/​lib/​utils.ts cn の再公開を削除
packages/​hub/​src/​lib/​__tests__/​utils.test.ts cn のテストを削除
packages/​hub/​src/​components/​ui/​separator.tsx 不要になった区切り部品を削除
packages/​hub/​src/​components/​ui/​select.tsx Radix ベースの選択部品を削除
packages/​hub/​src/​components/​ui/​button.tsx Tailwind ベースのボタンを削除
packages/​hub/​src/​components/​MovedNotice.tsx 移転案内を共通化
packages/​hub/​src/​components/​MovedNotice.module.css 移転案内の CSS を追加
packages/​hub/​src/​components/​LocaleSelector.tsx ネイティブ select に置換
packages/​hub/​src/​components/​LocaleSelector.module.css 言語選択の CSS を追加
packages/​hub/​src/​components/​layout/​Header.tsx ヘッダーを CSS Modules 化
packages/​hub/​src/​components/​layout/​Header.module.css ヘッダーの通常 CSS を定義
packages/​hub/​src/​components/​layout/​Footer.tsx 区切りを hr に置換
packages/​hub/​src/​components/​layout/​Footer.module.css フッターの CSS を追加
packages/​hub/​src/​components/​Image.tsx Tailwind 依存のクラス処理を削除
packages/​hub/​src/​app/​page.tsx 共通の移転案内を使用
packages/​hub/​src/​app/​page.module.css レイアウトを通常 CSS に置換
packages/​hub/​src/​app/​not-found.tsx 共通の移転案内を使用
packages/​hub/​src/​app/​layout.tsx body の Tailwind クラスを削除
packages/​hub/​src/​app/​globals.css 通常 CSS のリセット・配色に置換
packages/​hub/​src/​app/​[lang]/​test/​test.module.css テストページの CSS を追加
packages/​hub/​src/​app/​[lang]/​test/​page.tsx 通常のボタンと CSS Modules に置換
packages/​hub/​postcss.config.mjs Tailwind 用 PostCSS 設定を削除
packages/​hub/​package.json 不要な UI・CSS 依存を削除
packages/​hub/​components.json shadcn/ui 設定を削除
packages/​hub/​AGENTS.md CSS 方針とローカル E2E 手順を追記
packages/​extension/​vite.config.ts Tailwind v4 と互換プラグインを導入
packages/​extension/​tailwind.config.js v3 設定を削除
packages/​extension/​src/​lib/​vite-plugin-manifest.ts 配信 CSS の単位検査を追加
packages/​extension/​src/​lib/​postcss-shadow-dom-properties.ts Shadow DOM 用の変数初期化を追加
packages/​extension/​src/​lib/​findRemUsages.ts ルート相対単位の検出を追加
packages/​extension/​src/​lib/​__tests__/​utils.cn.test.ts v4 クラスの結合テストを追加
packages/​extension/​src/​lib/​__tests__/​postcss-shadow-dom-properties.test.ts 変数初期化とレイヤー順を検証
packages/​extension/​src/​lib/​__tests__/​findRemUsages.test.ts 単位検出のテストを追加
packages/​extension/​src/​components/​ui/​toggle.tsx アウトラインのクラス名を更新
packages/​extension/​src/​components/​ui/​textarea.tsx 影・アウトラインを v4 化
packages/​extension/​src/​components/​ui/​switch.tsx 影・アウトラインを v4 化
packages/​extension/​src/​components/​ui/​select.tsx 属性・寸法・変数の記法を更新
packages/​extension/​src/​components/​ui/​scroll-area.tsx アウトラインのクラス名を更新
packages/​extension/​src/​components/​ui/​radio-group.tsx アウトラインのクラス名を更新
packages/​extension/​src/​components/​ui/​popover.tsx 重なり順・アウトラインを v4 化
packages/​extension/​src/​components/​ui/​menubar.tsx メニューのクラス記法を更新
packages/​extension/​src/​components/​ui/​input.tsx 影・アウトラインを v4 化
packages/​extension/​src/​components/​ui/​form.tsx 文字サイズを px 化
packages/​extension/​src/​components/​ui/​button.tsx アウトラインのクラス名を更新
packages/​extension/​src/​components/​Popup.module.css テーマ参照を追加し文字サイズを px 化
packages/​extension/​src/​components/​pageAction/​StepList.tsx 接続線の角丸クラスを更新
packages/​extension/​src/​components/​pageAction/​PageActionRunner.tsx ぼかし・配置のクラスを更新
packages/​extension/​src/​components/​pageAction/​PageActionRecorder.tsx 重なり順の記法を更新
packages/​extension/​src/​components/​pageAction/​PageActionRecorder.module.css テーマ参照と角丸を更新
packages/​extension/​src/​components/​pageAction/​PageActionItem.tsx 角丸・影・余白を更新
packages/​extension/​src/​components/​pageAction/​InputEditor.tsx 配置のクラス記法を更新
packages/​extension/​src/​components/​pageAction/​Controller.tsx 背景ぼかしのクラス名を更新
packages/​extension/​src/​components/​option/​TableOfContents.module.css テーマ参照を追加
packages/​extension/​src/​components/​option/​PromptHistoryBanner.tsx 重なり順・影の記法を更新
packages/​extension/​src/​components/​option/​Option.module.css テーマ参照と背景効果を更新
packages/​extension/​src/​components/​option/​HubBanner.module.css テーマ参照を追加
packages/​extension/​src/​components/​option/​field/​UserVariablesField.tsx バッジの影を v4 化
packages/​extension/​src/​components/​option/​field/​PopupPlacementField.tsx 選択項目の影を v4 化
packages/​extension/​src/​components/​option/​field/​OpenModeToggleField.tsx トグルの影を v4 化
packages/​extension/​src/​components/​option/​field/​InputField.tsx プレビューの角丸を更新
packages/​extension/​src/​components/​option/​field/​InfoTooltip.tsx トリガーの角丸を更新
packages/​extension/​src/​components/​option/​field/​IconField.tsx 文字サイズ・角丸・影を更新
packages/​extension/​src/​components/​option/​editor/​UserStyleList.tsx ボタン配置の記法を更新
packages/​extension/​src/​components/​option/​editor/​ShortcutList.module.css テーマ参照を追加
packages/​extension/​src/​components/​option/​editor/​SearchUrlAssistDialog.tsx 縦横比・グラデーションを更新
packages/​extension/​src/​components/​option/​editor/​SearchUrlAssistButton.tsx グラデーション・余白を更新
packages/​extension/​src/​components/​option/​editor/​PageRuleList.tsx 入力欄・アイコンのクラスを更新
packages/​extension/​src/​components/​option/​editor/​PageActionSection.tsx 移動量の記法を更新
packages/​extension/​src/​components/​option/​editor/​CommandListMenu.tsx 件数表示の角丸を更新
packages/​extension/​src/​components/​option/​editor/​CommandEditDialog.tsx プレビューの角丸を更新
packages/​extension/​src/​components/​option/​editor/​CommandEditDialog.module.css テーマ参照とグラデーションを更新
packages/​extension/​src/​components/​option/​editor/​__tests__/​SearchUrlAssistButton.test.tsx 新クラス名に期待値を更新
packages/​extension/​src/​components/​OpenInTab.tsx ボタンの角丸を更新
packages/​extension/​src/​components/​onboarding/​steps/​StepCustomize.tsx important・透過色の記法を更新
packages/​extension/​src/​components/​onboarding/​OnboardingTargetText.tsx フィルターの記法を更新
packages/​extension/​src/​components/​onboarding/​OnboardingLayout.tsx 子要素セレクターの記法を更新
packages/​extension/​src/​components/​onboarding/​OnboardingConfetti.tsx important の記法を更新
packages/​extension/​src/​components/​menu/​MenuFolder.tsx 間隔の記法を更新
packages/​extension/​src/​components/​menu/​Menu.tsx 間隔の記法を更新
packages/​extension/​src/​components/​help/​PageActionHelp.tsx 幅・余白・角丸を更新
packages/​extension/​src/​components/​help/​help.module.css テーマ参照と角丸を更新
packages/​extension/​src/​components/​global.css v4 テーマ・px トークン・独自 utility を定義
packages/​extension/​src/​components/​App.css CSS import の形式を更新
packages/​extension/​postcss.config.cjs 旧 PostCSS 設定を削除
packages/​extension/​package.json v4 関連依存へ更新
packages/​extension/​e2e/​utils/​hubRoute.ts ローカル Hub への転送を追加
packages/​extension/​e2e/​fixtures.ts E2E に Hub 転送を組み込み
packages/​extension/​AGENTS.md v4・Shadow DOM の開発方針を追記
package.json 共通依存を整理し Node 要件を更新
docs/​design/​tailwindcss-v4-migration.md 移行方針・検証手順・実装メモを追加

Review effort: Balanced

Comment thread packages/extension/src/components/global.css
Comment thread packages/extension/src/lib/postcss-shadow-dom-properties.ts Outdated
ujiro99 and others added 7 commits October 20, 2026 13:57
…properties

- Remove the unlayered `background: none` from the menu button so that
  layered utilities such as `hover:bg-accent` take effect.
- Reset `@property` custom properties without an initial value to `initial`
  inside the shadow root, so values from ancestors or the host page are not
  inherited.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Tailwind v4 outputs translate utilities as the `translate` property,
which stacks with the slide keyframes' `transform`, so the dialog
slid in from the top-left. Drop the slide classes as upstream shadcn does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The hover area was rendered inside PopoverContent, so the content's
zoom/slide enter transforms were also applied to the part covering the
anchor. The area moved during the animation, causing unintended
mouseenter/mouseleave and the folder menu toggling repeatedly.

- Render the area via a portal into the anchor's root (ShadowRoot or
  body) with fixed viewport coordinates, and follow page scroll/resize
- Ignore animation/transition events bubbling from descendants
- Skip re-render when neither position nor size has changed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PopoverContent stays mounted during its exit animation, so the hover
area of a closing folder kept capturing the pointer. Its bridge overlaps
the lower part of the neighboring folder and morphs with the exit
animation, which toggled the previous and the newly opened folder back
and forth and made the open folder's background blink.

Render the hover area only while the popover is open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Chrome (macOS), the background transition on the folder button
combined with the end of the popover enter/exit animation dropped the
open folder's background for one frame, which looked like a flicker.

- Remove the background transition from menu items and folders
- Drop the hover background and the undefined itemOnlyIcon class from
  the folder button
- Update @radix-ui/react-dialog, react-menubar and react-popover

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ujiro99
ujiro99 marked this pull request as ready for review October 21, 2026 01:10
@ujiro99
ujiro99 merged commit 4c6bdd6 into dev-1.4.0 Oct 21, 2026
4 checks passed
@ujiro99
ujiro99 deleted the feat/tailwindcss-v4 branch October 21, 2026 01:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants