From 70ba3530159fed9b18bfcf1930ee1c1993add441 Mon Sep 17 00:00:00 2001 From: "Carlos E. Feria Vila" Date: Thu, 23 Dec 2021 10:41:30 +0100 Subject: [PATCH] feat(confirmationContext): add confirmationContext for managing yes/no modals (#19) * add confirmation context * Remove empty function --- src/context/ConfirmationContext.tsx | 166 ++++++++++++++++++++++++++++ src/context/index.ts | 1 + src/index.ts | 2 + 3 files changed, 169 insertions(+) create mode 100644 src/context/ConfirmationContext.tsx create mode 100644 src/context/index.ts diff --git a/src/context/ConfirmationContext.tsx b/src/context/ConfirmationContext.tsx new file mode 100644 index 0000000..0566ef2 --- /dev/null +++ b/src/context/ConfirmationContext.tsx @@ -0,0 +1,166 @@ +import React, { useReducer } from 'react'; +import { ActionType, createAction, getType } from 'typesafe-actions'; +import { Button, ButtonVariant, Modal, ModalVariant } from '@patternfly/react-core'; + +interface Options { + title: string; + titleIconVariant?: + | 'success' + | 'danger' + | 'warning' + | 'info' + | 'default' + | React.ComponentType; + message: string | React.ReactNode; + confirmBtnLabel: string; + cancelBtnLabel: string; + confirmBtnVariant: ButtonVariant; + onConfirm: () => void; +} + +const openAction = createAction('open')(); +const enableProcessingAction = createAction('enableProcessing')(); +const closeAction = createAction('close')(); + +interface IConfirmmationContext { + open: (options: Options) => void; + enableProcessing: () => void; + close: () => void; +} + +const ConfirmationContext = React.createContext({ + open: () => undefined, + enableProcessing: () => undefined, + close: () => undefined, +}); + +// + +export type Action = ActionType< + typeof openAction | typeof enableProcessingAction | typeof closeAction +>; + +export type State = Readonly<{ + isOpen: boolean; + isProcessing: boolean; + + title: string; + titleIconVariant?: + | 'success' + | 'danger' + | 'warning' + | 'info' + | 'default' + | React.ComponentType; + message: string | React.ReactNode; + confirmBtnLabel: string; + cancelBtnLabel: string; + confirmBtnVariant: ButtonVariant; + + hideCancelBtn: boolean; + + onConfirm: () => void; +}>; + +export const defaultState: State = { + isOpen: false, + isProcessing: false, + + title: '', + titleIconVariant: undefined, + message: '', + confirmBtnLabel: 'Confirm', + cancelBtnLabel: 'Cancel', + confirmBtnVariant: ButtonVariant.primary, + + hideCancelBtn: false, + + onConfirm: () => undefined, +}; + +const reducer = (state: State, action: Action): State => { + switch (action.type) { + case getType(openAction): + return { + ...state, + ...action.payload, + isOpen: true, + }; + case getType(enableProcessingAction): + return { + ...state, + isProcessing: true, + }; + case getType(closeAction): + return defaultState; + default: + return state; + } +}; + +// + +interface IConfirmationContextProviderProps { + children: React.ReactNode; +} + +export const ConfirmationContextProvider: React.FunctionComponent = + ({ children }: IConfirmationContextProviderProps) => { + const [state, dispatch] = useReducer(reducer, { ...defaultState }); + + const onOpen = (options: Options) => dispatch(openAction(options)); + const onProcessing = () => dispatch(enableProcessingAction()); + const onCancel = () => { + dispatch(closeAction()); + }; + + const confirmBtn = ( + + ); + + const cancelBtn = !state.hideCancelBtn ? ( + + ) : undefined; + + return ( + + {children} + + {state.message} + + + ); + }; + +export const useConfirmationContext = (): IConfirmmationContext => + React.useContext(ConfirmationContext); diff --git a/src/context/index.ts b/src/context/index.ts new file mode 100644 index 0000000..ed287a8 --- /dev/null +++ b/src/context/index.ts @@ -0,0 +1 @@ +export * from "./ConfirmationContext"; diff --git a/src/index.ts b/src/index.ts index 71c4422..95ad309 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,3 +9,5 @@ export * from './hooks/useModal'; export * from './hooks/useTable'; export * from './hooks/useTableControls'; export * from './hooks/useToolbar'; + +export * from './context/ConfirmationContext';