Skip to content

Commit

Permalink
refactor(components): refactor modal for web (app and pd) (#17193)
Browse files Browse the repository at this point in the history
* refactor(components): refactor modal for web (app and pd)
  • Loading branch information
koji authored Jan 8, 2025
1 parent 9e0d3cb commit 0c3e609
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import {
DIRECTION_ROW,
Flex,
Icon,
LegacyStyledText,
Link,
Modal,
PrimaryButton,
SPACING,
Modal,
LegacyStyledText,
TYPOGRAPHY,
} from '@opentrons/components'
import { getTopPortalEl } from '/app/App/portal'
Expand Down
70 changes: 27 additions & 43 deletions components/src/modals/Modal.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,36 @@
import type * as React from 'react'
import { PrimaryButton, StyledText } from '../atoms'
import { SPACING } from '../ui-style-constants'
import { Flex } from '../primitives'
import { JUSTIFY_END } from '../styles'
import { Modal as ModalComponent } from './Modal'

import { LegacyStyledText } from '../atoms'
import { SPACING, TYPOGRAPHY } from '../ui-style-constants'
import { PrimaryBtn } from '../primitives'
import { COLORS } from '../helix-design-system'
import { Modal } from './Modal'
import type { Meta, StoryObj } from '@storybook/react'

import type { Story, Meta } from '@storybook/react'

export default {
const meta: Meta<typeof ModalComponent> = {
title: 'Library/Molecules/modals/Modal',
component: Modal,
} as Meta

const Template: Story<React.ComponentProps<typeof Modal>> = args => (
<Modal {...args} />
)
component: ModalComponent,
}
export default meta
type Story = StoryObj<typeof ModalComponent>
const bodyText = 'Modal body goes here'

const Children = (
<>
<LegacyStyledText
fontWeight={TYPOGRAPHY.fontWeightSemiBold}
fontSize={TYPOGRAPHY.fontSizeP}
paddingTop={SPACING.spacing4}
>
{'Modal body goes here'}
</LegacyStyledText>
<StyledText desktopStyle="bodyDefaultRegular">{bodyText}</StyledText>
)

<PrimaryBtn
backgroundColor={COLORS.blue50}
marginTop="28rem"
textTransform={TYPOGRAPHY.textTransformNone}
>
<LegacyStyledText
fontWeight={TYPOGRAPHY.fontWeightRegular}
fontSize={TYPOGRAPHY.fontSizeP}
>
{'btn text'}
</LegacyStyledText>
</PrimaryBtn>
</>
const Footer = (
<Flex justifyContent={JUSTIFY_END} padding={SPACING.spacing24}>
<PrimaryButton onClick={() => {}}>{'btn text'}</PrimaryButton>
</Flex>
)

export const Primary = Template.bind({})
Primary.args = {
type: 'info',
onClose: () => {},
closeOnOutsideClick: false,
title: 'Modal Title',
children: Children,
export const Modal: Story = {
args: {
type: 'info',
onClose: () => {},
closeOnOutsideClick: false,
title: 'Modal Title',
children: Children,
footer: Footer,
},
}
1 change: 0 additions & 1 deletion components/src/modals/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export const Modal = (props: ModalProps): JSX.Element => {
name: 'ot-alert',
color: iconColor(type),
size: '1.25rem',
marginRight: SPACING.spacing8,
}

const modalHeader = (
Expand Down
122 changes: 63 additions & 59 deletions components/src/modals/ModalHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { css } from 'styled-components'
import styled, { css } from 'styled-components'

import { Icon } from '../icons'
import { Box, Btn, Flex } from '../primitives'
import { LegacyStyledText } from '../atoms'
import { ALIGN_CENTER, JUSTIFY_CENTER, JUSTIFY_SPACE_BETWEEN } from '../styles'
import { SPACING, TYPOGRAPHY } from '../ui-style-constants'
import { StyledText } from '../atoms'
import {
ALIGN_CENTER,
DISPLAY_FLEX,
JUSTIFY_CENTER,
JUSTIFY_SPACE_BETWEEN,
} from '../styles'
import { SPACING } from '../ui-style-constants'
import { COLORS } from '../helix-design-system'

import type { MouseEventHandler, ReactNode } from 'react'
Expand All @@ -21,22 +26,6 @@ export interface ModalHeaderProps {
closeButton?: ReactNode
}

const closeIconStyles = css`
display: flex;
justify-content: ${JUSTIFY_CENTER};
align-items: ${ALIGN_CENTER};
border-radius: 0.875rem;
width: 1.625rem;
height: 1.625rem;
&:hover {
background-color: ${COLORS.grey30};
}
&:active {
background-color: ${COLORS.grey35};
}
`

export const ModalHeader = (props: ModalHeaderProps): JSX.Element => {
const {
icon,
Expand All @@ -45,57 +34,72 @@ export const ModalHeader = (props: ModalHeaderProps): JSX.Element => {
titleElement1,
titleElement2,
backgroundColor,
color,
color = COLORS.black90,
closeButton,
} = props
return (
<>
<Flex
alignItems={ALIGN_CENTER}
justifyContent={JUSTIFY_SPACE_BETWEEN}
paddingX={SPACING.spacing24}
paddingY={SPACING.spacing16}
<StyledModalHeader
backgroundColor={backgroundColor}
data-testid="Modal_header"
role="heading"
>
<Flex alignItems={ALIGN_CENTER} gridGap={SPACING.spacing8}>
<Flex alignItems={ALIGN_CENTER} gridGap={SPACING.spacing16}>
{icon != null && <Icon {...icon} data-testid="Modal_header_icon" />}
{titleElement1}
{titleElement2}
{/* TODO (nd: 08/07/2024) Convert to StyledText once designs are resolved */}
<LegacyStyledText
as="h3"
fontWeight={TYPOGRAPHY.fontWeightSemiBold}
color={color}
>
<StyledText color={color} desktopStyle="bodyLargeSemiBold">
{title}
</LegacyStyledText>
</StyledText>
</Flex>
{closeButton != null
? closeButton
: onClose != null && (
<Btn
onClick={onClose}
css={closeIconStyles}
data-testid={`ModalHeader_icon_close${
typeof title === 'string' ? `_${title}` : ''
}`}
>
<Icon
name="close"
width={SPACING.spacing24}
height={SPACING.spacing24}
color={color}
/>
</Btn>
)}
</Flex>
<Box
borderBottom={`1px solid ${COLORS.grey30}`}
marginY="0"
width="100%"
data-testid="divider"
/>
{closeButton != null ||
(onClose != null && (
<Btn
onClick={onClose}
css={closeIconStyles}
data-testid={`ModalHeader_icon_close${
typeof title === 'string' ? `_${title}` : ''
}`}
>
<Icon
name="close"
width={SPACING.spacing24}
height={SPACING.spacing24}
color={color}
/>
</Btn>
))}
</StyledModalHeader>
<StyledDivider data-testid="divider" />
</>
)
}

const StyledModalHeader = styled(Flex)`
padding: ${SPACING.spacing16} ${SPACING.spacing24};
justify-content: ${JUSTIFY_SPACE_BETWEEN};
align-items: ${ALIGN_CENTER};
background-color: ${props => props.backgroundColor};
`

const StyledDivider = styled(Box)`
border-bottom: 1px solid ${COLORS.grey30};
margin: 0;
width: 100%;
`

const closeIconStyles = css`
display: ${DISPLAY_FLEX};
justify-content: ${JUSTIFY_CENTER};
align-items: ${ALIGN_CENTER};
border-radius: 0.875rem;
width: 1.625rem;
height: 1.625rem;
&:hover {
background-color: ${COLORS.grey30};
}
&:active {
background-color: ${COLORS.grey35};
}
`
4 changes: 3 additions & 1 deletion components/src/modals/ModalShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ALIGN_CENTER,
ALIGN_END,
CURSOR_DEFAULT,
DISPLAY_FLEX,
JUSTIFY_CENTER,
JUSTIFY_END,
OVERFLOW_AUTO,
Expand Down Expand Up @@ -110,7 +111,7 @@ const ContentArea = styled.div<{
position: Position
noPadding: boolean
}>`
display: flex;
display: ${DISPLAY_FLEX};
position: ${POSITION_ABSOLUTE};
align-items: ${({ position }) =>
position === 'center' ? ALIGN_CENTER : ALIGN_END};
Expand All @@ -137,6 +138,7 @@ const ModalArea = styled.div<
box-shadow: ${BORDERS.smallDropShadow};
height: ${({ isFullPage }) => (isFullPage ? '100%' : 'auto')};
background-color: ${COLORS.white};
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
border-radius: ${BORDERS.borderRadius16};
}
Expand Down
7 changes: 1 addition & 6 deletions components/src/modals/__tests__/ModalHeader.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import '@testing-library/jest-dom/vitest'
import { describe, it, expect, vi, beforeEach } from 'vitest'

import { renderWithProviders } from '../../testing/utils'
import { ModalHeader } from '../ModalHeader'
import { COLORS } from '../../helix-design-system'
import { SPACING } from '../../ui-style-constants'
import { ALIGN_CENTER, JUSTIFY_CENTER } from '../../styles'
import { ModalHeader } from '../ModalHeader'

import type { ComponentProps } from 'react'

Expand Down Expand Up @@ -40,7 +39,6 @@ describe('ModalHeader', () => {
name: 'ot-alert',
color: COLORS.black90,
size: '1.25rem',
marginRight: SPACING.spacing8,
}
render(props)
expect(screen.getByTestId('Modal_header_icon')).toHaveStyle(
Expand All @@ -52,9 +50,6 @@ describe('ModalHeader', () => {
expect(screen.getByTestId('Modal_header_icon')).toHaveStyle(
`height: 1.25rem`
)
expect(screen.getByTestId('Modal_header_icon')).toHaveStyle(
`margin-right: ${SPACING.spacing8}`
)
})

it('should call a mock function when clicking close icon', () => {
Expand Down

0 comments on commit 0c3e609

Please sign in to comment.