返回 DeepSeek-Reasonix
InlineConfirmButton.tsx
根目录 / desktop / frontend / src / components / InlineConfirmButton.tsx
1 import { useEffect, useState } from "react";
2
3 // Row-level destructive actions should confirm in place instead of opening a
4 // global modal. First click arms the action, second click confirms it, and the
5 // adjacent Cancel button or any disabled state returns the button to normal.
6 export function InlineConfirmButton({
7 label,
8 confirmLabel,
9 cancelLabel,
10 disabled = false,
11 danger = false,
12 onConfirm,
13 }: {
14 label: string;
15 confirmLabel: string;
16 cancelLabel: string;
17 disabled?: boolean;
18 danger?: boolean;
19 onConfirm: () => void | Promise<void>;
20 }) {
21 const [armed, setArmed] = useState(false);
22
23 useEffect(() => {
24 if (disabled) setArmed(false);
25 }, [disabled]);
26
27 const run = async () => {
28 if (!armed) {
29 setArmed(true);
30 return;
31 }
32 setArmed(false);
33 await onConfirm();
34 };
35
36 return (
37 <span className="inline-confirm">
38 <button
39 className={`btn btn--small${armed && danger ? " btn--danger" : ""}`}
40 disabled={disabled}
41 type="button"
42 onClick={run}
43 >
44 {armed ? confirmLabel : label}
45 </button>
46 {armed && (
47 <button className="btn btn--small" disabled={disabled} type="button" onClick={() => setArmed(false)}>
48 {cancelLabel}
49 </button>
50 )}
51 </span>
52 );
53 }
54
54 lines Plain Text