Zehn Blöcke für die Abschnitte der Pilotseite (Arbeitspaket C)

Dokumentschema v6 ergänzt iconcard, stat, quote, logos, cta, contact,
divider, spacer, accordion und accordionitem - die Abschnittsarten,
aus denen die Startseite von kant-it.de besteht.

Symbole liegen als Inline-SVG aus einer festen Liste im Template:
kein Symbolschriftsatz, keine externe Anfrage. Kontaktdaten werden zu
tel:- und mailto:-Verweisen mit bereinigter Nummer. Das Akkordeon
nutzt details/summary und braucht damit kein öffentliches
JavaScript.

Tabs sind bewusst nicht umgesetzt: ohne JavaScript gibt es dafür
keine zugängliche Lösung, und eine CSS-Variante über Radiobuttons
wird als Auswahlfeld statt als Tabliste angekündigt. Begründung in
ADR 015.

Zwei Fehler von den Tests gefunden und behoben: die Regel "ein
Akkordeon-Eintrag gehört in ein Akkordeon" griff nicht auf oberster
Dokumentebene, und ein JavaScript-Test suchte im vorherigen
Dokumentstand, weil history.document vor history.change ausgewertet
wurde.

Geprüft: 107 PHP-Tests / 380 Assertions unter PHP 8.2.12 und 8.4.22,
13 JavaScript-Modelltests, Lint/Format/Container. Keine Browser- oder
Lighthouse-Läufe; für die neuen Blöcke liegt damit keine visuelle
Kontrolle und keine Barrierefreiheitsprüfung vor.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
kantarciandClaude Opus 5 committed 2026-09-12 11:34:48 +02:00
1 parent ebd5883593
commit 8600384f1a
14 files changed
+442 -27

No files matched your search

+35
View File
@@ -176,3 +176,38 @@ test('the post list block carries only its filter, lifts the schema to v5 and un
assert.deepEqual(history.document, fixture());
assert.equal(history.document.schemaVersion, 1);
});
test('v6 containers accept only their own children and an accordion starts with one entry', () => {
const history = new EditorHistory(fixture());
const accordion = history.change(doc => insertBlock(doc, 'accordion', 's2'));
const block = locate(history.document.blocks, accordion).block;
assert.equal(history.document.schemaVersion, 6);
// An empty accordion would render as nothing, so it comes with one entry.
assert.equal(block.children.length, 1);
assert.equal(block.children[0].type, 'accordionitem');
assert.deepEqual(block.children[0].props, { title: 'Eine Frage', open: false });
// Only accordion entries go into an accordion, and an entry goes nowhere else.
assert.equal(canContain(block, { type: 'text' }), false);
assert.equal(canContain(block, { type: 'accordionitem' }), true);
assert.equal(canContain({ type: 'section', children: [] }, { type: 'accordionitem' }), false);
assert.equal(canContain(block.children[0], { type: 'text' }), true);
// A logo strip takes images only, like a gallery.
const logos = history.change(doc => insertBlock(doc, 'logos', 's2'));
const strip = locate(history.document.blocks, logos).block;
assert.equal(canContain(strip, { type: 'image' }), true);
assert.equal(canContain(strip, { type: 'iconcard' }), false);
// Leaf blocks stay leaves and keep their defaults.
// Two statements on purpose: history.change() replaces the document, so reading
// history.document.blocks in the same expression would search the previous snapshot.
const statId = history.change(doc => insertBlock(doc, 'stat', 's2'));
const stat = locate(history.document.blocks, statId).block;
assert.equal(stat.children, undefined);
assert.deepEqual(stat.props, { value: '15+', label: 'Jahre Erfahrung' });
history.undo(); history.undo(); history.undo();
assert.deepEqual(history.document, fixture());
});