1 import { type Dispatch, type SetStateAction, useCallback, useState } from 'react';
3 import type { Maybe, MaybeNull } from '@proton/pass/types';
4 import { pipe, tap } from '@proton/pass/utils/fp/pipe';
5 import noop from '@proton/utils/noop';
7 type UseConfirmResult<P, R> = {
9 confirm: () => Maybe<R>;
10 prompt: Dispatch<SetStateAction<MaybeNull<P>>>;
11 } & ({ pending: true; param: P } | { pending: false; param: null });
14 * The `useConfirm` hook lets you manage and confirm the execution of a callback.
15 * It allows you to initiate an action, confirm it when ready, and cancel it if
16 * necessary. This hook is particularly useful when you want to confirm a potentially
17 * destructive action, such as deleting an item, before executing it. Typically you
18 * would use the `pending` state to toggle the visiblity of a prompt, ie :
21 * const action = useConfirm((id: string) => items.remove(id))
22 * // call `action.prompt('some-id')` to initiate
25 * open={action.pending}
26 * onClose={action.cancel}
27 * onSubmit={action.confirm}
31 export const useConfirm = <P extends any, R extends any>(action: (param: P) => R) => {
32 const [param, setParam] = useState<MaybeNull<P>>(null);
34 const cancel = useCallback(() => setParam(null), []);
35 const confirm = useCallback(pipe(param ? () => action(param) : noop, tap(cancel)), [param, action]);
39 pending: param !== null,
43 } as UseConfirmResult<P, R>;