Kundenansicht neu (Aufträge): Zeitleiste barrierefrei, "mehr anzeigen" mit Auftragstitel im Namen und aria-controls, "Im Chat antworten" bricht nicht um
Der Knopf "mehr anzeigen"/"weniger anzeigen" bekommt einen aria-label mit dem Auftragstitel (der sichtbare Text steht vorn im Namen, der Titel nur als Text) und aria-controls auf die Liste seines Auftrags (eindeutige Id je Liste); beides zieht beim Umschalten mit. Der Linktext "Im Chat antworten" trägt white-space: nowrap und bleibt in einer Zeile beisammen. Tests: DOM-Test für Name, Verknüpfung, Umschalten, fremden Titel und Ersatztitel; CSS-Test für nowrap. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
14dc2ad1bf
commit
ace4c85e72
3 files changed
+55
-8
No files matched your search
@@ -120,7 +120,7 @@
|
||||
.kn-az-kopf .kn-pille { flex: none; margin-top: 2px; }
|
||||
.kn-az-info { margin: 8px 0 0; font-size: 14px; line-height: 20px; }
|
||||
.kn-az-info a { color: var(--kn-orange-fg); text-decoration: none; }
|
||||
.kn-az-info-link { font-weight: 600; text-decoration: underline; text-decoration-color: currentColor; text-underline-offset: 3px; }
|
||||
.kn-az-info-link { font-weight: 600; text-decoration: underline; text-decoration-color: currentColor; text-underline-offset: 3px; white-space: nowrap; } /* der Linktext bleibt zusammen */
|
||||
.kn-az-balken { display: flex; gap: 3px; margin: 12px 0 0; padding: 0; list-style: none; }
|
||||
.kn-az-balken li { position: relative; flex: 1; height: 4px; }
|
||||
.kn-az-balken li::before { content: ""; position: absolute; inset: 0; border-radius: 2px; background: var(--kn-line); } /* die Fläche liegt im Pseudo-Element: der Lesetext darunter bleibt auf Weiß */
|
||||
|
||||
@@ -122,12 +122,15 @@ const KEINE_EINTRAEGE = 'Noch keine Arbeiten dokumentiert.'
|
||||
|
||||
/** Knopf, der den nächsten Wrapper [data-einklappbar] auf- und zuklappt (is-open); die Zeilen dahinter tragen [data-extra]. Die CSS-Regeln dazu gelten nur für
|
||||
direkte Kinder (ansichten.css, .kn-az-…): die allgemeine Regel .kn-einklappbar würde bei verschachtelten Wrappern auch offene Zeilen verbergen. */
|
||||
function umschalter({ attribut, klasse, mehr, weniger }) {
|
||||
const knopf = h('button', { type: 'button', class: klasse, [attribut]: true, 'aria-expanded': 'false' }, mehr)
|
||||
function umschalter({ attribut, klasse, mehr, weniger, name, steuert }) {
|
||||
// name: Zusatz für den Namen des Knopfes („mehr anzeigen zu „Titel““, der sichtbare Text steht vorn im Namen); steuert: Id der Liste, die er auf- und zuklappt
|
||||
const nameFuer = (text) => (name ? `${text} zu „${name}“` : null)
|
||||
const knopf = h('button', { type: 'button', class: klasse, [attribut]: true, 'aria-expanded': 'false', 'aria-label': nameFuer(mehr), 'aria-controls': steuert || null }, mehr)
|
||||
knopf.addEventListener('click', () => {
|
||||
const offen = knopf.closest('[data-einklappbar]').classList.toggle('is-open')
|
||||
knopf.textContent = offen ? weniger : mehr
|
||||
knopf.setAttribute('aria-expanded', String(offen))
|
||||
if (name) knopf.setAttribute('aria-label', nameFuer(offen ? weniger : mehr))
|
||||
})
|
||||
return knopf
|
||||
}
|
||||
@@ -143,28 +146,34 @@ function baueBalken(status) {
|
||||
h('span', { class: 'kn-nur-lesen' }, `${stufe.name}, ${zustandText(stufe)}`))))
|
||||
}
|
||||
|
||||
function baueZeitleiste(zeilen) {
|
||||
let listenNummer = 0 // Ids der Listen für aria-controls: eindeutig je Seite, auch wenn die Ansicht mehrmals gezeichnet wird
|
||||
|
||||
function baueZeitleiste(zeilen, titel) {
|
||||
const { sichtbar, rest } = kuerze(zeilen, MAX_ZEILEN)
|
||||
listenNummer += 1
|
||||
const listenId = `kn-az-zeilen-${listenNummer}`
|
||||
const zeile = (z, extra) => h('li', { 'data-extra': extra },
|
||||
z.datum ? h('time', { class: 'kn-az-datum', datetime: z.iso || null }, z.datum) : h('span', { class: 'kn-az-datum', 'aria-hidden': 'true' }),
|
||||
h('span', { class: 'kn-az-text' }, z.text))
|
||||
return h('div', { class: 'kn-az-zeitleiste', 'data-einklappbar': true },
|
||||
// Trägt ein Datum das Jahr (TT.MM.JJ), bekommt die Datumsspalte aller Zeilen die Breite dafür, damit die Texte bündig bleiben
|
||||
h('ol', { class: zeilen.some((z) => z.datum.length > 6) ? 'kn-az-zeilen kn-az-mit-jahr' : 'kn-az-zeilen' }, sichtbar.map((z) => zeile(z, false)), rest.map((z) => zeile(z, true))),
|
||||
rest.length ? umschalter({ attribut: 'data-mehr', klasse: 'kn-textknopf kn-az-mehr', mehr: 'mehr anzeigen', weniger: 'weniger anzeigen' }) : null)
|
||||
h('ol', { id: listenId, class: zeilen.some((z) => z.datum.length > 6) ? 'kn-az-zeilen kn-az-mit-jahr' : 'kn-az-zeilen' }, sichtbar.map((z) => zeile(z, false)), rest.map((z) => zeile(z, true))),
|
||||
// Mehrere Knöpfe „mehr anzeigen“ auf einer Seite: der Name nennt den Auftrag, aria-controls die Liste
|
||||
rest.length ? umschalter({ attribut: 'data-mehr', klasse: 'kn-textknopf kn-az-mehr', mehr: 'mehr anzeigen', weniger: 'weniger anzeigen', name: titel, steuert: listenId }) : null)
|
||||
}
|
||||
|
||||
function baueAuftragsBlock(auftrag, jetzt, extra) {
|
||||
const status = auftrag.status && typeof auftrag.status === 'object' ? auftrag.status : {}
|
||||
const zeilen = zeitleistenZeilen(auftrag, jetzt)
|
||||
const titel = auftrag.topic || 'Dein Auftrag'
|
||||
return h('li', { class: 'kn-az', 'data-auftrag': auftrag.number || null, 'data-extra': extra },
|
||||
h('div', { class: 'kn-az-kopf' },
|
||||
h('h3', { class: 'kn-az-titel' }, auftrag.topic || 'Dein Auftrag'),
|
||||
h('h3', { class: 'kn-az-titel' }, titel),
|
||||
status.label ? h('span', { class: K.pille[statusTon(status.tone)] }, status.label) : null),
|
||||
// Die ganze Zeile führt in den Chat (große Tippfläche am Handy); unterstrichen ist nur „Im Chat antworten“
|
||||
braucheInfo(auftrag) ? h('p', { class: 'kn-az-info' }, h('a', zuAnsicht('chat'), 'Wir brauchen eine Info von dir · ', h('span', { class: 'kn-az-info-link' }, 'Im Chat antworten'))) : null,
|
||||
baueBalken(status),
|
||||
zeilen.length ? baueZeitleiste(zeilen) : h('p', { class: 'kn-az-leer' }, KEINE_EINTRAEGE))
|
||||
zeilen.length ? baueZeitleiste(zeilen, titel) : h('p', { class: 'kn-az-leer' }, KEINE_EINTRAEGE))
|
||||
}
|
||||
|
||||
/** „Was wir zuletzt erledigt haben“: ein Block je Auftrag; fünf offen, der Rest hinter „Ältere Aufträge anzeigen“. Ohne Aufträge ein ruhiger Satz. */
|
||||
|
||||
Reference in new issue
Block a user