Skip to content

Commit

Permalink
Add ConfirmationModal from Tobira
Browse files Browse the repository at this point in the history
Adds the confirmation modal from tobira
  • Loading branch information
Arnei committed May 23, 2024
1 parent 2339768 commit 21e3b30
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
101 changes: 101 additions & 0 deletions src/confirmationModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import {
ReactNode,
FormEvent,
PropsWithChildren,
forwardRef,
useState,
useRef,
useImperativeHandle,
} from "react";
import { bug, ModalProps, ModalHandle, Modal, Spinner, Button, boxError } from ".";
import { currentRef } from "./utilFunc";


type ConfirmationModalProps = Omit<ModalProps, "closable" | "title"> & {
title?: string;
buttonContent: ReactNode;
onSubmit?: () => void;
text: {
generalActionCancel: string,
generalActionClose: string,
manageAreYouSure: string,
},
};

export type ConfirmationModalHandle = ModalHandle & {
done: () => void;
reportError: (error: JSX.Element) => void;
};

export const ConfirmationModal
= forwardRef<ConfirmationModalHandle, PropsWithChildren<ConfirmationModalProps>>(
({
title: titleOverride,
buttonContent,
onSubmit,
text,
children,
}, ref) => {
const title = titleOverride ?? text.manageAreYouSure ?? bug("missing translation");

const [inFlight, setInFlight] = useState(false);
const [error, setError] = useState<JSX.Element | undefined>();

const modalRef = useRef<ModalHandle>(null);

useImperativeHandle(ref, () => ({
open: () => {
setInFlight(false);
setError(undefined);
currentRef(modalRef).open();
},
done: () => {
currentRef(modalRef).close?.();
},
reportError: (error: JSX.Element) => {
setInFlight(false);
setError(error);
},
}));

const onSubmitWrapper = (event: FormEvent) => {
event.preventDefault();
// Don't let the event escape the portal,
// which might be sitting inside of other `form` elements.
event.stopPropagation();
setInFlight(true);
setError(undefined);
onSubmit?.();
};

return <Modal
title={title}
closable={!inFlight}
ref={modalRef}
text={{ generalActionClose: text.generalActionClose }}
>
{children}
<form onSubmit={onSubmitWrapper} css={{ marginTop: 32 }}>
<div css={{
display: "flex",
gap: 12,
justifyContent: "center",
flexWrap: "wrap",
}}>
<Button disabled={inFlight} onClick={
() => currentRef(modalRef).close?.()
}>
{text.generalActionCancel}
</Button>
<Button disabled={inFlight} type="submit" kind="danger" css={{
whiteSpace: "normal",
}}>
{buttonContent}
</Button>
</div>
{inFlight && <div css={{ marginTop: 16 }}><Spinner size={20} /></div>}
</form>
{boxError(error)}
</Modal>;
},
);
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from "./button";
export * from "./card";
export * from "./colorScheme";
export * from "./config";
export * from "./confirmationModal";
export * from "./err";
export * from "./errorBox";
export * from "./floating";
Expand Down

0 comments on commit 21e3b30

Please sign in to comment.