fix(shell): aria-current in der Navigation, Suche wird bei Seitenwechsel geleert, Live-Regionen bleiben gerendert
- Router: onRouteChange meldet jede neue Seite (vor dem Aufbau). Die Kopfzeile markiert damit den aktuellen Navigationslink mit aria-current="page" („Community“ auch auf der Detailseite) und leert das Suchfeld, wenn die neue Seite nicht die Startseite mit ?q= ist (bisher blieb „testbank“ auf /gestalten stehen). - Spenden-Knopf in der Kopfzeile trägt title „Unterstützen“ (zwischen 600 und 1179 px nur Symbol). - .detail-msg:empty und .auth-msg:empty sind nicht mehr display: none (Live-Regionen standen nicht im Zugänglichkeitsbaum), sondern ohne Platz im Layout, aber gerendert; Test liest die CSS-Dateien. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c62075f2d4
commit
aa9f9548ad
7 files changed
+233
-10
No files matched your search
@@ -629,8 +629,17 @@
|
||||
color: var(--danger-text);
|
||||
}
|
||||
|
||||
/* Leer bleibt die Meldungszeile gerendert (Live-Region), nimmt aber keinen Platz ein: mit display: none stünde sie nicht im
|
||||
Zugänglichkeitsbaum, und Screenreader meldeten den Text nicht, der später hineinkommt. */
|
||||
.detail-msg:empty {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
clip-path: inset(50%);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.detail-admin {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
// Als Text lesen: vitest verarbeitet CSS-Importe (auch ?raw) nicht zu Text.
|
||||
const accountCss = readFileSync(resolve(import.meta.dirname, '../account/account.css'), 'utf8');
|
||||
const communityCss = readFileSync(resolve(import.meta.dirname, 'community.css'), 'utf8');
|
||||
|
||||
/** Die Deklarationen einer Regel, deren Auswahlkriterium genau `selector` ist (mehrere Regeln: alle zusammen). */
|
||||
function declarations(css: string, selector: string): string {
|
||||
const found: string[] = [];
|
||||
for (const rule of css.matchAll(/([^{}]+)\{([^{}]*)\}/g)) {
|
||||
const selectors = rule[1].replace(/\/\*[\s\S]*?\*\//g, '').split(',').map((part) => part.trim());
|
||||
if (selectors.includes(selector)) found.push(rule[2]);
|
||||
}
|
||||
return found.join('\n');
|
||||
}
|
||||
|
||||
describe('Live-Regionen (role alert/status) bleiben gerendert, auch leer', () => {
|
||||
it.each([
|
||||
['community.css', '.detail-msg:empty', communityCss],
|
||||
['account.css', '.auth-msg:empty', accountCss],
|
||||
])('%s: %s ist nicht display: none, sondern aus dem Layout genommen und optisch leer', (_file, selector, css) => {
|
||||
const rule = declarations(css, selector);
|
||||
expect(rule).not.toBe('');
|
||||
expect(rule).not.toMatch(/display\s*:\s*none/);
|
||||
expect(rule).not.toMatch(/visibility\s*:\s*hidden/);
|
||||
expect(rule).toMatch(/position\s*:\s*absolute/); // kein Platz im Layout (kein Gap im Flex-Container)
|
||||
expect(rule).toMatch(/width\s*:\s*1px/);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user