refactor(ui): FilterSelect and Combobox draw their checks with MenuCheck

They still painted their own 14px box beside the menus' 16px MenuCheck. A contract test holds the
filled-box paint to MenuCheck alone.
This commit is contained in:
2026-09-27 15:02:42 +02:00
parent 5ebb4cb506
commit dddf79ec2f
3 changed files with 24 additions and 20 deletions
+3 -8
View File
@@ -1,7 +1,8 @@
import clsx from "clsx"; import clsx from "clsx";
import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react"; import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Check, ChevronDown } from "lucide-react"; import { ChevronDown } from "lucide-react";
import { MenuCheck } from "./MenuCheck";
import { PopoverSurface, PopoverItem } from "./AnchoredPopover"; import { PopoverSurface, PopoverItem } from "./AnchoredPopover";
import { useAnchoredPopover } from "./anchoredPopoverHooks"; import { useAnchoredPopover } from "./anchoredPopoverHooks";
import { useScrollFade } from "../../lib/useScrollFade"; import { useScrollFade } from "../../lib/useScrollFade";
@@ -285,13 +286,7 @@ export default function Combobox({
renderOption(o, on) renderOption(o, on)
) : ( ) : (
<> <>
<span <MenuCheck kind={multiple ? "many" : "one"} on={on} />
className={`flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded border ${
on ? "border-accent bg-accent text-accent-fg" : "border-border"
}`}
>
{on && <Check className="h-2.5 w-2.5" />}
</span>
<span className="flex-1 truncate">{o.label ?? o.value}</span> <span className="flex-1 truncate">{o.label ?? o.value}</span>
{o.count != null && ( {o.count != null && (
<span className="shrink-0 text-2xs tabular-nums text-muted"> <span className="shrink-0 text-2xs tabular-nums text-muted">
+2 -12
View File
@@ -1,5 +1,5 @@
import { useState } from "react"; import { useState } from "react";
import { Check } from "lucide-react"; import { MenuCheck } from "./MenuCheck";
import { SelectTrigger } from "./SelectTrigger"; import { SelectTrigger } from "./SelectTrigger";
import { PopoverItem, PopoverSurface } from "./AnchoredPopover"; import { PopoverItem, PopoverSurface } from "./AnchoredPopover";
import { useAnchoredPopover } from "./anchoredPopoverHooks"; import { useAnchoredPopover } from "./anchoredPopoverHooks";
@@ -129,17 +129,7 @@ export default function FilterSelect({
on ? "text-fg" : "text-muted" on ? "text-fg" : "text-muted"
}`} }`}
> >
{multiple ? ( <MenuCheck kind={multiple ? "many" : "one"} on={on} />
<span
className={`flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded border ${
on ? "border-accent bg-accent text-accent-fg" : "border-border"
}`}
>
{on && <Check className="h-2.5 w-2.5" />}
</span>
) : (
<Check className={`h-3.5 w-3.5 shrink-0 ${on ? "text-accent" : "opacity-0"}`} />
)}
<span className="flex-1 truncate">{o.label}</span> <span className="flex-1 truncate">{o.label}</span>
{o.count != null && ( {o.count != null && (
<span className="shrink-0 text-2xs tabular-nums text-muted">{o.count}</span> <span className="shrink-0 text-2xs tabular-nums text-muted">{o.count}</span>
@@ -0,0 +1,19 @@
import { readdirSync, readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
// E28 review L2: `ui/MenuCheck` is the ONE drawn check box of a checkable row (S3e3b replaced seven
// hand-drawn copies), yet FilterSelect and Combobox still painted their own — a 14px box beside the
// menus' 16px one. The filled-box paint is the tell: it may live in MenuCheck only.
describe("the drawn check box", () => {
it("is painted by MenuCheck alone", () => {
const root = new URL("../", import.meta.url);
const offenders = readdirSync(root, { recursive: true, encoding: "utf8" })
.filter((f) => f.endsWith(".tsx") && !f.includes(".test.") && !f.endsWith("MenuCheck.tsx"))
.filter((f) =>
/border-accent bg-accent text-accent-fg/.test(
readFileSync(new URL(f.replace(/\\/g, "/"), root), "utf8"),
),
);
expect(offenders).toEqual([]);
});
});