diff options
Diffstat (limited to 'FrontEnd/src/components/dialog')
-rw-r--r-- | FrontEnd/src/components/dialog/Dialog.css | 33 | ||||
-rw-r--r-- | FrontEnd/src/components/dialog/Dialog.tsx | 50 | ||||
-rw-r--r-- | FrontEnd/src/components/dialog/DialogOverlay.css | 13 | ||||
-rw-r--r-- | FrontEnd/src/components/dialog/DialogOverlay.tsx | 66 | ||||
-rw-r--r-- | FrontEnd/src/components/dialog/FullPageDialog.css | 43 | ||||
-rw-r--r-- | FrontEnd/src/components/dialog/FullPageDialog.tsx | 63 |
6 files changed, 135 insertions, 133 deletions
diff --git a/FrontEnd/src/components/dialog/Dialog.css b/FrontEnd/src/components/dialog/Dialog.css index 3f0f9cb6..387f6f21 100644 --- a/FrontEnd/src/components/dialog/Dialog.css +++ b/FrontEnd/src/components/dialog/Dialog.css @@ -1,26 +1,9 @@ -.cru-dialog-overlay {
- position: fixed;
- z-index: 1040;
- left: 0;
- top: 0;
- right: 0;
- bottom: 0;
+.cru-dialog-normal {
overflow: auto;
- padding: 20vh 1em;
+ padding: 20vh 1em 0;
}
-.cru-dialog-background {
- position: absolute;
- z-index: -1;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- background-color: var(--cru-dialog-overlay-color);
- opacity: 0.8;
-}
-
-.cru-dialog-container {
+.cru-dialog-normal .cru-dialog-container {
max-width: 100%;
min-width: 30vw;
@@ -33,18 +16,18 @@ }
@media (min-width: 576px) {
- .cru-dialog-container {
+ .cru-dialog-normal .cru-dialog-container {
max-width: 800px;
}
}
-.cru-dialog-enter .cru-dialog-container {
+.cru-dialog-normal-enter .cru-dialog-container {
opacity: 0;
transform: scale(0, 0);
transform-origin: center;
}
-.cru-dialog-enter-active .cru-dialog-container {
+.cru-dialog-normal-enter-active .cru-dialog-container {
opacity: 1;
transform: scale(1, 1);
transform-origin: center;
@@ -53,13 +36,13 @@ opacity 0.3s;
}
-.cru-dialog-exit .cru-dialog-container {
+.cru-dialog-normal-exit .cru-dialog-container {
opacity: 1;
transform: scale(1, 1);
transform-origin: center;
}
-.cru-dialog-exit-active .cru-dialog-container {
+.cru-dialog-normal-exit-active .cru-dialog-container {
opacity: 0;
transform: scale(0, 0);
transform-origin: center;
diff --git a/FrontEnd/src/components/dialog/Dialog.tsx b/FrontEnd/src/components/dialog/Dialog.tsx index 2d0b34db..b5524a11 100644 --- a/FrontEnd/src/components/dialog/Dialog.tsx +++ b/FrontEnd/src/components/dialog/Dialog.tsx @@ -1,10 +1,8 @@ -import { ReactNode, useRef } from "react"; -import classNames from "classnames"; -import { CSSTransition } from "react-transition-group"; +import { ReactNode } from "react"; import { ThemeColor } from "../common"; -import InPortal from "../InPortal"; +import DialogOverlay from "./DialogOverlay"; import "./Dialog.css"; @@ -23,41 +21,15 @@ export default function Dialog({ children, disableCloseOnClickOnOverlay, }: DialogProps) { - const nodeRef = useRef(null); - const lastPointerDownIdRef = useRef<number | null>(null); - return ( - <InPortal> - <CSSTransition - nodeRef={nodeRef} - mountOnEnter - unmountOnExit - in={open} - timeout={300} - classNames="cru-dialog" - > - <div - 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> + <DialogOverlay + open={open} + onClose={onClose} + transitionClassNames="cru-dialog-normal" + overlayClassName={`cru-dialog-normal cru-theme-${color ?? "primary"}`} + disableCloseOnClickOnOverlay={disableCloseOnClickOnOverlay} + > + {children} + </DialogOverlay> ); } diff --git a/FrontEnd/src/components/dialog/DialogOverlay.css b/FrontEnd/src/components/dialog/DialogOverlay.css new file mode 100644 index 00000000..51a124fa --- /dev/null +++ b/FrontEnd/src/components/dialog/DialogOverlay.css @@ -0,0 +1,13 @@ +.cru-dialog-overlay { + position: fixed; + z-index: 1040; + inset: 0; +} + +.cru-dialog-background { + position: fixed; + z-index: -1; + inset: 0; + background-color: var(--cru-dialog-overlay-color); + opacity: 0.8; +} diff --git a/FrontEnd/src/components/dialog/DialogOverlay.tsx b/FrontEnd/src/components/dialog/DialogOverlay.tsx new file mode 100644 index 00000000..f7b58474 --- /dev/null +++ b/FrontEnd/src/components/dialog/DialogOverlay.tsx @@ -0,0 +1,66 @@ +import { ReactNode, useRef } from "react"; +import classNames from "classnames"; +import { CSSTransition } from "react-transition-group"; + +import InPortal from "../InPortal"; + +import "./DialogOverlay.css"; + +interface DialogOverlayProps { + open: boolean; + onClose: () => void; + transitionClassNames: string; + overlayClassName?: string; + containerClassName?: string; + children?: ReactNode; + disableCloseOnClickOnOverlay?: boolean; +} + +export default function DialogOverlay({ + open, + onClose, + transitionClassNames, + overlayClassName, + containerClassName, + children, + disableCloseOnClickOnOverlay, +}: DialogOverlayProps) { + const nodeRef = useRef(null); + const lastPointerDownIdRef = useRef<number | null>(null); + + return ( + <InPortal> + <CSSTransition + nodeRef={nodeRef} + mountOnEnter + unmountOnExit + in={open} + timeout={300} + classNames={transitionClassNames} + > + <div + ref={nodeRef} + className={classNames("cru-dialog-overlay", overlayClassName)} + > + <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={classNames("cru-dialog-container", containerClassName)} + > + {children} + </div> + </div> + </CSSTransition> + </InPortal> + ); +} diff --git a/FrontEnd/src/components/dialog/FullPageDialog.css b/FrontEnd/src/components/dialog/FullPageDialog.css index 3ba8ba15..175cbb40 100644 --- a/FrontEnd/src/components/dialog/FullPageDialog.css +++ b/FrontEnd/src/components/dialog/FullPageDialog.css @@ -1,45 +1,32 @@ -.cru-dialog-full-page {
- position: fixed;
- z-index: 1030;
- left: 0;
- top: 0;
- right: 0;
+.cru-dialog-full-page .cru-dialog-container {
+ position: absolute;
bottom: 0;
+ width: 100%;
+ height: 85%;
+ border-top: 2px solid var(--cru-theme-color);
+ padding-top: 0.5em;
background-color: var(--cru-background-color);
- padding-top: 56px;
}
-.cru-dialog-full-page-top-bar {
- height: 56px;
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- z-index: 1;
- background-color: var(--cru-theme-color);
- display: flex;
- align-items: center;
-}
-
-.cru-dialog-full-page-content-container {
+.cru-dialog-full-page-content {
overflow: scroll;
}
-.cru-dialog-full-page-back-button {
- margin-left: 0.5em;
+.cru-dialog-full-page-back {
+ float: right;
+ padding-right: 0.5em;
}
-.cru-dialog-full-page-enter {
- transform: translate(100%, 0);
+.cru-dialog-full-page-enter .cru-dialog-container {
+ transform: translate(0, 100%);
}
-.cru-dialog-full-page-enter-active {
+.cru-dialog-full-page-enter-active .cru-dialog-container {
transform: none;
transition: transform 0.3s;
}
-.cru-dialog-full-page-exit-active {
+.cru-dialog-full-page-exit-active .cru-dialog-container {
transition: transform 0.3s;
- transform: translate(100%, 0);
+ transform: translate(0, 100%);
}
-
diff --git a/FrontEnd/src/components/dialog/FullPageDialog.tsx b/FrontEnd/src/components/dialog/FullPageDialog.tsx index b0a39ee3..44ea2a7b 100644 --- a/FrontEnd/src/components/dialog/FullPageDialog.tsx +++ b/FrontEnd/src/components/dialog/FullPageDialog.tsx @@ -1,10 +1,8 @@ -import { ReactNode, useRef } from "react"; -import classNames from "classnames"; -import { CSSTransition } from "react-transition-group"; +import { ReactNode } from "react"; import { ThemeColor } from "../common"; import { IconButton } from "../button"; -import InPortal from "../InPortal"; +import DialogOverlay from "./DialogOverlay"; import "./FullPageDialog.css"; @@ -12,8 +10,8 @@ interface FullPageDialogProps { open: boolean; onClose: () => void; color?: ThemeColor; - contentContainerClassName?: string; - children: ReactNode; + children?: ReactNode; + disableCloseOnClickOnOverlay?: boolean; } export default function FullPageDialog({ @@ -21,42 +19,25 @@ export default function FullPageDialog({ onClose, color, children, - contentContainerClassName, + disableCloseOnClickOnOverlay, }: FullPageDialogProps) { - const nodeRef = useRef(null); - return ( - <InPortal> - <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"}`} - > - <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> - </CSSTransition> - </InPortal> + <DialogOverlay + open={open} + onClose={onClose} + transitionClassNames="cru-dialog-full-page" + overlayClassName={`cru-dialog-full-page cru-theme-${color ?? "primary"}`} + disableCloseOnClickOnOverlay={disableCloseOnClickOnOverlay} + > + <div className="cru-dialog-full-page-content"> + <IconButton + icon="x-lg" + color={color ?? "primary"} + className="cru-dialog-full-page-back" + onClick={onClose} + /> + {children} + </div> + </DialogOverlay> ); } |