Implement the 032-inline-confirm-buttons feature that replaces single-click destructive actions with a reusable ConfirmButton component providing inline two-step confirmation (click to arm, click to execute), applied to the remove combatant and clear encounter buttons, with CSS scale pulse animation, 5-second auto-revert, click-outside/Escape/blur dismissal, full keyboard accessibility, and 13 unit tests via @testing-library/react

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lukas
2026-03-11 09:51:21 +01:00
parent d101906776
commit 0747d044f3
17 changed files with 1364 additions and 32 deletions

View File

@@ -11,7 +11,7 @@ import { ConditionPicker } from "./condition-picker";
import { ConditionTags } from "./condition-tags";
import { D20Icon } from "./d20-icon";
import { HpAdjustPopover } from "./hp-adjust-popover";
import { Button } from "./ui/button";
import { ConfirmButton } from "./ui/confirm-button";
import { Input } from "./ui/input";
interface Combatant {
@@ -543,19 +543,12 @@ export function CombatantRow({
</div>
{/* Actions */}
<Button
variant="ghost"
size="icon"
className="h-7 w-7 text-muted-foreground hover:text-hover-destructive opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto focus:opacity-100 focus:pointer-events-auto transition-opacity"
onClick={(e) => {
e.stopPropagation();
onRemove(id);
}}
title="Remove combatant"
aria-label="Remove combatant"
>
<X size={16} />
</Button>
<ConfirmButton
icon={<X size={16} />}
label="Remove combatant"
onConfirm={() => onRemove(id)}
className="h-7 w-7 text-muted-foreground opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto focus:opacity-100 focus:pointer-events-auto transition-opacity"
/>
</div>
</div>
);