Files
michaelschiemer/docs/claude/x-component-syntax.md
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

7.9 KiB

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)

<x-datatable id="users" page="1" pageSize="25" />
<x-counter id="demo" initialValue="0" />

HTML Components (Static)

<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

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

<!-- 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

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

<!-- 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:

<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

<!-- 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)

<include template="livecomponent-datatable" data="{id: 'users', page: 1}" />

Neu

<x-datatable id="users" page="1" />

Von <x-button> (FrameworkComponentProcessor)

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

<!-- 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

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

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

<!-- 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! 🎉