Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(components): refactor modal for web (app and pd) #17193

Merged
merged 12 commits into from
Jan 8, 2025
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
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: 64 additions & 58 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,74 @@ 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>
))}
{/* </Flex> */}
</StyledModalHeader>
koji marked this conversation as resolved.
Show resolved Hide resolved
<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
Loading