
# インポートと仮想モジュール

TailwindPHPはコンパイル前に`@import`ルールを解決します。インポート先には、組み込み仮想モジュール（`tailwindcss`など）、`importPaths`オプションによるディスク上のファイル、カスタムリゾルバーが返す任意のものを指定できます。

## 仮想モジュール

`@import "tailwindcss"`は、多くのプロジェクトで使われるエントリーポイントです。次の4行に展開されます。レイヤー順序の宣言と、それぞれのカスケードレイヤーに割り当てられた3つのサブインポートです。

```css
@layer theme, base, components, utilities;
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css" layer(utilities);
```

各サブインポートは、それぞれ単独でインポートできる仮想モジュールです。利用可能な仮想モジュールは次のとおりです。

| モジュール | 内容 |
|--------|----------|
| `tailwindcss` | 完全なバンドル: テーマ + Preflight + ユーティリティ。 |
| `tailwindcss/theme.css` | テーマ変数のみ（色、基本スペーシング、ブレークポイントなど）。 |
| `tailwindcss/preflight.css` | Preflightの基本リセット。 |
| `tailwindcss/utilities.css` | ユーティリティレイヤー。 |
| `tw-animate-css` | `tw-animate-css`アニメーションユーティリティ。 |

各パーツを個別にインポートすると、Preflightを省いたり、レイヤーの順序を変更したりできます（下記参照）。

## tw-animate-cssによるアニメーション

[tw-animate-css](https://github.com/Wombosvideo/tw-animate-css)はTailwindCSS v4向けのアニメーションライブラリで、`tailwindcss-animate`のドロップイン代替です。組み込み仮想モジュールとして提供されるため、ユーティリティレイヤーと一緒にインポートすると、入場・退場アニメーションのクラスも他のユーティリティと同様にコンパイルされます。

```css
@import "tw-animate-css";
@import "tailwindcss/utilities.css";
```

アニメーションユーティリティには次のものがあります。

- **入場 / 退場** — `animate-in`, `animate-out`
- **フェード** — `fade-in`, `fade-out`
- **ズーム** — `zoom-in`, `zoom-out`
- **回転** — `spin-in`, `spin-out`
- **ぼかし** — `blur-in`, `blur-out`
- **スライド** — `slide-in-from-top` / `-bottom` / `-left` / `-right`と対応する`slide-out-to-*`、およびRTL対応の`-start` / `-end`
- **タイミング** — `duration-*`, `delay-*`, `repeat-1` / `repeat-infinite`, `direction-normal` / `-reverse` / `-alternate`、`fill-mode-none` / `-forwards` / `-backwards` / `-both`
- **再生状態** — `running`, `paused`
- **コンポーネントアニメーション** — `accordion-down` / `accordion-up`, `collapsible-down` / `collapsible-up`、`caret-blink`

これらのクラスは他のユーティリティと同様にTailwindのバリアントとスタックできるため、shadcn/uiのダイアログやドロップダウンのパターンにそのまま適用できます。

## `importPaths`オプション

ファイルシステムを使って`@import`を解決するには、`generate()`の配列形式で`importPaths`を渡します。単一のパス、ディレクトリ、またはそれらの配列を指定できます。

```php
use TailwindPHP\tw;

// Single file
$css = tw::generate([
    'content'     => '<div class="flex btn">Hello</div>',
    'importPaths' => '/path/to/styles.css',
]);

// Directory (loads all .css files alphabetically)
$css = tw::generate([
    'content'     => '<div class="flex btn">Hello</div>',
    'importPaths' => '/path/to/css/',
]);

// Multiple paths — files and directories
$css = tw::generate([
    'content'     => '<div class="flex btn card">Hello</div>',
    'importPaths' => [
        '/path/to/base.css',
        '/path/to/components/',
    ],
]);

// Combine with inline css
$css = tw::generate([
    'content'     => '<div class="flex btn custom">Hello</div>',
    'css'         => '.custom { color: red; }',
    'importPaths' => '/path/to/styles.css',
]);
```

### ネストされたインポート

読み込んだファイル内のインポートは、そのファイルを基準に解決されます。`/path/to/styles.css`に`@import "./components/buttons.css"`が含まれる場合、パスは`/path/to/`を基準に解決されます。

```css
/* /path/to/styles.css */
@import "tailwindcss";
@import "./components/buttons.css";
@import "./components/cards.css";

@theme {
    --color-brand: #3b82f6;
}
```

### 重複排除

同じファイルまたは仮想モジュールを複数回インポートしても、最初の読み込み後は何も起こりません。`@import "tailwindcss"`行の繰り返しや、同じ部分ファイルをインポートする2つのファイルは自動的に重複排除されます。これにより循環インポートも防げます。

## カスタムリゾルバー

仮想ファイルシステム、データベース、その他のファイルシステム以外のソースでは、呼び出し可能な値を`importPaths`として渡します。インポートURIと、インポートの解決先となる基準ディレクトリを受け取り、CSSまたは`null`を返します。

```php
use TailwindPHP\tw;

$css = tw::generate([
    'content'     => '<div class="flex virtual-class">Hello</div>',
    'importPaths' => function (?string $uri, ?string $fromFile): ?string {
        if ($uri === null) {
            // Entry CSS — returned when no file is supplied
            return '@import "tailwindcss"; @import "custom.css";';
        }
        if ($uri === 'custom.css') {
            return '.virtual-class { color: purple; }';
        }
        return null; // Unknown imports are silently skipped
    },
]);
```

`$uri`が`null`の場合（最初の呼び出しで、2つ目の引数も`null`）、エントリーCSSを返します。それ以外のURIでは、そのCSSの内容を返すか、`null`を返してファイルシステム検索にフォールバックします。見つからない場合、インポートは何も通知されずにスキップされます。

## 事前確認

Preflightは、[modern-normalize](https://github.com/sindresorhus/modern-normalize)を基盤とした、Tailwind独自の基本リセットです。ブラウザー間の差異を整え、ユーティリティが予測どおりに動作するようにします。既定のマージンを削除し、見出しやリストのスタイルを解除し、画像をブロック要素にし、`border-width`だけでボーダーが描画されるようにボーダースタイルをリセットし、ボタンがフォントを継承するようにするなどの処理を行います。

Preflightは`@import "tailwindcss"`に含まれているため、完全なバンドルをインポートすれば、すでに利用できます。

```php
use TailwindPHP\tw;

$css = tw::generate([
    'content' => '<div class="flex p-4">Hello</div>',
    'css'     => '@import "tailwindcss";',
]);
```

### Preflightの拡張

`@layer base`を使うと、Preflightの上に独自の基本スタイルを追加できます。

```php
use TailwindPHP\tw;

$css = tw::generate([
    'content' => '<article><h1>Title</h1><p>Content</p></article>',
    'css'     => '
        @import "tailwindcss";
        @layer base {
            h1 { font-size: var(--text-2xl); }
            h2 { font-size: var(--text-xl); }
            a  { color: var(--color-blue-600); text-decoration-line: underline; }
        }
    ',
]);
```

### Preflightを無効にする

既存のプロジェクトに組み込む場合は、必要なパーツだけをインポートし、Preflightの行を省略します。

```php
use TailwindPHP\tw;

$css = tw::generate([
    'content' => '<div class="flex p-4">Hello</div>',
    'css'     => '
        @layer theme, base, components, utilities;
        @import "tailwindcss/theme.css" layer(theme);
        @import "tailwindcss/utilities.css" layer(utilities);
    ',
]);
```

## インポート修飾子

Tailwindのファイルを個別にインポートする場合、修飾子は適用対象のインポートに指定します。

```css
/* Assign the import to a cascade layer */
@import "tailwindcss/utilities.css" layer(utilities);

/* prefix affects both theme variables and utilities */
@import "tailwindcss/theme.css" layer(theme) prefix(tw);
@import "tailwindcss/utilities.css" layer(utilities) prefix(tw);

/* important affects utilities */
@import "tailwindcss/utilities.css" layer(utilities) important;

/* theme(static) or theme(inline) affects theme variables */
@import "tailwindcss/theme.css" layer(theme) theme(static);

/* theme(reference): utilities use the variables with a fallback, no :root block */
@import "tailwindcss/theme.css" layer(theme) theme(reference);
```

## 参照インポート

`@import "…" reference`は定義だけを読み込むファイルです。`@theme`の値、ファイル内で定義された`@utility`と`@custom-variant`は使用できますが、そのファイルからCSSは出力されません。ファイルの内容を`@media reference { … }`で囲むのと同じで、こちらの書き方もできます。

```css
@import "tailwindcss/utilities.css";

@media reference {
    @theme {
        --color-brand: #f00;
    }
}
```

`bg-brand`は`background-color: var(--color-brand, #f00);`にコンパイルされ、`--color-brand`宣言は出力されません。

現在のリリースにおける制限は2つです（[#14](https://github.com/inline0/tailwindphp/issues/14)）。

- 参照インポートと`@media reference`ブロックは、`tailwindcss`または`tailwindcss/utilities.css`の`@import`の**後**に置いてください。前に置くと、出力全体が空になります。
- 組み込み仮想モジュール（`@import "tailwindcss" reference;`）への`reference`は、まだ効果がありません。テーマ、Preflight、ユーティリティは引き続き出力されます。

テーマ変数については[Theme](https://tailwindphp.inline0.dev/ja/docs/usage/theme)、クラス名のスキャン対象ファイルを制御する方法については[@source](https://tailwindphp.inline0.dev/ja/docs/usage/source)を参照してください。
