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

fix(components, protocol-designer): Fix text wrap issues in PD #16385

Merged
merged 10 commits into from
Oct 1, 2024
Merged
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Flex } from '../../../primitives'
import {
ALIGN_CENTER,
ALIGN_FLEX_START,
DIRECTION_ROW,
FLEX_AUTO,
JUSTIFY_SPACE_BETWEEN,
Expand All @@ -22,7 +22,7 @@ export const ListItemDescriptor = (
flexDirection={DIRECTION_ROW}
gridGap={SPACING.spacing8}
width="100%"
alignItems={ALIGN_CENTER}
alignItems={ALIGN_FLEX_START}
justifyContent={type === 'mini' ? JUSTIFY_SPACE_BETWEEN : 'none'}
padding={
type === 'mini'
Expand All @@ -36,7 +36,9 @@ export const ListItemDescriptor = (
>
{description}
</Flex>
<Flex flex={type === 'default' && '1.95'}>{content}</Flex>
<Flex flex={type === 'default' && '1.95'} overflowWrap="anywhere">
{content}
</Flex>
</Flex>
)
}
15 changes: 10 additions & 5 deletions components/src/molecules/DropdownMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
DIRECTION_COLUMN,
DIRECTION_ROW,
JUSTIFY_SPACE_BETWEEN,
NO_WRAP,
OVERFLOW_AUTO,
OVERFLOW_HIDDEN,
POSITION_ABSOLUTE,
Expand Down Expand Up @@ -235,12 +234,9 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element {
font-weight: ${dropdownType === 'rounded'
? TYPOGRAPHY.pSemiBold
: TYPOGRAPHY.pRegular};
white-space: ${NO_WRAP};
overflow: ${OVERFLOW_HIDDEN};
text-overflow: ellipsis;
`}
>
<StyledText desktopStyle="captionRegular">
<StyledText desktopStyle="captionRegular" css={MENU_TEXT_STYLE}>
{currentOption.name}
</StyledText>
</Flex>
Expand Down Expand Up @@ -311,3 +307,12 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element {
</Flex>
)
}

const MENU_TEXT_STYLE = css`
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: ${OVERFLOW_HIDDEN};
text-overflow: ellipsis;
word-wrap: break-word;
-webkit-line-clamp: 1;
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useTranslation } from 'react-i18next'
import { css } from 'styled-components'
import {
ALIGN_CENTER,
DIRECTION_COLUMN,
Flex,
InfoScreen,
LiquidIcon,
ListItem,
ListItemDescriptor,
OVERFLOW_HIDDEN,
SPACING,
StyledText,
} from '@opentrons/components'

import type { AllIngredGroupFields } from '../../labware-ingred/types'

interface LiquidDefinitionsProps {
allIngredientGroupFields: AllIngredGroupFields
}

export function LiquidDefinitions({
allIngredientGroupFields,
}: LiquidDefinitionsProps): JSX.Element {
const { t } = useTranslation('protocol_overview')
return (
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing12}>
<StyledText desktopStyle="headingSmallBold">
{t('liquid_defs')}
</StyledText>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing4}>
{Object.keys(allIngredientGroupFields).length > 0 ? (
Object.values(allIngredientGroupFields).map((liquid, index) => (
<ListItem
type="noActive"
key={`${liquid.name}_${liquid.displayColor}_${index}`}
>
<ListItemDescriptor
type="default"
description={
<Flex alignItems={ALIGN_CENTER} gridGap={SPACING.spacing8}>
<LiquidIcon color={liquid.displayColor} />
<StyledText
desktopStyle="bodyDefaultRegular"
overflowWrap="anywhere"
id="liquid-name"
css={LIQUID_DEFINITION_TEXT}
>
{liquid.name}
</StyledText>
</Flex>
}
content={liquid.description ?? t('na')}
/>
</ListItem>
))
) : (
<InfoScreen content={t('no_liquids_defined')} />
)}
</Flex>
</Flex>
)
}

const LIQUID_DEFINITION_TEXT = css`
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: ${OVERFLOW_HIDDEN};
text-overflow: ellipsis;
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { describe, it, vi, beforeEach } from 'vitest'
import { screen } from '@testing-library/react'

import { renderWithProviders } from '../../../__testing-utils__'
import { i18n } from '../../../assets/localization'
import { LiquidDefinitions } from '../LiquidDefinitions'

import type { ComponentProps } from 'react'
import type { InfoScreen } from '@opentrons/components'

vi.mock('@opentrons/components', async importOriginal => {
const actual = await importOriginal<typeof InfoScreen>()
return {
...actual,
InfoScreen: () => <div>mock InfoScreen</div>,
}
})

const mockAllIngredientGroupFields = {
'0': {
name: 'EtOH',
displayColor: '#b925ff',
description: 'Immer fisch Hergestllter EtOH',
serialize: false,
liquidGroupId: '0',
},
'1': {
name: '10mM Tris pH8,5',
displayColor: '#ffd600',
description: null,
serialize: false,
liquidGroupId: '1',
},
'2': {
name: 'Amplicon PCR sample + AMPure XP beads',
displayColor: '#9dffd8',
description: '25µl Amplicon PCR + 20 µl AMPure XP beads',
serialize: false,
liquidGroupId: '2',
},
}

const render = (props: ComponentProps<typeof LiquidDefinitions>) => {
return renderWithProviders(<LiquidDefinitions {...props} />, {
i18nInstance: i18n,
})
}

describe('LiquidDefinitions', () => {
let props: ComponentProps<typeof LiquidDefinitions>

beforeEach(() => {
props = {
allIngredientGroupFields: {},
}
})

it('should render text and InfoScreen if no liquid', () => {
render(props)
screen.getByText('Liquid Definitions')
screen.getByText('mock InfoScreen')
})

it('should render liquid information if there are liquids', () => {
props = {
allIngredientGroupFields: mockAllIngredientGroupFields,
}
render(props)
screen.getByText('EtOH')
screen.getByText('Immer fisch Hergestllter EtOH')

screen.getByText('10mM Tris pH8,5')
screen.getByText('N/A')

screen.getByText('Amplicon PCR sample + AMPure XP beads')
screen.getByText('25µl Amplicon PCR + 20 µl AMPure XP beads')
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { selectors as labwareIngredSelectors } from '../../../labware-ingred/sel
import { ProtocolOverview } from '../index'
import { DeckThumbnail } from '../DeckThumbnail'
import { OffDeckThumbnail } from '../OffdeckThumbnail'
import { LiquidDefinitions } from '../LiquidDefinitions'

import type { NavigateFunction } from 'react-router-dom'

Expand All @@ -27,6 +28,8 @@ vi.mock('../../../organisms/MaterialsListModal')
vi.mock('../../../labware-ingred/selectors')
vi.mock('../../../organisms')
vi.mock('../../../labware-ingred/selectors')
vi.mock('../LiquidDefinitions')

const mockNavigate = vi.fn()

vi.mock('react-router-dom', async importOriginal => {
Expand Down Expand Up @@ -72,6 +75,9 @@ describe('ProtocolOverview', () => {
vi.mocked(OffDeckThumbnail).mockReturnValue(
<div>mock OffdeckThumbnail</div>
)
vi.mocked(LiquidDefinitions).mockReturnValue(
<div>mock LiquidDefinitions</div>
)
})

it('renders each section with text', () => {
Expand Down Expand Up @@ -101,7 +107,7 @@ describe('ProtocolOverview', () => {
screen.getByText('Right pipette')
screen.getByText('Extension mount')
// liquids
screen.getByText('Liquid Definitions')
screen.getByText('mock LiquidDefinitions')
// steps
screen.getByText('Protocol steps')
})
Expand Down
47 changes: 8 additions & 39 deletions protocol-designer/src/pages/ProtocolOverview/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useEffect } from 'react'
import { Fragment, useState, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router-dom'
import { useDispatch, useSelector } from 'react-redux'
Expand All @@ -16,7 +16,6 @@ import {
JUSTIFY_FLEX_END,
JUSTIFY_SPACE_BETWEEN,
LargeButton,
LiquidIcon,
ListItem,
ListItemDescriptor,
Modal,
Expand Down Expand Up @@ -58,6 +57,7 @@ import {
import { DeckThumbnail } from './DeckThumbnail'
import { OffDeckThumbnail } from './OffdeckThumbnail'
import { getWarningContent } from './UnusedModalContent'
import { LiquidDefinitions } from './LiquidDefinitions'

import type { CreateCommand, PipetteName } from '@opentrons/shared-data'
import type { DeckSlot } from '@opentrons/step-generation'
Expand Down Expand Up @@ -223,8 +223,9 @@ export function ProtocolOverview(): JSX.Element {
const cancelModal = (): void => {
setShowExportWarningModal(false)
}

return (
<>
<Fragment>
{showEditMetadataModal ? (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to specify that this is a fragment here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's getting a warning because of the recently eslint change.

<EditProtocolMetadataModal
onClose={() => {
Expand Down Expand Up @@ -449,41 +450,9 @@ export function ProtocolOverview(): JSX.Element {
) : null}
</Flex>
</Flex>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing12}>
<StyledText desktopStyle="headingSmallBold">
{t('liquid_defs')}
</StyledText>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing4}>
{Object.keys(allIngredientGroupFields).length > 0 ? (
Object.values(allIngredientGroupFields).map(
(liquid, index) => (
<ListItem
type="noActive"
key={`${liquid.name}_${liquid.displayColor}_${index}`}
>
<ListItemDescriptor
type="default"
description={
<Flex
alignItems={ALIGN_CENTER}
gridGap={SPACING.spacing8}
>
<LiquidIcon color={liquid.displayColor} />
<StyledText desktopStyle="bodyDefaultRegular">
{liquid.name}
</StyledText>
</Flex>
}
content={liquid.description ?? t('na')}
/>
</ListItem>
)
)
) : (
<InfoScreen content={t('no_liquids_defined')} />
)}
</Flex>
</Flex>
<LiquidDefinitions
allIngredientGroupFields={allIngredientGroupFields}
/>
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing12}>
<Flex>
<StyledText desktopStyle="headingSmallBold">
Expand Down Expand Up @@ -562,7 +531,7 @@ export function ProtocolOverview(): JSX.Element {
</Flex>
</Flex>
</Flex>
</>
</Fragment>
)
}

Expand Down
Loading