# Leadity Vertrag für Komponentenkomposition

Status: verbindlicher Querschnittsvertrag für alle Komponentenpakete. `DESIGN.md` bleibt die kanonische Kurzfassung. Dieser Vertrag definiert strukturelles Eigentum, zulässige Verschachtelung und die technische Prüfung gegen lokale Nachbauten.

## 1. Grundsatz

Komplexe Komponenten komponieren ausschließlich registrierte Basiskomponenten. Gemeinsame CSS-Klassen oder kopiertes HTML gelten nicht als Komponentenwiederverwendung.

- Eine **Primitive** besitzt ihr internes DOM, ihre Zustände und ihre zugängliche Semantik selbst.
- Ein **Composite** ordnet registrierte Kinder an und übergibt ausschließlich Props, Daten, Ereignisse und dokumentierte Slots.
- Eine Seite beziehungsweise ein Template konfiguriert Composites. Es erzeugt deren interne Controls nicht selbst.
- Existiert eine registrierte Komponente, ist ein lokaler DOM-Nachbau derselben Semantik unzulässig.

## 2. Eigentum und Quellen

- Die ausführbare Registry liegt in `ui_kits/app/component-registry.js`.
- Jeder Eintrag benennt Komponentenname, Custom-Element-Tag, Typ `primitive|composite`, Figma-Node und zulässige Kinder.
- Komponenten-Markup wird ausschließlich im Renderer der besitzenden Komponente erzeugt.
- Verhaltenslayer wie `filter-form-controls.js` binden Ereignisse und Zustände. Benötigen sie sichtbare Unterkomponenten, instanziieren sie diese über `LeadityComponents.create()`.
- HTML-Templates und Previews verwenden Custom Elements sowie Props beziehungsweise fachliche Daten. Sie enthalten keine kopierten internen Komponentenunterbäume.

## 3. Verbindlicher Filterbaum

```text
FilterCard
├─ Select · Sortierung
├─ FilterPopover
│  ├─ Multiselect · Verantwortliche Person
│  ├─ Multiselect · Bearbeitungsstatus
│  ├─ DatePicker · Fällig bis
│  ├─ Select · Delegiert
│  ├─ Select · Nachhaltigkeitsdimension
│  └─ Toggle · Gesetzte Filter merken
└─ FilterElement[]
   └─ FilterRemove
```

Die FilterCard besitzt Toolbar, aktive Filterzone, Live-Region und Popover-Komposition. Seiten liefern Schnellfilter, Sortieroptionen, ID-Präfixe und fachliche Optionsdaten.

## 3.1 Verbindlicher Dropdown- und Listenbaum

```text
LanguageSelect
└─ Select · Controlled OpenState

SelectWithChip
├─ Select · Controlled OpenState
└─ Chip · Paket-5-Icon-Chip

SelectWithButton
├─ Select · Controlled OpenState
└─ FieldAction · Bearbeiten, nur Filled
```

ListBox und Yearpicker sind eigenständige Registry-Primitives. Verbraucher liefern ausschließlich Props, Optionsdaten und reale Assetpfade; rohe Listen-, Jahresraster-, Flaggen-Select- oder Aktionsunterbäume sind unzulässig.

## 3.2 Verbindlicher Auswahlbaum

```text
ChoiceGroup
├─ Checkbox[] · native Checkbox innerhalb der Primitive
└─ Radio[] · natives Radio innerhalb der Primitive
```

Checkbox und Radio besitzen ihre sichtbare Geometrie, Zustände, Labels und mindestens 40 px wirksame Trefferfläche selbst. Data-, Task- und Template-Verbraucher dürfen fachliche Datenattribute und Kontextklassen an den inneren nativen Input übergeben, aber keine zweite Kontrollschale zeichnen.

## 3.3 Verbindliche Spezialfeld-Eigentümer

Search, Password, Slider und InputGroup sind eigenständige Registry-Primitives. Ihre internen Icons, Aktionen, Inputs, Tracks, Popoverinhalte und Addons gehören vollständig dem jeweiligen Renderer. InputDate bleibt Eigentum von DatePicker. Der Verhaltenslayer darf Werte und ARIA-Zustände synchronisieren, aber keine sichtbaren Unterbäume erzeugen.

## 3.4 Verbindlicher Elementsteuerungsbaum

```text
DragHandle · Primitive

DotMenu · Composite
└─ MenuItem[] · Primitive
```

Data-, Task- und Template-Verbraucher liefern ausschließlich IDs, zugängliche Labels, fachliche Aktionen und Sortierdaten. Trigger, Font-Awesome-Glyph, Popover und Menüeinträge gehören vollständig den registrierten Komponenten. Der gemeinsame Overlay-Layer steuert Positionierung und Schließen; `item-controls.js` steuert Sortierung und Menütastatur.

## 3.5 Verbindlicher Inhaltsstrukturbaum

```text
TabContainer · Composite
├─ Tab[] · Primitive
└─ optional DotMenu · registriertes Composite

Splitter · Separator-Primitive
└─ SplitterPanel[2] · Composite

Accordion · Composite
└─ AccordionItem[] · Composite
   ├─ AccordionHeader · Primitive
   └─ fachlicher Panel-Slot

Stepper · Composite
└─ StepperStep[] · Primitive
```

Tabbuttons, Auswahlzustand, Overflow-Steuerung und Panelzuordnung gehören dem registrierten TabContainer. Accordion-Header, Öffnungszustand und Headernavigation gehören dem registrierten Accordion; Verbraucher liefern nur Labels und fachliche Panel-Slots. Schrittmarken, Verbindungslinien, aktueller Index und optionale Rücksprungaktionen gehören dem registrierten Stepper. Splitter-Separator, Größenwert und Pointer-/Tastaturbindung gehören dem registrierten Splitter. Rohe Tablisten, Accordion-/Stepper-Unterbäume, lokale Separatoren und parallele Renderer sind unzulässig. Der Detailvertrag steht in `content-structure-contract.md`.

## 4. Zustands- und Datenvertrag

- Props und Daten bleiben getrennt vom internen DOM.
- Komponenten besitzen eindeutige, aus dem Instanzpräfix abgeleitete IDs.
- Rohwert, sichtbarer Wert und Mehrfachauswahlstatus werden nicht über DOM-Text als gemeinsame Ersatzquelle vermischt.
- Select, Multiselect und DatePicker besitzen ihre kontrollierten Open-Renderer, Proxywerte, `aria-expanded`-/`aria-selected`-Bindung und Tastaturführung selbst. FilterPopover darf weder native Browser-Open-States erzwingen noch Listen- oder Kalender-DOM lokal ergänzen.
- `empty`, `filled`, `multiple` und `open` sind unabhängige Zustandsdimensionen. Das Öffnen eines leeren Controls setzt den Feldzustand nicht auf `filled`.
- Verhalten sucht Controls innerhalb der besitzenden Komponenteninstanz. Globale Selektoren zwischen mehreren Instanzen sind unzulässig.
- Dynamisch erzeugte sichtbare Komponenten werden über die Registry instanziiert; `innerHTML` ist kein Komponenten-Renderer.

## 5. Figma-zu-Code-Ablauf

1. Vor der Umsetzung einer komplexen Figma-Komponente ihren Instanzbaum erfassen.
2. Jedes verschachtelte Kind auf einen Registry-Eintrag oder einen bestätigten produktiven Adapter abbilden.
3. Fehlende Zuordnungen als Blocker beziehungsweise Designsystem-Lücke dokumentieren; nicht approximieren.
4. Primitive Zustände zuerst verifizieren, danach das Composite zusammensetzen.
5. Komponentenreferenz, Template und Preview aus derselben Quelle instanziieren.

## 6. P0-Prüfung

`scripts/verify-component-composition.mjs` muss ohne Fehler durchlaufen.

Die Prüfung blockiert mindestens:

- rohe FilterCard- oder FilterPopover-Container in HTML-Dateien;
- kopierte Popover-Unterstrukturen und interne Filterbindungen in Verbrauchern;
- lokale `renderFilters()`-Implementierungen;
- fehlende Registry-Abhängigkeiten;
- DOM-Erzeugung von FilterElement oder FilterRemove außerhalb ihrer registrierten Renderer.
- fehlende zentrale Empty-/Open-Bindung, browserabhängige Filter-Dropdowns oder ein automatischer Suchfokus, der den belegten Open-State verändert.
- rohe ListBox-, Yearpicker-, Language-Select- oder Select-Composite-Unterbäume in HTML-Verbrauchern.
- fehlende Registry-Abhängigkeiten für LanguageSelect, SelectWithChip und SelectWithButton oder sichtbare native Language-Selects.
- lokal erzeugte Jahresbuttons, lokale Statuschip-Ersatzflächen oder eine Plus-Aktion im SelectWithButton.
- rohe Checkbox-/Radio-Inputs in HTML-Verbrauchern, fehlende Registry-Scripts oder lokale 16-/20-px-Auswahlgeometrien in Data-/Task-Styles.
- ChoiceGroup-Unterbäume, die Checkbox- oder Radio-Markup statt registrierter Kinder erzeugen.
- rohe Search-, Password-, Slider- oder InputGroup-Unterbäume in HTML-Verbrauchern sowie sichtbare Spezialfeld-DOM-Erzeugung im Verhaltenslayer.
- parallele InputDate-Renderer, zwei sichtbare Range-Wertfelder oder Passwortkriterien außerhalb der Password-Primitive.
- rohe `.task-dot-menu`-, `.task-menu-list`-, `.task-menu-item`- oder `data-drag-handle`-Unterbäume in HTML-Verbrauchern.
- fehlende Registry-Abhängigkeiten für `DotMenu → MenuItem` oder nicht registrierte DragHandle-/DotMenu-Instanzen.
- rohe `data-local-tabs`-, `.leadity-local-tab*`-, lokale Accordion-/Stepper- oder lokale Splitter-Unterbäume in HTML-Verbrauchern.
- fehlende Registry-Abhängigkeiten für `TabContainer → Tab`, `Accordion → AccordionItem → AccordionHeader`, `Stepper → StepperStep` und `Splitter → SplitterPanel` oder Verbraucher ohne `content-structure.css` und `content-structure.js`.

Neue Komponentenpakete erweitern Manifest und Prüfer gemeinsam. Eine nur dokumentierte Regel ohne maschinenlesbares Gate schließt kein Prüfpaket.

## 7. Produktionsadapter

Die statische OpenDesign-Registry bildet den ausführbaren Vertrag ab. `integrations/production-mapping.json` ordnet alle 42 Registry-Einträge am unveränderlichen Frontend-Commit den realen Vue-Dateien, PrimeVue-Primitives, Props, Events, Zuständen und Abhängigkeiten zu. `references/production-adapter-contract.md` definiert die Statussemantik und Aktualisierung. Ein Frameworkwechsel erlaubt eine andere Rendertechnik, aber keinen abweichenden Komponentenbaum.

`partial` ist eine dokumentierte Integrationsdifferenz und keine vollständige Drop-in-Zuordnung. `unmapped` erlaubt keine lokale Ersatzkomponente. Leadity verwendet kein Code Connect.

## 8. Prüfkriterien

- Jede komplexe Komponente besitzt einen dokumentierten Abhängigkeitsbaum.
- Jedes Kind stammt aus Registry oder bestätigtem Produktionsadapter.
- Verbraucher enthalten ausschließlich Komponenteninstanz, Props, Daten und Slots.
- Änderungen einer Primitive erscheinen ohne Markupkopie in allen Composite-Instanzen.
- P0-Linter, Interaktionsprüfung und visuelle Zustandsprüfung bestehen gemeinsam.
