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(app): refine file upload, input field components #15097

Merged
merged 5 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/src/assets/localization/en/device_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@
"update_robot_software": "Update robot software manually with a local file (.zip)",
"updating": "Updating",
"update_requires_restarting_robot": "Updating the robot software requires restarting the robot",
"upload_custom_logo_description": "Upload a logo for the robot to display during boot up. If no file is uploaded, we will display an anonymous logo.",
"upload_custom_logo_description": "Upload a logo for the robot to display during boot up.",
"upload_custom_logo_dimensions": "The logo must fit within dimensions 1024 x 600 and be a PNG file (.png).",
"upload_custom_logo": "Upload custom logo",
"usage_settings": "Usage Settings",
Expand Down
2 changes: 1 addition & 1 deletion app/src/atoms/InputField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ function Input(props: InputFieldProps): JSX.Element {
`

const TITLE_STYLE = css`
color: ${hasError ? COLORS.red50 : COLORS.black90};
color: ${COLORS.black90};
padding-bottom: ${SPACING.spacing8};
text-align: ${textAlign};
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
Expand Down
31 changes: 31 additions & 0 deletions app/src/molecules/FileUpload/FileUpload.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from 'react'
import testFile from './__tests__/test-file.png'
import { FileUpload } from '.'

import type { StoryFn, Meta } from '@storybook/react'

const file = new File([testFile], 'a-file-to-test.png')
const handleClick = (): void => console.log('clicked the file')

export default {
title: 'App/Molecules/FileUpload',
component: FileUpload,
} as Meta

const FileUploadTemplate: StoryFn<
React.ComponentProps<typeof FileUpload>
> = args => <FileUpload {...args} />

export const FileUploadComponent = FileUploadTemplate.bind({})
FileUploadComponent.args = {
file,
fileError: null,
handleClick,
}

export const FileUploadError = FileUploadTemplate.bind({})
FileUploadError.args = {
file,
fileError: 'a terrible file',
handleClick,
}
42 changes: 42 additions & 0 deletions app/src/molecules/FileUpload/__tests__/FileUpload.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import * as React from 'react'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { screen } from '@testing-library/react'

import { renderWithProviders } from '../../../__testing-utils__'
import { i18n } from '../../../i18n'
import { FileUpload } from '..'
import testFile from './test-file.png'

const render = (props: React.ComponentProps<typeof FileUpload>) => {
return renderWithProviders(<FileUpload {...props} />, {
i18nInstance: i18n,
})[0]
}

const handleClick = vi.fn()

describe('FileUpload', () => {
let props: React.ComponentProps<typeof FileUpload>

beforeEach(() => {
const file = new File([testFile], 'a-file-to-test.png')

props = {
file,
fileError: null,
handleClick,
}
})
it('renders file upload', () => {
render(props)
screen.getByText('a-file-to-test.png')
const removeFile = screen.getByLabelText('remove_file')
removeFile.click()
expect(handleClick).toBeCalled()
})

it('renders file upload error', () => {
render({ ...props, fileError: 'oops this is a bad file' })
screen.getByText('oops this is a bad file')
})
})
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 14 additions & 2 deletions app/src/molecules/FileUpload/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
JUSTIFY_SPACE_BETWEEN,
SPACING,
StyledText,
truncateString,
} from '@opentrons/components'

const FILE_UPLOAD_STYLE = css`
Expand All @@ -23,6 +24,13 @@ const FILE_UPLOAD_STYLE = css`
}
`

const FILE_UPLOAD_FOCUS_VISIBLE = css`
&:focus-visible {
border-radius: ${BORDERS.borderRadius4};
box-shadow: 0 0 0 ${SPACING.spacing2} ${COLORS.blue50};
}
`

interface FileUploadProps {
file: File
fileError: string | null
Expand All @@ -36,7 +44,11 @@ export function FileUpload({
}: FileUploadProps): JSX.Element {
return (
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing4}>
<Btn onClick={handleClick} aria-label="remove_file">
<Btn
onClick={handleClick}
aria-label="remove_file"
css={FILE_UPLOAD_FOCUS_VISIBLE}
>
<Flex
alignItems={ALIGN_CENTER}
backgroundColor={fileError == null ? COLORS.grey20 : COLORS.red30}
Expand All @@ -46,7 +58,7 @@ export function FileUpload({
padding={SPACING.spacing8}
css={FILE_UPLOAD_STYLE}
>
<StyledText as="p">{file.name}</StyledText>
<StyledText as="p">{truncateString(file.name, 34, 19)}</StyledText>
<Icon name="close" size="1.5rem" borderRadius="50%" />
</Flex>
</Btn>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export function FactoryModeSlideout({
<Controller
control={control}
name="factoryModeInput"
render={({ field, fieldState }) => (
render={({ field }) => (
<InputField
id="factoryModeInput"
name="factoryModeInput"
Expand All @@ -234,21 +234,16 @@ export function FactoryModeSlideout({
clearErrors()
}}
value={field.value}
error={fieldState.error?.message && ' '}
error={
errors.factoryModeInput != null
? errors.factoryModeInput.message
: null
}
onBlur={field.onBlur}
title={t('enter_factory_password')}
/>
)}
/>
{errors.factoryModeInput != null ? (
<StyledText
as="label"
color={COLORS.red50}
marginTop={SPACING.spacing4}
>
{errors.factoryModeInput.message}
</StyledText>
) : null}
</Flex>
) : null}
{currentStep === 2 ? (
Expand Down
Loading