From 905f34156472e6c94879e54b05c5a8fc65729dee Mon Sep 17 00:00:00 2001 From: Doug Martin Date: Thu, 26 Sep 2024 11:29:26 -0400 Subject: [PATCH] feat: Replace browser confirm dialog with lightbox dialog [PT-188245120] This should prevent fullscreen mode from exiting due to the system confirm dialog showing. --- src/components/app.tsx | 41 +++++++++++++++++---------- src/components/confirm-modal.scss | 46 +++++++++++++++++++++++++++++++ src/components/confirm-modal.tsx | 35 +++++++++++++++++++++++ 3 files changed, 108 insertions(+), 14 deletions(-) create mode 100644 src/components/confirm-modal.scss create mode 100644 src/components/confirm-modal.tsx diff --git a/src/components/app.tsx b/src/components/app.tsx index 804a67e..c09777d 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -14,6 +14,7 @@ import PauseIcon from "../assets/pause.svg"; import DropdownUpArrowIcon from "../assets/dropdown-up-arrow-icon.svg"; import DropdownDownArrowIcon from "../assets/dropdown-down-arrow-icon.svg"; import { SpeedToggle } from "./speed-toggle"; +import { ConfirmModal, IConfirmModal } from "./confirm-modal"; import "./app.scss"; @@ -146,6 +147,7 @@ export const App = () => { const [highlightOutput, setHighlightOutput] = useState<{group: SequenceGroup, sequence: Node[]}|undefined>(); const [delimiterType, setDelimiterType] = useState( delimiter === "" ? "none" : (delimiter === " " ? "space" : "other")); + const [confirmModal, setConfirmModal] = useState(undefined); const handleDimensionChange = ({width, height}: {width: number, height: number}) => { widthRef.current = width; @@ -519,23 +521,33 @@ export const App = () => { }; const handleReset = useCallback(() => { - if (confirm("Are you sure you want to reset?\n\nAny changes you have made will be lost.")) { - setLengthLimit(defaultLengthLimit); - setDelimiter(defaultDelimiter); - setStartingState(defaultStartingState); - setSequenceGroups([]); - setFastSimulation(defaultFastSimulation); - setGraph(initialGraph ? {...initialGraph} : {nodes: [], edges: []}); - setFitViewAt(Date.now()); - } + setConfirmModal({ + title: "Reset?", + message: <>Are you sure you want to reset?
Any changes you have made will be lost., + onOk: () => { + setLengthLimit(defaultLengthLimit); + setDelimiter(defaultDelimiter); + setStartingState(defaultStartingState); + setSequenceGroups([]); + setFastSimulation(defaultFastSimulation); + setGraph(initialGraph ? {...initialGraph} : {nodes: [], edges: []}); + setFitViewAt(Date.now()); + }, + onClose: () => setConfirmModal(undefined) + }); }, [initialGraph, setGraph]); const handleReturnToMainMenu = () => { - if (confirm("Are you sure you want to go back to the main menu?\n\nAny changes you have made will be lost.")) { - setGraph({nodes: [], edges: []}); - setInitialGraph(undefined); - setViewMode(undefined); - } + setConfirmModal({ + title: "Back To Main Menu?", + message: <>Are you sure you want to go back to the main menu?
Any changes you have made will be lost., + onOk: () => { + setGraph({nodes: [], edges: []}); + setInitialGraph(undefined); + setViewMode(undefined); + }, + onClose: () => setConfirmModal(undefined) + }); }; const handleFitView = () => { @@ -636,6 +648,7 @@ export const App = () => { } {maybeRenderRightBar()} + {confirmModal && } ); diff --git a/src/components/confirm-modal.scss b/src/components/confirm-modal.scss new file mode 100644 index 0000000..6abec62 --- /dev/null +++ b/src/components/confirm-modal.scss @@ -0,0 +1,46 @@ +.confirmModalBackground { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: #000; + opacity: 0.25; + z-index: 100; +} +.confirmModal { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; + justify-content: center; + align-items: center; + z-index: 101; + user-select: none; + + .confirmModalContent { + min-width: 200px; + + .confirmModalTitle { + background-color: #177991; + color: white; + padding: 5px 10px; + } + + .confirmModalInnerContent { + padding: 10px; + background-color: white; + display: flex; + flex-direction: column; + gap: 10px; + + .confirmModalButtons { + display: flex; + gap: 5px; + justify-content: flex-end; + } + } + } +} \ No newline at end of file diff --git a/src/components/confirm-modal.tsx b/src/components/confirm-modal.tsx new file mode 100644 index 0000000..9c994bc --- /dev/null +++ b/src/components/confirm-modal.tsx @@ -0,0 +1,35 @@ +import React, { ReactNode } from "react"; + +import "./confirm-modal.scss"; + +export interface IConfirmModal { + title: string; + message: string|ReactNode; + onOk: () => void, + onClose: () => void +} + +export const ConfirmModal = ({ title, message, onOk, onClose }: IConfirmModal) => { + const handleOk = () => { + onOk(); + onClose(); + }; + + return ( + <> +
+
+
+
{title}
+
+ {message} +
+ + +
+
+
+
+ + ); +};