diff --git a/web/modals/modal.css b/web/modals/modal.css index 98ea82f1c..837d23d1a 100644 --- a/web/modals/modal.css +++ b/web/modals/modal.css @@ -1,81 +1,85 @@ div.modalContainer { display: flex; background-color: var(--modal-background-primary-default); border-radius: 8px; flex-direction: column; margin: 20px; overflow: hidden; } div.modalContainerSmall { width: 330px; } div.modalContainerLarge { width: 500px; } .modalHeaderButtonsContainer { margin-left: 24px; display: flex; column-gap: 8px; align-items: center; } .modalButton { color: var(--modal-close-primary-default); } .modalButton:hover { color: var(--modal-close-primary-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(--modal-header-primary-default); 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); } .subheaderContainer { margin-top: 16px; } .modalContentContainer { padding: 16px 32px 24px; } .buttonContainer { background-color: var(--modal-background-secondary-default); padding: 16px 32px; } .primaryButtonContainer > button { width: 100%; } + +.emptyButtonContainerOffset { + height: 8px; +} diff --git a/web/modals/modal.react.js b/web/modals/modal.react.js index b52bd612c..b1136e852 100644 --- a/web/modals/modal.react.js +++ b/web/modals/modal.react.js @@ -1,153 +1,155 @@ // @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, +subtitle?: string, +icon?: Icon, +onClose: () => void, +withCloseButton?: boolean, +size?: ModalSize, +modalHeaderCentered?: boolean, +secondaryHeaderButton?: React.Node, +subheader?: React.Node, +primaryButton?: 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, subheader, primaryButton, } = props; const modalContainerClasses = classNames(css.modalContainer, { [css.modalContainerLarge]: size === 'large', [css.modalContainerSmall]: size === 'small', }); const modalHeader = classNames({ [css.modalHeader]: true, [css.modalHeaderCentered]: modalHeaderCentered, }); const headerButtons = React.useMemo(() => { if (!withCloseButton && !secondaryHeaderButton) { return null; } let closeButton; if (withCloseButton) { closeButton = ( ); } return (
{secondaryHeaderButton}
{closeButton}
); }, [onClose, secondaryHeaderButton, withCloseButton]); const headerIcon = React.useMemo(() => { if (!icon) { return null; } return ; }, [icon]); const subtitleNode = React.useMemo(() => { if (!subtitle) { return null; } return

{subtitle}

; }, [subtitle]); const subheaderContainer = React.useMemo(() => { if (!subheader) { return null; } return
{subheader}
; }, [subheader]); const buttonContainer = React.useMemo(() => { if (!primaryButton) { - return null; + // for empty modals we should add a bottom offset to match the height + // of the padding at the top of the modal + return
; } const className = classNames( css.buttonContainer, css.primaryButtonContainer, ); return
{primaryButton}
; }, [primaryButton]); const modal = React.useMemo( () => (

{headerIcon} {name}

{headerButtons}
{subtitleNode}
{subheaderContainer}
{children}
{buttonContainer}
), [ buttonContainer, children, headerButtons, headerIcon, modalContainerClasses, modalHeader, name, onClose, subheaderContainer, subtitleNode, ], ); return modal; } export default Modal;