- ui/tabs.tsx nur noch Variante segment: Leiste auf --muted, aktiver Tab mit Kartenfläche, fetter Schrift und 3-px-Balken in --primary-ink; 44 px bei Touch, kompakt mit Maus; inaktive Schrift ≥ 6,27:1. - ActiveHistoryTabs als Vorlage auf Tabs für 10 Listen (Pfeiltasten schalten direkt, Daten sind geladen), mit toolbar und heading. - Einstellungen (Automatisierung, Benutzer & Rollen) und Statistik mit manueller Aktivierung: Pfeil bewegt den Fokus, Enter/Leertaste wählt; ?tab= über router.replace. TabSwitcher entfernt. - Menüeinträge (Dropdown, Select) mit innerem Fokusring ≥ 3:1. - Aufgaben: der Prioritätsfilter lädt die Liste jetzt neu (queryKey). - Wächter: keine eigenen tablist/tab/tabpanel außerhalb ui/tabs.tsx. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
68 lines
2.6 KiB
TypeScript
68 lines
2.6 KiB
TypeScript
import { render, screen } from "@testing-library/react";
|
|
import { describe, expect, it } from "vitest";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuCheckboxItem,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuRadioGroup,
|
|
DropdownMenuRadioItem,
|
|
DropdownMenuSub,
|
|
DropdownMenuSubTrigger,
|
|
DropdownMenuTrigger,
|
|
} from "./dropdown-menu";
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select";
|
|
|
|
/**
|
|
* Menu and select items keep `outline-hidden` (the item itself is the moving highlight), so the
|
|
* accent fill alone was the focus cue, and it stays below 3:1 on the popover. Each item now
|
|
* draws a 2 px inset ring in --ring while focused (≥ 3:1 in all four sets, contrast.spec.ts).
|
|
*/
|
|
const FOCUS_CUE = ["focus:inset-ring-2", "focus:inset-ring-ring"];
|
|
|
|
function expectFocusCue(element: HTMLElement) {
|
|
const classes = element.className.split(/\s+/);
|
|
for (const token of FOCUS_CUE) expect(classes, token).toContain(token);
|
|
}
|
|
|
|
describe("menu items show a focus cue of at least 3:1 (task A8)", () => {
|
|
it("every dropdown item kind draws the inset ring while focused", () => {
|
|
render(
|
|
<DropdownMenu open>
|
|
<DropdownMenuTrigger>Mehr</DropdownMenuTrigger>
|
|
<DropdownMenuContent>
|
|
<DropdownMenuItem>Exportieren</DropdownMenuItem>
|
|
<DropdownMenuItem variant="destructive">Löschen</DropdownMenuItem>
|
|
<DropdownMenuCheckboxItem checked>Mit Details</DropdownMenuCheckboxItem>
|
|
<DropdownMenuRadioGroup value="a">
|
|
<DropdownMenuRadioItem value="a">Liste</DropdownMenuRadioItem>
|
|
</DropdownMenuRadioGroup>
|
|
<DropdownMenuSub>
|
|
<DropdownMenuSubTrigger>Weitere</DropdownMenuSubTrigger>
|
|
</DropdownMenuSub>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>,
|
|
);
|
|
expectFocusCue(screen.getByRole("menuitem", { name: "Exportieren" }));
|
|
expectFocusCue(screen.getByRole("menuitem", { name: "Löschen" }));
|
|
expectFocusCue(screen.getByRole("menuitemcheckbox", { name: "Mit Details" }));
|
|
expectFocusCue(screen.getByRole("menuitemradio", { name: "Liste" }));
|
|
expectFocusCue(screen.getByRole("menuitem", { name: "Weitere" }));
|
|
});
|
|
|
|
it("a select option draws the inset ring while focused", () => {
|
|
render(
|
|
<Select open value="a">
|
|
<SelectTrigger aria-label="Status">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="a">Aktiv</SelectItem>
|
|
<SelectItem value="b">Aufgelöst</SelectItem>
|
|
</SelectContent>
|
|
</Select>,
|
|
);
|
|
for (const option of screen.getAllByRole("option")) expectFocusCue(option);
|
|
});
|
|
});
|