# LiveComponents Slot System

Umfassende Dokumentation des Slot Systems für flexible Component-Komposition im Custom PHP Framework.

## Übersicht

Das Slot System ermöglicht es Components, flexible Bereiche zu definieren, in die Parent Components ihren eigenen Content einfügen können - ähnlich wie **Vue's Slots** oder **React's children/render props** Pattern.

**Key Features:**
- ✅ **Named Slots** - Spezifische Placement Points (header, footer, sidebar)
- ✅ **Default Slots** - Unnamed slot für allgemeinen Content
- ✅ **Scoped Slots** - Slots mit Zugriff auf Component-Daten via Context
- ✅ **Required Slots** - Validation dass notwendige Slots gefüllt sind
- ✅ **Default Content** - Fallback-Content wenn Slot nicht gefüllt wird
- ✅ **Content Processing** - Automatische Wrapper und Transformationen
- ✅ **Custom Validation** - Component-spezifische Slot-Validierung
- ✅ **XSS Protection** - Automatisches HTML-Escaping in Context-Values

## Architektur

```
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│ SlotDefinition  │───▶│  SlotManager    │───▶│  SlotProcessor  │
│ (What exists)   │    │  (Resolution)   │    │  (Rendering)    │
└─────────────────┘    └─────────────────┘    └─────────────────┘
         │                      │                        │
   SlotContent            SupportsSlots             DomProcessor
   (Provided)             (Component)               (Template)
         │                      │                        │
   SlotContext ──────────────────────────────────────────┘
   (Scoped Data)
```

## Kern-Komponenten

### 1. SlotDefinition - Slot-Definition Value Object

Definiert welche Slots in einer Component verfügbar sind.

```php
final readonly class SlotDefinition
{
    public function __construct(
        public string $name,                // Slot name (z.B. 'header', 'footer')
        public string $defaultContent = '', // Fallback content
        public array $props = [],           // Props für scoped slots
        public bool $required = false       // Pflicht-Slot?
    ) {}
}
```

**Factory Methods:**

```php
// Default (unnamed) Slot
SlotDefinition::default('<p>Default content</p>');

// Named Slot
SlotDefinition::named('header', '<h1>Default Header</h1>');

// Scoped Slot mit Props
SlotDefinition::scoped('content', ['userId', 'userName'], '<p>Default</p>');

// Required Slot
SlotDefinition::named('body')->withRequired(true);
```

**Beispiel:**

```php
public function getSlotDefinitions(): array
{
    return [
        SlotDefinition::named('header', '<h2>Default Header</h2>'),
        SlotDefinition::named('body')->withRequired(true),
        SlotDefinition::scoped('footer', ['closeFunction'], '<button onclick="{closeFunction}">Close</button>'),
    ];
}
```

---

### 2. SlotContent - Slot-Content Value Object

Repräsentiert den Content, der einen Slot füllt.

```php
final readonly class SlotContent
{
    public function __construct(
        public string $slotName,           // Name des Slots
        public string $content,            // HTML/Text content
        public array $data = [],           // Data für scoped slots
        public ?ComponentId $componentId = null // Optional: Component reference
    ) {}
}
```

**Factory Methods:**

```php
// Default slot content
SlotContent::default('<p>Main content</p>');

// Named slot content
SlotContent::named('header', '<h1>Custom Header</h1>');

// Named slot with data (for scoped slots)
SlotContent::named('content', '<p>{userName}</p>', ['userName' => 'John']);

// Content from component
SlotContent::fromComponent('header', $componentId, '<h1>Header</h1>');
```

**Hilfsmethoden:**

```php
$content = SlotContent::named('header', '<h1>Header</h1>');

$content->isDefault();          // false
$content->isEmpty();            // false
$content->hasData();            // false
$content->isFromComponent();    // false

// Content transformieren
$updated = $content->withContent('<h2>New Header</h2>');
$withData = $content->withData(['key' => 'value']);
```

---

### 3. SlotContext - Scoped Slot Context

Provides context/data to scoped slots, ermöglicht Parent Zugriff auf Child-Component-Daten.

```php
final readonly class SlotContext
{
    public function __construct(
        public array $data = [],      // Context data
        public array $metadata = []   // Additional metadata
    ) {}
}
```

**Factory Methods:**

```php
// Empty context
SlotContext::empty();

// Context with data
SlotContext::create([
    'userId' => 123,
    'userName' => 'John Doe',
    'isAdmin' => true,
]);

// Context with metadata
SlotContext::create(
    data: ['userId' => 123],
    metadata: ['timestamp' => time()]
);
```

**Fluent API:**

```php
$context = SlotContext::empty()
    ->with('userId', 123)
    ->with('userName', 'John Doe')
    ->withData(['role' => 'admin'])
    ->withMetadata(['version' => '1.0']);

// Zugriff
$userId = $context->get('userId');           // 123
$role = $context->get('role', 'guest');      // 'admin'
$hasUser = $context->has('userId');          // true

// Manipulation
$updated = $context->without('role');
$merged = $context1->merge($context2);
```

---

### 4. SupportsSlots Interface

Components die Slots unterstützen müssen dieses Interface implementieren.

```php
interface SupportsSlots
{
    /**
     * Get slot definitions for this component
     * @return array<SlotDefinition>
     */
    public function getSlotDefinitions(): array;

    /**
     * Get context data for a specific slot (scoped slots)
     */
    public function getSlotContext(string $slotName): SlotContext;

    /**
     * Process slot content before rendering
     */
    public function processSlotContent(SlotContent $content): SlotContent;

    /**
     * Validate that required slots are filled
     * @return array<string> Validation errors (empty if valid)
     */
    public function validateSlots(array $providedSlots): array;
}
```

**Implementierung:**

```php
final readonly class CardComponent implements LiveComponent, SupportsSlots
{
    public function getSlotDefinitions(): array
    {
        return [
            SlotDefinition::named('header', '<div class="card-header-default">Card Header</div>'),
            SlotDefinition::named('body')->withRequired(true),
            SlotDefinition::named('footer', ''),
        ];
    }

    public function getSlotContext(string $slotName): SlotContext
    {
        // Card doesn't need scoped slots
        return SlotContext::empty();
    }

    public function processSlotContent(SlotContent $content): SlotContent
    {
        // Apply card-specific CSS classes
        $wrappedContent = match ($content->slotName) {
            'header' => '<div class="card-header">' . $content->content . '</div>',
            'body' => '<div class="card-body">' . $content->content . '</div>',
            'footer' => '<div class="card-footer">' . $content->content . '</div>',
            default => $content->content
        };

        return $content->withContent($wrappedContent);
    }

    public function validateSlots(array $providedSlots): array
    {
        $errors = [];

        // Custom validation: warn if footer without header
        $hasHeader = false;
        $hasFooter = false;

        foreach ($providedSlots as $slot) {
            if ($slot->slotName === 'header') $hasHeader = true;
            if ($slot->slotName === 'footer') $hasFooter = true;
        }

        if ($hasFooter && !$hasHeader) {
            $errors[] = 'Card footer provided without header - consider adding a header';
        }

        return $errors;
    }
}
```

---

### 5. SlotManager - Core Slot Management

Zentrale Verwaltung von Slot-Resolution, Validation und Rendering.

```php
final class SlotManager
{
    /**
     * Register slot contents for a component
     */
    public function registerSlotContents(ComponentId $componentId, array $contents): void;

    /**
     * Get registered slot contents for a component
     * @return array<SlotContent>
     */
    public function getSlotContents(ComponentId $componentId): array;

    /**
     * Resolve slot content for rendering
     * Priority: Provided content > Default content
     */
    public function resolveSlotContent(
        SupportsSlots $component,
        SlotDefinition $definition,
        array $providedContents
    ): string;

    /**
     * Validate slots for a component
     * @return array<string> Validation errors (empty if valid)
     */
    public function validateSlots(SupportsSlots $component, array $providedContents): array;

    /**
     * Check if component has specific slot
     */
    public function hasSlot(SupportsSlots $component, string $slotName): bool;

    /**
     * Get slot definition by name
     */
    public function getSlotDefinition(SupportsSlots $component, string $slotName): ?SlotDefinition;

    /**
     * Clear all registered slot contents
     */
    public function clear(): void;

    /**
     * Get statistics about registered slots
     */
    public function getStats(): array;
}
```

**Resolution-Logik:**

1. **Find Provided Content** - Suche SlotContent für Slot-Name
2. **Process Content** - Führe `processSlotContent()` aus
3. **Inject Context** (bei scoped slots) - Ersetze `{context.key}` Placeholders
4. **Return Content** - Oder Default Content wenn nichts provided

**Context Injection:**

```php
// Scoped slot content
$content = '<p>User: {context.userName} (ID: {context.userId})</p>';

// Context data
$context = SlotContext::create([
    'userId' => 123,
    'userName' => 'John Doe',
]);

// After injection
// Result: '<p>User: John Doe (ID: 123)</p>'
```

---

### 6. SlotProcessor - Template Integration

DomProcessor für Template-Rendering mit Slot-Unterstützung.

```php
final readonly class SlotProcessor implements DomProcessor
{
    public function __construct(
        private SlotManager $slotManager
    ) {}

    public function process(DomWrapper $dom, RenderContext $context): DomWrapper
    {
        // Check if component supports slots
        if ($component instanceof SupportsSlots) {
            return $this->processWithSlotSystem($dom, $context, $component);
        }

        // Fallback to legacy slot processing
        return $this->processLegacySlots($dom, $context);
    }
}
```

**Features:**
- ✅ Integration mit SlotManager
- ✅ Backward compatibility (legacy slots)
- ✅ Automatic slot validation
- ✅ Error handling (development vs production)
- ✅ Context injection für scoped slots

---

## Slot-Patterns

### Pattern 1: Named Slots - Basic Layout Composition

**Use Case:** Component mit mehreren spezifischen Bereichen (Header, Body, Footer).

**Component Definition:**

```php
final readonly class CardComponent implements SupportsSlots
{
    public function getSlotDefinitions(): array
    {
        return [
            SlotDefinition::named('header', '<div class="card-header-default">Default Header</div>'),
            SlotDefinition::named('body')->withRequired(true),
            SlotDefinition::named('footer', ''),
        ];
    }
}
```

**Template:**

```html
<div class="card">
    <slot name="header">
        <div class="card-header-default">Default Header</div>
    </slot>

    <slot name="body"></slot>

    <slot name="footer"></slot>
</div>
```

**Usage:**

```html
<component name="card" id="user-card">
    <slot name="header">
        <h2>User Profile</h2>
        <p>John Doe</p>
    </slot>

    <slot name="body">
        <p><strong>Email:</strong> john@example.com</p>
        <p><strong>Role:</strong> Administrator</p>
    </slot>

    <slot name="footer">
        <button>Edit Profile</button>
        <button>View Activity</button>
    </slot>
</component>
```

**Result:**
- ✅ Custom header mit User-Info
- ✅ Custom body mit Details
- ✅ Custom footer mit Actions
- ✅ Alle Slots mit CSS-Wrappern via `processSlotContent()`

---

### Pattern 2: Default Slot - Unnamed Content

**Use Case:** Container-Component die beliebigen Content aufnimmt.

**Component Definition:**

```php
final readonly class ContainerComponent implements SupportsSlots
{
    public function getSlotDefinitions(): array
    {
        return [
            SlotDefinition::default('<div class="empty-container">No content</div>'),
            SlotDefinition::named('title'),
            SlotDefinition::named('actions', ''),
        ];
    }
}
```

**Template:**

```html
<div class="container">
    <slot name="title">
        <h2>Container</h2>
    </slot>

    <!-- Default slot: all unnamed content goes here -->
    <slot>
        <div class="empty-container">No content provided</div>
    </slot>

    <slot name="actions"></slot>
</div>
```

**Usage:**

```html
<component name="container" id="wrapper">
    <slot name="title">
        <h2>Welcome Container</h2>
    </slot>

    <!-- This goes into the default slot -->
    <h1>Welcome to the Platform</h1>
    <p>This is the main content.</p>
    <p>All unnamed content appears in the default slot.</p>

    <slot name="actions">
        <button>Get Started</button>
        <button>Learn More</button>
    </slot>
</component>
```

**Result:**
- ✅ Named slots (title, actions) für spezifischen Content
- ✅ Default slot für flexiblen, unstrukturierten Content
- ✅ Fallback Content wenn Default Slot leer

---

### Pattern 3: Scoped Slots - Component Data Access

**Use Case:** Parent braucht Zugriff auf Child-Component-Daten (z.B. Modal ID, Close Function).

**Component Definition:**

```php
final readonly class ModalComponent implements SupportsSlots
{
    public function getSlotDefinitions(): array
    {
        return [
            SlotDefinition::named('title', '<h3>Modal Title</h3>'),
            SlotDefinition::scoped('content', ['modalId', 'isOpen', 'closeFunction'])->withRequired(true),
            SlotDefinition::scoped('actions', ['closeFunction', 'modalId']),
        ];
    }

    public function getSlotContext(string $slotName): SlotContext
    {
        $modalId = $this->id->toString();
        $isOpen = $this->state->get('isOpen', false);

        return match ($slotName) {
            'content', 'actions' => SlotContext::create([
                'modalId' => $modalId,
                'isOpen' => $isOpen,
                'closeFunction' => "closeModal('{$modalId}')",
            ]),
            default => SlotContext::empty()
        };
    }
}
```

**Template:**

```html
<div class="modal" data-modal-id="{component.id}">
    <slot name="title">
        <h3>Modal Title</h3>
    </slot>

    <!-- Scoped slot: parent can access context -->
    <slot name="content"></slot>

    <!-- Scoped slot: parent can use closeFunction -->
    <slot name="actions">
        <button onclick="{context.closeFunction}">Close</button>
    </slot>
</div>
```

**Usage:**

```html
<component name="modal" id="confirm-delete-modal">
    <slot name="title">
        <h3>Confirm Delete</h3>
    </slot>

    <slot name="content">
        <p>Are you sure you want to delete this item?</p>
        <p>This action cannot be undone.</p>
        <!-- Access component data via {context.key} -->
        <p><small>Modal ID: {context.modalId}</small></p>
    </slot>

    <slot name="actions">
        <!-- Use component's close function -->
        <button onclick="{context.closeFunction}">Cancel</button>
        <button class="btn-danger">Delete</button>
    </slot>
</component>
```

**Result:**
- ✅ Parent-Slot-Content hat Zugriff auf Child-Component-Daten
- ✅ `{context.modalId}` wird durch echte Modal-ID ersetzt
- ✅ `{context.closeFunction}` wird durch `closeModal('modal-id')` ersetzt
- ✅ XSS-Protection: Alle Context-Values werden HTML-escaped

---

### Pattern 4: Complex Layout - Multi-Slot Composition

**Use Case:** Page-Layout mit mehreren Bereichen (Header, Sidebar, Main, Footer).

**Component Definition:**

```php
final readonly class LayoutComponent implements SupportsSlots
{
    public function getSlotDefinitions(): array
    {
        return [
            SlotDefinition::scoped('sidebar', ['sidebarWidth', 'isCollapsed'], '<aside>Default Sidebar</aside>'),
            SlotDefinition::named('main')->withRequired(true),
            SlotDefinition::named('footer', '<footer>Default Footer</footer>'),
            SlotDefinition::named('header', ''),
        ];
    }

    public function getSlotContext(string $slotName): SlotContext
    {
        $sidebarWidth = $this->state->get('sidebarWidth', '250px');
        $isCollapsed = $this->state->get('sidebarCollapsed', false);

        return match ($slotName) {
            'sidebar' => SlotContext::create([
                'sidebarWidth' => $sidebarWidth,
                'isCollapsed' => $isCollapsed,
            ]),
            default => SlotContext::empty()
        };
    }
}
```

**Usage:**

```html
<component name="layout" id="dashboard-layout">
    <slot name="header">
        <header class="app-header">
            <h1>My Application</h1>
            <nav>...</nav>
        </header>
    </slot>

    <slot name="sidebar">
        <!-- Scoped: access layout dimensions -->
        <aside style="width: {context.sidebarWidth}">
            <nav class="sidebar-nav">
                <ul>
                    <li><a href="/dashboard">Dashboard</a></li>
                    <li><a href="/users">Users</a></li>
                    <li><a href="/settings">Settings</a></li>
                </ul>
            </nav>
        </aside>
    </slot>

    <slot name="main">
        <main class="main-content">
            <h2>Dashboard</h2>
            <p>Welcome to your dashboard!</p>
        </main>
    </slot>

    <slot name="footer">
        <footer class="app-footer">
            <p>&copy; 2025 My Application</p>
        </footer>
    </slot>
</component>
```

---

## Slot Validation

### Required Slots

```php
SlotDefinition::named('body')->withRequired(true);
```

**Validation:**
- ✅ Automatische Prüfung via `SlotManager::validateSlots()`
- ✅ Fehler wenn Required Slot nicht gefüllt oder leer
- ✅ Validation-Errors als Array zurückgegeben

**Error Handling:**

```php
$errors = $slotManager->validateSlots($component, $providedSlots);

if (!empty($errors)) {
    // Development: Show errors
    // Production: Log errors
    foreach ($errors as $error) {
        error_log("Slot validation error: $error");
    }
}
```

### Custom Validation

Components können eigene Validation-Logik in `validateSlots()` implementieren:

```php
public function validateSlots(array $providedSlots): array
{
    $errors = [];

    // Custom logic: warn if footer without header
    $hasHeader = false;
    $hasFooter = false;

    foreach ($providedSlots as $slot) {
        if ($slot->slotName === 'header') $hasHeader = true;
        if ($slot->slotName === 'footer') $hasFooter = true;
    }

    if ($hasFooter && !$hasHeader) {
        $errors[] = 'Card footer provided without header - visual consistency issue';
    }

    return $errors;
}
```

---

## Content Processing

### Automatic Wrapping

Components können Slot-Content automatisch wrappen via `processSlotContent()`:

```php
public function processSlotContent(SlotContent $content): SlotContent
{
    $wrappedContent = match ($content->slotName) {
        'header' => '<div class="card-header">' . $content->content . '</div>',
        'body' => '<div class="card-body">' . $content->content . '</div>',
        'footer' => '<div class="card-footer">' . $content->content . '</div>',
        default => $content->content
    };

    return $content->withContent($wrappedContent);
}
```

**Result:**
- ✅ Automatische CSS-Wrapper für jeden Slot
- ✅ Konsistentes Styling ohne manuelle Wrapper im Parent
- ✅ Component-spezifische Transformationen

### State-Based Processing

```php
public function processSlotContent(SlotContent $content): SlotContent
{
    // Get padding from state
    $padding = $this->state->get('padding', 'medium');
    $paddingClass = 'container-padding-' . $padding;

    $wrappedContent = match ($content->slotName) {
        'default' => "<div class=\"container-content {$paddingClass}\">" . $content->content . '</div>',
        default => $content->content
    };

    return $content->withContent($wrappedContent);
}
```

---

## Security

### XSS Protection

**Automatic HTML Escaping** in scoped context values:

```php
private function formatValue(mixed $value): string
{
    if (is_scalar($value)) {
        return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
    }

    if (is_array($value)) {
        return htmlspecialchars(json_encode($value), ENT_QUOTES, 'UTF-8');
    }

    return '';
}
```

**Result:**
- ✅ Alle Context-Values werden automatisch escaped
- ✅ `<script>` → `&lt;script&gt;`
- ✅ Schutz vor XSS-Attacken via Scoped Slots

**Beispiel:**

```php
// Malicious context value
$context = SlotContext::create([
    'userInput' => '<script>alert("XSS")</script>',
]);

// In slot content
'<p>{context.userInput}</p>'

// After injection (safe!)
'<p>&lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;</p>'
```

---

## Best Practices

### 1. Slot Design

**✅ DO:**
- Klare Slot-Namen verwenden (`header`, `body`, `footer` statt `slot1`, `slot2`)
- Default Content für alle Optional Slots definieren
- Required Slots nur für essentiellen Content
- Scoped Slots für Component-Daten die Parent braucht

**❌ DON'T:**
- Zu viele Slots definieren (max. 5-6 für Übersichtlichkeit)
- Alle Slots als Required markieren
- Sensitive Daten in Scoped Context legen
- Komplexe Logik in `processSlotContent()`

### 2. Content Processing

**✅ DO:**
- Automatische Wrapper für konsistentes Styling
- State-basierte Transformationen (padding, themes)
- Slot-spezifische CSS-Klassen
- Immutable Content-Transformationen (`withContent()`)

**❌ DON'T:**
- Content manipulieren ohne `withContent()`
- Seiteneffekte in `processSlotContent()`
- Zu aggressive Transformationen
- Parent-Content überschreiben

### 3. Validation

**✅ DO:**
- Required Slots für kritischen Content
- Custom Validation für logische Konsistenz
- Hilfreiche Error-Messages
- Validation in Development zeigen, in Production loggen

**❌ DON'T:**
- Validation-Errors swallowing
- Generische Error-Messages
- Validation-Logic in Templates
- Performance-intensive Validation

### 4. Scoped Slots

**✅ DO:**
- Nur notwendige Daten in Context legen
- HTML-Escaping ist automatisch (vertrauen)
- Dokumentierte Context-Props in SlotDefinition
- Klare Naming Convention (`{context.key}`)

**❌ DON'T:**
- Sensitive Daten in Context (Passwords, Tokens)
- Zu viele Context-Props (max. 5-6)
- Komplexe Objekte in Context
- Manual HTML-Escaping (ist redundant)

---

## Testing

### Unit Tests - SlotManager

```php
it('resolves provided content over default content', function () {
    $component = new TestComponent();
    $definition = SlotDefinition::named('header', '<h2>Default</h2>');
    $providedContent = [
        SlotContent::named('header', '<h1>Custom</h1>'),
    ];

    $result = $this->slotManager->resolveSlotContent(
        $component,
        $definition,
        $providedContent
    );

    expect($result)->toBe('<h1>Custom</h1>');
});
```

### Integration Tests - Components

```php
it('renders CardComponent with custom slots', function () {
    $component = new CardComponent(
        id: ComponentId::generate(),
        state: ComponentState::fromArray([])
    );

    $providedSlots = [
        SlotContent::named('header', '<h2>User Profile</h2>'),
        SlotContent::named('body', '<p>User details...</p>'),
    ];

    $errors = $this->slotManager->validateSlots($component, $providedSlots);
    expect($errors)->toBeEmpty();
});
```

### Template Tests

```php
it('processes slots in template', function () {
    $html = '<component name="card">
        <slot name="header"><h1>Header</h1></slot>
        <slot name="body"><p>Body</p></slot>
    </component>';

    $result = $this->templateRenderer->render($html, [
        'component' => new CardComponent(...),
    ]);

    expect($result)->toContain('card-header');
    expect($result)->toContain('card-body');
});
```

---

## Troubleshooting

### Problem: Slot Content wird nicht angezeigt

**Ursache:** Slot-Name stimmt nicht überein.

**Lösung:**
```php
// Check slot definitions
$slotNames = $this->slotManager->getSlotNames($component);
var_dump($slotNames); // ['header', 'body', 'footer']

// Verify provided content
foreach ($providedSlots as $slot) {
    echo $slot->slotName; // Muss mit Definition übereinstimmen
}
```

### Problem: Scoped Context wird nicht injiziert

**Ursache:** Slot nicht als Scoped definiert.

**Lösung:**
```php
// ❌ WRONG: Named slot (no context injection)
SlotDefinition::named('content');

// ✅ CORRECT: Scoped slot with props
SlotDefinition::scoped('content', ['modalId', 'closeFunction']);
```

### Problem: XSS in Context Values

**Ursache:** Custom formatValue() ohne Escaping.

**Lösung:**
```php
// ❌ WRONG: No escaping
private function formatValue(mixed $value): string
{
    return (string) $value; // XSS vulnerability!
}

// ✅ CORRECT: Automatic escaping
private function formatValue(mixed $value): string
{
    if (is_scalar($value)) {
        return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
    }
    return '';
}
```

### Problem: Required Slot Validation schlägt fehl

**Ursache:** Slot ist empty oder nur Whitespace.

**Lösung:**
```php
// Check if slot is truly empty
$content = SlotContent::named('body', '   ');
if ($content->isEmpty()) {
    // Will fail required validation
}

// ✅ Provide actual content
SlotContent::named('body', '<p>Content</p>');
```

---

## Performance

### Slot Resolution Performance

**Typical Performance:**
- Slot Resolution: < 1ms per slot
- Context Injection: < 0.5ms per placeholder
- Validation: < 2ms für 5-6 slots
- Total Overhead: < 5ms per component

**Optimizations:**
- ✅ Slot definitions gecached in Component
- ✅ Keine Reflection für Slot-Discovery
- ✅ Simple string replacement für Context
- ✅ Minimal regex usage

### Best Practices für Performance

**✅ DO:**
- Slot definitions im Constructor definieren
- Simple Context-Values (strings, ints)
- Cached Component-Instances
- Minimal Validation-Logic

**❌ DON'T:**
- Dynamic Slot-Definitions
- Complex Objects in Context
- Database-Queries in `getSlotContext()`
- Expensive Transformations in `processSlotContent()`

---

## Migration Guide

### Von Legacy Slots zu Slot System

**Before (Legacy):**

```php
final class OldCard
{
    public function render(array $slots): string
    {
        $header = $slots['header'] ?? '<h2>Default</h2>';
        $body = $slots['body'] ?? '';

        return "<div class='card'>$header $body</div>";
    }
}
```

**After (Slot System):**

```php
final readonly class NewCard implements SupportsSlots
{
    public function getSlotDefinitions(): array
    {
        return [
            SlotDefinition::named('header', '<h2>Default</h2>'),
            SlotDefinition::named('body')->withRequired(true),
        ];
    }

    public function processSlotContent(SlotContent $content): SlotContent
    {
        // Automatic wrapping
        $wrapped = "<div class='card-{$content->slotName}'>{$content->content}</div>";
        return $content->withContent($wrapped);
    }
}
```

**Benefits:**
- ✅ Type-safe Slot-Definitionen
- ✅ Automatische Validation
- ✅ Scoped Slots Support
- ✅ Content Processing Hooks
- ✅ Better Developer Experience

---

## Zusammenfassung

Das **Slot System** bietet eine flexible, typsichere Lösung für Component-Komposition:

**✅ Features:**
- Named, Default und Scoped Slots
- Required Slots mit Validation
- Default Content Fallbacks
- Automatic Content Processing
- XSS Protection
- Custom Validation Hooks
- Template Integration
- Backward Compatibility

**✅ Architecture:**
- Value Objects für Type Safety
- SlotManager für Orchestration
- SupportsSlots Interface für Components
- SlotProcessor für Template-Rendering
- Framework-compliant (readonly, final, composition)

**✅ Use Cases:**
- Layout Components (Header/Sidebar/Main/Footer)
- Modal/Dialog Components
- Card/Container Components
- Complex Nested Compositions
- Dynamic Content Injection

**Nächste Schritte:**
- Weitere Example Components erstellen
- Performance Optimizations
- Advanced Caching für Slot-Resolution
- Visual Slot Editor (optional)
