CP Registry

Developer Guide

Technische Dokumentation für Entwickler: Architektur, CLI, Component-Entwicklung, TYPO3-Integration und Testing.

Architektur

Das CP-Registry-System besteht aus vier Teilen:

Registry (cp-registry/)

Kanonische Component-Bibliothek. Astro-Projekt mit Showcase-Website. Components leben unter src/components/, Manifeste unter registry/components/.

CLI (cli/)

TypeScript-CLI cp-components mit Commander.js. Kopiert Components von der Registry ins Projekt. Vorkompiliert unter cli/dist/, installierbar via setup.sh oder npm link.

TYPO3-Sync (packages/typo3-sync/)

Astro-Integration die CSS zusammenfuehrt, Pfade umschreibt und Assets ins TYPO3-Sitepackage kopiert. Hooks: astro:config:setup + astro:build:done.

Projekte (pro Kunde)

Eigenständige Astro-Projekte mit kopierten Components. Jedes Projekt hat eigene Brand-Tokens in colors.css. Components dürfen frei angepasst werden.

Tech Stack

Technologie Version Einsatz
Astro6.xStatic Site Generator, Component Framework
Tailwind CSS4.2Utility-First CSS, @theme Syntax
TypeScript5.9CLI, A11y-Scripts, Typings
OKLCHFarbraum für perceptuell gleichmäßige Farben
React19.xChart-Components (via @astrojs/react)
Recharts3.xChart-Bibliothek (Area, Bar, Line, Pie, Radar, Radial)
Vitest4.xUnit Tests, A11y Tests mit axe-core
Swiper12.xSlider/Carousel Component

CLI im Detail

Das CLI nutzt @clack/prompts für ein interaktives Interface. Alle Befehle funktionieren auch non-interaktiv mit Flags.

Installation

cd cp-registry
pnpm install            # Projekt-Dependencies

# CLI global installieren (empfohlen)
./cli/setup.sh

# Prüfen
cp-components --help

Wichtig: Die CLI wird mit npm link global installiert (nicht pnpm link!). Das Setup-Script kümmert sich automatisch darum.

Deinstallation

# CLI global entfernen
./cli/setup.sh uninstall

Update

# Nach git pull: CLI neu bauen und re-linken
./cli/setup.sh update

# Status prüfen
./cli/setup.sh status

Ohne globale Installation

Falls du die CLI nicht global installieren willst, kannst du sie direkt aus dem Repository ausführen:

# Über npm-Script
npm run cli -- add accordion button

# Oder direkt
node cli/dist/index.js --help

init

Ohne Flags startet ein interaktiver Wizard: Projektname, Sitepackage, Components und Skills per Multi-Select.

# Interaktiv (empfohlen)
cp-components init

# Non-interaktiv
cp-components init --name "mein-projekt" --sitepackage "mein_sitepackage"

add

Ohne Argumente: interaktiver Multi-Select mit Beschreibungen. Mit Argumenten: direktes Installieren.

# Interaktiv (zeigt alle verfügbaren Components)
cp-components add

# Direkt
cp-components add accordion button card hero navigation

# Dry Run (nur Vorschau)
cp-components add accordion --dry-run

new

Scaffoldet eine neue Component mit Boilerplate (Astro-Datei, Manifest, Showcase-Seite).

cp-components new Timeline -c content
cp-components new SearchBar -c ui --with-script

diff, sync & remove

# Unterschiede anzeigen
cp-components diff accordion

# Alle unmodifizierten updaten
cp-components sync
cp-components sync --force   # Auch modifizierte

# Component entfernen
cp-components remove accordion
cp-components remove accordion -f   # Dependency-Warnungen ignorieren

skills

Installiert Claude Code Skills und Agents in das Zielprojekt.

# Interaktiv (Multi-Select)
cp-components skills

# Alle installieren
cp-components skills all

# Nur universelle (funktionieren in jedem Projekt)
cp-components skills --universal

# Bestimmte nach Name
cp-components skills pr review-pr a11y-auditor

# Nur auflisten
cp-components skills --list

validate

Prüft alle Component-Manifeste auf Konsistenz (Pflichtfelder, Datei-Existenz, Naming).

cp-components validate

Component Manifest

Jedes Component hat ein JSON-Manifest unter registry/components/. Komplexe Components werden in mehrere Dateien aufgeteilt:

{
  "name": "DatePicker",
  "category": "form",
  "description": "Datumswahl mit Kalender-Popover und Tastatursteuerung.",
  "files": [
    "src/components/DatePicker/DatePicker.astro",
    "src/components/DatePicker/datepicker.css",
    "src/components/DatePicker/datepicker.ts"
  ],
  "dependencies": {
    "components": [],       // Andere Components die mitinstalliert werden
    "npm": [],              // npm-Pakete die gebraucht werden (z.B. "swiper")
    "modules": ["a11y/utils"]  // Shared Modules (optional)
  },
  "requiredTokens": [       // Design-Tokens die vorhanden sein müssen
    "--color-brand-primary",
    "--color-brand-border",
    "--color-brand-surface",
    "--color-brand-foreground"
  ],
  "types": [],               // TypeScript-Typdefinitionen
  "globalsImports": []       // CSS-Imports für globals.css (optional)
}

Neues Component erstellen

1. Component-Dateien

Erstelle unter src/components/{Name}/. Nutze nur semantische Tokens (bg-brand-*, text-brand-*). Kein Hardcoding von Farben.

Datei-Aufteilung: Komplexe Components werden in separate Dateien aufgeteilt:

  • {Name}.astro — Template + Props (nur Markup)
  • {name}.css — Styles (Popover-Animationen, States etc.)
  • {name}.ts — Client-Side Logik (Keyboard-Navigation, Events)
// In der .astro-Datei:
---
import './datepicker.css';   // CSS im Frontmatter importieren
---
<div>...</div>
<script>import './datepicker.ts';</script>  // TS per Script-Tag

2. Registry Manifest

JSON unter registry/components/{name}.json. Liste alle Dateien (inkl. .css und .ts), Dependencies und genutzten Tokens.

3. Showcase-Seite

Astro-Page unter src/pages/components/{name}.astro mit allen Varianten, Props-Tabelle und Nutzungsbeispielen.

4. Tests (optional)

A11y-Tests unter tests/ mit Vitest + axe-core. Teste Keyboard-Navigation, ARIA-Attribute und Focus-Management.

TYPO3-Integration

Build-Prozess

Der TYPO3-Build (pnpm build:typo3) macht folgendes:

  1. Astro baut das Projekt normal (statisches HTML/CSS/JS)
  2. Die Integration sammelt alle CSS-Dateien und vereint sie in einer Datei
  3. Pfade werden umgeschrieben: url(/fonts/Inter.woff2) wird zu url(../Fonts/Inter.woff2)
  4. Assets werden in das TYPO3-Sitepackage kopiert: packages/{sitepackage}/Resources/Public/
  5. Fonts bekommen vorhersagbare Namen (kein Content-Hash)

CSS in TYPO3

Eine einzige CSS-Datei wird generiert und ins Sitepackage kopiert. In TYPO3:

# TypoScript
page.includeCSS {
  main = EXT:mein_sitepackage/Resources/Public/Css/style.css
}

JavaScript in TYPO3

Astro rendert statisches HTML. Client-Side-Scripts (z.B. Accordion, Navigation, Gallery) werden als separate JS-Dateien exportiert.

Automatisches JS-Handling durch typo3-sync

Der typo3-sync kopiert JavaScript-Dateien automatisch aus dist/assets/JavaScript/ ins Sitepackage unter Resources/Public/JavaScript/. Entry-Scripts bekommen sprechende Namen (z.B. accordion.js, navigation.js), Chunks landen unter JavaScript/chunks/. Es ist kein manuelles Kopieren nötig.

Strategie 1: Einzelne Component-Scripts

Jedes Component hat sein eigenes Script. TYPO3 laedt nur was auf der Seite gebraucht wird.

# TypoScript - pro Component
page.includeJSFooter {
  accordion = EXT:mein_sitepackage/Resources/Public/JavaScript/accordion.js
  accordion.defer = 1

  navigation = EXT:mein_sitepackage/Resources/Public/JavaScript/navigation.js
  navigation.defer = 1

  gallery = EXT:mein_sitepackage/Resources/Public/JavaScript/gallery.js
  gallery.defer = 1
}

Vorteil: Kleinere Bundles, schnellere Seiten. Nachteil: Mehr HTTP-Requests.

Strategie 2: Globales Bundle

Alle Scripts in einer Datei. Einfacher zu verwalten.

# TypoScript - globales Bundle
page.includeJSFooter {
  main = EXT:mein_sitepackage/Resources/Public/JavaScript/main.js
  main.defer = 1
}

Vorteil: Ein Request, gut cacheable. Nachteil: Groessere Datei, alle Scripts werden geladen.

Empfehlung

Für die meisten Projekte ist das globale Bundle die bessere Wahl. Die Component-Scripts sind klein (zusammen typischerweise unter 15KB gzipped). Einzelne Scripts lohnen sich erst bei sehr großen Projekten mit vielen exklusiven Seiten-Typen.

Testing

Vitest + axe-core

# Tests ausführen
pnpm test

# Watch-Modus
pnpm test:watch

Tests liegen unter tests/. A11y-Utilities werden mit Unit-Tests geprüft, Components mit axe-core auf WCAG-Konformität getestet.

Test-Beispiel

import { describe, it, expect } from 'vitest';
import { uid, ensureId, getFocusable } from '../src/components/a11y/utils';

describe('uid', () => {
  it('generiert einzigartige IDs', () => {
    const id1 = uid('test');
    const id2 = uid('test');
    expect(id1).not.toBe(id2);
  });
});

describe('getFocusable', () => {
  it('findet alle interaktiven Elemente', () => {
    const div = document.createElement('div');
    div.innerHTML = '<button>OK</button><input /><span>Text</span>';
    document.body.appendChild(div);
    expect(getFocusable(div)).toHaveLength(2);
  });
});

Claude Code Integration

Das Registry bringt eigene Skills (Slash-Commands) und Agents für Claude Code mit — plus globale Harnesses, generelle Disziplin-Skills und Subagents.

Vollständige Dev-Doku aller Skills und Agents: → /docs/claude-code

Schnelle Installation der universellen Skills in ein eigenes Projekt: cp-components skills --universal

CSS-Architektur

Das CSS ist in Schichten (Layers) organisiert:

/* globals.css - Ladereihenfolge */

@import "tailwindcss";           /* Framework */

/* Theme Layer: Tokens (überschreibbar pro Projekt) */
@import "./theme/colors.css"       layer(theme);
@import "./theme/fonts.css"        layer(theme);
@import "./theme/breakpoints.css"  layer(theme);

/* Base Layer: Reset + Grundlagen */
@import "./base/reset.css"         layer(base);
@import "./base/grid.css"          layer(components);
@import "./base/typography.css"    layer(components);

/* Utilities Layer: Spacing + Animationen */
@import "./utilities/spacings.css"    layer(utilities);
@import "./utilities/animations.css"  layer(utilities);

Wichtig: Die Layer-Reihenfolge bestimmt die Spezifitaet. Theme-Tokens können von jedem Layer genutzt werden. Tailwind-Utilities überschreiben alles (kein Layer).