fix(quick-260921-jt4): widget-catalog-modal Hintergrund wird echte Schaltflaeche

- Aeussere Flaeche verliert onClick, die bislang nur optische
  Hintergrund-Flaeche wird eine benannte <button> und traegt onClose
  (D-01); verliert dabei aria-hidden, weil ein fokussierbares Element
  nicht verborgen sein darf
- stopPropagation auf der Dialogflaeche entfaellt als toter Code, weil
  der Hintergrund jetzt Geschwister statt Vorfahr ist
- Fest verdrahtetes englisches aria-label="Close" durch common.close
  ersetzt
- Neuer Katalogschluessel widgets.catalogClose in de.json/en.json
- Neue Testdatei: Hintergrund schliesst (Klick + Tastatur), Dialogklick
  schliesst nicht, Escape weiterhin, Kartenauswahl fuegt Widget hinzu

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
This commit is contained in:
2026-09-21 14:41:54 +02:00
parent a8531d44df
commit 3d0bc0bfaa
4 changed files with 142 additions and 8 deletions
@@ -31,6 +31,7 @@ export function WidgetCatalogModal({
onAddWidget,
}: WidgetCatalogModalProps) {
const t = useTranslations('widgets');
const tCommon = useTranslations('common');
const dialogRef = useRef<HTMLDivElement>(null);
// Focus trap + Escape handler
@@ -53,12 +54,16 @@ export function WidgetCatalogModal({
if (!isOpen) return null;
return (
<div
className="fixed inset-0 z-50 flex items-center justify-center"
onClick={onClose}
>
{/* Backdrop — visually only, hidden from assistive tech */}
<div className="fixed inset-0 bg-black/50" aria-hidden="true" />
<div className="fixed inset-0 z-50 flex items-center justify-center">
{/* Hintergrund — jetzt eine echte, benannte Schaltflaeche statt einer rein
optischen Flaeche: ein fokussierbares Element darf vor der Vorlesehilfe
nicht verborgen sein (D-01). */}
<button
type="button"
onClick={onClose}
aria-label={t('catalogClose')}
className="fixed inset-0 bg-black/50"
/>
{/* Dialog */}
<div
@@ -67,7 +72,6 @@ export function WidgetCatalogModal({
aria-modal="true"
aria-label={t('catalogTitle')}
className="relative z-50 w-full max-w-[480px] rounded-lg border bg-card p-6 shadow-xl"
onClick={(e) => e.stopPropagation()}
tabIndex={-1}
>
{/* Header */}
@@ -79,7 +83,7 @@ export function WidgetCatalogModal({
type="button"
onClick={onClose}
className="rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
aria-label="Close"
aria-label={tCommon('close')}
>
<svg
aria-hidden="true"