# X-Component Syntax

**Unified component system** für LiveComponents und HTML Components mit moderner `<x-*>` Syntax.

## Übersicht

Der **XComponentProcessor** handelt beide Komponenten-Typen automatisch:

### **LiveComponents** (Interactive/Stateful)
```html
<x-datatable id="users" page="1" pageSize="25" />
<x-counter id="demo" initialValue="0" />
```

### **HTML Components** (Static)
```html
<x-button variant="primary">Submit</x-button>
<x-card title="Profile">Content here</x-card>
```

---

## Auto-Detection

Der Processor erkennt **automatisch** welcher Komponenten-Typ verwendet werden soll:

```
1. Prüfe: Ist LiveComponent mit #[LiveComponent] registriert?
   → Ja: Process as LiveComponent (stateful)

2. Prüfe: Ist HTML Component mit #[ComponentName] registriert?
   → Ja: Process as HTML Component (static)

3. Keins gefunden?
   → Error with helpful message
```

---

## LiveComponents

### Definition
```php
use App\Framework\LiveComponents\Attributes\LiveComponent;
use App\Framework\LiveComponents\Contracts\LiveComponentContract;

#[LiveComponent(name: 'datatable')]
final readonly class DataTableComponent implements LiveComponentContract
{
    public function __construct(
        private ComponentId $id,
        private ?ComponentData $initialData = null
    ) {}

    #[Action]
    public function changePage(int $page): void
    {
        // Interactive behavior
    }

    public function getRenderData(): RenderData
    {
        return new RenderData(
            templatePath: 'livecomponent-datatable',
            data: [
                'page' => $this->getData()->get('page'),
                'items' => $this->loadItems()
            ]
        );
    }
}
```

### Usage
```html
<!-- Basic usage -->
<x-datatable id="users" page="1" pageSize="25" />

<!-- Type coercion -->
<x-datatable
    id="users"           <!-- string: "users" -->
    page="1"             <!-- int: 1 -->
    pageSize="25"        <!-- int: 25 -->
    sortAsc="true"       <!-- bool: true -->
    filters='["active"]' <!-- array: ["active"] -->
/>

<!-- Rendered output (with state wrapper) -->
<div
    data-component-id="datatable:users"
    data-component-state='{"page":1,"pageSize":25}'
>
    <!-- Component HTML -->
</div>
```

### Features
- ✅ **Stateful**: Komponente behält State
- ✅ **Interactive**: `#[Action]` Methods für User-Interaktion
- ✅ **Type Coercion**: Automatische Typ-Konvertierung
- ✅ **Prop Validation**: Validierung gegen ComponentMetadata
- ✅ **SSE Support**: Server-Sent Events für Realtime Updates

---

## HTML Components

### Definition
```php
use App\Framework\View\Attributes\ComponentName;
use App\Framework\View\ValueObjects\HtmlElement;

#[ComponentName(tag: 'button')]
final readonly class Button extends HtmlElement
{
    public function __construct(
        private string $content,
        private string $variant = 'default'
    ) {}

    public function withVariant(string $variant): self
    {
        return new self($this->content, $variant);
    }

    public function __toString(): string
    {
        return sprintf(
            '<button class="btn btn-%s">%s</button>',
            $this->variant,
            htmlspecialchars($this->content)
        );
    }
}
```

### Usage
```html
<!-- Basic usage -->
<x-button>Click me</x-button>

<!-- With variant modifier -->
<x-button variant="primary">Submit</x-button>

<!-- Rendered output (static HTML) -->
<button class="btn btn-primary">Submit</button>
```

### Features
- ✅ **Stateless**: Einfache HTML-Generierung
- ✅ **Factory Methods**: Static constructors für Variants
- ✅ **Modifiers**: Fluent API mit `withX()` Methods
- ✅ **Type Safe**: PHP Classes statt Template Strings

---

## Type Coercion (LiveComponents only)

LiveComponents supporten automatische Typ-Konvertierung:

```html
<x-component
    string="text"           <!-- "text" -->
    int="123"               <!-- 123 -->
    float="12.5"            <!-- 12.5 -->
    bool-true="true"        <!-- true -->
    bool-false="false"      <!-- false -->
    null-value="null"       <!-- null -->
    array='[1,2,3]'         <!-- [1,2,3] -->
    object='{"key":"val"}'  <!-- ["key" => "val"] -->
/>
```

**HTML Components** erhalten alle Attribute als **Strings**.

---

## Error Handling

### Development Mode
```html
<!-- Invalid component -->
<x-unknown id="test" />

<!-- Error display -->
<div style="border:2px solid red;...">
  <strong>XComponentProcessor Error:</strong>
  <pre>
    Unknown component: <x-unknown>

    Available LiveComponents: datatable, counter, chart
    Available HTML Components: button, card, badge
  </pre>
</div>
```

### Production Mode
- Component wird **entfernt** (silent fail)
- Error wird **geloggt** (optional)
- Kein Crash, Seite funktioniert weiter

---

## Migration von alten Syntaxen

### Von `<include>` zu `<x-*>`

#### Alt (LiveComponents)
```html
<include template="livecomponent-datatable" data="{id: 'users', page: 1}" />
```

#### Neu
```html
<x-datatable id="users" page="1" />
```

### Von `<x-button>` (FrameworkComponentProcessor)

**Keine Migration nötig!** Der neue XComponentProcessor handelt das automatisch.

```html
<!-- Works the same -->
<x-button variant="primary">Click</x-button>
```

---

## Best Practices

### LiveComponents
1. **Explizite IDs**: Verwende aussagekräftige `id` Attribute
2. **Type Hints**: Nutze ComponentMetadata für Prop-Validierung
3. **State Management**: Halte State minimal und serialisierbar
4. **Actions**: Präfixe Action-Methods mit Action-Verben

### HTML Components
1. **Factory Methods**: Nutze static factories für Variants
2. **Immutability**: Komponenten sollten readonly sein
3. **Modifiers**: Fluent API mit `withX()` Methods
4. **Type Safety**: Return type `self` für Modifiers

---

## Performance

### LiveComponents
- **First Render**: ~5-10ms (inkl. ComponentRegistry + Rendering)
- **Updates**: ~2-5ms (nur State Update + Re-Render)
- **Caching**: Optional via `Cacheable` Interface

### HTML Components
- **Rendering**: ~0.5-1ms (Pure PHP, kein I/O)
- **No Overhead**: Direkt zu HTML compiled

---

## Testing

### LiveComponent Test
```php
it('renders datatable component via x-syntax', function() {
    $html = '<x-datatable id="test" page="1" />';

    $result = $this->processor->process($dom, $context);

    expect($result)->toContain('data-component-id="datatable:test"');
    expect($result)->toContain('data-component-state');
});
```

### HTML Component Test
```php
it('renders button component via x-syntax', function() {
    $html = '<x-button variant="primary">Click</x-button>';

    $result = $this->processor->process($dom, $context);

    expect($result)->toBe('<button class="btn btn-primary">Click</button>');
});
```

---

## Troubleshooting

### Component nicht gefunden
```
Unknown component: <x-foo>

Available LiveComponents: datatable, counter
Available HTML Components: button, card
```

**Lösung**:
1. Prüfe `#[LiveComponent]` oder `#[ComponentName]` Attribute
2. Prüfe dass Component-Name korrekt ist
3. Prüfe dass Discovery System läuft

### Props werden nicht erkannt
```
LiveComponent 'datatable' has no property 'pagesize'
Available properties: page, pageSize, sortBy
```

**Lösung**:
- Prüfe Schreibweise (Case-Sensitive!)
- Prüfe ComponentMetadata

### Type Coercion funktioniert nicht
```html
<!-- Problem: "1" bleibt String -->
<x-datatable page="1" />
```

**Lösung**:
- Nur für **LiveComponents**!
- HTML Components erhalten Strings
- Prüfe dass Component LiveComponent ist

---

## Zusammenfassung

| Feature | LiveComponents | HTML Components |
|---------|---------------|----------------|
| **Syntax** | `<x-name />` | `<x-name>content</x-name>` |
| **State** | ✅ Stateful | ❌ Stateless |
| **Interactivity** | ✅ Actions | ❌ Static HTML |
| **Type Coercion** | ✅ Automatic | ❌ Strings only |
| **Validation** | ✅ Via Metadata | ❌ No validation |
| **Performance** | ~5-10ms | ~0.5-1ms |
| **Use Case** | Complex UI | Simple HTML |

**Both use the same `<x-*>` syntax!** 🎉
