diff options
author | crupest <crupest@outlook.com> | 2023-09-21 17:45:06 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2023-09-21 17:45:21 +0800 |
commit | ffe0ef6dc532f5bf0226e074f95a351b36c5abbd (patch) | |
tree | f4437b59c982980b94088aebd38039635b54b58a /FrontEnd | |
parent | 4bedca2bf5f3a6aaef004e7a85a9bfab4a9deede (diff) | |
download | timeline-ffe0ef6dc532f5bf0226e074f95a351b36c5abbd.tar.gz timeline-ffe0ef6dc532f5bf0226e074f95a351b36c5abbd.tar.bz2 timeline-ffe0ef6dc532f5bf0226e074f95a351b36c5abbd.zip |
...
Diffstat (limited to 'FrontEnd')
-rw-r--r-- | FrontEnd/index.html | 1 | ||||
-rw-r--r-- | FrontEnd/src/components/InPortal.tsx | 14 | ||||
-rw-r--r-- | FrontEnd/src/components/dialog/Dialog.tsx | 60 | ||||
-rw-r--r-- | FrontEnd/src/components/dialog/FullPageDialog.tsx | 55 |
4 files changed, 76 insertions, 54 deletions
diff --git a/FrontEnd/index.html b/FrontEnd/index.html index 64f55c90..859c3be7 100644 --- a/FrontEnd/index.html +++ b/FrontEnd/index.html @@ -26,6 +26,7 @@ </strong>
</noscript>
<div id="app"></div>
+ <div id="portal"></div>
<script type="module" src="./src/index.tsx"></script>
</body>
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> ); } |