From 796583d1a06f71a65dc5f81cf04b1361cc522b2d Mon Sep 17 00:00:00 2001 From: Vadzim Hvazdovich Date: Fri, 19 Jul 2024 17:27:46 +0300 Subject: [PATCH 1/5] EPMRPP-89804 || Update Modal component --- src/components/modal/modal.module.scss | 2 +- src/components/modal/modal.stories.tsx | 47 ++++++++++++++++++- src/components/modal/modal.tsx | 37 +++++++++++---- .../modalContent/modalContent.module.scss | 2 +- .../modal/modalHeader/modalHeader.module.scss | 20 ++++++-- .../modal/modalHeader/modalHeader.tsx | 17 ++++++- 6 files changed, 107 insertions(+), 18 deletions(-) diff --git a/src/components/modal/modal.module.scss b/src/components/modal/modal.module.scss index 1a0040b..3612d4c 100644 --- a/src/components/modal/modal.module.scss +++ b/src/components/modal/modal.module.scss @@ -45,7 +45,7 @@ $WIDTH-LARGE: 720px; transform: translate(-50%); display: inline-block; margin-bottom: 10px; - padding: 32px 48px; + padding: 32px 40px; box-sizing: border-box; background-color: var(--rp-ui-base-bg-100); text-align: left; diff --git a/src/components/modal/modal.stories.tsx b/src/components/modal/modal.stories.tsx index 6bbbadc..cca6651 100644 --- a/src/components/modal/modal.stories.tsx +++ b/src/components/modal/modal.stories.tsx @@ -1,5 +1,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Modal } from './modal'; +import { FC, useState } from 'react'; +import { Button } from '@components/button'; const meta: Meta = { title: 'Modal', @@ -32,6 +34,49 @@ export const Default: Story = { args: {}, }; +export const WithoutFooter: Story = { + args: { + withoutFooter: true, + headerDescription: 'title description', + }, +}; + +export const WithSteps: Story = { + render: (args) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const [step, setStep] = useState(1); + + const CustomFooter: FC<{ closeHandler: () => void }> = ({ closeHandler }) => { + return ( +
+ + + + +
+ ); + }; + + return ( + + content for step {step} + + ); + }, +}; + export const Small: Story = { args: { size: 'small', @@ -55,7 +100,7 @@ export const Scrollable: Story = { scrollable: true, children: ( <> -

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in diff --git a/src/components/modal/modal.tsx b/src/components/modal/modal.tsx index 7539a8e..44ec79a 100644 --- a/src/components/modal/modal.tsx +++ b/src/components/modal/modal.tsx @@ -18,7 +18,7 @@ const MODAL_HEADER_AND_FOOTER_HEIGHT = 176; type ModalOverlay = 'default' | 'light-cyan'; interface ModalProps { - onClose: () => void; + onClose?: () => void; title?: ReactNode; headerNode?: ReactNode; children?: ReactNode; @@ -31,6 +31,10 @@ interface ModalProps { okButton?: ButtonProps; cancelButton?: ButtonProps; scrollable?: boolean; + withoutFooter?: boolean; + CustomFooter?: FC<{ closeHandler: () => void }>; + headerContentClassName?: string; + headerDescription?: string; } // TODO: Fix issue with modal positioning @@ -48,6 +52,10 @@ export const Modal: FC = ({ zIndex = 2, allowCloseOutside = true, scrollable = false, + withoutFooter = false, + CustomFooter = null, + headerContentClassName = '', + headerDescription = '', }) => { const [isShown, setShown] = useState(false); const [modalHeight, setModalHeight] = useState(0); @@ -106,7 +114,13 @@ export const Modal: FC = ({ exit={{ opacity: 0, marginTop: -modalMargin }} transition={{ duration: 0.3 }} > - + {scrollable ? ( {children} @@ -114,13 +128,18 @@ export const Modal: FC = ({ ) : ( {children} )} - + {!withoutFooter && + (CustomFooter ? ( + + ) : ( + + ))} )} diff --git a/src/components/modal/modalContent/modalContent.module.scss b/src/components/modal/modalContent/modalContent.module.scss index a5cfb50..1fdee72 100644 --- a/src/components/modal/modalContent/modalContent.module.scss +++ b/src/components/modal/modalContent/modalContent.module.scss @@ -3,11 +3,11 @@ .modal-content { width: calc(100% - 34px); - margin-top: 13px; font-family: var(--rp-ui-base-font-family); font-weight: $fw-regular; @include font-scale(); color: var(--rp-ui-color-text); white-space: pre-line; word-break: break-word; + padding: 8px 0 16px; } diff --git a/src/components/modal/modalHeader/modalHeader.module.scss b/src/components/modal/modalHeader/modalHeader.module.scss index d28256c..d0d20a3 100644 --- a/src/components/modal/modalHeader/modalHeader.module.scss +++ b/src/components/modal/modalHeader/modalHeader.module.scss @@ -7,13 +7,10 @@ font-weight: $fw-regular; @include font-scale(x4-medium); color: var(--rp-ui-color-text); - padding-bottom: 24px; + padding-bottom: 8px; } .modal-header-content { - display: flex; - justify-content: stretch; - align-items: center; width: 100%; padding-right: 30px; box-sizing: border-box; @@ -34,3 +31,18 @@ line-height: normal; cursor: pointer; } + +.modal-header-description { + display: inline-block; + width: 100%; + padding-bottom: 16px; + font-family: var(--rp-ui-base-font-family); + font-weight: $fw-regular; + @include font-scale(); + color: var(--rp-ui-base-almost-black); +} + +.modal-header-spacer { + width: 100%; + height: 8px; +} diff --git a/src/components/modal/modalHeader/modalHeader.tsx b/src/components/modal/modalHeader/modalHeader.tsx index fac0fd0..47b6c7a 100644 --- a/src/components/modal/modalHeader/modalHeader.tsx +++ b/src/components/modal/modalHeader/modalHeader.tsx @@ -7,15 +7,28 @@ const cx = classNames.bind(styles); interface ModalHeaderProps { title?: ReactNode; + headerContentClassName?: string; headerNode?: ReactNode; + headerDescription?: string; onClose: () => void; } -export const ModalHeader: FC = ({ title, onClose, headerNode }) => ( +export const ModalHeader: FC = ({ + title, + headerContentClassName = '', + headerDescription, + onClose, + headerNode, +}) => (

-
+
{title && {title}} {headerNode && headerNode} + {headerDescription ? ( + {headerDescription} + ) : ( +
+ )}
From b8ec7994c8429bce3a16fb2f426f649f1c615ead Mon Sep 17 00:00:00 2001 From: Vadzim Hvazdovich Date: Tue, 23 Jul 2024 13:46:38 +0300 Subject: [PATCH 2/5] EPMRPP-89804 || height fix --- src/components/modal/README.md | 1 + src/components/modal/modal.module.scss | 13 +++++++ src/components/modal/modal.stories.tsx | 34 +++++++++++++++++ src/components/modal/modal.tsx | 38 +++++++++++++++---- .../modalContent/modalContent.module.scss | 2 +- .../modal/modalHeader/modalHeader.module.scss | 21 +++------- .../modal/modalHeader/modalHeader.tsx | 22 ++--------- 7 files changed, 88 insertions(+), 43 deletions(-) diff --git a/src/components/modal/README.md b/src/components/modal/README.md index 6b6ff94..9247f72 100644 --- a/src/components/modal/README.md +++ b/src/components/modal/README.md @@ -17,6 +17,7 @@ Default width - 480px, height 100% - **className**: _string_, optional, default = "" - **size**: _string_, optional, default = "default" - **onClose**: _function_, optional, default = () => {} +- **contextHeight**: _boolean_, optional, default = undefined ### Variants diff --git a/src/components/modal/modal.module.scss b/src/components/modal/modal.module.scss index 3612d4c..5fe55c7 100644 --- a/src/components/modal/modal.module.scss +++ b/src/components/modal/modal.module.scss @@ -1,3 +1,6 @@ +@import 'src/assets/styles/variables/typography'; +@import 'src/assets/styles/mixins/font-scale'; + $WIDTH-SMALL: 320px; $WIDTH-DEFAULT: 480px; $WIDTH-LARGE: 720px; @@ -56,6 +59,16 @@ $WIDTH-LARGE: 720px; max-height: 90%; } +.modal-header-description { + display: inline-block; + width: 100%; + padding-bottom: 24px; + font-family: var(--rp-ui-base-font-family); + font-weight: $fw-regular; + @include font-scale(); + color: var(--rp-ui-base-almost-black); +} + .size-default { @include modalWidth($WIDTH-DEFAULT); } diff --git a/src/components/modal/modal.stories.tsx b/src/components/modal/modal.stories.tsx index cca6651..e544017 100644 --- a/src/components/modal/modal.stories.tsx +++ b/src/components/modal/modal.stories.tsx @@ -127,3 +127,37 @@ export const Scrollable: Story = { ), }, }; + +export const ScrollableWithoutFooter: Story = { + args: { + scrollable: true, + withoutFooter: true, + children: ( + <> +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt + ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation + ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur + sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id + est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud + exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure + dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. + Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit + anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis + nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute + irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia + deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing + elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim + veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. + Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat + nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia + deserunt mollit anim id est laborum. +

+ + ), + }, +}; diff --git a/src/components/modal/modal.tsx b/src/components/modal/modal.tsx index 44ec79a..3a45656 100644 --- a/src/components/modal/modal.tsx +++ b/src/components/modal/modal.tsx @@ -13,7 +13,10 @@ import styles from './modal.module.scss'; const cx = classNames.bind(styles); const MODAL_MAX_RATIO = 0.9; -const MODAL_HEADER_AND_FOOTER_HEIGHT = 176; +const MODAL_HEADER_HEIGHT = 32 + 24; +const MODAL_HEADER_WITH_DESCRIPTION_HEIGHT = 32 + 8; +const MODAL_FOOTER_HEIGHT = 36 + 16; +const MODAL_LAYOUT_PADDING = 32 * 2; type ModalOverlay = 'default' | 'light-cyan'; @@ -33,8 +36,8 @@ interface ModalProps { scrollable?: boolean; withoutFooter?: boolean; CustomFooter?: FC<{ closeHandler: () => void }>; - headerContentClassName?: string; headerDescription?: string; + contextHeight?: number; } // TODO: Fix issue with modal positioning @@ -54,8 +57,8 @@ export const Modal: FC = ({ scrollable = false, withoutFooter = false, CustomFooter = null, - headerContentClassName = '', headerDescription = '', + contextHeight, }) => { const [isShown, setShown] = useState(false); const [modalHeight, setModalHeight] = useState(0); @@ -65,7 +68,24 @@ export const Modal: FC = ({ const windowHeight = windowSize.height; const modalMaxHeight = windowHeight * MODAL_MAX_RATIO; const modalMargin = (windowHeight - modalHeight) / 2; - const contentMaxHeight = modalMaxHeight - MODAL_HEADER_AND_FOOTER_HEIGHT; + const getContentMaxHeight = () => { + if (contextHeight) { + return contextHeight; + } + + let contentMaxHeight = modalMaxHeight - MODAL_LAYOUT_PADDING; + if (!withoutFooter) { + contentMaxHeight = contentMaxHeight - MODAL_FOOTER_HEIGHT; + } + + if (headerDescription) { + contentMaxHeight = contentMaxHeight - MODAL_HEADER_WITH_DESCRIPTION_HEIGHT; + } else { + contentMaxHeight = contentMaxHeight - MODAL_HEADER_HEIGHT; + } + + return contentMaxHeight; + }; const closeModal = () => { setShown(false); @@ -116,13 +136,15 @@ export const Modal: FC = ({ > + {headerNode && headerNode} + {headerDescription && ( + {headerDescription} + )} {scrollable ? ( - + {children} ) : ( diff --git a/src/components/modal/modalContent/modalContent.module.scss b/src/components/modal/modalContent/modalContent.module.scss index 1fdee72..eff3288 100644 --- a/src/components/modal/modalContent/modalContent.module.scss +++ b/src/components/modal/modalContent/modalContent.module.scss @@ -9,5 +9,5 @@ color: var(--rp-ui-color-text); white-space: pre-line; word-break: break-word; - padding: 8px 0 16px; + padding: 0 0 16px; } diff --git a/src/components/modal/modalHeader/modalHeader.module.scss b/src/components/modal/modalHeader/modalHeader.module.scss index d0d20a3..694625f 100644 --- a/src/components/modal/modalHeader/modalHeader.module.scss +++ b/src/components/modal/modalHeader/modalHeader.module.scss @@ -7,7 +7,11 @@ font-weight: $fw-regular; @include font-scale(x4-medium); color: var(--rp-ui-color-text); - padding-bottom: 8px; + padding-bottom: 24px; + + &.width-description { + padding-bottom: 8px; + } } .modal-header-content { @@ -31,18 +35,3 @@ line-height: normal; cursor: pointer; } - -.modal-header-description { - display: inline-block; - width: 100%; - padding-bottom: 16px; - font-family: var(--rp-ui-base-font-family); - font-weight: $fw-regular; - @include font-scale(); - color: var(--rp-ui-base-almost-black); -} - -.modal-header-spacer { - width: 100%; - height: 8px; -} diff --git a/src/components/modal/modalHeader/modalHeader.tsx b/src/components/modal/modalHeader/modalHeader.tsx index 47b6c7a..6e26b56 100644 --- a/src/components/modal/modalHeader/modalHeader.tsx +++ b/src/components/modal/modalHeader/modalHeader.tsx @@ -7,28 +7,14 @@ const cx = classNames.bind(styles); interface ModalHeaderProps { title?: ReactNode; - headerContentClassName?: string; - headerNode?: ReactNode; - headerDescription?: string; onClose: () => void; + withDescription?: boolean; } -export const ModalHeader: FC = ({ - title, - headerContentClassName = '', - headerDescription, - onClose, - headerNode, -}) => ( -
-
+export const ModalHeader: FC = ({ title, onClose, withDescription = false }) => ( +
+
{title && {title}} - {headerNode && headerNode} - {headerDescription ? ( - {headerDescription} - ) : ( -
- )}
From e3beb8c5a2fbf3e4048214882eba3478a16cdc96 Mon Sep 17 00:00:00 2001 From: Vadzim Hvazdovich Date: Tue, 23 Jul 2024 14:18:15 +0300 Subject: [PATCH 3/5] EPMRPP-89804 || focus fix --- src/components/modal/modal.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/modal/modal.tsx b/src/components/modal/modal.tsx index 3a45656..5346f53 100644 --- a/src/components/modal/modal.tsx +++ b/src/components/modal/modal.tsx @@ -109,10 +109,6 @@ export const Modal: FC = ({ useEffect(() => { setShown(true); - if (modalRef && modalRef.current) { - modalRef.current.focus(); - } - document.addEventListener('keydown', onKeydown, false); return () => document.removeEventListener('keydown', onKeydown, false); @@ -133,6 +129,7 @@ export const Modal: FC = ({ animate={{ opacity: 1, marginTop: modalMargin }} exit={{ opacity: 0, marginTop: -modalMargin }} transition={{ duration: 0.3 }} + onAnimationComplete={() => modalRef.current?.focus()} > Date: Tue, 23 Jul 2024 15:24:27 +0300 Subject: [PATCH 4/5] EPMRPP-89804 || code review fixes - 1 --- src/components/modal/README.md | 3 +-- src/components/modal/modal.stories.tsx | 3 ++- src/components/modal/modal.tsx | 36 ++++++++++---------------- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/components/modal/README.md b/src/components/modal/README.md index 9247f72..b8ea51a 100644 --- a/src/components/modal/README.md +++ b/src/components/modal/README.md @@ -9,7 +9,6 @@ Default width - 480px, height 100% ### Props : - **title**: _string_, optional, default = "" -- **headerNode**: _node_, optional, default = null - **children**: _node_, optional, default = null - **footerNode**: _node_, optional, default = null - **okButton**: _object_, optional, default = null @@ -17,7 +16,7 @@ Default width - 480px, height 100% - **className**: _string_, optional, default = "" - **size**: _string_, optional, default = "default" - **onClose**: _function_, optional, default = () => {} -- **contextHeight**: _boolean_, optional, default = undefined +- **description**: _node_, optional, default = null ### Variants diff --git a/src/components/modal/modal.stories.tsx b/src/components/modal/modal.stories.tsx index e544017..6544c13 100644 --- a/src/components/modal/modal.stories.tsx +++ b/src/components/modal/modal.stories.tsx @@ -37,7 +37,7 @@ export const Default: Story = { export const WithoutFooter: Story = { args: { withoutFooter: true, - headerDescription: 'title description', + description: 'title description', }, }; @@ -98,6 +98,7 @@ export const OverlayLightCyan: Story = { export const Scrollable: Story = { args: { scrollable: true, + description: 'title description', children: ( <>

diff --git a/src/components/modal/modal.tsx b/src/components/modal/modal.tsx index 5346f53..803dd7c 100644 --- a/src/components/modal/modal.tsx +++ b/src/components/modal/modal.tsx @@ -23,7 +23,6 @@ type ModalOverlay = 'default' | 'light-cyan'; interface ModalProps { onClose?: () => void; title?: ReactNode; - headerNode?: ReactNode; children?: ReactNode; footerNode?: ReactNode; className?: string; @@ -36,14 +35,12 @@ interface ModalProps { scrollable?: boolean; withoutFooter?: boolean; CustomFooter?: FC<{ closeHandler: () => void }>; - headerDescription?: string; - contextHeight?: number; + description?: ReactNode; } // TODO: Fix issue with modal positioning export const Modal: FC = ({ title, - headerNode, children, footerNode, okButton, @@ -57,8 +54,7 @@ export const Modal: FC = ({ scrollable = false, withoutFooter = false, CustomFooter = null, - headerDescription = '', - contextHeight, + description = null, }) => { const [isShown, setShown] = useState(false); const [modalHeight, setModalHeight] = useState(0); @@ -69,16 +65,12 @@ export const Modal: FC = ({ const modalMaxHeight = windowHeight * MODAL_MAX_RATIO; const modalMargin = (windowHeight - modalHeight) / 2; const getContentMaxHeight = () => { - if (contextHeight) { - return contextHeight; - } - let contentMaxHeight = modalMaxHeight - MODAL_LAYOUT_PADDING; if (!withoutFooter) { contentMaxHeight = contentMaxHeight - MODAL_FOOTER_HEIGHT; } - if (headerDescription) { + if (description) { contentMaxHeight = contentMaxHeight - MODAL_HEADER_WITH_DESCRIPTION_HEIGHT; } else { contentMaxHeight = contentMaxHeight - MODAL_HEADER_HEIGHT; @@ -129,23 +121,23 @@ export const Modal: FC = ({ animate={{ opacity: 1, marginTop: modalMargin }} exit={{ opacity: 0, marginTop: -modalMargin }} transition={{ duration: 0.3 }} - onAnimationComplete={() => modalRef.current?.focus()} + onAnimationStart={() => modalRef.current?.focus()} > - - {headerNode && headerNode} - {headerDescription && ( - {headerDescription} - )} + {scrollable ? ( + {description && ( + {description} + )} {children} ) : ( - {children} + <> + {description && ( + {description} + )} + {children} + )} {!withoutFooter && (CustomFooter ? ( From ff5067945fd6c13d1c8380928f3ef2845bf9d5ef Mon Sep 17 00:00:00 2001 From: Vadzim Hvazdovich Date: Wed, 24 Jul 2024 10:10:22 +0300 Subject: [PATCH 5/5] EPMRPP-89804 || code review fixes - 2 --- src/components/modal/modal.module.scss | 2 +- src/components/modal/modal.tsx | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/components/modal/modal.module.scss b/src/components/modal/modal.module.scss index 5fe55c7..162f53b 100644 --- a/src/components/modal/modal.module.scss +++ b/src/components/modal/modal.module.scss @@ -59,7 +59,7 @@ $WIDTH-LARGE: 720px; max-height: 90%; } -.modal-header-description { +.description { display: inline-block; width: 100%; padding-bottom: 24px; diff --git a/src/components/modal/modal.tsx b/src/components/modal/modal.tsx index 803dd7c..1f26f22 100644 --- a/src/components/modal/modal.tsx +++ b/src/components/modal/modal.tsx @@ -126,16 +126,12 @@ export const Modal: FC = ({ {scrollable ? ( - {description && ( - {description} - )} + {description && {description}} {children} ) : ( <> - {description && ( - {description} - )} + {description && {description}} {children} )}