fix: Make sure we don't toggle models on hover (#12599)

* fix: Make sure we don't toggle models on hover

* Revert to switch with stop prop event

* global stopPropogation property for switches
This commit is contained in:
Eric Hare
2026-04-10 08:22:44 -07:00
committed by GitHub
parent e245d05f62
commit 954bc8065d
3 changed files with 62 additions and 15 deletions

View File

@ -4,25 +4,47 @@ import * as SwitchPrimitives from "@radix-ui/react-switch";
import * as React from "react";
import { cn } from "@/utils/utils";
interface SwitchProps
extends React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> {
stopPropagation?: boolean;
}
const Switch = React.forwardRef<
React.ElementRef<typeof SwitchPrimitives.Root>,
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
>(({ className, ...props }, ref) => (
<SwitchPrimitives.Root
className={cn(
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent px-0.5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
className,
)}
{...props}
ref={ref}
>
<SwitchPrimitives.Thumb
SwitchProps
>(
(
{ className, stopPropagation = false, onClick, onPointerDown, ...props },
ref,
) => (
<SwitchPrimitives.Root
className={cn(
"pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0",
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent px-0.5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
className,
)}
/>
</SwitchPrimitives.Root>
));
onClick={(event) => {
onClick?.(event);
if (stopPropagation) {
event.stopPropagation();
}
}}
onPointerDown={(event) => {
onPointerDown?.(event);
if (stopPropagation) {
event.stopPropagation();
}
}}
{...props}
ref={ref}
>
<SwitchPrimitives.Thumb
className={cn(
"pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0",
)}
/>
</SwitchPrimitives.Root>
),
);
Switch.displayName = SwitchPrimitives.Root.displayName;
export { Switch };

View File

@ -147,6 +147,29 @@ describe("ModelSelection", () => {
expect(onModelToggle).toHaveBeenCalledWith("gpt-4", expect.any(Boolean));
});
it("should not bubble toggle clicks to parent containers", async () => {
const onModelToggle = jest.fn();
const onParentClick = jest.fn();
const user = userEvent.setup();
render(
<div onClick={onParentClick}>
<ModelSelection {...defaultProps} onModelToggle={onModelToggle} />
</div>,
);
const toggle = screen.getByTestId(
"embeddings-toggle-text-embedding-ada-002",
);
await user.click(toggle);
expect(onModelToggle).toHaveBeenCalledWith(
"text-embedding-ada-002",
expect.any(Boolean),
);
expect(onParentClick).not.toHaveBeenCalled();
});
});
describe("Empty States", () => {

View File

@ -46,6 +46,8 @@ const ModelRow = ({
checked={enabled}
onCheckedChange={(checked) => onToggle(model.model_name, checked)}
data-testid={`${testIdPrefix}-toggle-${model.model_name}`}
aria-label={`${enabled ? "Disable" : "Enable"} ${model.model_name}`}
stopPropagation
/>
)}
</div>