Pure `nix fmt` output from the commit before this one — no hand edits. 203 files: 52 md, 42 tsx, 32 js, 32 css, 21 ts, 13 html, 8 json, 3 mjs. Reproduce with `nix develop -c nix fmt` on the parent commit; the result should be byte-identical to this tree. None of the 13 `.prettierignore` entries appears here — verified by intersecting the changed-file list against the ignore file, with a control proving the intersection finds a match when one exists.
35 lines
1.3 KiB
TypeScript
35 lines
1.3 KiB
TypeScript
// Lightweight two-click confirm for a destructive-but-recoverable button
|
|
// ("mark all read", "mark done") — deliberately NOT the old modal system
|
|
// (@hive/shared/modal.js's `themedConfirm`, itself built on the
|
|
// shadow-DOM `<hive-dialog>` custom element): a full backdrop+dialog is
|
|
// more machinery than a "did you mean to click that" nudge needs, and
|
|
// mara's ask for this rewrite was real Preact components, not a port of
|
|
// the old widget family. First click arms the button (caller renders a
|
|
// distinct "sure? click again" label off `armed`); a second click within
|
|
// `resetMs` fires `onConfirm`; anything else (timeout, blur) disarms.
|
|
import { useEffect, useRef, useState } from "preact/hooks";
|
|
|
|
export function useConfirmClick(onConfirm: () => void, resetMs = 2500) {
|
|
const [armed, setArmed] = useState(false);
|
|
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
|
|
useEffect(
|
|
() => () => {
|
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
},
|
|
[],
|
|
);
|
|
|
|
function trigger() {
|
|
if (armed) {
|
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
setArmed(false);
|
|
onConfirm();
|
|
return;
|
|
}
|
|
setArmed(true);
|
|
timerRef.current = setTimeout(() => setArmed(false), resetMs);
|
|
}
|
|
|
|
return { armed, trigger };
|
|
}
|