Skip to content

Commit

Permalink
fix(components, protocol-designer): Fix text wrap issues in PD (#16385)
Browse files Browse the repository at this point in the history
* fix(components, protocol-designer): Fix text wrap issues in PD
  • Loading branch information
koji authored Oct 1, 2024
1 parent 88d7237 commit 680ee12
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 48 deletions.
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;
`
71 changes: 71 additions & 0 deletions protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx
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 ? (
<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

0 comments on commit 680ee12

Please sign in to comment.