
# カスタムプラグイン

カスタムプラグインは、`TailwindPHP\Plugin\PluginInterface`を実装するPHPクラスです。`PluginAPI`インスタンスを受け取り、これを使って静的ユーティリティ、機能的ユーティリティ、コンポーネント、バリアントを登録します。`registerPlugin()`で登録すると、組み込みのtypographyおよびformsプラグインと同じ仕組みにより、`@plugin`ディレクティブで名前を指定して読み込めます。

## `PluginInterface`

3つのメソッドを実装します。

```php
namespace TailwindPHP\Plugin;

interface PluginInterface
{
    public function getName(): string;
    public function __invoke(PluginAPI $api, array $options = []): void;
    public function getThemeExtensions(array $options = []): array;
}
```

- `getName()`は`@plugin "..."`で使う識別子を返します。
- `__invoke()`はプラグインを実行し、`$api`を通じてすべてを登録します。`$options`配列には`@plugin` CSSブロックの値が入ります。
- `getThemeExtensions()`はユーティリティ生成前にマージするテーマの名前空間を返します。該当するものがなければ`[]`を返します。

## 例

```php
use TailwindPHP\Plugin\PluginInterface;
use TailwindPHP\Plugin\PluginAPI;

class MyCustomPlugin implements PluginInterface
{
    public function getName(): string
    {
        return 'my-custom-plugin';
    }

    public function __invoke(PluginAPI $api, array $options = []): void
    {
        // Static utilities
        $api->addUtilities([
            '.btn' => [
                'padding' => '0.5rem 1rem',
                'border-radius' => '0.25rem',
                'font-weight' => '600',
            ],
            '.btn-primary' => [
                'background-color' => 'blue',
                'color' => 'white',
            ],
        ]);

        // Functional utilities (generates .gutter-sm, .gutter-md, .gutter-lg)
        $api->matchUtilities(
            [
                'gutter' => fn ($value) => ['padding-inline' => $value],
            ],
            ['values' => ['sm' => '1rem', 'md' => '2rem', 'lg' => '3rem']]
        );

        // Component classes (sorted into the components layer)
        $api->addComponents([
            '.card' => [
                'background-color' => 'white',
                'border-radius' => '0.5rem',
                'padding' => '1rem',
            ],
        ]);

        // Custom variant (see the note below the API reference)
        $api->addVariant('hocus', '&:hover, &:focus');

        // Read a theme value
        $primary = $api->theme('colors.blue.500', '#3b82f6');
    }

    public function getThemeExtensions(array $options = []): array
    {
        return []; // Return theme additions if needed
    }
}
```

## `PluginAPI`リファレンス

APIはTailwindCSSプラグインAPIに準拠しています。

| メソッド | シグネチャ | 用途 |
|--------|-----------|---------|
| `addBase` | `addBase(array $css): void` | ベースレイヤーのスタイルを追加します。 |
| `addUtilities` | `addUtilities(array $utilities, array $options = []): void` | セレクターをキーに静的ユーティリティクラスを登録します。 |
| `matchUtilities` | `matchUtilities(array $utilities, array $options = []): void` | 機能的ユーティリティを登録します。`$options['values']`は値マップを指定し、`$options['supportsNegativeValues']`は負の値を有効にします。 |
| `addComponents` | `addComponents(array $components, array $options = []): void` | コンポーネントクラス（componentsレイヤー）を登録します。 |
| `matchComponents` | `matchComponents(array $components, array $options = []): void` | 値マップ付きの機能的コンポーネントを登録します。 |
| `addVariant` | `addVariant(string $name, string\|array $variant): void` | セレクターから静的バリアントを登録します。 |
| `matchVariant` | `matchVariant(string $name, callable $callback, array $options = []): void` | 機能的バリアントを登録します。`$options['values']`は値マップを指定します。 |
| `theme` | `theme(string $path, mixed $defaultValue = null): mixed` | ドット区切りのパスでテーマ値を読み取ります（e.g。`colors.blue.500`）。 |
| `config` | `config(?string $path = null, mixed $defaultValue = null): mixed` | ドット区切りのパスで設定値を読み取ります。`$path`がnullの場合は設定全体を返します。 |
| `prefix` | `prefix(string $className): string` | 設定済みのプレフィックスをクラス名に適用します。 |

`matchUtilities`、`matchComponents`、`matchVariant`に渡すコールバックは、値と、`modifier`キーを含む2番目の引数配列を受け取ります。

コアTailwindで使われていないユーティリティ名を選んでください。プラグインのユーティリティがコアのものと同じ名前の場合（たとえば`tab-*`は、v4.3以降、コアTailwindでは`tab-size`に使われています）、両方の宣言が同じルールに入り、コアの宣言が後に来るため優先されます。そのため、プラグインの`tab-4`を`7`に割り当てても、`tab-size: 4`が生成されます。

> **既知の問題:** `addVariant()`で登録したバリアントと、`matchVariant()`が登録する値ごとのバリアントは、現在のリリースでは適用されません。上の例の`hocus:flex`は`.hocus\:flex { display: flex; }`にコンパイルされますが、`:hover`/`:focus`セレクターは付きません（[#10](https://github.com/inline0/tailwindphp/issues/10)）。修正されるまでは、機能する[`@custom-variant`](https://tailwindphp.inline0.dev/ja/docs/usage/directives#custom-variant)を使ってCSSでバリアントを定義してください。`@custom-variant hocus (&:hover, &:focus);`。

## 登録と使用

プラグインインスタンスを登録し、`getName()`で指定した名前を参照します。

```php
use TailwindPHP\tw;
use function TailwindPHP\registerPlugin;

registerPlugin(new MyCustomPlugin());

$css = tw::generate(
    '<div class="btn btn-primary card gutter-md">…</div>',
    '@plugin "my-custom-plugin"; @import "tailwindcss/utilities.css";'
);
```

`$api->theme()`で公開される値については[テーマ](https://tailwindphp.inline0.dev/ja/docs/usage/theme)、`@plugin`ディレクティブについては[プラグイン](https://tailwindphp.inline0.dev/ja/docs/plugins)を参照してください。
