diff --git a/web/modals/modal.css b/web/modals/modal.css index 7ee81ecb7..e134a415e 100644 --- a/web/modals/modal.css +++ b/web/modals/modal.css @@ -1,57 +1,64 @@ div.modalContainer { display: flex; background-color: var(--modal-bg); border-radius: 8px; flex-direction: column; margin: 20px; overflow: hidden; } div.modalContainerSmall { width: 330px; } div.modalContainerLarge { width: 500px; } -.modalClose { +.modalHeaderButtonsContainer { + margin-left: 24px; + display: flex; + column-gap: 8px; + align-items: center; +} + +.modalButton { color: var(--modal-close-color); } -.modalClose:hover { +.modalButton:hover { color: var(--modal-close-color-hover); } div.modalHeader { display: flex; flex-direction: column; padding: 32px 32px 0 32px; } div.modalHeaderTitle { display: flex; justify-content: space-between; align-items: center; } div.modalHeaderCentered { justify-content: center; } h2.title { font-size: 20px; font-weight: 500; line-height: 32px; color: var(--fg); display: flex; align-items: center; column-gap: 8px; } h2.subtitle { font-size: var(--xs-font-12); font-weight: 400; line-height: 18px; color: var(--modal-fg); } diff --git a/web/modals/modal.react.js b/web/modals/modal.react.js index 51ba0ef7e..cada016e3 100644 --- a/web/modals/modal.react.js +++ b/web/modals/modal.react.js @@ -1,94 +1,124 @@ // @flow import classNames from 'classnames'; import * as React from 'react'; import ModalOverlay from 'lib/components/modal-overlay.react.js'; import SWMansionIcon, { type Icon, } from 'lib/components/SWMansionIcon.react.js'; import css from './modal.css'; import Button from '../components/button.react.js'; export type ModalSize = 'small' | 'large' | 'fit-content'; export type ModalOverridableProps = { - +name: string, + +name?: string, +subtitle?: string, +icon?: Icon, +onClose: () => void, +withCloseButton?: boolean, +size?: ModalSize, +modalHeaderCentered?: boolean, + +secondaryHeaderButton?: React.Node, }; type ModalProps = { ...ModalOverridableProps, +children?: React.Node, }; function Modal(props: ModalProps): React.Node { const { size = 'small', children, onClose, name, subtitle, icon, withCloseButton = true, modalHeaderCentered = false, + secondaryHeaderButton, } = props; const modalContainerClasses = classNames(css.modalContainer, { [css.modalContainerLarge]: size === 'large', [css.modalContainerSmall]: size === 'small', }); const modalHeader = classNames({ [css.modalHeader]: true, [css.modalHeaderCentered]: modalHeaderCentered, }); - const cornerCloseButton = React.useMemo(() => { - if (!withCloseButton) { + const headerButtons = React.useMemo(() => { + if (!withCloseButton && !secondaryHeaderButton) { return null; } + + let closeButton; + if (withCloseButton) { + closeButton = ( + + ); + } + return ( - +
+
{secondaryHeaderButton}
+ {closeButton} +
); - }, [onClose, withCloseButton]); + }, [onClose, secondaryHeaderButton, withCloseButton]); const headerIcon = React.useMemo(() => { if (!icon) { return null; } return ; }, [icon]); - let subtitleNode; - if (subtitle) { - subtitleNode =

{subtitle}

; - } - return ( - -
-
-
-

- {headerIcon} - {name} -

- {cornerCloseButton} + const subtitleNode = React.useMemo(() => { + if (!subtitle) { + return null; + } + return

{subtitle}

; + }, [subtitle]); + + const modal = React.useMemo( + () => ( + +
+
+
+

+ {headerIcon} + {name} +

+ {headerButtons} +
+ {subtitleNode}
- {subtitleNode} + {children}
- {children} -
- + + ), + [ + children, + headerButtons, + headerIcon, + modalContainerClasses, + modalHeader, + name, + onClose, + subtitleNode, + ], ); + + return modal; } export default Modal; diff --git a/web/modals/user-profile/user-profile-modal.react.js b/web/modals/user-profile/user-profile-modal.react.js index 4c2bbeed5..57945b62a 100644 --- a/web/modals/user-profile/user-profile-modal.react.js +++ b/web/modals/user-profile/user-profile-modal.react.js @@ -1,37 +1,37 @@ // @flow import * as React from 'react'; import { useModalContext } from 'lib/components/modal-provider.react.js'; import type { UserInfo } from 'lib/types/user-types.js'; import UserProfile from './user-profile.react.js'; import { useSelector } from '../../redux/redux-utils.js'; import Modal from '../modal.react.js'; type Props = { +userID: string, }; function UserProfileModal(props: Props): React.Node { const { userID } = props; const { popModal } = useModalContext(); const userInfo: ?UserInfo = useSelector( state => state.userStore.userInfos[userID], ); const userProfileModal = React.useMemo( () => ( - + ), [popModal, userInfo], ); return userProfileModal; } export default UserProfileModal;