Skip to content

Commit

Permalink
feat(confirmationContext): add confirmationContext for managing yes/n…
Browse files Browse the repository at this point in the history
…o modals (#19)

* add confirmation context

* Remove empty function
  • Loading branch information
carlosthe19916 authored Dec 23, 2021
1 parent 813b5e2 commit 70ba353
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 0 deletions.
166 changes: 166 additions & 0 deletions src/context/ConfirmationContext.tsx
Original file line number Diff line number Diff line change
@@ -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<any>;
message: string | React.ReactNode;
confirmBtnLabel: string;
cancelBtnLabel: string;
confirmBtnVariant: ButtonVariant;
onConfirm: () => void;
}

const openAction = createAction('open')<Options>();
const enableProcessingAction = createAction('enableProcessing')();
const closeAction = createAction('close')();

interface IConfirmmationContext {
open: (options: Options) => void;
enableProcessing: () => void;
close: () => void;
}

const ConfirmationContext = React.createContext<IConfirmmationContext>({
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<any>;
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<IConfirmationContextProviderProps> =
({ 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 = (
<Button
key="confirm"
aria-label="confirm"
variant={state.confirmBtnVariant}
isDisabled={state.isProcessing}
onClick={state.onConfirm}
>
{state.confirmBtnLabel}
</Button>
);

const cancelBtn = !state.hideCancelBtn ? (
<Button
key="cancel"
aria-label="cancel"
variant={ButtonVariant.link}
isDisabled={state.isProcessing}
onClick={onCancel}
>
{state.cancelBtnLabel}
</Button>
) : undefined;

return (
<ConfirmationContext.Provider
value={{
open: onOpen,
enableProcessing: onProcessing,
close: onCancel,
}}
>
{children}
<Modal
variant={ModalVariant.small}
title={state.title}
titleIconVariant={state.titleIconVariant}
isOpen={state.isOpen}
onClose={onCancel}
aria-label="confirm-dialog"
actions={!state.hideCancelBtn ? [confirmBtn, cancelBtn] : [confirmBtn]}
>
{state.message}
</Modal>
</ConfirmationContext.Provider>
);
};

export const useConfirmationContext = (): IConfirmmationContext =>
React.useContext(ConfirmationContext);
1 change: 1 addition & 0 deletions src/context/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ConfirmationContext";
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ export * from './hooks/useModal';
export * from './hooks/useTable';
export * from './hooks/useTableControls';
export * from './hooks/useToolbar';

export * from './context/ConfirmationContext';

0 comments on commit 70ba353

Please sign in to comment.