
# Benutzerdefinierte Plugins

Ein benutzerdefiniertes Plugin ist eine PHP-Klasse, die `TailwindPHP\Plugin\PluginInterface` implementiert. Sie erhält eine `PluginAPI`-Instanz und verwendet sie, um statische und funktionale Utilities, Komponenten und Varianten zu registrieren. Sobald das Plugin mit `registerPlugin()` registriert ist, wird es anhand seines Namens in einer `@plugin`-Direktive aufgelöst — nach demselben Mechanismus wie die integrierten Plugins für Typografie und Formulare.

## `PluginInterface`

Implementiere drei Methoden:

```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()` gibt den Bezeichner zurück, der in `@plugin "..."` verwendet wird.
- `__invoke()` führt das Plugin aus und registriert alles über `$api`. Das Array `$options` enthält die Werte aus dem `@plugin`-CSS-Block.
- `getThemeExtensions()` gibt Theme-Namespaces zurück, die vor dem Generieren der Utilities zusammengeführt werden (gib `[]` zurück, wenn keine vorhanden sind).

## Beispiel

```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
    }
}
```

## Referenz zu `PluginAPI`

Die API spiegelt die TailwindCSS-Plugin-API wider:

| Methode | Signatur | Zweck |
|--------|-----------|---------|
| `addBase` | `addBase(array $css): void` | Fügt Stile zur Basisebene hinzu. |
| `addUtilities` | `addUtilities(array $utilities, array $options = []): void` | Registriert statische Utility-Klassen anhand ihres Selektors. |
| `matchUtilities` | `matchUtilities(array $utilities, array $options = []): void` | Registriert funktionale Utilities; `$options['values']` stellt die Wertzuordnung bereit, `$options['supportsNegativeValues']` aktiviert negative Werte. |
| `addComponents` | `addComponents(array $components, array $options = []): void` | Registriert Komponentenklassen (Komponentenebene). |
| `matchComponents` | `matchComponents(array $components, array $options = []): void` | Registriert funktionale Komponenten mit einer Wertzuordnung. |
| `addVariant` | `addVariant(string $name, string\|array $variant): void` | Registriert eine statische Variante anhand eines Selektors. |
| `matchVariant` | `matchVariant(string $name, callable $callback, array $options = []): void` | Registriert eine funktionale Variante; `$options['values']` stellt die Wertzuordnung bereit. |
| `theme` | `theme(string $path, mixed $defaultValue = null): mixed` | Liest einen Theme-Wert anhand eines Punktpfads (e.g. `colors.blue.500`). |
| `config` | `config(?string $path = null, mixed $defaultValue = null): mixed` | Liest einen Konfigurationswert anhand eines Punktpfads oder die gesamte Konfiguration, wenn `$path` null ist. |
| `prefix` | `prefix(string $className): string` | Wendet das konfigurierte Präfix auf einen Klassennamen an. |

Der Callback für `matchUtilities`, `matchComponents` und `matchVariant` erhält den Wert sowie ein Array als zweites Argument, das einen `modifier`-Schlüssel enthält.

Wähle Utility-Namen, die Tailwind Core nicht bereits verwendet. Wenn ein Plugin-Utility denselben Namen wie ein Core-Utility hat (zum Beispiel `tab-*`, das Tailwind Core seit v4.3 für `tab-size` verwendet), landen beide Deklarationen in derselben Regel. Da die Core-Deklaration zuletzt kommt, hat sie Vorrang: Ein Plugin-`tab-4` mit der Zuordnung `7` erzeugt weiterhin `tab-size: 4`.

> **Bekanntes Problem:** Mit `addVariant()` registrierte Varianten und die von `matchVariant()` registrierten Varianten pro Wert werden in der aktuellen Version nicht angewendet. `hocus:flex` aus dem obigen Beispiel wird ohne `:hover`/`:focus`-Selektor zu `.hocus\:flex { display: flex; }` kompiliert ([#10](https://github.com/inline0/tailwindphp/issues/10)). Bis das behoben ist, definiere die Variante in CSS mit [`@custom-variant`](https://tailwindphp.inline0.dev/de/docs/usage/directives#custom-variant). Das funktioniert: `@custom-variant hocus (&:hover, &:focus);`.

## Registrieren und verwenden

Registriere die Plugin-Instanz und verweise anschließend auf den Namen aus `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";'
);
```

Weitere Informationen zur `@plugin`-Direktive und zum Laden findest du unter [Plugins](https://tailwindphp.inline0.dev/de/docs/plugins), zu den über `$api->theme()` bereitgestellten Werten unter [Theme](https://tailwindphp.inline0.dev/de/docs/usage/theme).
