Skip to content

Comparison Table

Überblick

mmm-comparison-table stellt mehrere gleichartige Angebote untereinander zum Vergleich dar — Darlehensvarianten, Tarife, Preisstufen. Jede Zeile zeigt in der Kopfzeile die Kennzahlen und klappt auf Klick ein Detail-Panel mit weiteren Werten und Fußnoten auf.

Die Komponente besteht aus fünf Teilen: der Tabelle selbst als <ul>, den Zeilen als <li> sowie den inhaltlichen Bausteinen Segment, Detail und Note. Die Zeile ist inhaltsunabhängig — sie kennt nur Chevron, Aufklappverhalten und Trennlinien, nicht die Daten, die projiziert werden.

Einbindung

Die Konstante COMPARISON_TABLE bündelt alle fünf Komponenten und kann in die imports gespreizt werden:

import { COMPARISON_TABLE } from '@mmm/designsystem';
@Component({
imports: [...COMPARISON_TABLE],
// …
})
export class OfferListComponent {}

Einzelne Klassen (ComparisonTableComponent, ComparisonTableRowComponent, ComparisonTableSegmentComponent, ComparisonTableDetailComponent, ComparisonTableNoteComponent) lassen sich alternativ gezielt importieren.

Subkomponenten

  • ul[mmmComparisonTable]: Tabellencontainer, hält die Design-Tokens und den Query-Container
  • li[mmmComparisonTableRow]: eine aufklappbare Zeile mit Trigger und Panel
  • mmm-comparison-table-segment: beschriftete Zelle in der Kopfzeile
  • mmm-comparison-table-detail: Label-Wert-Zeile im aufgeklappten Panel
  • mmm-comparison-table-note: Fußnote am Fuß des Panels

Die Selektoren der ersten beiden sind Attribute auf echten <ul>- und <li>-Elementen, damit die Struktur ul > li ohne Wrapper-Element erhalten bleibt.

Slots einer Zeile

SlotPositionZweck
[comparisonTableLead]im Trigger-Button, neben dem Chevronhervorgehobene Leitzelle, üblicherweise ein Segment mit variant="lead"
Standardzweite Zeile (schmal) bzw. neben dem Lead (breit)die Segmente der Kopfzeile, beliebig viele
[comparisonTableTrailing]außerhalb des Trigger-Buttons, am Zeilenendeinteraktive Inhalte wie Checkbox, Link oder Button
[comparisonTableDetails]aufklappbares Panelmmm-comparison-table-detail und mmm-comparison-table-note

[comparisonTableTrailing] liegt bewusst außerhalb des Buttons: ein Bedienelement innerhalb eines <button> ist ungültiges HTML und per Tastatur nicht erreichbar. Eine Auswahl-Spalte gehört deshalb immer in diesen Slot.

Auf mmm-comparison-table-segment existiert zusätzlich der Slot [comparisonTableSegmentLabel] für Labels, die kein reiner String sind.

Inputs

li[mmmComparisonTableRow]

InputTypBeschreibung
expandedbooleanÖffnungszustand der Zeile, zweiweg-bindbar über [(expanded)]; ohne Bindung verwaltet die Zeile ihn selbst
triggerLabelstring | undefinedÜberschreibt den Accessible Name des Triggers; ohne Wert benennt sich der Button über seinen Textinhalt

mmm-comparison-table-segment

InputTypBeschreibung
labelstring | undefinedLabel als reiner Text; entfällt, wenn [comparisonTableSegmentLabel] projiziert wird
variant'default' | 'lead'lead ist die vergrößerte, akzentfarbene Darstellung der Leitzelle
align'left' | 'center' | 'right'Textausrichtung der Zelle
dividerboolean | undefinedVertikale Haarlinie vor der Zelle; ohne Angabe abgeleitet aus variant (alles außer lead)
growboolean | undefinedVerteilt den verfügbaren Platz gleichmäßig; ohne Angabe abgeleitet aus variant (alles außer lead)

mmm-comparison-table-detail

InputTypBeschreibung
labelstringPflicht. Bezeichnung links in der Detailzeile

ul[mmmComparisonTable] und mmm-comparison-table-note haben keine Inputs.

Outputs

li[mmmComparisonTableRow]

OutputTypBeschreibung
expandedChangeEventEmitter<boolean>Meldet den geänderten Öffnungszustand

Die übrigen Komponenten des Sets haben keine Outputs.

Responsives Verhalten

Die Zeile hat zwei Layouts, und umgeschaltet wird über eine Container-Query auf der Tabelle, nicht über eine Media-Query auf dem Viewport. Ausschlaggebend ist die Breite der Tabelle selbst: in einer Sidebar, einem Modal oder einer Spalte eines Split-Layouts ist sie auch auf großen Bildschirmen schmal.

  • Schmal (Standard): zwei Zeilen — Lead und Trailing oben, darunter die Segmente in gleich breiten Spalten, getrennt durch eine Linie über die volle Breite.
  • Breit (ab 37.5rem Inline-Größe der Tabelle): alles auf einer Linie — Lead, Segmente, Trailing am Zeilenende.

Drei Metriken sind dabei responsiv und liegen als -narrow/-wide-Paar vor: gap, rule-height und lead-size. Aufgelöst werden sie auf der Zeile, weil ein Element seinen eigenen Query-Container nicht abfragen kann.

Zum Übersteuern dieser drei immer die Inputs setzen (--mmm-comparison-table-gap-narrow bzw. -wide), nicht die aufgelöste Variable. Ein Wert direkt auf --mmm-comparison-table-gap wirkt nur, solange die Tabelle schmal ist.

Der Umschaltpunkt selbst ist die Sass-Variable $wide-min-width in styling/components/_comparison-table.scss. Container-Queries können keine Custom Properties lesen, der Wert wird also zur Build-Zeit eingesetzt und lässt sich nur per @use … with (…) aus einem Build heraus ändern, der das Partial selbst kompiliert.

SCSS-Variablen

Alle --mmm-comparison-table-*-Variablen werden auf dem <ul> deklariert; Zeilen, Segmente, Details und Notes erben sie. Ein ganzes Tabellen-Theme entsteht daher durch Übersteuern auf dem <ul>, einem Wrapper oder :root.

Farben:

  • --mmm-comparison-table-accent
  • --mmm-comparison-table-text
  • --mmm-comparison-table-label
  • --mmm-comparison-table-divider
  • --mmm-comparison-table-row-border-color
  • --mmm-comparison-table-focus-color

Abstände und Maße:

  • --mmm-comparison-table-gap-narrow
  • --mmm-comparison-table-gap-wide
  • --mmm-comparison-table-rule-height-narrow
  • --mmm-comparison-table-rule-height-wide
  • --mmm-comparison-table-inset
  • --mmm-comparison-table-row-padding
  • --mmm-comparison-table-row-spacing
  • --mmm-comparison-table-panel-offset
  • --mmm-comparison-table-lead-gap
  • --mmm-comparison-table-lead-padding
  • --mmm-comparison-table-detail-padding

Typografie:

  • --mmm-comparison-table-label-size
  • --mmm-comparison-table-label-line-height
  • --mmm-comparison-table-value-size
  • --mmm-comparison-table-value-line-height
  • --mmm-comparison-table-lead-size-narrow
  • --mmm-comparison-table-lead-size-wide
  • --mmm-comparison-table-detail-size
  • --mmm-comparison-table-note-size
  • --mmm-comparison-table-note-line-height

Motion:

  • --mmm-comparison-table-duration

Hinweise

  • Jede Zeile verwaltet ihren Zustand eigenständig, es können also mehrere Panels gleichzeitig offen sein. Für Akkordeon-Verhalten mit nur einem offenen Panel [(expanded)] von außen steuern.
  • Trigger und Panel sind über aria-expanded und aria-controls verknüpft; das geschlossene Panel ist inert und damit nicht fokussierbar.
  • Das Aufklappen animiert über grid-template-rows: 0fr → 1fr, also ohne JavaScript-Messung. Bei prefers-reduced-motion: reduce entfallen Animation und Chevron-Rotation.
  • Ein projiziertes [comparisonTableSegmentLabel] bringt keine Typografie mit. Für das Label-Aussehen zusätzlich class="mmm-comparison-table-segment__label" setzen.
  • divider und grow als Binding setzen ([divider]="false"), nicht als Attribut (divider="false") — sonst greift die Ableitung aus variant nicht wie erwartet.
  • Segmente ohne Inhalt blenden sich aus: fehlen Segmente oder Trailing-Inhalte, entfallen auch die zugehörigen Trennlinien.
  • Die Zeile bringt ihr Layout selbst mit und verwendet keine Grid-Klassen aus Bootstrap oder Quasar.

Beispiel

Comparison Table

Zwei Darlehensangebote im Vergleich, mit Auswahl-Checkbox und aufklappbaren Details.

  • Auswahl
    Nettodarlehensbetrag 200.000,00 EUR Anfängliche Tilgung 2,00 % p.a. Restschuld bei Zinsbindungsende 152.480,00 EUR Repräsentatives Beispiel: Nettodarlehensbetrag 200.000,00 EUR, gebundener Sollzins 3,34 % p.a., effektiver Jahreszins 3,39 %.
  • Auswahl
    Nettodarlehensbetrag 200.000,00 EUR Anfängliche Tilgung 2,00 % p.a. Restschuld bei Zinsbindungsende 118.940,00 EUR Längere Zinsbindung, höhere Rate: die Restschuld am Ende der Bindung fällt entsprechend niedriger aus.