fix(analyzer): multi-select option click swallowed by nested Radix button

Radix Checkbox renders as <button role="checkbox">, which we were nesting
inside the option <button>. Browsers can swallow the outer click in that
arrangement despite pointer-events-none on the inner element. Replaced the
option with <div role="option" tabIndex={0}> and an inline non-button
visual checkbox (square + Check icon when selected). Keyboard support
(Enter/Space) preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
lorentz 2026-04-29 14:26:50 -04:00
parent bd3401df1c
commit 98843a80ba

View file

@ -8,9 +8,8 @@ import {
} from '@/components/ui/popover';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Checkbox } from '@/components/ui/checkbox';
import { Badge } from '@/components/ui/badge';
import { ChevronDown, Search, X } from 'lucide-react';
import { Check, ChevronDown, Search, X } from 'lucide-react';
export interface MultiSelectOption {
value: string;
@ -127,15 +126,32 @@ export function MultiSelect({
filtered.map((opt) => {
const checked = valueSet.has(opt.value);
return (
<button
<div
key={opt.value}
type="button"
role="option"
aria-selected={checked}
tabIndex={0}
onClick={() => toggle(opt.value)}
className="flex items-center gap-2 w-full px-3 py-1.5 text-sm hover:bg-accent text-left"
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
toggle(opt.value);
}
}}
className="flex items-center gap-2 w-full px-3 py-1.5 text-sm hover:bg-accent cursor-pointer select-none focus:bg-accent focus:outline-none"
>
<Checkbox checked={checked} className="pointer-events-none" />
<span
className={`w-4 h-4 shrink-0 rounded-sm border flex items-center justify-center transition ${
checked
? 'bg-primary border-primary text-primary-foreground'
: 'border-input bg-background'
}`}
aria-hidden="true"
>
{checked && <Check className="w-3 h-3" strokeWidth={3} />}
</span>
<span className="truncate">{opt.label}</span>
</button>
</div>
);
})
)}