Skip to content

Commit

Permalink
refactor(protocol-designer): tiprack option redesign to not have scro…
Browse files Browse the repository at this point in the history
…ll (#15141)

closes RQA-2681
  • Loading branch information
jerader authored and Carlos-fernandez committed Jun 3, 2024
1 parent 088f65b commit 2b0cdc3
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 47 deletions.
5 changes: 4 additions & 1 deletion components/src/forms/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ function DropdownIndicator(
[styles.flipped]: props.selectProps.menuIsOpen,
})}
>
<Icon name="menu-down" className={cx(styles.dropdown_indicator_icon)} />
<Icon
name="menu-down-pd"
className={cx(styles.dropdown_indicator_icon)}
/>
</div>
</reactSelectComponents.DropdownIndicator>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,99 @@
import * as React from 'react'
import { useTranslation } from 'react-i18next'
import { css } from 'styled-components'
import {
Flex,
Text,
Icon,
DIRECTION_ROW,
COLORS,
SPACING,
ALIGN_CENTER,
StyledText,
BORDERS,
useHoverTooltip,
Tooltip,
} from '@opentrons/components'

interface TiprackOptionProps {
onClick: React.MouseEventHandler
isSelected: boolean
isDisabled: boolean
text: React.ReactNode
}
export function TiprackOption(props: TiprackOptionProps): JSX.Element {
const { text, onClick, isSelected } = props
const { text, onClick, isSelected, isDisabled } = props
const { t } = useTranslation('tooltip')
const [targetProps, tooltipProps] = useHoverTooltip()

const OPTION_STYLE = css`
background-color: ${COLORS.white};
border-radius: ${BORDERS.borderRadius8};
border: 1px ${BORDERS.styleSolid} ${COLORS.grey30};
&:hover {
background-color: ${COLORS.grey10};
border: 1px ${BORDERS.styleSolid} ${COLORS.grey35};
}
&:focus {
outline: 2px ${BORDERS.styleSolid} ${COLORS.blue50};
outline-offset: 3px;
}
`

const OPTION_SELECTED_STYLE = css`
${OPTION_STYLE}
background-color: ${COLORS.blue10};
border: 1px ${BORDERS.styleSolid} ${COLORS.blue50};
&:hover {
border: 1px ${BORDERS.styleSolid} ${COLORS.blue50};
box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2);
}
`

const OPTION_DISABLED_STYLE = css`
${OPTION_STYLE}
background-color: ${COLORS.white};
border: 1px ${BORDERS.styleSolid} ${COLORS.grey30};
&:hover {
border: 1px ${BORDERS.styleSolid} ${COLORS.grey30};
background-color: ${COLORS.white};
}
`

let optionStyle
if (isDisabled) {
optionStyle = OPTION_DISABLED_STYLE
} else if (isSelected) {
optionStyle = OPTION_SELECTED_STYLE
} else {
optionStyle = OPTION_STYLE
}

return (
<Flex
aria-label={`TiprackOption_flex_${text}`}
cursor="pointer"
onClick={onClick}
flexDirection={DIRECTION_ROW}
padding={SPACING.spacing6}
width="15rem"
alignItems={ALIGN_CENTER}
gridGap={SPACING.spacing4}
>
<Icon
aria-label={`TiprackOption_${
isSelected ? 'checkbox-marked' : 'checkbox-blank-outline'
}`}
color={isSelected ? COLORS.blue50 : COLORS.grey50}
size="1.25rem"
name={isSelected ? 'checkbox-marked' : 'checkbox-blank-outline'}
/>
<Text fontSize="0.75rem">{text}</Text>
</Flex>
<>
<Flex
aria-label={`TiprackOption_flex_${text}`}
onClick={isDisabled ? undefined : onClick}
flexDirection={DIRECTION_ROW}
alignItems={ALIGN_CENTER}
width="13.5rem"
css={optionStyle}
padding={SPACING.spacing8}
border={
isSelected && !isDisabled
? BORDERS.activeLineBorder
: BORDERS.lineBorder
}
borderRadius={BORDERS.borderRadius8}
cursor={isDisabled ? 'auto' : 'pointer'}
{...targetProps}
>
<StyledText as="label">{text}</StyledText>
</Flex>
{isDisabled ? (
<Tooltip {...tooltipProps}>{t('disabled_no_space_pipette')}</Tooltip>
) : null}
</>
)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react'
import { Flex, DIRECTION_COLUMN } from '@opentrons/components'
import { Flex, DIRECTION_COLUMN, SPACING } from '@opentrons/components'
import { TiprackOption } from './TiprackOption'
import type { Mount } from '@opentrons/components'
import type { FormPipettesByMount } from '../../../step-forms'
Expand Down Expand Up @@ -30,21 +30,32 @@ export const TiprackSelect = (

return (
<Flex height="15rem" overflowY="scroll" flexDirection={DIRECTION_COLUMN}>
{tiprackOptions.map(option => (
<TiprackOption
isSelected={selectedValues.includes(option.value)}
key={option.name}
text={option.name}
onClick={() => {
const updatedValues = selectedValues?.includes(option.value)
? selectedValues.filter(value => value !== option.value)
: [...(selectedValues ?? []), option.value]
onSetFieldValue(
`pipettesByMount.${mount}.tiprackDefURI`,
updatedValues.slice(0, 3)
)
}}
/>
{tiprackOptions.map((option, index) => (
<Flex
marginBottom={SPACING.spacing4}
width="max-width"
key={`${option.name}_${index}`}
overflow="hidden"
>
<TiprackOption
isDisabled={
selectedValues?.length === 3 &&
!selectedValues.includes(option.value)
}
isSelected={selectedValues.includes(option.value)}
key={option.name}
text={option.name}
onClick={() => {
const updatedValues = selectedValues?.includes(option.value)
? selectedValues.filter(value => value !== option.value)
: [...(selectedValues ?? []), option.value]
onSetFieldValue(
`pipettesByMount.${mount}.tiprackDefURI`,
updatedValues.slice(0, 3)
)
}}
/>
</Flex>
))}
</Flex>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from 'react'
import { vi, describe, beforeEach, it, expect } from 'vitest'
import { screen } from '@testing-library/react'
import { BORDERS, COLORS } from '@opentrons/components'
import { fireEvent, screen } from '@testing-library/react'
import { renderWithProviders } from '../../../../__testing-utils__'
import { COLORS } from '@opentrons/components'
import { TiprackOption } from '../TiprackOption'

const render = (props: React.ComponentProps<typeof TiprackOption>) => {
Expand All @@ -15,22 +15,35 @@ describe('TiprackOption', () => {
props = {
onClick: vi.fn(),
isSelected: true,
isDisabled: false,
text: 'mockText',
}
})
it('renders a selected tiprack option', () => {
render(props)
screen.getByText('mockText')
expect(screen.getByLabelText('TiprackOption_checkbox-marked')).toHaveStyle(
`color: ${COLORS.blue50}`
expect(screen.getByLabelText('TiprackOption_flex_mockText')).toHaveStyle(
`background-color: ${COLORS.blue10}`
)
fireEvent.click(screen.getByText('mockText'))
expect(props.onClick).toHaveBeenCalled()
})
it('renders an unselected tiprack option', () => {
props.isSelected = false
render(props)
screen.getByText('mockText')
expect(
screen.getByLabelText('TiprackOption_checkbox-blank-outline')
).toHaveStyle(`color: ${COLORS.grey50}`)
expect(screen.getByLabelText('TiprackOption_flex_mockText')).toHaveStyle(
`background-color: ${COLORS.white}`
)
fireEvent.click(screen.getByText('mockText'))
expect(props.onClick).toHaveBeenCalled()
})
it('renders a disabled tiprack option', () => {
props.isSelected = false
props.isDisabled = true
render(props)
expect(screen.getByLabelText('TiprackOption_flex_mockText')).toHaveStyle(
`border: 1px ${BORDERS.styleSolid} ${COLORS.grey30}`
)
})
})

0 comments on commit 2b0cdc3

Please sign in to comment.