admin: group sources and safe search become rac checkboxes

the assigned sources list is a rac checkboxgroup and safe search uses the same drawn checkbox, extracted to a shared ui component with grouped and standalone modes enforced by a discriminated union. the label carries a 44px pointer-target floor on both axes, the focus ring is driven from rac's focus-visible state and guarded by a test, and toggleSource is gone because the group hands back the whole set.
This commit is contained in:
2026-08-29 12:33:00 +02:00
parent 3c674966be
commit f1de80477a
7 changed files with 281 additions and 64 deletions
@@ -89,6 +89,29 @@ test("the source assignment saves the full set via PUT", async () => {
});
});
test("the source checkboxes form one named group, and each carries its own state", async () => {
await openProtection(2);
await screen.findByRole("heading", { name: "kids", level: 2 });
// The section heading names the group; the boxes belong to it rather than
// sitting loose beside the group's other checkboxes.
const group = await screen.findByRole("group", { name: "Assigned sources" });
const ads = within(group).getByRole("checkbox", { name: "Ads" }) as HTMLInputElement;
expect(ads.checked).toBe(false);
// Safe search is the group's own field, not one of its sources.
expect(within(group).queryByRole("checkbox", { name: "Safe search" })).toBeNull();
fireEvent.click(ads);
await waitFor(() => expect(ads.checked).toBe(true));
// Discard returns the group to the server's set rather than clearing it.
fireEvent.click(screen.getByRole("button", { name: "Discard" }));
await waitFor(() =>
expect((within(group).getByRole("checkbox", { name: "Ads" }) as HTMLInputElement).checked).toBe(false),
);
expect(writes("PUT")).toEqual([]);
});
test("only the selected group's rules are listed", async () => {
await openProtection(2);
await screen.findByRole("heading", { name: "kids", level: 2 });