Skip to content

Commit 4a2f61f

Browse files
authored
refactor(app): refine file upload, input field components (#15097)
adds focus state, file name truncation, test, and story for FileUpload component. removes InputField title error color. removes anonymous logo copy. closes PLAT-292, RQA-2689, RQA-2690, RQA-2701
1 parent a78ea71 commit 4a2f61f

File tree

7 files changed

+95
-15
lines changed

7 files changed

+95
-15
lines changed

app/src/assets/localization/en/device_settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@
294294
"update_robot_software": "Update robot software manually with a local file (.zip)",
295295
"updating": "Updating",
296296
"update_requires_restarting_robot": "Updating the robot software requires restarting the robot",
297-
"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.",
297+
"upload_custom_logo_description": "Upload a logo for the robot to display during boot up.",
298298
"upload_custom_logo_dimensions": "The logo must fit within dimensions 1024 x 600 and be a PNG file (.png).",
299299
"upload_custom_logo": "Upload custom logo",
300300
"usage_settings": "Usage Settings",

app/src/atoms/InputField/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ function Input(props: InputFieldProps): JSX.Element {
214214
`
215215

216216
const TITLE_STYLE = css`
217-
color: ${hasError ? COLORS.red50 : COLORS.black90};
217+
color: ${COLORS.black90};
218218
padding-bottom: ${SPACING.spacing8};
219219
text-align: ${textAlign};
220220
@media ${RESPONSIVENESS.touchscreenMediaQuerySpecs} {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import * as React from 'react'
2+
import testFile from './__tests__/test-file.png'
3+
import { FileUpload } from '.'
4+
5+
import type { StoryFn, Meta } from '@storybook/react'
6+
7+
const file = new File([testFile], 'a-file-to-test.png')
8+
const handleClick = (): void => console.log('clicked the file')
9+
10+
export default {
11+
title: 'App/Molecules/FileUpload',
12+
component: FileUpload,
13+
} as Meta
14+
15+
const FileUploadTemplate: StoryFn<
16+
React.ComponentProps<typeof FileUpload>
17+
> = args => <FileUpload {...args} />
18+
19+
export const FileUploadComponent = FileUploadTemplate.bind({})
20+
FileUploadComponent.args = {
21+
file,
22+
fileError: null,
23+
handleClick,
24+
}
25+
26+
export const FileUploadError = FileUploadTemplate.bind({})
27+
FileUploadError.args = {
28+
file,
29+
fileError: 'a terrible file',
30+
handleClick,
31+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import * as React from 'react'
2+
import { beforeEach, describe, expect, it, vi } from 'vitest'
3+
import { screen } from '@testing-library/react'
4+
5+
import { renderWithProviders } from '../../../__testing-utils__'
6+
import { i18n } from '../../../i18n'
7+
import { FileUpload } from '..'
8+
import testFile from './test-file.png'
9+
10+
const render = (props: React.ComponentProps<typeof FileUpload>) => {
11+
return renderWithProviders(<FileUpload {...props} />, {
12+
i18nInstance: i18n,
13+
})[0]
14+
}
15+
16+
const handleClick = vi.fn()
17+
18+
describe('FileUpload', () => {
19+
let props: React.ComponentProps<typeof FileUpload>
20+
21+
beforeEach(() => {
22+
const file = new File([testFile], 'a-file-to-test.png')
23+
24+
props = {
25+
file,
26+
fileError: null,
27+
handleClick,
28+
}
29+
})
30+
it('renders file upload', () => {
31+
render(props)
32+
screen.getByText('a-file-to-test.png')
33+
const removeFile = screen.getByLabelText('remove_file')
34+
removeFile.click()
35+
expect(handleClick).toBeCalled()
36+
})
37+
38+
it('renders file upload error', () => {
39+
render({ ...props, fileError: 'oops this is a bad file' })
40+
screen.getByText('oops this is a bad file')
41+
})
42+
})
939 KB
Loading

app/src/molecules/FileUpload/index.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
JUSTIFY_SPACE_BETWEEN,
1313
SPACING,
1414
StyledText,
15+
truncateString,
1516
} from '@opentrons/components'
1617

1718
const FILE_UPLOAD_STYLE = css`
@@ -23,6 +24,13 @@ const FILE_UPLOAD_STYLE = css`
2324
}
2425
`
2526

27+
const FILE_UPLOAD_FOCUS_VISIBLE = css`
28+
&:focus-visible {
29+
border-radius: ${BORDERS.borderRadius4};
30+
box-shadow: 0 0 0 ${SPACING.spacing2} ${COLORS.blue50};
31+
}
32+
`
33+
2634
interface FileUploadProps {
2735
file: File
2836
fileError: string | null
@@ -36,7 +44,11 @@ export function FileUpload({
3644
}: FileUploadProps): JSX.Element {
3745
return (
3846
<Flex flexDirection={DIRECTION_COLUMN} gridGap={SPACING.spacing4}>
39-
<Btn onClick={handleClick} aria-label="remove_file">
47+
<Btn
48+
onClick={handleClick}
49+
aria-label="remove_file"
50+
css={FILE_UPLOAD_FOCUS_VISIBLE}
51+
>
4052
<Flex
4153
alignItems={ALIGN_CENTER}
4254
backgroundColor={fileError == null ? COLORS.grey20 : COLORS.red30}
@@ -46,7 +58,7 @@ export function FileUpload({
4658
padding={SPACING.spacing8}
4759
css={FILE_UPLOAD_STYLE}
4860
>
49-
<StyledText as="p">{file.name}</StyledText>
61+
<StyledText as="p">{truncateString(file.name, 34, 19)}</StyledText>
5062
<Icon name="close" size="1.5rem" borderRadius="50%" />
5163
</Flex>
5264
</Btn>

app/src/organisms/Devices/RobotSettings/AdvancedTab/AdvancedTabSlideouts/FactoryModeSlideout.tsx

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ export function FactoryModeSlideout({
224224
<Controller
225225
control={control}
226226
name="factoryModeInput"
227-
render={({ field, fieldState }) => (
227+
render={({ field }) => (
228228
<InputField
229229
id="factoryModeInput"
230230
name="factoryModeInput"
@@ -234,21 +234,16 @@ export function FactoryModeSlideout({
234234
clearErrors()
235235
}}
236236
value={field.value}
237-
error={fieldState.error?.message && ' '}
237+
error={
238+
errors.factoryModeInput != null
239+
? errors.factoryModeInput.message
240+
: null
241+
}
238242
onBlur={field.onBlur}
239243
title={t('enter_factory_password')}
240244
/>
241245
)}
242246
/>
243-
{errors.factoryModeInput != null ? (
244-
<StyledText
245-
as="label"
246-
color={COLORS.red50}
247-
marginTop={SPACING.spacing4}
248-
>
249-
{errors.factoryModeInput.message}
250-
</StyledText>
251-
) : null}
252247
</Flex>
253248
) : null}
254249
{currentStep === 2 ? (

0 commit comments

Comments
 (0)