Update selected item color in Pass menu
[ProtonMail-WebClient.git] / packages / pass / hooks / useConfirm.ts
blob387788cab96ca4e1dead35bc1d8972bb9727e878
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> = {
8     cancel: () => void;
9     confirm: () => Maybe<R>;
10     prompt: Dispatch<SetStateAction<MaybeNull<P>>>;
11 } & ({ pending: true; param: P } | { pending: false; param: null });
13 /**
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 :
19  *
20  * ```typescript
21  * const action = useConfirm((id: string) => items.remove(id))
22  * // call `action.prompt('some-id')` to initiate
23  *
24  * <Prompt
25  *   open={action.pending}
26  *   onClose={action.cancel}
27  *   onSubmit={action.confirm}
28  * />
29  * ```
30  */
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]);
37     return {
38         param,
39         pending: param !== null,
40         cancel,
41         confirm,
42         prompt: setParam,
43     } as UseConfirmResult<P, R>;