aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2023-09-21 17:45:06 +0800
committercrupest <crupest@outlook.com>2023-09-21 17:45:21 +0800
commitffe0ef6dc532f5bf0226e074f95a351b36c5abbd (patch)
treef4437b59c982980b94088aebd38039635b54b58a /FrontEnd/src
parent4bedca2bf5f3a6aaef004e7a85a9bfab4a9deede (diff)
downloadtimeline-ffe0ef6dc532f5bf0226e074f95a351b36c5abbd.tar.gz
timeline-ffe0ef6dc532f5bf0226e074f95a351b36c5abbd.tar.bz2
timeline-ffe0ef6dc532f5bf0226e074f95a351b36c5abbd.zip
...
Diffstat (limited to 'FrontEnd/src')
-rw-r--r--FrontEnd/src/components/InPortal.tsx14
-rw-r--r--FrontEnd/src/components/dialog/Dialog.tsx60
-rw-r--r--FrontEnd/src/components/dialog/FullPageDialog.tsx55
3 files changed, 75 insertions, 54 deletions
diff --git a/FrontEnd/src/components/InPortal.tsx b/FrontEnd/src/components/InPortal.tsx
new file mode 100644
index 00000000..7cb57ea8
--- /dev/null
+++ b/FrontEnd/src/components/InPortal.tsx
@@ -0,0 +1,14 @@
+import { ReactNode } from "react";
+import ReactDOM from "react-dom";
+
+const optionalPortalElement = window.document.getElementById("portal");
+if (optionalPortalElement == null) {
+ throw Error("No portal element found.");
+}
+
+const portalElement = optionalPortalElement;
+
+export default function InPortal({ children }: { children: ReactNode }) {
+ return ReactDOM.createPortal(<>{children}</>, portalElement);
+}
+
diff --git a/FrontEnd/src/components/dialog/Dialog.tsx b/FrontEnd/src/components/dialog/Dialog.tsx
index 15c898f1..2d0b34db 100644
--- a/FrontEnd/src/components/dialog/Dialog.tsx
+++ b/FrontEnd/src/components/dialog/Dialog.tsx
@@ -4,6 +4,8 @@ import { CSSTransition } from "react-transition-group";
import { ThemeColor } from "../common";
+import InPortal from "../InPortal";
+
import "./Dialog.css";
interface DialogProps {
@@ -25,35 +27,37 @@ export default function Dialog({
const lastPointerDownIdRef = useRef<number | null>(null);
return (
- <CSSTransition
- nodeRef={nodeRef}
- mountOnEnter
- unmountOnExit
- in={open}
- timeout={300}
- classNames="cru-dialog"
- >
- <div
- ref={nodeRef}
- className={classNames(
- `cru-theme-${color ?? "primary"}`,
- "cru-dialog-overlay",
- )}
+ <InPortal>
+ <CSSTransition
+ nodeRef={nodeRef}
+ mountOnEnter
+ unmountOnExit
+ in={open}
+ timeout={300}
+ classNames="cru-dialog"
>
<div
- className="cru-dialog-background"
- onPointerDown={(e) => {
- lastPointerDownIdRef.current = e.pointerId;
- }}
- onPointerUp={(e) => {
- if (lastPointerDownIdRef.current === e.pointerId) {
- if (!disableCloseOnClickOnOverlay) onClose();
- }
- lastPointerDownIdRef.current = null;
- }}
- />
- <div className="cru-dialog-container">{children}</div>
- </div>
- </CSSTransition>
+ ref={nodeRef}
+ className={classNames(
+ `cru-theme-${color ?? "primary"}`,
+ "cru-dialog-overlay",
+ )}
+ >
+ <div
+ className="cru-dialog-background"
+ onPointerDown={(e) => {
+ lastPointerDownIdRef.current = e.pointerId;
+ }}
+ onPointerUp={(e) => {
+ if (lastPointerDownIdRef.current === e.pointerId) {
+ if (!disableCloseOnClickOnOverlay) onClose();
+ }
+ lastPointerDownIdRef.current = null;
+ }}
+ />
+ <div className="cru-dialog-container">{children}</div>
+ </div>
+ </CSSTransition>
+ </InPortal>
);
}
diff --git a/FrontEnd/src/components/dialog/FullPageDialog.tsx b/FrontEnd/src/components/dialog/FullPageDialog.tsx
index ad5abfde..b0a39ee3 100644
--- a/FrontEnd/src/components/dialog/FullPageDialog.tsx
+++ b/FrontEnd/src/components/dialog/FullPageDialog.tsx
@@ -4,6 +4,7 @@ import { CSSTransition } from "react-transition-group";
import { ThemeColor } from "../common";
import { IconButton } from "../button";
+import InPortal from "../InPortal";
import "./FullPageDialog.css";
@@ -25,35 +26,37 @@ export default function FullPageDialog({
const nodeRef = useRef(null);
return (
- <CSSTransition
- nodeRef={nodeRef}
- mountOnEnter
- unmountOnExit
- in={open}
- timeout={300}
- classNames="cru-dialog-full-page"
- >
- <div
- ref={nodeRef}
- className={`cru-dialog-full-page cru-theme-${color ?? "primary"}`}
+ <InPortal>
+ <CSSTransition
+ nodeRef={nodeRef}
+ mountOnEnter
+ unmountOnExit
+ in={open}
+ timeout={300}
+ classNames="cru-dialog-full-page"
>
- <div className="cru-dialog-full-page-top-bar">
- <IconButton
- icon="arrow-left"
- color="light"
- className="cru-dialog-full-page-back-button"
- onClick={onClose}
- />
- </div>
<div
- className={classNames(
- "cru-dialog-full-page-content-container",
- contentContainerClassName,
- )}
+ ref={nodeRef}
+ className={`cru-dialog-full-page cru-theme-${color ?? "primary"}`}
>
- {children}
+ <div className="cru-dialog-full-page-top-bar">
+ <IconButton
+ icon="arrow-left"
+ color="light"
+ className="cru-dialog-full-page-back-button"
+ onClick={onClose}
+ />
+ </div>
+ <div
+ className={classNames(
+ "cru-dialog-full-page-content-container",
+ contentContainerClassName,
+ )}
+ >
+ {children}
+ </div>
</div>
- </div>
- </CSSTransition>
+ </CSSTransition>
+ </InPortal>
);
}