diff --git a/components/src/atoms/ListItem/ListItemChildren/ListItemDescriptor.tsx b/components/src/atoms/ListItem/ListItemChildren/ListItemDescriptor.tsx
index 7560bf25e5e..51d9ca9e181 100644
--- a/components/src/atoms/ListItem/ListItemChildren/ListItemDescriptor.tsx
+++ b/components/src/atoms/ListItem/ListItemChildren/ListItemDescriptor.tsx
@@ -1,6 +1,6 @@
import { Flex } from '../../../primitives'
import {
- ALIGN_CENTER,
+ ALIGN_FLEX_START,
DIRECTION_ROW,
FLEX_AUTO,
JUSTIFY_SPACE_BETWEEN,
@@ -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'
@@ -36,7 +36,9 @@ export const ListItemDescriptor = (
>
{description}
- {content}
+
+ {content}
+
)
}
diff --git a/components/src/molecules/DropdownMenu/index.tsx b/components/src/molecules/DropdownMenu/index.tsx
index d82aa20b4f8..30a02209121 100644
--- a/components/src/molecules/DropdownMenu/index.tsx
+++ b/components/src/molecules/DropdownMenu/index.tsx
@@ -9,7 +9,6 @@ import {
DIRECTION_COLUMN,
DIRECTION_ROW,
JUSTIFY_SPACE_BETWEEN,
- NO_WRAP,
OVERFLOW_AUTO,
OVERFLOW_HIDDEN,
POSITION_ABSOLUTE,
@@ -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;
`}
>
-
+
{currentOption.name}
@@ -311,3 +307,12 @@ export function DropdownMenu(props: DropdownMenuProps): JSX.Element {
)
}
+
+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;
+`
diff --git a/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx b/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx
new file mode 100644
index 00000000000..03c274ce104
--- /dev/null
+++ b/protocol-designer/src/pages/ProtocolOverview/LiquidDefinitions.tsx
@@ -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 (
+
+
+ {t('liquid_defs')}
+
+
+ {Object.keys(allIngredientGroupFields).length > 0 ? (
+ Object.values(allIngredientGroupFields).map((liquid, index) => (
+
+
+
+
+ {liquid.name}
+
+
+ }
+ content={liquid.description ?? t('na')}
+ />
+
+ ))
+ ) : (
+
+ )}
+
+
+ )
+}
+
+const LIQUID_DEFINITION_TEXT = css`
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 3;
+ overflow: ${OVERFLOW_HIDDEN};
+ text-overflow: ellipsis;
+`
diff --git a/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx b/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx
new file mode 100644
index 00000000000..832cea4d800
--- /dev/null
+++ b/protocol-designer/src/pages/ProtocolOverview/__tests__/LiquidDefinitions.test.tsx
@@ -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()
+ return {
+ ...actual,
+ InfoScreen: () => mock InfoScreen
,
+ }
+})
+
+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) => {
+ return renderWithProviders(, {
+ i18nInstance: i18n,
+ })
+}
+
+describe('LiquidDefinitions', () => {
+ let props: ComponentProps
+
+ 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')
+ })
+})
diff --git a/protocol-designer/src/pages/ProtocolOverview/__tests__/ProtocolOverview.test.tsx b/protocol-designer/src/pages/ProtocolOverview/__tests__/ProtocolOverview.test.tsx
index e77515eaba0..471898802f6 100644
--- a/protocol-designer/src/pages/ProtocolOverview/__tests__/ProtocolOverview.test.tsx
+++ b/protocol-designer/src/pages/ProtocolOverview/__tests__/ProtocolOverview.test.tsx
@@ -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'
@@ -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 => {
@@ -72,6 +75,9 @@ describe('ProtocolOverview', () => {
vi.mocked(OffDeckThumbnail).mockReturnValue(
mock OffdeckThumbnail
)
+ vi.mocked(LiquidDefinitions).mockReturnValue(
+ mock LiquidDefinitions
+ )
})
it('renders each section with text', () => {
@@ -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')
})
diff --git a/protocol-designer/src/pages/ProtocolOverview/index.tsx b/protocol-designer/src/pages/ProtocolOverview/index.tsx
index 92c2ec27724..0009f4cf624 100644
--- a/protocol-designer/src/pages/ProtocolOverview/index.tsx
+++ b/protocol-designer/src/pages/ProtocolOverview/index.tsx
@@ -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'
@@ -16,7 +16,6 @@ import {
JUSTIFY_FLEX_END,
JUSTIFY_SPACE_BETWEEN,
LargeButton,
- LiquidIcon,
ListItem,
ListItemDescriptor,
Modal,
@@ -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'
@@ -223,8 +223,9 @@ export function ProtocolOverview(): JSX.Element {
const cancelModal = (): void => {
setShowExportWarningModal(false)
}
+
return (
- <>
+
{showEditMetadataModal ? (
{
@@ -449,41 +450,9 @@ export function ProtocolOverview(): JSX.Element {
) : null}
-
-
- {t('liquid_defs')}
-
-
- {Object.keys(allIngredientGroupFields).length > 0 ? (
- Object.values(allIngredientGroupFields).map(
- (liquid, index) => (
-
-
-
-
- {liquid.name}
-
-
- }
- content={liquid.description ?? t('na')}
- />
-
- )
- )
- ) : (
-
- )}
-
-
+
@@ -562,7 +531,7 @@ export function ProtocolOverview(): JSX.Element {
- >
+
)
}