Fix ConfirmButton Enter/Space keydown bubbling to parent row handler
The button's onClick stopped mouse event propagation, but keyboard Enter/Space fired a separate keydown event that bubbled to the combatant row's onKeyDown, opening the stat block side panel instead of arming/confirming the button. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -195,4 +195,24 @@ describe("ConfirmButton", () => {
|
|||||||
fireEvent.blur(button);
|
fireEvent.blur(button);
|
||||||
expect(screen.getByTestId("x-icon")).toBeTruthy();
|
expect(screen.getByTestId("x-icon")).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Enter/Space keydown stops propagation to prevent parent handlers", () => {
|
||||||
|
const parentHandler = vi.fn();
|
||||||
|
render(
|
||||||
|
// biome-ignore lint/a11y/noStaticElementInteractions: test wrapper
|
||||||
|
<div onKeyDown={parentHandler}>
|
||||||
|
<ConfirmButton
|
||||||
|
icon={<XIcon />}
|
||||||
|
label="Remove combatant"
|
||||||
|
onConfirm={vi.fn()}
|
||||||
|
/>
|
||||||
|
</div>,
|
||||||
|
);
|
||||||
|
const button = screen.getByRole("button");
|
||||||
|
|
||||||
|
fireEvent.keyDown(button, { key: "Enter" });
|
||||||
|
fireEvent.keyDown(button, { key: " " });
|
||||||
|
|
||||||
|
expect(parentHandler).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ export function ConfirmButton({
|
|||||||
};
|
};
|
||||||
}, [isConfirming, revert]);
|
}, [isConfirming, revert]);
|
||||||
|
|
||||||
|
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
|
||||||
|
if (e.key === "Enter" || e.key === " ") {
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleClick = useCallback(
|
const handleClick = useCallback(
|
||||||
(e: React.MouseEvent) => {
|
(e: React.MouseEvent) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -95,6 +101,7 @@ export function ConfirmButton({
|
|||||||
"bg-destructive text-primary-foreground rounded-md animate-confirm-pulse hover:bg-destructive hover:text-primary-foreground",
|
"bg-destructive text-primary-foreground rounded-md animate-confirm-pulse hover:bg-destructive hover:text-primary-foreground",
|
||||||
)}
|
)}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
onBlur={revert}
|
onBlur={revert}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
aria-label={isConfirming ? `Confirm ${label.toLowerCase()}` : label}
|
aria-label={isConfirming ? `Confirm ${label.toLowerCase()}` : label}
|
||||||
|
|||||||
Reference in New Issue
Block a user