From bd2e4307d2114f6dcafb4ae3629978d8e25b8194 Mon Sep 17 00:00:00 2001 From: Mustajab Ikram Date: Fri, 8 Sep 2023 02:04:32 +0530 Subject: [PATCH] Refactor/modal component tests 1332 (#1392) * feat: Add separate constants in theme for modal sizes and paddings * feat: Implement dynamic sizing and padding for Modal * feat: use dynamic modal feature for csv import * fix: Remove redundant props from spreadsheet-import * fix: use theme.spacing() instead * fix: place types to Modal.tsx, convert ternary to switch-case, give default value * fix: give px to modal sizes * enhance: add color style to modal * feat: add modal to storybook --- .../components/ModalWrapper.tsx | 2 +- .../src/modules/ui/modal/components/Modal.tsx | 43 +++++++++++++++- .../components/__stories__/Modal.stories.tsx | 49 ++++++++++--------- front/src/modules/ui/theme/constants/modal.ts | 7 +++ front/src/modules/ui/theme/constants/theme.ts | 2 + 5 files changed, 77 insertions(+), 26 deletions(-) create mode 100644 front/src/modules/ui/theme/constants/modal.ts diff --git a/front/src/modules/spreadsheet-import/components/ModalWrapper.tsx b/front/src/modules/spreadsheet-import/components/ModalWrapper.tsx index 8a136e81b..60e47cb87 100644 --- a/front/src/modules/spreadsheet-import/components/ModalWrapper.tsx +++ b/front/src/modules/spreadsheet-import/components/ModalWrapper.tsx @@ -37,7 +37,7 @@ export const ModalWrapper = ({ children, isOpen, onClose }: Props) => { const { rtl } = useSpreadsheetImportInternal(); return ( - + {children} diff --git a/front/src/modules/ui/modal/components/Modal.tsx b/front/src/modules/ui/modal/components/Modal.tsx index 204c72520..a32624920 100644 --- a/front/src/modules/ui/modal/components/Modal.tsx +++ b/front/src/modules/ui/modal/components/Modal.tsx @@ -12,14 +12,46 @@ import { import { ModalHotkeyScope } from './types/ModalHotkeyScope'; -const StyledModalDiv = styled(motion.div)` +const StyledModalDiv = styled(motion.div)<{ + size?: ModalSize; + padding?: ModalPadding; +}>` display: flex; flex-direction: column; background: ${({ theme }) => theme.background.primary}; + color: ${({ theme }) => theme.font.color.primary}; border-radius: ${({ theme }) => theme.border.radius.md}; overflow: hidden; max-height: 90vh; z-index: 10000; // should be higher than Backdrop's z-index + + width: ${({ size, theme }) => { + switch (size) { + case 'small': + return theme.modal.size.sm; + case 'medium': + return theme.modal.size.md; + case 'large': + return theme.modal.size.lg; + default: + return 'auto'; + } + }}; + + padding: ${({ padding, theme }) => { + switch (padding) { + case 'none': + return theme.spacing(0); + case 'small': + return theme.spacing(2); + case 'medium': + return theme.spacing(4); + case 'large': + return theme.spacing(6); + default: + return 'auto'; + } + }}; `; const StyledHeader = styled.div` @@ -85,12 +117,17 @@ function ModalFooter({ children, ...restProps }: ModalFooterProps) { /** * Modal */ +export type ModalSize = 'small' | 'medium' | 'large'; +export type ModalPadding = 'none' | 'small' | 'medium' | 'large'; + type ModalProps = React.PropsWithChildren & React.ComponentProps<'div'> & { isOpen?: boolean; onClose?: () => void; hotkeyScope?: ModalHotkeyScope; onEnter?: () => void; + size?: ModalSize; + padding?: ModalPadding; }; const modalVariants = { @@ -105,6 +142,8 @@ export function Modal({ onClose, hotkeyScope = ModalHotkeyScope.Default, onEnter, + size = 'medium', + padding = 'medium', ...restProps }: ModalProps) { const modalRef = useRef(null); @@ -157,6 +196,8 @@ export function Modal({ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore ref={modalRef} + size={size} + padding={padding} initial="hidden" animate="visible" exit="exit" diff --git a/front/src/modules/ui/modal/components/__stories__/Modal.stories.tsx b/front/src/modules/ui/modal/components/__stories__/Modal.stories.tsx index cd7e461d2..994ef085a 100644 --- a/front/src/modules/ui/modal/components/__stories__/Modal.stories.tsx +++ b/front/src/modules/ui/modal/components/__stories__/Modal.stories.tsx @@ -1,39 +1,40 @@ -import styled from '@emotion/styled'; -import { Meta, StoryObj } from '@storybook/react'; +import type { Meta, StoryObj } from '@storybook/react'; import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; import { Modal } from '../Modal'; +import { ModalHotkeyScope } from '../types/ModalHotkeyScope'; const meta: Meta = { title: 'UI/Modal/Modal', component: Modal, - decorators: [ComponentDecorator], }; -export default meta; +export default meta; type Story = StoryObj; -const StyledContentContainer = styled.div` - color: ${({ theme }) => theme.font.color.primary}; - margin: 5px; - padding: ${({ theme }) => theme.spacing(10)}; -`; - -const args = { - isOpen: true, - children: ( - - Lorem ipsum - - ), -}; - export const Default: Story = { - args, + args: { + isOpen: true, + size: 'medium', + padding: 'medium', + hotkeyScope: ModalHotkeyScope.Default, + children: ( + <> + Stay in touch + + This is a dummy newletter form so don't bother trying to test it. Not + that I expect you to, anyways. :) + + + By using Twenty, you're opting for the finest CRM experience you'll + ever encounter. + + + ), + }, decorators: [ComponentDecorator], -}; - -Default.argTypes = { - children: { control: false }, + argTypes: { + children: { control: false }, + }, }; diff --git a/front/src/modules/ui/theme/constants/modal.ts b/front/src/modules/ui/theme/constants/modal.ts new file mode 100644 index 000000000..30099fde8 --- /dev/null +++ b/front/src/modules/ui/theme/constants/modal.ts @@ -0,0 +1,7 @@ +export const modal = { + size: { + sm: '300px', + md: '400px', + lg: '53%', + }, +}; diff --git a/front/src/modules/ui/theme/constants/theme.ts b/front/src/modules/ui/theme/constants/theme.ts index 3239f423d..4867e524c 100644 --- a/front/src/modules/ui/theme/constants/theme.ts +++ b/front/src/modules/ui/theme/constants/theme.ts @@ -7,6 +7,7 @@ import { boxShadowDark, boxShadowLight } from './boxShadow'; import { color, grayScale } from './colors'; import { fontDark, fontLight } from './font'; import { icon } from './icon'; +import { modal } from './modal'; import { tagDark, tagLight } from './tag'; import { text } from './text'; @@ -14,6 +15,7 @@ const common = { color: color, grayScale: grayScale, icon: icon, + modal: modal, text: text, blur: blur, animation: animation,